From c26351712a21dece24ffee1b0a05ed4686412792 Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 18 May 2023 12:40:12 -0300 Subject: [PATCH] [lua] Add new 'beforepaintemptytilemap' app event Now a tileManagementPlugin can customize the creation of empty tiles when the user starts drawing on an empty cel. To implement: https://github.com/aseprite/Attachment-System/issues/119 Related to: https://github.com/aseprite/Attachment-System/issues/127 --- src/app/app.h | 8 +++++++- src/app/script/events_class.cpp | 18 +++++++++++++++++- src/app/ui/editor/standby_state.cpp | 12 ++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/app/app.h b/src/app/app.h index eceee3d3f..a44be9f66 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2022 Igara Studio S.A. +// Copyright (C) 2018-2023 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -127,6 +127,12 @@ namespace app { obs::signal ColorSpaceChange; obs::signal PalettePresetsChange; + // Signal triggered for TileManagementPlugin that want to create a + // tile on-the-fly when the active tilemap cel is empty (it's like + // a way to customize the "tilemap/tileset", instead of + // Manual/Auto/Semi, the plugin can offer a custom behavior). + obs::signal BeforePaintEmptyTilemap; + private: class CoreModules; class LoadLanguage; diff --git a/src/app/script/events_class.cpp b/src/app/script/events_class.cpp index 62dcfe18e..c4a394613 100644 --- a/src/app/script/events_class.cpp +++ b/src/app/script/events_class.cpp @@ -158,6 +158,7 @@ public: BgColorChange, BeforeCommand, AfterCommand, + BeforePaintEmptyTilemap, }; AppEvents() { @@ -174,6 +175,8 @@ public: return BeforeCommand; else if (std::strcmp(eventName, "aftercommand") == 0) return AfterCommand; + else if (std::strcmp(eventName, "beforepaintemptytilemap") == 0) + return BeforePaintEmptyTilemap; else return Unknown; } @@ -181,7 +184,8 @@ public: private: void onAddFirstListener(EventType eventType) override { - auto ctx = App::instance()->context(); + auto app = App::instance(); + auto ctx = app->context(); auto& pref = Preferences::instance(); switch (eventType) { case SiteChange: @@ -203,6 +207,10 @@ private: m_afterCmdConn = ctx->AfterCommandExecution .connect(&AppEvents::onAfterCommand, this); break; + case BeforePaintEmptyTilemap: + m_beforePaintConn = app->BeforePaintEmptyTilemap + .connect(&AppEvents::onBeforePaintEmptyTilemap, this); + break; } } @@ -223,6 +231,9 @@ private: case AfterCommand: m_afterCmdConn.disconnect(); break; + case BeforePaintEmptyTilemap: + m_beforePaintConn.disconnect(); + break; } } @@ -253,6 +264,10 @@ private: { "params", ev.params() } }); } + void onBeforePaintEmptyTilemap() { + call(BeforePaintEmptyTilemap); + } + // ContextObserver impl void onActiveSiteChange(const Site& site) override { const bool fromUndo = (site.document() && @@ -264,6 +279,7 @@ private: obs::scoped_connection m_bgConn; obs::scoped_connection m_beforeCmdConn; obs::scoped_connection m_afterCmdConn; + obs::scoped_connection m_beforePaintConn; }; class SpriteEvents : public Events diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index f09e936ac..a73bc20d4 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2022 Igara Studio S.A. +// Copyright (C) 2018-2023 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -645,7 +645,15 @@ DrawingState* StandbyState::startDrawingState( if (editor->layer()->isTilemap() && editor->sprite()->hasTileManagementPlugin() && !editor->layer()->cel(editor->frame())) { - return nullptr; + // Trigger event so the plugin can create a cel on-the-fly + App::instance()->BeforePaintEmptyTilemap(); + + if (!editor->layer() || + !editor->layer()->cel(editor->frame())) { + return nullptr; + } + // In other case, it looks like PaintEmptyTilemap event created + // the cel... } // We need to clear and redraw the brush boundaries after the // first mouse pressed/point shape if drawn. This is to avoid