From e6f4e64aa4e4d0609e91f874ed05c71d823372bd Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 14 Mar 2025 23:24:17 -0400 Subject: [PATCH] Add onLayoutOpened API callback --- docsrc/manual/scripting-capabilities.rst | 11 +++- include/scripting.h | 4 ++ include/ui/mapview.h | 6 +- resources/text/script_template.txt | 5 ++ src/editor.cpp | 6 ++ src/mainwindow.cpp | 10 +--- src/scriptapi/apioverlay.cpp | 76 +++++++++++++----------- src/scriptapi/scripting.cpp | 10 ++++ 8 files changed, 82 insertions(+), 46 deletions(-) diff --git a/docsrc/manual/scripting-capabilities.rst b/docsrc/manual/scripting-capabilities.rst index b645f49a..ac1cf521 100644 --- a/docsrc/manual/scripting-capabilities.rst +++ b/docsrc/manual/scripting-capabilities.rst @@ -153,11 +153,18 @@ Callbacks .. js:function:: onMapOpened(mapName) - Called when a map or layout is opened. + Called when a map is opened. - :param mapName: the name of the opened map or layout + :param mapName: the name of the opened map :type mapName: string +.. js:function:: onLayoutOpened(layoutName) + + Called when a layout is opened, either by selecting a new map/layout in the map list or swapping the layout for the current map. + + :param layoutName: the name of the opened layout + :type layoutName: string + .. js:function:: onBlockChanged(x, y, prevBlock, newBlock) Called when a block is changed on the map. For example, this is called when a user paints a new tile or changes the collision property of a block. diff --git a/include/scripting.h b/include/scripting.h index c08bbd74..6870f159 100644 --- a/include/scripting.h +++ b/include/scripting.h @@ -9,6 +9,8 @@ #include #include +// !! New callback functions or changes to existing callback function names/arguments +// should be synced to resources/text/script_template.txt and docsrc/manual/scripting-capabilities.rst enum CallbackType { OnProjectOpened, OnProjectClosed, @@ -17,6 +19,7 @@ enum CallbackType { OnBlockHoverChanged, OnBlockHoverCleared, OnMapOpened, + OnLayoutOpened, OnMapResized, OnBorderResized, OnMapShifted, @@ -43,6 +46,7 @@ public: static void cb_BlockHoverChanged(int x, int y); static void cb_BlockHoverCleared(); static void cb_MapOpened(QString mapName); + static void cb_LayoutOpened(QString layoutName); static void cb_MapResized(int oldWidth, int oldHeight, int newWidth, int newHeight); static void cb_BorderResized(int oldWidth, int oldHeight, int newWidth, int newHeight); static void cb_MapShifted(int xDelta, int yDelta); diff --git a/include/ui/mapview.h b/include/ui/mapview.h index 7355da9d..aa271757 100644 --- a/include/ui/mapview.h +++ b/include/ui/mapview.h @@ -70,11 +70,13 @@ public: Q_INVOKABLE void addTileImage(int x, int y, QJSValue tileObj, bool setTransparency = false, int layer = 0); Q_INVOKABLE void addMetatileImage(int x, int y, int metatileId, bool setTransparency = false, int layer = 0); -private: - QMap overlayMap; protected: virtual void drawForeground(QPainter *painter, const QRectF &rect) override; virtual void keyPressEvent(QKeyEvent*) override; +private: + QMap overlayMap; + + void updateScene(); }; #endif // GRAPHICSVIEW_H diff --git a/resources/text/script_template.txt b/resources/text/script_template.txt index fdd1949f..4b5134d1 100644 --- a/resources/text/script_template.txt +++ b/resources/text/script_template.txt @@ -13,6 +13,11 @@ export function onMapOpened(mapName) { } +// Called when a layout is opened, either by selecting a new map/layout in the map list or swapping the layout for the current map. +export function onLayoutOpened(layoutName) { + +} + // Called when a block is changed on the map. For example, this is called when a user paints a new tile or changes the collision property of a block. export function onBlockChanged(x, y, prevBlock, newBlock) { diff --git a/src/editor.cpp b/src/editor.cpp index d8c13d62..2e290f8a 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1191,6 +1191,9 @@ bool Editor::setLayout(QString layoutId) { return false; } + QString prevLayoutName; + if (this->layout) prevLayoutName = this->layout->name; + Layout *loadedLayout = this->project->loadLayout(layoutId); if (!loadedLayout) { return false; @@ -1218,6 +1221,9 @@ bool Editor::setLayout(QString layoutId) { if (index < 0) index = 0; this->ui->comboBox_LayoutSelector->setCurrentIndex(index); + if (this->layout->name != prevLayoutName) + Scripting::cb_LayoutOpened(this->layout->name); + return true; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6195025c..85e0df3e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -988,7 +988,6 @@ bool MainWindow::setLayout(QString layoutId) { connect(editor->layout, &Layout::needsRedrawing, this, &MainWindow::redrawMapScene, Qt::UniqueConnection); - Scripting::cb_MapOpened(layout->name); updateTilesetEditor(); userConfig.recentMapOrLayout = layoutId; @@ -2848,13 +2847,10 @@ void MainWindow::reloadScriptEngine() { // Lying to the scripts here, simulating a project reload Scripting::cb_ProjectOpened(projectConfig.projectDir); if (this->editor) { - QString curName; + if (this->editor->layout) + Scripting::cb_LayoutOpened(this->editor->layout->name); if (this->editor->map) - curName = this->editor->map->name(); - else if (editor->layout) - curName = this->editor->layout->name; - - Scripting::cb_MapOpened(curName); + Scripting::cb_MapOpened(this->editor->map->name()); } } diff --git a/src/scriptapi/apioverlay.cpp b/src/scriptapi/apioverlay.cpp index b12f5f09..4b1f75b8 100644 --- a/src/scriptapi/apioverlay.cpp +++ b/src/scriptapi/apioverlay.cpp @@ -2,15 +2,21 @@ #include "scripting.h" #include "imageproviders.h" +void MapView::updateScene() { + if (this->scene()) { + this->scene()->update(); + } +} + void MapView::clear(int layer) { this->getOverlay(layer)->clearItems(); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, clear all layers void MapView::clear() { this->clearOverlayMap(); - this->scene()->update(); + this->updateScene(); } void MapView::hide(int layer) { @@ -37,14 +43,14 @@ bool MapView::getVisibility(int layer) { void MapView::setVisibility(bool visible, int layer) { this->getOverlay(layer)->setHidden(!visible); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set visibility of all layers void MapView::setVisibility(bool visible) { foreach (Overlay * layer, this->overlayMap) layer->setHidden(!visible); - this->scene()->update(); + this->updateScene(); } int MapView::getX(int layer) { @@ -57,49 +63,49 @@ int MapView::getY(int layer) { void MapView::setX(int x, int layer) { this->getOverlay(layer)->setX(x); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set x of all layers void MapView::setX(int x) { foreach (Overlay * layer, this->overlayMap) layer->setX(x); - this->scene()->update(); + this->updateScene(); } void MapView::setY(int y, int layer) { this->getOverlay(layer)->setY(y); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set y of all layers void MapView::setY(int y) { foreach (Overlay * layer, this->overlayMap) layer->setY(y); - this->scene()->update(); + this->updateScene(); } void MapView::setClippingRect(int x, int y, int width, int height, int layer) { this->getOverlay(layer)->setClippingRect(QRectF(x, y, width, height)); - this->scene()->update(); + this->updateScene(); } void MapView::setClippingRect(int x, int y, int width, int height) { QRectF rect = QRectF(x, y, width, height); foreach (Overlay * layer, this->overlayMap) layer->setClippingRect(rect); - this->scene()->update(); + this->updateScene(); } void MapView::clearClippingRect(int layer) { this->getOverlay(layer)->clearClippingRect(); - this->scene()->update(); + this->updateScene(); } void MapView::clearClippingRect() { foreach (Overlay * layer, this->overlayMap) layer->clearClippingRect(); - this->scene()->update(); + this->updateScene(); } QJSValue MapView::getPosition(int layer) { @@ -109,26 +115,26 @@ QJSValue MapView::getPosition(int layer) { void MapView::setPosition(int x, int y, int layer) { this->getOverlay(layer)->setPosition(x, y); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set position of all layers void MapView::setPosition(int x, int y) { foreach (Overlay * layer, this->overlayMap) layer->setPosition(x, y); - this->scene()->update(); + this->updateScene(); } void MapView::move(int deltaX, int deltaY, int layer) { this->getOverlay(layer)->move(deltaX, deltaY); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, move all layers void MapView::move(int deltaX, int deltaY) { foreach (Overlay * layer, this->overlayMap) layer->move(deltaX, deltaY); - this->scene()->update(); + this->updateScene(); } int MapView::getOpacity(int layer) { @@ -137,14 +143,14 @@ int MapView::getOpacity(int layer) { void MapView::setOpacity(int opacity, int layer) { this->getOverlay(layer)->setOpacity(opacity); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set opacity of all layers void MapView::setOpacity(int opacity) { foreach (Overlay * layer, this->overlayMap) layer->setOpacity(opacity); - this->scene()->update(); + this->updateScene(); } qreal MapView::getHorizontalScale(int layer) { @@ -157,38 +163,38 @@ qreal MapView::getVerticalScale(int layer) { void MapView::setHorizontalScale(qreal scale, int layer) { this->getOverlay(layer)->setHScale(scale); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set horizontal scale of all layers void MapView::setHorizontalScale(qreal scale) { foreach (Overlay * layer, this->overlayMap) layer->setHScale(scale); - this->scene()->update(); + this->updateScene(); } void MapView::setVerticalScale(qreal scale, int layer) { this->getOverlay(layer)->setVScale(scale); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set vertical scale of all layers void MapView::setVerticalScale(qreal scale) { foreach (Overlay * layer, this->overlayMap) layer->setVScale(scale); - this->scene()->update(); + this->updateScene(); } void MapView::setScale(qreal hScale, qreal vScale, int layer) { this->getOverlay(layer)->setScale(hScale, vScale); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set scale of all layers void MapView::setScale(qreal hScale, qreal vScale) { foreach (Overlay * layer, this->overlayMap) layer->setScale(hScale, vScale); - this->scene()->update(); + this->updateScene(); } int MapView::getRotation(int layer) { @@ -197,41 +203,41 @@ int MapView::getRotation(int layer) { void MapView::setRotation(int angle, int layer) { this->getOverlay(layer)->setRotation(angle); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, set rotation of all layers void MapView::setRotation(int angle) { foreach (Overlay * layer, this->overlayMap) layer->setRotation(angle); - this->scene()->update(); + this->updateScene(); } void MapView::rotate(int degrees, int layer) { this->getOverlay(layer)->rotate(degrees); - this->scene()->update(); + this->updateScene(); } // Overload. No layer provided, rotate all layers void MapView::rotate(int degrees) { foreach (Overlay * layer, this->overlayMap) layer->rotate(degrees); - this->scene()->update(); + this->updateScene(); } void MapView::addText(QString text, int x, int y, QString color, int fontSize, int layer) { this->getOverlay(layer)->addText(text, x, y, color, fontSize); - this->scene()->update(); + this->updateScene(); } void MapView::addRect(int x, int y, int width, int height, QString borderColor, QString fillColor, int rounding, int layer) { if (this->getOverlay(layer)->addRect(x, y, width, height, borderColor, fillColor, rounding)) - this->scene()->update(); + this->updateScene(); } void MapView::addPath(QList xCoords, QList yCoords, QString borderColor, QString fillColor, int layer) { if (this->getOverlay(layer)->addPath(xCoords, yCoords, borderColor, fillColor)) - this->scene()->update(); + this->updateScene(); } void MapView::addPath(QList> coords, QString borderColor, QString fillColor, int layer) { @@ -250,7 +256,7 @@ void MapView::addPath(QList> coords, QString borderColor, QString fil void MapView::addImage(int x, int y, QString filepath, int layer, bool useCache) { if (this->getOverlay(layer)->addImage(x, y, filepath, useCache)) - this->scene()->update(); + this->updateScene(); } void MapView::createImage(int x, int y, QString filepath, int width, int height, int xOffset, int yOffset, qreal hScale, qreal vScale, int paletteId, bool setTransparency, int layer, bool useCache) { @@ -260,7 +266,7 @@ void MapView::createImage(int x, int y, QString filepath, int width, int height, if (paletteId != -1) palette = Tileset::getPalette(paletteId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary); if (this->getOverlay(layer)->addImage(x, y, filepath, useCache, width, height, xOffset, yOffset, hScale, vScale, palette, setTransparency)) - this->scene()->update(); + this->updateScene(); } void MapView::addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int paletteId, bool setTransparency, int layer) { @@ -274,7 +280,7 @@ void MapView::addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int if (setTransparency) image.setColor(0, qRgba(0, 0, 0, 0)); if (this->getOverlay(layer)->addImage(x, y, image)) - this->scene()->update(); + this->updateScene(); } void MapView::addTileImage(int x, int y, QJSValue tileObj, bool setTransparency, int layer) { @@ -293,5 +299,5 @@ void MapView::addMetatileImage(int x, int y, int metatileId, bool setTransparenc if (setTransparency) image.setColor(0, qRgba(0, 0, 0, 0)); if (this->getOverlay(layer)->addImage(x, y, image)) - this->scene()->update(); + this->updateScene(); } diff --git a/src/scriptapi/scripting.cpp b/src/scriptapi/scripting.cpp index 3eb9afd6..05fd31d9 100644 --- a/src/scriptapi/scripting.cpp +++ b/src/scriptapi/scripting.cpp @@ -12,6 +12,7 @@ const QMap callbackFunctions = { {OnBlockHoverChanged, "onBlockHoverChanged"}, {OnBlockHoverCleared, "onBlockHoverCleared"}, {OnMapOpened, "onMapOpened"}, + {OnLayoutOpened, "onLayoutOpened"}, {OnMapResized, "onMapResized"}, {OnBorderResized, "onBorderResized"}, {OnMapShifted, "onMapShifted"}, @@ -258,6 +259,15 @@ void Scripting::cb_MapOpened(QString mapName) { instance->invokeCallback(OnMapOpened, args); } +void Scripting::cb_LayoutOpened(QString layoutName) { + if (!instance) return; + + QJSValueList args { + layoutName, + }; + instance->invokeCallback(OnLayoutOpened, args); +} + void Scripting::cb_MapResized(int oldWidth, int oldHeight, int newWidth, int newHeight) { if (!instance) return;