Skip to content

Commit

Permalink
Scripting: Added Tool.targetLayerType
Browse files Browse the repository at this point in the history
This new property specifies the target layer type for which this tool
should be enabled, providing a convenient alternative to implementing
Tool.updateEnabledState.

Closes mapeditor#3248
  • Loading branch information
bjorn committed Feb 28, 2023
1 parent f18b4bf commit cf1b45e
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 26 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Scripting: Added tiled.projectFilePath
* Scripting: Added tiled.versionLessThan
* Scripting: Added TileMap.toImage (#3519)
* Scripting: Added Tool.targetLayerType (#3248)
* Scripting: Added region.contiguousRegions() (#3576)
* Scripting: Allow assigning null to Tile.objectGroup (by Logan Higinbotham, #3495)
* Scripting: Allow changing the items in a combo box added to a dialog
Expand Down
17 changes: 17 additions & 0 deletions docs/scripting-doc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,11 @@ declare class Tile extends TiledObject {
* The base class of the various supported layer types.
*/
declare class Layer extends TiledObject {
static readonly TileLayerType: number
static readonly ObjectGroupType: number
static readonly ImageLayerType: number
static readonly GroupLayerType: number

/**
* Unique (map-wide) ID of the layer
*
Expand Down Expand Up @@ -3271,6 +3276,18 @@ interface Tool {
*/
usesWangSets: boolean;

/**
* The target layer type for which this tool should be enabled. A convenient
* alternative to overriding {@link updateEnabledState}.
*
* The value can be any combination of the layer types
* {@link Layer.TileLayerType}, {@link Layer.ObjectGroupType},
* {@link Layer.ImageLayerType} and {@link Layer.GroupLayerType}.
*
* @since 1.10
*/
targetLayerType: number;

/**
* Called when the tool was activated.
*/
Expand Down
7 changes: 2 additions & 5 deletions src/tiled/abstractobjecttool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ AbstractObjectTool::AbstractObjectTool(Id id,
QObject *parent)
: AbstractTool(id, name, icon, shortcut, parent)
{
setTargetLayerType(Layer::ObjectGroupType);

QIcon flipHorizontalIcon(QLatin1String(":images/24/flip-horizontal.png"));
QIcon flipVerticalIcon(QLatin1String(":images/24/flip-vertical.png"));
QIcon rotateLeftIcon(QLatin1String(":images/24/rotate-left.png"));
Expand Down Expand Up @@ -241,11 +243,6 @@ void AbstractObjectTool::filterMapObjects(QList<MapObject *> &mapObjects) const
}
}

void AbstractObjectTool::updateEnabledState()
{
setEnabled(currentObjectGroup() != nullptr);
}

ObjectGroup *AbstractObjectTool::currentObjectGroup() const
{
if (!mapDocument())
Expand Down
6 changes: 0 additions & 6 deletions src/tiled/abstractobjecttool.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ class AbstractObjectTool : public AbstractTool
void filterMapObjects(QList<MapObject*> &mapObjects) const;

protected:
/**
* Overridden to only enable this tool when the currently selected layer is
* an object group.
*/
void updateEnabledState() override;

ObjectGroup *currentObjectGroup() const;
QList<MapObject*> mapObjectsAt(const QPointF &pos) const;
MapObject *topMostMapObjectAt(const QPointF &pos) const;
Expand Down
9 changes: 7 additions & 2 deletions src/tiled/abstracttiletool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "mapdocument.h"
#include "maprenderer.h"
#include "mapscene.h"
#include "tile.h"
#include "tilelayer.h"
#include "tilestamp.h"

Expand All @@ -45,6 +44,8 @@ AbstractTileTool::AbstractTileTool(Id id,
, mBrushItem(brushItem)
, mBrushVisible(false)
{
setTargetLayerType(Layer::TileLayerType);

if (!mBrushItem)
mBrushItem = new BrushItem;
mBrushItem->setVisible(false);
Expand Down Expand Up @@ -160,7 +161,7 @@ void AbstractTileTool::mapDocumentChanged(MapDocument *oldDocument,

void AbstractTileTool::updateEnabledState()
{
setEnabled(currentTileLayer() != nullptr);
AbstractTool::updateEnabledState();
updateBrushVisibility();
}

Expand Down Expand Up @@ -212,6 +213,9 @@ TileLayer *AbstractTileTool::currentTileLayer() const

void AbstractTileTool::updateBrushVisibility()
{
if (!mBrushItem)
return;

// Show the tile brush only when at least one target layer is visible
bool showBrush = false;
if (mBrushVisible) {
Expand All @@ -223,6 +227,7 @@ void AbstractTileTool::updateBrushVisibility()
}
}
}

mBrushItem->setVisible(showBrush);
}

Expand Down
20 changes: 19 additions & 1 deletion src/tiled/abstracttool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ void AbstractTool::setVisible(bool visible)
emit visibleChanged(visible);
}

void AbstractTool::setTargetLayerType(int targetLayerType)
{
if (mTargetLayerType == targetLayerType)
return;

mTargetLayerType = targetLayerType;
updateEnabledState();
}

Tile *AbstractTool::tile() const
{
return toolManager()->tile();
Expand Down Expand Up @@ -170,7 +179,16 @@ void AbstractTool::changeEvent(const ChangeEvent &event)

void AbstractTool::updateEnabledState()
{
setEnabled(mMapDocument != nullptr);
// By default, no tool is enabled when there is no map selected
bool enabled = mMapDocument != nullptr;

// If a target layer type is set, check if the current layer matches
if (mTargetLayerType) {
auto layer = currentLayer();
enabled &= layer && layer->layerType() & mTargetLayerType;
}

setEnabled(enabled);
}

Layer *AbstractTool::currentLayer() const
Expand Down
11 changes: 11 additions & 0 deletions src/tiled/abstracttool.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "changeevents.h"
#include "id.h"
#include "layer.h"

#include <QCursor>
#include <QGraphicsSceneMouseEvent>
Expand Down Expand Up @@ -70,6 +71,7 @@ class AbstractTool : public QObject
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(bool usesSelectedTiles READ usesSelectedTiles WRITE setUsesSelectedTiles)
Q_PROPERTY(bool usesWangSets READ usesWangSets WRITE setUsesWangSets)
Q_PROPERTY(int targetLayerType READ targetLayerType WRITE setTargetLayerType)

public:
/**
Expand Down Expand Up @@ -111,6 +113,9 @@ class AbstractTool : public QObject
bool usesWangSets() const;
void setUsesWangSets(bool usesWangSets);

int targetLayerType() const;
void setTargetLayerType(int targetLayerType);

ToolManager *toolManager() const;
Tile *tile() const;
ObjectTemplate *objectTemplate() const;
Expand Down Expand Up @@ -231,6 +236,7 @@ class AbstractTool : public QObject
bool mVisible = true;
bool mUsesSelectedTiles = false;
bool mUsesWangSets = false;
int mTargetLayerType = 0;

ToolManager *mToolManager = nullptr;
MapDocument *mMapDocument = nullptr;
Expand Down Expand Up @@ -304,6 +310,11 @@ inline void AbstractTool::setUsesWangSets(bool usesWangSets)
mUsesWangSets = usesWangSets;
}

inline int AbstractTool::targetLayerType() const
{
return mTargetLayerType;
}

/**
* Returns the ToolManager with which this tool is registered, if any.
*/
Expand Down
9 changes: 9 additions & 0 deletions src/tiled/editablelayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ class EditableLayer : public EditableObject
Q_PROPERTY(bool isImageLayer READ isImageLayer CONSTANT)

public:
// Synchronized with Layer::LayerType
enum TypeFlag {
TileLayerType = 0x01,
ObjectGroupType = 0x02,
ImageLayerType = 0x04,
GroupLayerType = 0x08
};
Q_ENUM(TypeFlag)

explicit EditableLayer(std::unique_ptr<Layer> layer,
QObject *parent = nullptr);

Expand Down
7 changes: 1 addition & 6 deletions src/tiled/layeroffsettool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include "changelayer.h"
#include "grouplayer.h"
#include "layermodel.h"
#include "mapdocument.h"
#include "maprenderer.h"
#include "mapscene.h"
Expand All @@ -47,6 +46,7 @@ LayerOffsetTool::LayerOffsetTool(QObject *parent)
, mDragging(false)
, mApplyingChange(false)
{
setTargetLayerType(Layer::AnyLayerType);
}

void LayerOffsetTool::mouseEntered()
Expand Down Expand Up @@ -139,11 +139,6 @@ void LayerOffsetTool::languageChanged()
setName(tr("Offset Layers"));
}

void LayerOffsetTool::updateEnabledState()
{
setEnabled(currentLayer());
}

void LayerOffsetTool::mapDocumentChanged(MapDocument *oldDocument,
MapDocument *newDocument)
{
Expand Down
3 changes: 0 additions & 3 deletions src/tiled/layeroffsettool.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ class LayerOffsetTool : public AbstractTool

void languageChanged() override;

protected slots:
void updateEnabledState() override;

protected:
void mapDocumentChanged(MapDocument *oldDocument,
MapDocument *newDocument) override;
Expand Down
12 changes: 9 additions & 3 deletions src/tiled/scriptedtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ ScriptedTool::ScriptedTool(Id id, QJSValue object, QObject *parent)
: AbstractTileTool(id, QStringLiteral("<unnamed tool>"), QIcon(), QKeySequence(), nullptr, parent)
, mScriptObject(std::move(object))
{
setTargetLayerType(0); // default behavior is not to disable based on current layer

const QJSValue nameProperty = mScriptObject.property(QStringLiteral("name"));
if (nameProperty.isString())
setName(nameProperty.toString());
Expand All @@ -68,6 +70,10 @@ ScriptedTool::ScriptedTool(Id id, QJSValue object, QObject *parent)
if (usesWangSetsProperty.isBool())
setUsesWangSets(usesWangSetsProperty.toBool());

const QJSValue targetLayerTypeProperty = mScriptObject.property(QStringLiteral("targetLayerType"));
if (targetLayerTypeProperty.isNumber())
setTargetLayerType(targetLayerTypeProperty.toInt());

// Make members of ScriptedTool available through the original object
auto &scriptManager = ScriptManager::instance();
auto self = scriptManager.engine()->newQObject(this);
Expand Down Expand Up @@ -302,10 +308,10 @@ void ScriptedTool::updateStatusInfo()
void ScriptedTool::updateEnabledState()
{
if (!call(QStringLiteral("updateEnabledState"))) {
// Skipping AbstractTileTool since we do not want the enabled state to
// automatically depend on any selected tile layers.
AbstractTool::updateEnabledState();
AbstractTileTool::updateEnabledState();
return;
}

updateBrushVisibility();
}

Expand Down

0 comments on commit cf1b45e

Please sign in to comment.