From f311e3eddee4a4c688cb2a1f03f89d5e6f1d5bc2 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 9 Apr 2021 11:11:41 -0300 Subject: [PATCH 1/9] Fix selection feedback in indexed when mask color w/alpha=0 (fix #1412, fix #1667) Also reported recently here (and probably in several other places): https://community.aseprite.org/t/8462 --- src/app/ui/editor/tool_loop_impl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index 9d0c9ab78..5d661e7fc 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -247,9 +247,8 @@ public: RgbMap* getRgbMap() override { if (!m_rgbMap) { Sprite::RgbMapFor forLayer = - ((!m_layer || - m_layer->isBackground() || - m_sprite->pixelFormat() == IMAGE_RGB) ? + (((m_layer && m_layer->isBackground()) || + (m_sprite->pixelFormat() == IMAGE_RGB)) ? Sprite::RgbMapFor::OpaqueLayer: Sprite::RgbMapFor::TransparentLayer); m_rgbMap = m_sprite->rgbMap(m_frame, forLayer); From cff3475941a39d34bfb9a3d83aa2b9811471b0ff Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 9 Apr 2021 12:09:09 -0300 Subject: [PATCH 2/9] Don't show warning when saving indexed tga w/transparent pal entries --- src/app/file/tga_format.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/file/tga_format.cpp b/src/app/file/tga_format.cpp index 2e58b01bc..b52021ad7 100644 --- a/src/app/file/tga_format.cpp +++ b/src/app/file/tga_format.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -52,7 +52,8 @@ class TgaFormat : public FileFormat { FILE_SUPPORT_GRAY | FILE_SUPPORT_INDEXED | FILE_SUPPORT_SEQUENCES | - FILE_SUPPORT_GET_FORMAT_OPTIONS; + FILE_SUPPORT_GET_FORMAT_OPTIONS | + FILE_SUPPORT_PALETTE_WITH_ALPHA; } bool onLoad(FileOp* fop) override; From 5053443d21a5b80dd1f6a7159456a8e9e2027066 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 9 Apr 2021 12:09:45 -0300 Subject: [PATCH 3/9] Load indexed tga w/transparent pal entries as transparent layer Before this we were loading the file with a Background layer with a transparent palette entry. --- src/app/file/tga_format.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/file/tga_format.cpp b/src/app/file/tga_format.cpp index b52021ad7..bc2a4a7e8 100644 --- a/src/app/file/tga_format.cpp +++ b/src/app/file/tga_format.cpp @@ -149,8 +149,10 @@ bool TgaFormat::onLoad(FileOp* fop) tga::getr(c), tga::getg(c), tga::getb(c)); - if (tga::geta(c) < 255) + if (tga::geta(c) < 255) { fop->sequenceSetAlpha(i, tga::geta(c)); + fop->sequenceSetHasAlpha(true); // Is a transparent sprite + } } } // Generate grayscale palette From 3769d9112544c6101eee1722f5a185fa0b64b377 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 9 Apr 2021 16:22:50 -0300 Subject: [PATCH 4/9] [lua] Add Sprite.pixelRatio property Feature request: https://community.aseprite.org/t/8627 --- src/app/script/sprite_class.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/app/script/sprite_class.cpp b/src/app/script/sprite_class.cpp index 070a7b5fb..ba0d415db 100644 --- a/src/app/script/sprite_class.cpp +++ b/src/app/script/sprite_class.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2015-2018 David Capello // // This program is distributed under the terms of @@ -21,6 +21,7 @@ #include "app/cmd/remove_tag.h" #include "app/cmd/set_grid_bounds.h" #include "app/cmd/set_mask.h" +#include "app/cmd/set_pixel_ratio.h" #include "app/cmd/set_sprite_size.h" #include "app/cmd/set_transparent_color.h" #include "app/color_spaces.h" @@ -774,6 +775,23 @@ int Sprite_set_gridBounds(lua_State* L) return 0; } +int Sprite_get_pixelRatio(lua_State* L) +{ + const auto sprite = get_docobj(L, 1); + push_obj(L, sprite->pixelRatio()); + return 1; +} + +int Sprite_set_pixelRatio(lua_State* L) +{ + auto sprite = get_docobj(L, 1); + const gfx::Size pixelRatio = convert_args_into_size(L, 2); + Tx tx; + tx(new cmd::SetPixelRatio(sprite, pixelRatio)); + tx.commit(); + return 0; +} + const luaL_Reg Sprite_methods[] = { { "__eq", Sprite_eq }, { "resize", Sprite_resize }, @@ -824,6 +842,7 @@ const Property Sprite_properties[] = { { "transparentColor", Sprite_get_transparentColor, Sprite_set_transparentColor }, { "bounds", Sprite_get_bounds, nullptr }, { "gridBounds", Sprite_get_gridBounds, Sprite_set_gridBounds }, + { "pixelRatio", Sprite_get_pixelRatio, Sprite_set_pixelRatio }, { nullptr, nullptr, nullptr } }; From 2df3cd8a80d0b9ebbfad48847eb4ccd0e8526811 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 9 Apr 2021 17:28:20 -0300 Subject: [PATCH 5/9] [lua] Add app.command.ImportSpriteSheet() Feature request: https://community.aseprite.org/t/8482 --- src/app/CMakeLists.txt | 4 +- src/app/commands/cmd_import_sprite_sheet.cpp | 105 ++++++++++++------- src/app/commands/commands_list.h | 4 +- src/app/commands/new_params.cpp | 22 +++- 4 files changed, 94 insertions(+), 41 deletions(-) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 9538c2328..5e578947f 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -1,5 +1,5 @@ # Aseprite -# Copyright (C) 2018-2020 Igara Studio S.A. +# Copyright (C) 2018-2021 Igara Studio S.A. # Copyright (C) 2001-2018 David Capello # Generate a ui::Widget for each widget in a XML file @@ -231,7 +231,6 @@ if(ENABLE_UI) commands/cmd_goto_tab.cpp commands/cmd_grid.cpp commands/cmd_home.cpp - commands/cmd_import_sprite_sheet.cpp commands/cmd_invert_mask.cpp commands/cmd_keyboard_shortcuts.cpp commands/cmd_launch.cpp @@ -503,6 +502,7 @@ add_library(app-lib commands/cmd_export_sprite_sheet.cpp commands/cmd_flatten_layers.cpp commands/cmd_flip.cpp + commands/cmd_import_sprite_sheet.cpp commands/cmd_layer_from_background.cpp commands/cmd_load_palette.cpp commands/cmd_merge_down_layer.cpp diff --git a/src/app/commands/cmd_import_sprite_sheet.cpp b/src/app/commands/cmd_import_sprite_sheet.cpp index 9a4b2700d..89861bb57 100644 --- a/src/app/commands/cmd_import_sprite_sheet.cpp +++ b/src/app/commands/cmd_import_sprite_sheet.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -12,7 +12,7 @@ #include "app/app.h" #include "app/commands/command.h" #include "app/commands/commands.h" -#include "app/commands/params.h" +#include "app/commands/new_params.h" #include "app/context.h" #include "app/context_access.h" #include "app/doc_access.h" @@ -44,6 +44,14 @@ namespace app { using namespace ui; +struct ImportSpriteSheetParams : public NewParams { + Param ui { this, true, "ui" }; + Param type { this, app::SpriteSheetType::None, "type" }; + Param frameBounds { this, gfx::Rect(0, 0, 0, 0), "frameBounds" }; + Param padding { this, gfx::Size(0, 0), "padding" }; + Param partialTiles { this, false, "partialTiles" }; +}; + class ImportSpriteSheetWindow : public app::gen::ImportSpriteSheet , public SelectBoxDelegate { public: @@ -127,6 +135,17 @@ public: return m_padding; } + void updateParams(ImportSpriteSheetParams& params) { + params.type(sheetTypeValue()); + params.frameBounds(frameBounds()); + params.partialTiles(partialTilesValue()); + + if (paddingEnabledValue()) + params.padding(paddingThickness()); + else + params.padding(gfx::Size(0, 0)); + } + protected: void onSheetTypeChange() { @@ -372,7 +391,7 @@ private: DocumentPreferences* m_docPref; }; -class ImportSpriteSheetCommand : public Command { +class ImportSpriteSheetCommand : public CommandWithNewParams { public: ImportSpriteSheetCommand(); @@ -381,29 +400,44 @@ protected: }; ImportSpriteSheetCommand::ImportSpriteSheetCommand() - : Command(CommandId::ImportSpriteSheet(), CmdRecordableFlag) + : CommandWithNewParams(CommandId::ImportSpriteSheet(), CmdRecordableFlag) { } void ImportSpriteSheetCommand::onExecute(Context* context) { - ImportSpriteSheetWindow window(context); + Doc* document; + auto& params = this->params(); - window.openWindowInForeground(); - if (!window.ok()) - return; +#ifdef ENABLE_UI + if (context->isUIAvailable() && params.ui()) { + // TODO use params as input values for the ImportSpriteSheetWindow - Doc* document = window.document(); - DocumentPreferences* docPref = window.docPref(); - gfx::Rect frameBounds = window.frameBounds(); - gfx::Size padThickness = window.paddingThickness(); - bool partialTiles = window.partialTilesValue(); - bool paddingEnable = window.paddingEnabledValue(); - auto sheetType = window.sheetTypeValue(); + ImportSpriteSheetWindow window(context); + window.openWindowInForeground(); + if (!window.ok()) + return; - ASSERT(document); - if (!document) - return; + document = window.document(); + if (!document) + return; + + window.updateParams(params); + + DocumentPreferences* docPref = window.docPref(); + docPref->importSpriteSheet.type(params.type()); + docPref->importSpriteSheet.bounds(params.frameBounds()); + docPref->importSpriteSheet.partialTiles(params.partialTiles()); + docPref->importSpriteSheet.paddingBounds(params.padding()); + docPref->importSpriteSheet.paddingEnabled(window.paddingEnabledValue()); + } + else // We import the sprite sheet from the active document if there is no UI +#endif + { + document = context->activeDocument(); + if (!document) + return; + } // The list of frames imported from the sheet std::vector animation; @@ -411,39 +445,44 @@ void ImportSpriteSheetCommand::onExecute(Context* context) try { Sprite* sprite = document->sprite(); frame_t currentFrame = context->activeSite().frame(); + gfx::Rect frameBounds = params.frameBounds(); + const gfx::Size padding = params.padding(); render::Render render; render.setNewBlend(Preferences::instance().experimental.newBlend()); + if (frameBounds.isEmpty()) + frameBounds = sprite->bounds(); + // Each sprite in the sheet std::vector tileRects; int widthStop = sprite->width(); int heightStop = sprite->height(); - if (partialTiles) { + if (params.partialTiles()) { widthStop += frameBounds.w-1; heightStop += frameBounds.h-1; } - switch (sheetType) { + switch (params.type()) { case app::SpriteSheetType::Horizontal: - for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { + for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) { tileRects.push_back(gfx::Rect(x, frameBounds.y, frameBounds.w, frameBounds.h)); } break; case app::SpriteSheetType::Vertical: - for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { + for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) { tileRects.push_back(gfx::Rect(frameBounds.x, y, frameBounds.w, frameBounds.h)); } break; case app::SpriteSheetType::Rows: - for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { - for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { + for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) { + for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) { tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h)); } } break; case app::SpriteSheetType::Columns: - for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { - for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { + for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) { + for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) { tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h)); } } @@ -504,21 +543,15 @@ void ImportSpriteSheetCommand::onExecute(Context* context) api.setSpriteSize(sprite, frameBounds.w, frameBounds.h); tx.commit(); - - ASSERT(docPref); - if (docPref) { - docPref->importSpriteSheet.type(sheetType); - docPref->importSpriteSheet.bounds(frameBounds); - docPref->importSpriteSheet.partialTiles(partialTiles); - docPref->importSpriteSheet.paddingBounds(padThickness); - docPref->importSpriteSheet.paddingEnabled(paddingEnable); - } } catch (...) { throw; } - update_screen_for_document(document); +#ifdef ENABLE_UI + if (context->isUIAvailable()) + update_screen_for_document(document); +#endif } Command* CommandFactory::createImportSpriteSheetCommand() diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h index 03b5ea124..760f3bbaa 100644 --- a/src/app/commands/commands_list.h +++ b/src/app/commands/commands_list.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -22,6 +22,7 @@ FOR_EACH_COMMAND(ExportSpriteSheet) FOR_EACH_COMMAND(FlattenLayers) FOR_EACH_COMMAND(Flip) FOR_EACH_COMMAND(HueSaturation) +FOR_EACH_COMMAND(ImportSpriteSheet) FOR_EACH_COMMAND(InvertColor) FOR_EACH_COMMAND(LayerFromBackground) FOR_EACH_COMMAND(LoadPalette) @@ -86,7 +87,6 @@ FOR_EACH_COMMAND(GotoPreviousLayer) FOR_EACH_COMMAND(GotoPreviousTab) FOR_EACH_COMMAND(GridSettings) FOR_EACH_COMMAND(Home) -FOR_EACH_COMMAND(ImportSpriteSheet) FOR_EACH_COMMAND(InvertMask) FOR_EACH_COMMAND(KeyboardShortcuts) FOR_EACH_COMMAND(Launch) diff --git a/src/app/commands/new_params.cpp b/src/app/commands/new_params.cpp index 1281b52b7..0dd0f6309 100644 --- a/src/app/commands/new_params.cpp +++ b/src/app/commands/new_params.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -24,6 +24,7 @@ #include "filters/outline_filter.h" #include "filters/tiled_mode.h" #include "gfx/rect.h" +#include "gfx/size.h" #ifdef ENABLE_SCRIPTING #include "app/script/engine.h" @@ -61,6 +62,19 @@ void Param::fromString(const std::string& value) setValue(value); } +template<> +void Param::fromString(const std::string& value) +{ + gfx::Size size; + std::vector parts; + base::split_string(value, parts, ","); + if (parts.size() == 2) { + size.w = base::convert_to(parts[0]); + size.h = base::convert_to(parts[1]); + } + setValue(size); +} + template<> void Param::fromString(const std::string& value) { @@ -241,6 +255,12 @@ void Param::fromLua(lua_State* L, int index) setValue(std::string()); } +template<> +void Param::fromLua(lua_State* L, int index) +{ + setValue(script::convert_args_into_size(L, index)); +} + template<> void Param::fromLua(lua_State* L, int index) { From 8d6f889e0e2fe64583fa3c8add04ed4f1ebf47e0 Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 31 Mar 2021 19:26:54 -0300 Subject: [PATCH 6/9] Add option to keep the timeline selection when we draw on the canvas --- data/pref.xml | 5 ++++- data/strings/en.ini | 5 +++++ data/widgets/options.xml | 4 +++- src/app/ui/timeline/timeline.cpp | 18 +++++++++++++----- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/data/pref.xml b/data/pref.xml index aadf8d462..bc9f500bf 100644 --- a/data/pref.xml +++ b/data/pref.xml @@ -1,6 +1,6 @@ - + @@ -171,6 +171,9 @@ zoom levels -->