From b96d8c8c300abf4eaa93b104a6f520acf11ed223 Mon Sep 17 00:00:00 2001 From: MorganDavid Date: Mon, 17 May 2021 17:42:23 +0100 Subject: [PATCH 1/5] Show user what is about to close (fix #2030) --- src/app/ui/doc_view.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/ui/doc_view.cpp b/src/app/ui/doc_view.cpp index 9766ce98a..4de9d498a 100644 --- a/src/app/ui/doc_view.cpp +++ b/src/app/ui/doc_view.cpp @@ -284,6 +284,9 @@ bool DocView::onCloseView(Workspace* workspace, bool quitting) { // see if the sprite has changes while (m_document->isModified()) { + // Show user what they are about to close + ctx->setActiveView(this); + // ask what want to do the user with the changes in the sprite int ret = Alert::show( fmt::format( From a2328a37935b261a3a78b0886e1f1d4c401fce34 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 7 Dec 2021 15:45:52 -0300 Subject: [PATCH 2/5] Restore the previous active DocView when we close the non-active sprite Fixes https://github.com/aseprite/aseprite/pull/2727#issuecomment-852524240 Close #2030, close #2727, close #3080, close #3089 Originally reported in: https://community.aseprite.org/t/preview-file-to-save-when-closing/2779 --- src/app/ui/doc_view.cpp | 76 +++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/app/ui/doc_view.cpp b/src/app/ui/doc_view.cpp index 4de9d498a..0af9e8051 100644 --- a/src/app/ui/doc_view.cpp +++ b/src/app/ui/doc_view.cpp @@ -54,6 +54,32 @@ namespace app { using namespace ui; +namespace { + +// Used to show a view temporarily (the one with the file to be +// closed) and restore the previous view. E.g. When we close the +// non-active sprite pressing the cross button in a sprite tab. +class SetRestoreDocView { +public: + SetRestoreDocView(UIContext* ctx, DocView* newView) + : m_ctx(ctx) + , m_oldView(ctx->activeView()) { + if (newView != m_oldView) + m_ctx->setActiveView(newView); + else + m_oldView = nullptr; + } + + ~SetRestoreDocView() { + if (m_oldView) + m_ctx->setActiveView(m_oldView); + } + +private: + UIContext* m_ctx; + DocView* m_oldView; +}; + class AppEditor : public Editor, public EditorObserver, public EditorCustomizationDelegate { @@ -192,6 +218,8 @@ public: } }; +} // anonymous namespace + DocView::DocView(Doc* document, Type type, DocViewPreviewDelegate* previewDelegate) : Box(VERTICAL) @@ -275,45 +303,41 @@ bool DocView::onCloseView(Workspace* workspace, bool quitting) } UIContext* ctx = UIContext::instance(); + SetRestoreDocView restoreView(ctx, this); bool save_it; bool try_again = true; while (try_again) { // This flag indicates if we have to sabe the sprite before to destroy it save_it = false; - { - // see if the sprite has changes - while (m_document->isModified()) { - // Show user what they are about to close - ctx->setActiveView(this); - // ask what want to do the user with the changes in the sprite - int ret = Alert::show( - fmt::format( - Strings::alerts_save_sprite_changes(), - m_document->name(), - (quitting ? Strings::alerts_save_sprite_changes_quitting(): - Strings::alerts_save_sprite_changes_closing()))); + // See if the sprite has changes + while (m_document->isModified()) { + // ask what want to do the user with the changes in the sprite + int ret = Alert::show( + fmt::format( + Strings::alerts_save_sprite_changes(), + m_document->name(), + (quitting ? Strings::alerts_save_sprite_changes_quitting(): + Strings::alerts_save_sprite_changes_closing()))); - if (ret == 1) { - // "save": save the changes - save_it = true; - break; - } - else if (ret != 2) { - // "cancel" or "ESC" */ - return false; // we back doing nothing - } - else { - // "discard" - break; - } + if (ret == 1) { + // "save": save the changes + save_it = true; + break; + } + else if (ret != 2) { + // "cancel" or "ESC" */ + return false; // we back doing nothing + } + else { + // "discard" + break; } } // Does we need to save the sprite? if (save_it) { - ctx->setActiveView(this); ctx->updateFlags(); Command* save_command = From e7575f237384b8afb2ed89e7dc2e7d9c45d9c05a Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 10 Dec 2021 22:35:37 -0300 Subject: [PATCH 3/5] [lua] Fix crash using app.ranges.images/editableImages collections (fix #3069) We were pushing invalid doc::Image objects to the Lua stack (push_docobj) instead of pushing a ImageObj related to the given cels in the active range. --- src/app/script/engine.h | 2 +- src/app/script/images_class.cpp | 28 ++++++++++++++++------------ src/app/script/range_class.cpp | 30 +++++++++++++++++------------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/app/script/engine.h b/src/app/script/engine.h index 3bc6b801b..562f256f2 100644 --- a/src/app/script/engine.h +++ b/src/app/script/engine.h @@ -134,6 +134,7 @@ namespace app { int push_image_iterator_function(lua_State* L, const doc::Image* image, int extraArgIndex); void push_brush(lua_State* L, const doc::BrushRef& brush); void push_cel_image(lua_State* L, doc::Cel* cel); + void push_cel_images(lua_State* L, const doc::ObjectIds& cels); void push_cels(lua_State* L, const doc::ObjectIds& cels); void push_cels(lua_State* L, doc::Layer* layer); void push_cels(lua_State* L, doc::Sprite* sprite); @@ -141,7 +142,6 @@ namespace app { void push_doc_range(lua_State* L, Site& site); void push_group_layers(lua_State* L, doc::LayerGroup* group); void push_image(lua_State* L, doc::Image* image); - void push_images(lua_State* L, const doc::ObjectIds& images); void push_layers(lua_State* L, const doc::ObjectIds& layers); void push_palette(lua_State* L, doc::Palette* palette); void push_plugin(lua_State* L, Extension* ext); diff --git a/src/app/script/images_class.cpp b/src/app/script/images_class.cpp index 9cab6dc67..b7b5f6b3c 100644 --- a/src/app/script/images_class.cpp +++ b/src/app/script/images_class.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -9,8 +9,9 @@ #endif #include "app/script/docobj.h" +#include "app/script/engine.h" #include "app/script/luacpp.h" -#include "doc/image.h" +#include "doc/cel.h" #include "doc/object_ids.h" namespace app { @@ -21,10 +22,10 @@ using namespace doc; namespace { struct ImagesObj { - ObjectIds images; + ObjectIds cels; - ImagesObj(const ObjectIds& images) - : images(images) { + ImagesObj(const ObjectIds& cels) + : cels(cels) { } ImagesObj(const ImagesObj&) = delete; @@ -40,7 +41,7 @@ int Images_gc(lua_State* L) int Images_len(lua_State* L) { auto obj = get_obj(L, 1); - lua_pushinteger(L, obj->images.size()); + lua_pushinteger(L, obj->cels.size()); return 1; } @@ -48,10 +49,13 @@ int Images_index(lua_State* L) { auto obj = get_obj(L, 1); const int i = lua_tointeger(L, 2); - if (i >= 1 && i <= obj->images.size()) - push_docobj(L, obj->images[i-1]); - else - lua_pushnil(L); + if (i >= 1 && i <= obj->cels.size()) { + if (auto cel = doc::get(obj->cels[i-1])) { + push_cel_image(L, cel); + return 1; + } + } + lua_pushnil(L); return 1; } @@ -72,9 +76,9 @@ void register_images_class(lua_State* L) REG_CLASS(L, Images); } -void push_images(lua_State* L, const ObjectIds& images) +void push_cel_images(lua_State* L, const ObjectIds& cels) { - push_new(L, images); + push_new(L, cels); } } // namespace script diff --git a/src/app/script/range_class.cpp b/src/app/script/range_class.cpp index 79b6b48d4..f048cf029 100644 --- a/src/app/script/range_class.cpp +++ b/src/app/script/range_class.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -203,31 +203,35 @@ int Range_get_cels(lua_State* L) int Range_get_images(lua_State* L) { auto obj = get_obj(L, 1); - std::set imagesSet; + std::set set; for (auto celId : obj->cels) { Cel* cel = check_docobj(L, doc::get(celId)); - imagesSet.insert(cel->image()->id()); + if (Cel* link = cel->link()) + cel = link; + set.insert(cel->id()); } - ObjectIds images; - for (auto imageId : imagesSet) - images.push_back(imageId); - push_images(L, images); + ObjectIds cels; + for (auto celId : set) + cels.push_back(celId); + push_cel_images(L, cels); return 1; } int Range_get_editableImages(lua_State* L) { auto obj = get_obj(L, 1); - std::set imagesSet; + std::set set; for (auto celId : obj->cels) { Cel* cel = check_docobj(L, doc::get(celId)); + if (Cel* link = cel->link()) + cel = link; if (cel->layer()->isEditable()) - imagesSet.insert(cel->image()->id()); + set.insert(cel->id()); } - ObjectIds images; - for (auto imageId : imagesSet) - images.push_back(imageId); - push_images(L, images); + ObjectIds cels; + for (auto celId : set) + cels.push_back(celId); + push_cel_images(L, cels); return 1; } From f5678055914c984bf9d04464604edfb9ebcccbab Mon Sep 17 00:00:00 2001 From: Joshua Ogunyinka Date: Mon, 29 Nov 2021 17:18:56 +0400 Subject: [PATCH 4/5] Fix allowing alpha channel if layer is converted from indexed image (fix #3073) --- src/render/quantization.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/render/quantization.cpp b/src/render/quantization.cpp index 504fee6e3..fad89d2d4 100644 --- a/src/render/quantization.cpp +++ b/src/render/quantization.cpp @@ -276,8 +276,13 @@ Image* convert_pixel_format( if (!is_background && c == image->maskColor()) *dst_it = rgba(0, 0, 0, 0); - else - *dst_it = palette->getEntry(c); + else { + const uint32_t p = palette->getEntry(c); + if (is_background) + *dst_it = rgba(rgba_getr(p), rgba_getg(p), rgba_getb(p), 255); + else + *dst_it = p; + } } ASSERT(dst_it == dst_end); break; From 977994765cad82657ab33628e4cd919c31c59729 Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 15 Dec 2021 17:47:44 -0300 Subject: [PATCH 5/5] Normalize some cmake options from WITH_* to ENABLE_* --- CMakeLists.txt | 9 ++++----- src/CMakeLists.txt | 2 +- src/app/CMakeLists.txt | 6 +++--- src/app/file/file_formats_manager.cpp | 4 ++-- src/desktop/linux/CMakeLists.txt | 2 +- third_party/CMakeLists.txt | 2 +- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5bcd64fb..3a0af4815 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,10 +52,6 @@ enable_testing() # Options (these can be specified in cmake command line or modifying # CMakeCache.txt) -option(WITH_WEBP_SUPPORT "Enable support to load/save .webp files" on) -option(WITH_DESKTOP_INTEGRATION "Enable desktop integration modules" off) -option(WITH_QT_THUMBNAILER "Enable kde5/qt5 thumnailer" off) - option(USE_SHARED_CMARK "Use your installed copy of cmark" off) option(USE_SHARED_CURL "Use your installed copy of curl" off) option(USE_SHARED_GIFLIB "Use your installed copy of giflib" off) @@ -82,6 +78,9 @@ option(FULLSCREEN_PLATFORM "Enable fullscreen by default" off) option(ENABLE_CLANG_TIDY "Enable static analysis" off) option(ENABLE_CCACHE "Use CCache to improve recompilation speed (optional)" on) option(ENABLE_SENTRY "Use Sentry SDK to report crashes" off) +option(ENABLE_WEBP "Enable support to load/save .webp files" on) +option(ENABLE_DESKTOP_INTEGRATION "Enable desktop integration modules" off) +option(ENABLE_QT_THUMBNAILER "Enable kde5/qt5 thumnailer" off) set(CUSTOM_WEBSITE_URL "" CACHE STRING "Enable custom local webserver to check updates") if(ENABLE_SENTRY) @@ -235,7 +234,7 @@ include_directories(${PNG_INCLUDE_DIRS}) add_definitions(-DPNG_NO_MMX_CODE) # Do not use MMX optimizations in PNG code # libwebp -if(WITH_WEBP_SUPPORT) +if(ENABLE_WEBP) set(WEBP_LIBRARIES webp webpdemux libwebpmux) set(WEBP_INCLUDE_DIR ${LIBWEBP_DIR}/src) include_directories(${WEBP_INCLUDE_DIR}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb25aeac6..321f7b91d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -130,7 +130,7 @@ if(ENABLE_STEAM) add_subdirectory(steam) endif() -if(WITH_DESKTOP_INTEGRATION) +if(ENABLE_DESKTOP_INTEGRATION) add_subdirectory(desktop) endif() diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 8a4a36a26..09b44f64c 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -87,8 +87,8 @@ add_custom_command( DEPENDS ${GEN_DEP} ${widget_files} ${string_files} "${SOURCE_DATA_DIR}/gui.xml") list(APPEND generated_files ${output_fn}) -if(WITH_WEBP_SUPPORT) - add_definitions(-DASEPRITE_WITH_WEBP_SUPPORT) +if(ENABLE_WEBP) + add_definitions(-DENABLE_WEBP) endif() # libarchive definitions @@ -134,7 +134,7 @@ set(file_formats file/png_format.cpp file/svg_format.cpp file/tga_format.cpp) -if(WITH_WEBP_SUPPORT) +if(ENABLE_WEBP) list(APPEND file_formats file/webp_format.cpp) endif() diff --git a/src/app/file/file_formats_manager.cpp b/src/app/file/file_formats_manager.cpp index 22d91ae8a..5f1dff08f 100644 --- a/src/app/file/file_formats_manager.cpp +++ b/src/app/file/file_formats_manager.cpp @@ -32,7 +32,7 @@ extern FileFormat* CreatePngFormat(); extern FileFormat* CreateSvgFormat(); extern FileFormat* CreateTgaFormat(); -#ifdef ASEPRITE_WITH_WEBP_SUPPORT +#ifdef ENABLE_WEBP extern FileFormat* CreateWebPFormat(); #endif @@ -68,7 +68,7 @@ FileFormatsManager::FileFormatsManager() registerFormat(CreateSvgFormat()); registerFormat(CreateTgaFormat()); -#ifdef ASEPRITE_WITH_WEBP_SUPPORT +#ifdef ENABLE_WEBP registerFormat(CreateWebPFormat()); #endif } diff --git a/src/desktop/linux/CMakeLists.txt b/src/desktop/linux/CMakeLists.txt index b34c4d31d..cdeeb31db 100644 --- a/src/desktop/linux/CMakeLists.txt +++ b/src/desktop/linux/CMakeLists.txt @@ -10,6 +10,6 @@ install(PROGRAMS aseprite-thumbnailer DESTINATION bin) install(FILES gnome/aseprite.thumbnailer DESTINATION share/thumbnailers) # Qt Thumbnailer -if(WITH_QT_THUMBNAILER) +if(ENABLE_QT_THUMBNAILER) add_subdirectory(kde) endif() diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index d13d44c2c..dde9c1de1 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -33,7 +33,7 @@ if(NOT USE_SHARED_GIFLIB) add_subdirectory(giflib) endif() -if(WITH_WEBP_SUPPORT) +if(ENABLE_WEBP) set(WEBP_BUILD_EXTRAS OFF CACHE BOOL "Build extras.") set(WEBP_BUILD_ANIM_UTILS OFF CACHE BOOL "Build animation utilities.") set(WEBP_BUILD_CWEBP OFF CACHE BOOL "Build the cwebp command line tool.")