mirror of
https://github.com/huderlem/porymap.git
synced 2026-08-12 20:05:55 -05:00
Custom Scripts -> Plugins
Some checks failed
Build Porymap / build-linux (, 5.14.2) (push) Has been cancelled
Build Porymap / build-linux (, 6.8.*) (push) Has been cancelled
Build Porymap / build-linux (minimal, 5.14.2) (push) Has been cancelled
Build Porymap / build-macos (macos-15-intel) (push) Has been cancelled
Build Porymap / build-macos (macos-latest) (push) Has been cancelled
Build Porymap / build-static-windows (push) Has been cancelled
Some checks failed
Build Porymap / build-linux (, 5.14.2) (push) Has been cancelled
Build Porymap / build-linux (, 6.8.*) (push) Has been cancelled
Build Porymap / build-linux (minimal, 5.14.2) (push) Has been cancelled
Build Porymap / build-macos (macos-15-intel) (push) Has been cancelled
Build Porymap / build-macos (macos-latest) (push) Has been cancelled
Build Porymap / build-static-windows (push) Has been cancelled
This commit is contained in:
27
include/api/pluginsettings.h
Normal file
27
include/api/pluginsettings.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#ifndef PLUGINSETTINGS_H
|
||||
#define PLUGINSETTINGS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
// Holds the basic user-provided information about a plugin.
|
||||
struct PluginSettings {
|
||||
QString path;
|
||||
bool enabled = true;
|
||||
|
||||
// Plugins can either be specific to the project, or specific to the user.
|
||||
// This allows projects to send plugin scripts downstream to their users,
|
||||
// while still allowing them to use their own personal plugins.
|
||||
bool userOnly = true;
|
||||
|
||||
static QStringList filter(const QList<PluginSettings>& plugins) {
|
||||
QStringList paths;
|
||||
for (auto& plugin : plugins) {
|
||||
if (plugin.enabled) paths.append(plugin.path);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // PLUGINSETTINGS_H
|
||||
162
include/api/scripting.h
Normal file
162
include/api/scripting.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#pragma once
|
||||
#ifndef SCRIPTING_H
|
||||
#define SCRIPTING_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QStack>
|
||||
#include <QFileInfo>
|
||||
#include <QPointer>
|
||||
#include "scriptutility.h"
|
||||
#include "utility.h"
|
||||
|
||||
class Block;
|
||||
class Tile;
|
||||
class MainWindow;
|
||||
|
||||
#if __has_include(<QJSEngine>)
|
||||
#include <QJSEngine>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef QT_QML_LIB
|
||||
|
||||
// !! New callback functions or changes to existing callback function names/arguments
|
||||
// should be synced to resources/text/plugin_template.txt and docsrc/manual/scripting-capabilities.rst
|
||||
class Scripting : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Scripting(MainWindow *mainWindow);
|
||||
~Scripting();
|
||||
static void init(MainWindow *mainWindow);
|
||||
static void stop();
|
||||
static void populateGlobalObject();
|
||||
static QJSEngine* getEngine();
|
||||
static QString getCurrentScriptHash();
|
||||
static QAction* registerAction(const QString &functionName, const QString &actionName);
|
||||
static void setTimeout(QJSValue callback, int milliseconds);
|
||||
|
||||
static void cb_ProjectOpened(QString projectPath);
|
||||
static void cb_ProjectClosed(QString projectPath);
|
||||
static void cb_MetatileChanged(int x, int y, Block prevBlock, Block newBlock);
|
||||
static void cb_BorderMetatileChanged(int x, int y, uint16_t prevMetatileId, uint16_t newMetatileId);
|
||||
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, const QMargins &delta);
|
||||
static void cb_BorderResized(int oldWidth, int oldHeight, int newWidth, int newHeight);
|
||||
static void cb_MapShifted(int xDelta, int yDelta);
|
||||
static void cb_TilesetUpdated(const QString &tilesetName);
|
||||
static void cb_MainTabChanged(int oldTab, int newTab);
|
||||
static void cb_MapViewTabChanged(int oldTab, int newTab);
|
||||
static void cb_BorderVisibilityToggled(bool visible);
|
||||
static QImage cb_EventSpriteLoading(const QString &gfxName, const QString &direction);
|
||||
static QImage cb_SpeciesIconLoading(const QString &species);
|
||||
|
||||
static bool tryErrorJS(QJSValue js);
|
||||
static QJSValue fromBlock(Block block);
|
||||
static QJSValue fromTile(Tile tile);
|
||||
static Tile toTile(QJSValue obj);
|
||||
static QImage toImage(const QJSValue &obj);
|
||||
static QJSValue dimensions(int width, int height);
|
||||
static QJSValue margins(const QMargins &margins);
|
||||
static QJSValue position(int x, int y);
|
||||
static const QImage * getImage(const QString &filepath, bool useCache);
|
||||
static QJSValue dialogInput(QJSValue input, bool selectedOk);
|
||||
static QJSValue fileResponse(const QString &s, bool isError);
|
||||
static bool checkFilePermissions(const QString &filepath);
|
||||
|
||||
private:
|
||||
QPointer<MainWindow> mainWindow;
|
||||
QPointer<QJSEngine> engine;
|
||||
bool populated = false;
|
||||
|
||||
class Script
|
||||
{
|
||||
public:
|
||||
Script() {};
|
||||
|
||||
QString filepath() const { return m_filepath; }
|
||||
QString fileName() const {
|
||||
QFileInfo fileInfo(m_filepath);
|
||||
return fileInfo.fileName();
|
||||
}
|
||||
void setFilepath(const QString &filepath) { m_filepath = filepath; }
|
||||
|
||||
QJSValue module() const { return m_module; }
|
||||
void setModule(const QJSValue &module) { m_module = module; }
|
||||
|
||||
QString hash() {
|
||||
if (m_hash.isEmpty()) {
|
||||
// We won't need to check whether most scripts are trusted,
|
||||
// so only calculate the hash when it's first requested.
|
||||
m_hash = Util::getFileHash(m_filepath);
|
||||
}
|
||||
return m_hash;
|
||||
}
|
||||
private:
|
||||
QString m_filepath;
|
||||
QJSValue m_module;
|
||||
QString m_hash;
|
||||
};
|
||||
QList<QSharedPointer<Script>> scripts;
|
||||
|
||||
// Tracks the scripts that are currently being evaluated.
|
||||
// This is useful for identifying which script is responsible
|
||||
// for calling a function at any point in time.
|
||||
// Because executing a callback/action in one script may trigger
|
||||
// a callback/action in a different script we may need to keep
|
||||
// track of multiple scripts executing at once.
|
||||
QStack<QSharedPointer<Script>> scriptExecutionStack;
|
||||
|
||||
struct ActionScript {
|
||||
QSharedPointer<Script> script;
|
||||
QPointer<QAction> action;
|
||||
QString functionName;
|
||||
};
|
||||
QList<ActionScript> actionScripts;
|
||||
QSet<QTimer*> activeTimers;
|
||||
QMap<QString, const QImage*> imageCache;
|
||||
|
||||
void loadScript(const QString &filepath);
|
||||
QJSValue invokeCallback(const QString &functionName, const QJSValueList &args);
|
||||
void invokeAction(int actionIndex);
|
||||
QSharedPointer<Script> getActiveScript() const;
|
||||
QJSValue call(QSharedPointer<Script> script, QJSValue func, const QJSValueList &args = QJSValueList());
|
||||
bool askForTrust(QSharedPointer<Script> script, const QString &reason);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class Scripting
|
||||
{
|
||||
public:
|
||||
Scripting(MainWindow *) {}
|
||||
~Scripting() {}
|
||||
static void init(MainWindow *) {}
|
||||
static void stop() {}
|
||||
static void populateGlobalObject() {}
|
||||
|
||||
static void cb_ProjectOpened(QString) {};
|
||||
static void cb_ProjectClosed(QString) {};
|
||||
static void cb_MetatileChanged(int, int, Block, Block) {};
|
||||
static void cb_BorderMetatileChanged(int, int, uint16_t, uint16_t) {};
|
||||
static void cb_BlockHoverChanged(int, int) {};
|
||||
static void cb_BlockHoverCleared() {};
|
||||
static void cb_MapOpened(QString) {};
|
||||
static void cb_LayoutOpened(QString) {};
|
||||
static void cb_MapResized(int, int, const QMargins &) {};
|
||||
static void cb_BorderResized(int, int, int, int) {};
|
||||
static void cb_MapShifted(int, int) {};
|
||||
static void cb_TilesetUpdated(const QString &) {};
|
||||
static void cb_MainTabChanged(int, int) {};
|
||||
static void cb_MapViewTabChanged(int, int) {};
|
||||
static void cb_BorderVisibilityToggled(bool) {};
|
||||
static QImage cb_EventSpriteLoading(const QString &, const QString &) {return QImage();}
|
||||
static QImage cb_SpeciesIconLoading(const QString &) {return QImage();}
|
||||
};
|
||||
|
||||
#endif // QT_QML_LIB
|
||||
|
||||
#endif // SCRIPTING_H
|
||||
86
include/api/scriptutility.h
Normal file
86
include/api/scriptutility.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
#ifndef SCRIPTUTILITY_H
|
||||
#define SCRIPTUTILITY_H
|
||||
|
||||
#if __has_include(<QJSValue>)
|
||||
#include <QJSValue>
|
||||
#endif
|
||||
|
||||
#ifdef QT_QML_LIB
|
||||
|
||||
#include <QAction>
|
||||
#include <QMessageBox>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class ScriptUtility : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScriptUtility(MainWindow *mainWindow, QObject *parent = nullptr) : QObject(parent), window(mainWindow) {}
|
||||
~ScriptUtility() {};
|
||||
|
||||
Q_INVOKABLE bool registerAction(QString functionName, QString actionName, QString shortcut = "");
|
||||
Q_INVOKABLE bool registerToggleAction(QString functionName, QString actionName, QString shortcut = "", bool checked = false);
|
||||
Q_INVOKABLE void setTimeout(QJSValue callback, int milliseconds);
|
||||
Q_INVOKABLE void log(QString message);
|
||||
Q_INVOKABLE void warn(QString message);
|
||||
Q_INVOKABLE void error(QString message);
|
||||
Q_INVOKABLE void showMessage(QString text, QString informativeText = "", QString detailedText = "");
|
||||
Q_INVOKABLE void showWarning(QString text, QString informativeText = "", QString detailedText = "");
|
||||
Q_INVOKABLE void showError(QString text, QString informativeText = "", QString detailedText = "");
|
||||
Q_INVOKABLE bool showQuestion(QString text, QString informativeText = "", QString detailedText = "");
|
||||
Q_INVOKABLE QString showOpenFileDialog(const QString &caption = QString(), const QString &dir = QString(), const QStringList &filters = QStringList()) const;
|
||||
Q_INVOKABLE QString showSaveFileDialog(const QString &caption = QString(), const QString &dir = QString(), const QStringList &filters = QStringList()) const;
|
||||
Q_INVOKABLE QString showOpenDirectoryDialog(const QString &caption = QString(), const QString &dir = QString()) const;
|
||||
Q_INVOKABLE QJSValue readTextFile(const QString &path) const;
|
||||
Q_INVOKABLE QString writeTextFile(const QString &path, const QString &content, bool append = false) const;
|
||||
Q_INVOKABLE QJSValue getInputText(QString title, QString label, QString defaultValue = "");
|
||||
Q_INVOKABLE QJSValue getInputNumber(QString title, QString label, double defaultValue = 0, double min = INT_MIN, double max = INT_MAX, int decimals = 0, double step = 1);
|
||||
Q_INVOKABLE QJSValue getInputItem(QString title, QString label, QStringList items, int defaultValue = 0, bool editable = false);
|
||||
Q_INVOKABLE int getMainTab();
|
||||
Q_INVOKABLE void setMainTab(int index);
|
||||
Q_INVOKABLE int getMapViewTab();
|
||||
Q_INVOKABLE void setMapViewTab(int index);
|
||||
Q_INVOKABLE void setGridVisibility(bool visible);
|
||||
Q_INVOKABLE bool getGridVisibility();
|
||||
Q_INVOKABLE void setBorderVisibility(bool visible);
|
||||
Q_INVOKABLE bool getBorderVisibility();
|
||||
Q_INVOKABLE void setSmartPathsEnabled(bool visible);
|
||||
Q_INVOKABLE bool getSmartPathsEnabled();
|
||||
static Q_INVOKABLE QList<QString> getPluginScripts();
|
||||
static Q_INVOKABLE QList<QString> getCustomScripts() {return getPluginScripts();} // Alias for backwards-compatibility
|
||||
Q_INVOKABLE QList<int> getMetatileLayerOrder();
|
||||
Q_INVOKABLE void setMetatileLayerOrder(const QList<int> &order);
|
||||
Q_INVOKABLE QList<float> getMetatileLayerOpacity();
|
||||
Q_INVOKABLE void setMetatileLayerOpacity(const QList<float> &order);
|
||||
Q_INVOKABLE QList<QString> getMapNames();
|
||||
Q_INVOKABLE QList<QString> getMapConstants();
|
||||
Q_INVOKABLE QList<QString> getLayoutNames();
|
||||
Q_INVOKABLE QList<QString> getLayoutConstants();
|
||||
Q_INVOKABLE QList<QString> getTilesetNames();
|
||||
Q_INVOKABLE QList<QString> getPrimaryTilesetNames();
|
||||
Q_INVOKABLE QList<QString> getSecondaryTilesetNames();
|
||||
Q_INVOKABLE QList<QString> getMetatileBehaviorNames();
|
||||
Q_INVOKABLE QList<QString> getSongNames();
|
||||
Q_INVOKABLE QList<QString> getLocationNames();
|
||||
Q_INVOKABLE QList<QString> getWeatherNames();
|
||||
Q_INVOKABLE QList<QString> getMapTypeNames();
|
||||
Q_INVOKABLE QList<QString> getBattleSceneNames();
|
||||
Q_INVOKABLE bool isPrimaryTileset(QString tilesetName);
|
||||
Q_INVOKABLE bool isSecondaryTileset(QString tilesetName);
|
||||
|
||||
static bool validateMetatileLayerOrder(const QList<int> &order);
|
||||
|
||||
private:
|
||||
void runMessageBox(QString text, QString informativeText, QString detailedText, QMessageBox::Icon icon);
|
||||
QString detectProjectPath(const QString &path) const;
|
||||
|
||||
MainWindow *window;
|
||||
};
|
||||
|
||||
#endif // QT_QML_LIB
|
||||
|
||||
#endif // SCRIPTUTILITY_H
|
||||
Reference in New Issue
Block a user