From 09a892f5251d4d7a73b59fd5cb04e485208df6fd Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Sun, 3 May 2020 11:28:02 -0500 Subject: [PATCH] Add ability to register custom actions --- include/mainwindow.h | 1 + include/scripting.h | 6 ++++++ src/mainwindow.cpp | 17 +++++++++++++++ src/scripting.cpp | 39 ++++++++++++++++++++++++++++++++++ test_script.js | 50 +++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 110 insertions(+), 3 deletions(-) diff --git a/include/mainwindow.h b/include/mainwindow.h index 518c3d9d..751c1e90 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -72,6 +72,7 @@ public: void setTilesetPalettePreview(Tileset *tileset, int paletteIndex, QList> colors); Q_INVOKABLE void setPrimaryTilesetPalettePreview(int paletteIndex, QList> colors); Q_INVOKABLE void setSecondaryTilesetPalettePreview(int paletteIndex, QList> colors); + Q_INVOKABLE void registerAction(QString functionName, QString actionName); public slots: diff --git a/include/scripting.h b/include/scripting.h index 614965ea..e9fc9916 100644 --- a/include/scripting.h +++ b/include/scripting.h @@ -8,6 +8,7 @@ #include enum CallbackType { + OnProjectOpened, OnBlockChanged, OnMapOpened, }; @@ -20,6 +21,10 @@ public: static QJSValue dimensions(int width, int height); static QJSEngine *getEngine(); static void init(MainWindow *mainWindow); + static void registerAction(QString functionName, QString actionName); + static int numRegisteredActions(); + static void invokeAction(QString actionName); + static void cb_ProjectOpened(QString projectPath); static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock); static void cb_MapOpened(QString mapName); @@ -27,6 +32,7 @@ private: QJSEngine *engine; QStringList filepaths; QList modules; + QMap registeredActions; void loadModules(QStringList moduleFiles); void invokeCallback(CallbackType type, QJSValueList args); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ed9653d0..3ba56dde 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -348,6 +348,10 @@ bool MainWindow::openProject(QString dir) { } + if (success) { + Scripting::cb_ProjectOpened(dir); + } + return success; } @@ -2844,3 +2848,16 @@ void MainWindow::setSecondaryTilesetPalettePreview(int paletteIndex, QListsetTilesetPalettePreview(this->editor->map->layout->tileset_secondary, paletteIndex, colors); } + +void MainWindow::registerAction(QString functionName, QString actionName) { + if (!this->ui || !this->ui->menuTools) + return; + + Scripting::registerAction(functionName, actionName); + if (Scripting::numRegisteredActions() == 1) { + this->ui->menuTools->addSeparator(); + } + this->ui->menuTools->addAction(actionName, [actionName](){ + Scripting::invokeAction(actionName); + }); +} diff --git a/src/scripting.cpp b/src/scripting.cpp index 4fdab50d..ecd34d51 100644 --- a/src/scripting.cpp +++ b/src/scripting.cpp @@ -2,6 +2,7 @@ #include "log.h" QMap callbackFunctions = { + {OnProjectOpened, "on_project_opened"}, {OnBlockChanged, "on_block_changed"}, {OnMapOpened, "on_map_opened"}, }; @@ -54,6 +55,44 @@ void Scripting::invokeCallback(CallbackType type, QJSValueList args) { } } +void Scripting::registerAction(QString functionName, QString actionName) { + if (!instance) return; + instance->registeredActions.insert(actionName, functionName); +} + +int Scripting::numRegisteredActions() { + if (!instance) return 0; + return instance->registeredActions.size(); +} + +void Scripting::invokeAction(QString actionName) { + if (!instance) return; + if (!instance->registeredActions.contains(actionName)) return; + + QString functionName = instance->registeredActions.value(actionName); + for (QJSValue module : instance->modules) { + QJSValue callbackFunction = module.property(functionName); + if (callbackFunction.isError()) { + continue; + } + + QJSValue result = callbackFunction.call(QJSValueList()); + if (result.isError()) { + logError(QString("Module %1 encountered an error when calling '%2'").arg(module.toString()).arg(functionName)); + continue; + } + } +} + +void Scripting::cb_ProjectOpened(QString projectPath) { + if (!instance) return; + + QJSValueList args { + projectPath, + }; + instance->invokeCallback(OnProjectOpened, args); +} + void Scripting::cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock) { if (!instance) return; diff --git a/test_script.js b/test_script.js index bd14687c..85b3e72c 100644 --- a/test_script.js +++ b/test_script.js @@ -1,7 +1,51 @@ -export function on_block_changed(x, y, prevBlock, newBlock) { +const normalTint = [1, 1, 1] +const morningTint = [0.8, 0.7, 0.9]; +const nightTint = [0.6, 0.55, 1.0]; + +function applyTint(palette, tint) { + for (let i = 0; i < palette.length; i++) { + const color = palette[i]; + for (let j = 0; j < tint.length; j++) { + color[j] = Math.floor(color[j] * tint[j]); + } + } +} + +function applyTintToPalettes(tint) { try { - console.log("on_block_changed", x, y) - } catch (err) { + for (let i = 0; i < 13; i++) { + const primaryPalette = map.getPrimaryTilesetPalette(i) + applyTint(primaryPalette, tint) + map.setPrimaryTilesetPalettePreview(i, primaryPalette) + const secondaryPalette = map.getSecondaryTilesetPalette(i) + applyTint(secondaryPalette, tint) + map.setSecondaryTilesetPalettePreview(i, secondaryPalette) + } + } catch(err) { console.log(err) } } + +// Porymap callback when project is opened. +export function on_project_opened(projectPath) { + try { + console.log(`opened ${projectPath}`) + map.registerAction("resetTint", "View Day Tint") + map.registerAction("applyMorningTint", "View Morning Tint") + map.registerAction("applyNightTint", "View Night Tint") + } catch(err) { + console.log(err) + } +} + +export function resetTint() { + applyTintToPalettes(normalTint) +} + +export function applyMorningTint() { + applyTintToPalettes(morningTint) +} + +export function applyNightTint() { + applyTintToPalettes(nightTint) +}