From a1a0100f663d7d849fce032ccec5844161558b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Mon, 2 Mar 2026 19:08:57 +0100 Subject: [PATCH] Scripting: Added MapEditor.selectedTool and MapEditor.tool (#4330) Enables scripts to know which tool is selected, to select a different tool and potentially to modify or interact with the available tools. --- NEWS.md | 1 + docs/scripting-doc/index.d.ts | 45 +++++++++++++++++++++++++++++++++++ src/tiled/mapeditor.cpp | 16 +++++++++---- src/tiled/mapeditor.h | 13 ++++++++-- src/tiled/toolmanager.cpp | 11 +++++++++ src/tiled/toolmanager.h | 2 ++ 6 files changed, 81 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index 204d2dbd12..1856198db2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -29,6 +29,7 @@ * Scripting: Added API for custom property types (with dogboydog, #3971) * Scripting: Added TileMap.chunkSize and TileMap.compressionLevel properties * Scripting: Added tiled.session to read and write session properties (by Kanishka, #4345) +* Scripting: Added MapEditor.selectedTool and MapEditor.tool (#4330) * AutoMapping: Don't match rules based on empty input indexes * AutoMapping: Optimized reloading of rule maps and load rule maps on-demand * tBIN plugin: Added support for the tIDE XML format (by Casey Warrington, #4308) diff --git a/docs/scripting-doc/index.d.ts b/docs/scripting-doc/index.d.ts index beda504b8b..3dd9d8c1c7 100644 --- a/docs/scripting-doc/index.d.ts +++ b/docs/scripting-doc/index.d.ts @@ -2772,6 +2772,51 @@ interface MapEditor { * Access the Tilesets view. */ readonly tilesetsView: TilesetsView; + + /** + * Get or set the currently selected tool. + * + * @since 1.12 + */ + selectedTool: Tool | null; + + /** + * Signal emitted when {@link selectedTool} changes. + * + * @since 1.12 + */ + readonly selectedToolChanged: Signal; + + /** + * Returns the tool with the given `shortName`, or `null` if no tool was found. + * + * Can be used to retrieve tools registered with {@link tiled.registerTool} + * as well as the built-in tools: + * + * - BucketFillTool + * - CreateCapsuleObjectTool + * - CreateEllipseObjectTool + * - CreatePointObjectTool + * - CreatePolygonObjectTool + * - CreateRectangleObjectTool + * - CreateTemplateTool + * - CreateTileObjectTool + * - EditPolygonTool + * - EraserTool + * - LayerOffsetTool + * - MagicWandTool + * - ObjectReferenceTool (hidden) + * - ObjectSelectionTool + * - SelectSameTileTool + * - ShapeFillTool + * - StampTool + * - TileSelectionTool + * - WangTool + * - WorldMoveMapTool + * + * @since 1.12 + */ + tool(shortName: string): Tool | null; } /** diff --git a/src/tiled/mapeditor.cpp b/src/tiled/mapeditor.cpp index 80c529c6cd..9318cde09a 100644 --- a/src/tiled/mapeditor.cpp +++ b/src/tiled/mapeditor.cpp @@ -289,9 +289,9 @@ MapEditor::MapEditor(QObject *parent) connect(mTileStampsDock, &TileStampsDock::setStamp, this, &MapEditor::setStamp); - setSelectedTool(mToolManager->selectedTool()); + onSelectedToolChanged(mToolManager->selectedTool()); connect(mToolManager, &ToolManager::selectedToolChanged, - this, &MapEditor::setSelectedTool); + this, &MapEditor::onSelectedToolChanged); setupQuickStamps(); retranslateUi(); @@ -645,7 +645,7 @@ void MapEditor::restoreDocumentState(MapDocument *mapDocument) const mapDocument->switchCurrentLayer(layer); } -void MapEditor::setSelectedTool(AbstractTool *tool) +void MapEditor::onSelectedToolChanged(AbstractTool *tool) { if (mSelectedTool == tool) return; @@ -676,6 +676,7 @@ void MapEditor::setSelectedTool(AbstractTool *tool) } updateActiveUndoStack(); + emit selectedToolChanged(tool); } void MapEditor::updateActiveUndoStack() @@ -1097,9 +1098,14 @@ void MapEditor::setCurrentWangColorIndex(int newIndex) mWangDock->setCurrentWangColor(newIndex); } -AbstractTool *MapEditor::selectedTool() const +void MapEditor::setSelectedTool(AbstractTool *tool) +{ + mToolManager->selectTool(tool); +} + +AbstractTool *MapEditor::tool(const QByteArray &id) const { - return mSelectedTool; + return mToolManager->findTool(id); } } // namespace Tiled diff --git a/src/tiled/mapeditor.h b/src/tiled/mapeditor.h index b794460815..8b3b6e51ee 100644 --- a/src/tiled/mapeditor.h +++ b/src/tiled/mapeditor.h @@ -26,7 +26,6 @@ #include "clipboardmanager.h" #include "editor.h" -#include "tiled.h" #include "tileset.h" #include @@ -77,6 +76,7 @@ class MapEditor final : public Editor Q_PROPERTY(Tiled::EditableWangSet *currentWangSet READ currentWangSet WRITE setCurrentWangSet NOTIFY currentWangSetChanged) Q_PROPERTY(int currentWangColorIndex READ currentWangColorIndex WRITE setCurrentWangColorIndex NOTIFY currentWangColorIndexChanged) Q_PROPERTY(Tiled::MapView *currentMapView READ currentMapView CONSTANT) + Q_PROPERTY(Tiled::AbstractTool *selectedTool READ selectedTool WRITE setSelectedTool NOTIFY selectedToolChanged) public: explicit MapEditor(QObject *parent = nullptr); @@ -131,14 +131,18 @@ class MapEditor final : public Editor QAction *actionSelectPreviousTileset() const; AbstractTool *selectedTool() const; + void setSelectedTool(AbstractTool *tool); + + Q_INVOKABLE AbstractTool *tool(const QByteArray &id) const; signals: void currentBrushChanged(); void currentWangSetChanged(); void currentWangColorIndexChanged(int colorIndex); + void selectedToolChanged(AbstractTool *tool); private: - void setSelectedTool(AbstractTool *tool); + void onSelectedToolChanged(AbstractTool *tool); void currentDocumentChanged(Document *document); void updateActiveUndoStack(); @@ -224,4 +228,9 @@ inline MapView *MapEditor::currentMapView() const return viewForDocument(mCurrentMapDocument); } +inline AbstractTool *MapEditor::selectedTool() const +{ + return mSelectedTool; +} + } // namespace Tiled diff --git a/src/tiled/toolmanager.cpp b/src/tiled/toolmanager.cpp index 682e4b6d4e..0418e862f2 100644 --- a/src/tiled/toolmanager.cpp +++ b/src/tiled/toolmanager.cpp @@ -181,6 +181,17 @@ bool ToolManager::selectTool(AbstractTool *tool) return tool == nullptr; } +AbstractTool *ToolManager::findTool(Id id) +{ + const auto actions = mActionGroup->actions(); + for (QAction *action : actions) { + AbstractTool *abstractTool = action->data().value(); + if (abstractTool->id() == id) + return abstractTool; + } + return nullptr; +} + QAction *ToolManager::findAction(AbstractTool *tool) const { const auto actions = mActionGroup->actions(); diff --git a/src/tiled/toolmanager.h b/src/tiled/toolmanager.h index 6017669c2a..823eaf63d4 100644 --- a/src/tiled/toolmanager.h +++ b/src/tiled/toolmanager.h @@ -20,6 +20,7 @@ #pragma once +#include "id.h" #include "layer.h" #include @@ -63,6 +64,7 @@ class ToolManager : public QObject template Tool *findTool(); + AbstractTool *findTool(Id id); QAction *findAction(AbstractTool *tool) const;