diff --git a/NEWS.md b/NEWS.md index 714bb2f432..1b12dafb56 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ * Persisted collapsed state of the properties groups in the session (#4561) * Scripting: Added 'tiled.cell' function, 'cell.flags' property and 'TileLayerEdit.setCell' function (#4538) * Scripting: Added MapObject.resolvedClassName() (by MatusGuy, #4529) +* Scripting: Added Tileset.selectedTilesChanged signal (#4615) * Fixed crash when the selection becomes empty while starting a move (#4536) * Fixed Properties view update on 'Reset Template Instance' and 'Replace With Template' actions * Fixed restoring of the layout for maximized windows on startup (#4580) diff --git a/docs/scripting-doc/index.d.ts b/docs/scripting-doc/index.d.ts index ba2e6ebb07..7e8989010a 100644 --- a/docs/scripting-doc/index.d.ts +++ b/docs/scripting-doc/index.d.ts @@ -4288,6 +4288,13 @@ declare class Tileset extends Asset { */ selectedTiles: Tile[]; + /** + * The signal emitted when {@link selectedTiles} changes. + * + * @since 1.13 + */ + readonly selectedTilesChanged: Signal; + /** * Constructs a new Tileset. */ diff --git a/src/tiled/editableobject.cpp b/src/tiled/editableobject.cpp index c868124ef4..59913e66f2 100644 --- a/src/tiled/editableobject.cpp +++ b/src/tiled/editableobject.cpp @@ -53,7 +53,7 @@ void EditableObject::setPropertyImpl(const QString &name, const QVariant &value) { if (Document *doc = document()) asset()->push(new SetProperty(doc, { mObject }, name, propertyValueFromScript(value))); - else + else if (!checkReadOnly()) mObject->setProperty(name, propertyValueFromScript(value)); } @@ -67,7 +67,7 @@ void EditableObject::setPropertyImpl(const QStringList &path, const QVariant &va if (Document *doc = document()) // todo: add support for array indices in path asset()->push(new SetProperty(doc, { mObject }, toPropertyPath(path), propertyValueFromScript(value))); - else + else if (!checkReadOnly()) mObject->setProperty(toPropertyPath(path), propertyValueFromScript(value)); } @@ -75,7 +75,7 @@ void EditableObject::setProperties(const QVariantMap &properties) { if (Document *doc = document()) asset()->push(new ChangeProperties(doc, QString(), mObject, propertyValueFromScript(properties))); - else + else if (!checkReadOnly()) mObject->setProperties(propertyValueFromScript(properties)); } diff --git a/src/tiled/editabletileset.cpp b/src/tiled/editabletileset.cpp index 008ab6412e..ef0e6a7dc0 100644 --- a/src/tiled/editabletileset.cpp +++ b/src/tiled/editabletileset.cpp @@ -422,6 +422,7 @@ void EditableTileset::setDocument(Document *document) connect(doc, &TilesetDocument::tilesAdded, this, &EditableTileset::attachTiles); connect(doc, &TilesetDocument::tilesRemoved, this, &EditableTileset::detachTiles); connect(doc, &TilesetDocument::tileObjectGroupChanged, this, &EditableTileset::tileObjectGroupChanged); + connect(doc, &TilesetDocument::selectedTilesChanged, this, &EditableTileset::selectedTilesChanged); connect(doc->wangSetModel(), &TilesetWangSetModel::wangSetAdded, this, &EditableTileset::wangSetAdded); connect(doc->wangSetModel(), &TilesetWangSetModel::wangSetRemoved, this, &EditableTileset::wangSetRemoved); } diff --git a/src/tiled/editabletileset.h b/src/tiled/editabletileset.h index 21f8422183..ca1cd18493 100644 --- a/src/tiled/editabletileset.h +++ b/src/tiled/editabletileset.h @@ -60,7 +60,7 @@ class EditableTileset final : public EditableAsset Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(bool collection READ isCollection) // deprecated Q_PROPERTY(bool isCollection READ isCollection) - Q_PROPERTY(QList selectedTiles READ selectedTiles WRITE setSelectedTiles) + Q_PROPERTY(QList selectedTiles READ selectedTiles WRITE setSelectedTiles NOTIFY selectedTilesChanged) Q_PROPERTY(Tileset::TransformationFlags transformationFlags READ transformationFlags WRITE setTransformationFlags) public: @@ -188,6 +188,9 @@ public slots: void setBackgroundColor(const QColor &color); void setTransformationFlags(Tileset::TransformationFlags flags); +signals: + void selectedTilesChanged(); + protected: void setDocument(Document *document) override; diff --git a/src/tiled/tileseteditor.cpp b/src/tiled/tileseteditor.cpp index 280385d60c..2cf9bb206a 100644 --- a/src/tiled/tileseteditor.cpp +++ b/src/tiled/tileseteditor.cpp @@ -562,6 +562,10 @@ void TilesetEditor::selectionChanged() updateActions(); + // The view is being updated to match the document + if (mSynchronizingSelection) + return; + const QItemSelectionModel *s = view->selectionModel(); const QModelIndexList indexes = s->selection().indexes(); if (indexes.isEmpty()) @@ -574,7 +578,7 @@ void TilesetEditor::selectionChanged() if (Tile *tile = model->tileAt(index)) selectedTiles.append(tile); - QScopedValueRollback settingSelectedTiles(mSettingSelectedTiles, true); + QScopedValueRollback synchronizingSelection(mSynchronizingSelection, true); mCurrentTilesetDocument->setSelectedTiles(selectedTiles); } @@ -655,7 +659,8 @@ void TilesetEditor::tilesetChanged() void TilesetEditor::selectedTilesChanged() { - if (mSettingSelectedTiles) + // The document is being updated to match the view + if (mSynchronizingSelection) return; if (mCurrentTilesetDocument != sender()) @@ -671,6 +676,9 @@ void TilesetEditor::selectedTilesChanged() tileSelection.select(modelIndex, modelIndex); } + // Avoid setting the selection on the document again from selectionChanged + QScopedValueRollback synchronizingSelection(mSynchronizingSelection, true); + QItemSelectionModel *selectionModel = tilesetView->selectionModel(); selectionModel->select(tileSelection, QItemSelectionModel::SelectCurrent); if (!tileSelection.isEmpty()) { diff --git a/src/tiled/tileseteditor.h b/src/tiled/tileseteditor.h index f36805e506..d9df5b1647 100644 --- a/src/tiled/tileseteditor.h +++ b/src/tiled/tileseteditor.h @@ -182,7 +182,7 @@ class TilesetEditor final : public Editor TilesetDocument *mCurrentTilesetDocument = nullptr; Tile *mCurrentTile = nullptr; - bool mSettingSelectedTiles = false; + bool mSynchronizingSelection = false; }; inline QAction *TilesetEditor::addTilesAction() const