From 006572ae30b091d607d20fbe2b4251a58a2478ed Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 14 Jun 2024 21:21:07 -0400 Subject: [PATCH 1/9] expose tiled.project.propertyTypes to scripting, starting with some read-only propertie --- src/tiled/editableproject.cpp | 5 ++ src/tiled/editableproject.h | 4 +- src/tiled/libtilededitor.qbs | 2 + src/tiled/scriptmanager.cpp | 2 + src/tiled/scriptpropertytypes.cpp | 58 ++++++++++++++ src/tiled/scriptpropertytypes.h | 125 ++++++++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/tiled/scriptpropertytypes.cpp create mode 100644 src/tiled/scriptpropertytypes.h diff --git a/src/tiled/editableproject.cpp b/src/tiled/editableproject.cpp index 85e4108367..fa73f836b9 100644 --- a/src/tiled/editableproject.cpp +++ b/src/tiled/editableproject.cpp @@ -51,6 +51,11 @@ QStringList EditableProject::folders() const return project()->folders(); } +ScriptPropertyTypes *EditableProject::propertyTypes() const +{ + return new ScriptPropertyTypes(project()->propertyTypes()); +} + bool EditableProject::isReadOnly() const { return false; diff --git a/src/tiled/editableproject.h b/src/tiled/editableproject.h index 16a3913718..15c0e2116c 100644 --- a/src/tiled/editableproject.h +++ b/src/tiled/editableproject.h @@ -23,6 +23,7 @@ #include "editableasset.h" #include "project.h" +#include "scriptpropertytypes.h" #include @@ -38,6 +39,7 @@ class EditableProject final : public EditableAsset Q_PROPERTY(QString automappingRulesFile READ automappingRulesFile) Q_PROPERTY(QString fileName READ fileName) Q_PROPERTY(QStringList folders READ folders) + Q_PROPERTY(ScriptPropertyTypes *propertyTypes READ propertyTypes) public: EditableProject(ProjectDocument *projectDocument, QObject *parent = nullptr); @@ -49,7 +51,7 @@ class EditableProject final : public EditableAsset QString automappingRulesFile() const; QString fileName() const; QStringList folders() const; - + ScriptPropertyTypes *propertyTypes() const; Project *project() const; QSharedPointer createDocument() override; diff --git a/src/tiled/libtilededitor.qbs b/src/tiled/libtilededitor.qbs index 9e576776b4..d0ac26d075 100644 --- a/src/tiled/libtilededitor.qbs +++ b/src/tiled/libtilededitor.qbs @@ -463,6 +463,8 @@ DynamicLibrary { "scriptmodule.h", "scriptprocess.cpp", "scriptprocess.h", + "scriptpropertytypes.cpp", + "scriptpropertytypes.h", "selectionrectangle.cpp", "selectionrectangle.h", "selectsametiletool.cpp", diff --git a/src/tiled/scriptmanager.cpp b/src/tiled/scriptmanager.cpp index fc36e682da..f83bcb858a 100644 --- a/src/tiled/scriptmanager.cpp +++ b/src/tiled/scriptmanager.cpp @@ -49,6 +49,7 @@ #include "scriptimage.h" #include "scriptmodule.h" #include "scriptprocess.h" +#include "scriptpropertytypes.h" #include "tilecollisiondock.h" #include "tilelayer.h" #include "tilelayeredit.h" @@ -414,6 +415,7 @@ void ScriptManager::initialize() registerFileInfo(engine); registerGeometry(engine); registerProcess(engine); + registerPropertyTypes(engine); loadExtensions(); } diff --git a/src/tiled/scriptpropertytypes.cpp b/src/tiled/scriptpropertytypes.cpp new file mode 100644 index 0000000000..13410a198d --- /dev/null +++ b/src/tiled/scriptpropertytypes.cpp @@ -0,0 +1,58 @@ +/* + * scriptimage.cpp + * Copyright 2020, Thorbjørn Lindeijer + * + * This file is part of Tiled. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "scriptpropertytypes.h" + +namespace Tiled { + +QString ScriptPropertyType::name() const +{ + return mType->name; +} + +size_t ScriptPropertyTypes::count() +{ + return mTypes->count(); +} + +ScriptPropertyType *ScriptPropertyTypes::findTypeByName(const QString &name) +{ + const PropertyType *type = mTypes->findTypeByName(name); + if (!type) + return nullptr; + + if (type->isEnum()) + return new ScriptEnumPropertyType(static_cast(type)); + + if (type->isClass()) + return new ScriptClassPropertyType(static_cast(type)); + + return new ScriptPropertyType(type); +} + +void registerPropertyTypes(QJSEngine *jsEngine) +{ + jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), + jsEngine->newQMetaObject()); +} + +} // namespace Tiled + +#include "moc_scriptpropertytypes.cpp" diff --git a/src/tiled/scriptpropertytypes.h b/src/tiled/scriptpropertytypes.h new file mode 100644 index 0000000000..9404be08fe --- /dev/null +++ b/src/tiled/scriptpropertytypes.h @@ -0,0 +1,125 @@ +/* + * scriptimage.h + * Copyright 2020, Thorbjørn Lindeijer + * + * This file is part of Tiled. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#pragma once + +#include "propertytype.h" + +#include +#include + +namespace Tiled { +/** + * Scripting engine wrapper for PropertyType + */ +class ScriptPropertyType : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name) + Q_PROPERTY(bool isClass READ isClass) + Q_PROPERTY(bool isEnum READ isEnum) + Q_PROPERTY(QVariant defaultValue READ defaultValue) + +public: + ScriptPropertyType(const PropertyType *propertyType) + : mType(propertyType) + {} + + QString name() const; + bool isClass() const { return mType->isClass(); } + bool isEnum() const { return mType->isEnum(); } + QVariant defaultValue() { return mType->defaultValue(); } + +private: + const PropertyType *mType; +}; + +class ScriptEnumPropertyType : public ScriptPropertyType +{ + Q_OBJECT + + Q_PROPERTY(StorageType storageType READ storageType) + Q_PROPERTY(QStringList values READ values) + +public: + ScriptEnumPropertyType(const EnumPropertyType *propertyType) + : mEnumType(propertyType), + ScriptPropertyType(propertyType) + {} + // copied from propertytype.h + enum StorageType { + StringValue, + IntValue + }; + Q_ENUM(StorageType); + + StorageType storageType() const { return static_cast(mEnumType->storageType); } + QStringList values() const { return mEnumType->values; } + +private: + const EnumPropertyType *mEnumType; +}; + +class ScriptClassPropertyType : public ScriptPropertyType +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color) + +public: + ScriptClassPropertyType(const ClassPropertyType *propertyType) + : mClassType(propertyType), + ScriptPropertyType(propertyType) + {} + QColor color() const { return mClassType->color; } + // TODO: " No viable overloaded '=' " + // void setColor(const QColor &value) { mClassType->color = value; } + +private: + + const ClassPropertyType *mClassType; +}; + + +/** + * Scripting engine wrapper for SharedPropertyTypes + */ +class ScriptPropertyTypes : public QObject +{ + Q_OBJECT + Q_PROPERTY(size_t count READ count) + +public: + ScriptPropertyTypes(SharedPropertyTypes sharedPropertyTypes) + : mTypes(sharedPropertyTypes) + {} + size_t count(); + Q_INVOKABLE ScriptPropertyType *findTypeByName(const QString &name); + +private: + SharedPropertyTypes mTypes; +}; + +void registerPropertyTypes(QJSEngine *jsEngine); + +} // namespace Tiled + +Q_DECLARE_METATYPE(Tiled::ScriptPropertyTypes*) +Q_DECLARE_METATYPE(Tiled::ScriptPropertyType*) + From f00655ba9be30dc6f0b27b6a9319f8160a0a08e2 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 14 Jun 2024 22:40:26 -0400 Subject: [PATCH 2/9] rename findTypeByName to findByName, starting to add removal of types --- src/libtiled/propertytype.cpp | 15 ++++++++++++ src/libtiled/propertytype.h | 1 + src/tiled/scriptpropertytypes.cpp | 38 +++++++++++++++++++++++++++++-- src/tiled/scriptpropertytypes.h | 16 ++++++++++++- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/libtiled/propertytype.cpp b/src/libtiled/propertytype.cpp index 5200877d16..4a92a4468b 100644 --- a/src/libtiled/propertytype.cpp +++ b/src/libtiled/propertytype.cpp @@ -536,6 +536,21 @@ const PropertyType *PropertyTypes::findTypeById(int typeId) const return it == mTypes.end() ? nullptr : *it; } +/** + * Returns a pointer to the PropertyType matching the given \a typeId, or + * nullptr if it can't be found. + */ +const int PropertyTypes::findIndexByName(const QString &name) const +{ + if (name.isEmpty()) + return -1; + + for (int i =0; iname == name) + return i; + + return -1; +} /** * Returns a pointer to the PropertyType matching the given \a name and * \a usageFlags, or nullptr if it can't be found. diff --git a/src/libtiled/propertytype.h b/src/libtiled/propertytype.h index 99969713fa..f5184a0bc8 100644 --- a/src/libtiled/propertytype.h +++ b/src/libtiled/propertytype.h @@ -200,6 +200,7 @@ class TILEDSHARED_EXPORT PropertyTypes void mergeObjectTypes(const QVector &objectTypes); const PropertyType *findTypeById(int typeId) const; + const int findIndexByName(const QString &name) const; const PropertyType *findTypeByName(const QString &name, int usageFlags = ClassPropertyType::AnyUsage) const; const PropertyType *findPropertyValueType(const QString &name) const; const ClassPropertyType *findClassFor(const QString &name, const Object &object) const; diff --git a/src/tiled/scriptpropertytypes.cpp b/src/tiled/scriptpropertytypes.cpp index 13410a198d..a4dc877653 100644 --- a/src/tiled/scriptpropertytypes.cpp +++ b/src/tiled/scriptpropertytypes.cpp @@ -19,6 +19,9 @@ */ #include "scriptpropertytypes.h" +#include "preferences.h" +#include "project.h" +#include "projectmanager.h" namespace Tiled { @@ -32,9 +35,8 @@ size_t ScriptPropertyTypes::count() return mTypes->count(); } -ScriptPropertyType *ScriptPropertyTypes::findTypeByName(const QString &name) +ScriptPropertyType *ScriptPropertyTypes::toScriptType(const PropertyType *type) const { - const PropertyType *type = mTypes->findTypeByName(name); if (!type) return nullptr; @@ -47,6 +49,38 @@ ScriptPropertyType *ScriptPropertyTypes::findTypeByName(const QString &name) return new ScriptPropertyType(type); } +ScriptPropertyType *ScriptPropertyTypes::findByName(const QString &name) +{ + const PropertyType *type = mTypes->findTypeByName(name); + return toScriptType(type); +} + +void ScriptPropertyTypes::removeByName(const QString &name) +{ + int index = mTypes->findIndexByName(name); + if (index < 0 ) + return + + mTypes->removeAt(index); + applyPropertyChanges(); +} + +// TODO remove if we can implement an iterator +QVectorScriptPropertyTypes::all() const +{ + QVector scriptTypes; + for (const PropertyType *type : *mTypes) + scriptTypes.append(toScriptType(type)); + return scriptTypes; +} + +void ScriptPropertyTypes::applyPropertyChanges() +{ + emit Preferences::instance()->propertyTypesChanged(); + + Project &project = ProjectManager::instance()->project(); + project.save(); +} void registerPropertyTypes(QJSEngine *jsEngine) { jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), diff --git a/src/tiled/scriptpropertytypes.h b/src/tiled/scriptpropertytypes.h index 9404be08fe..345526fc55 100644 --- a/src/tiled/scriptpropertytypes.h +++ b/src/tiled/scriptpropertytypes.h @@ -23,6 +23,7 @@ #include "propertytype.h" #include +#include #include namespace Tiled { @@ -104,15 +105,28 @@ class ScriptPropertyTypes : public QObject { Q_OBJECT Q_PROPERTY(size_t count READ count) + Q_PROPERTY(QVector all READ all) public: ScriptPropertyTypes(SharedPropertyTypes sharedPropertyTypes) : mTypes(sharedPropertyTypes) {} size_t count(); - Q_INVOKABLE ScriptPropertyType *findTypeByName(const QString &name); + Q_INVOKABLE void removeByName(const QString &name); + Q_INVOKABLE ScriptPropertyType *findByName(const QString &name); + QVector all() const; + + // TODO: when I don't have a list of ScriptPropertyType, + // how can i make this iterable? + // Enable easy iteration over objects with range-based for + // QList::iterator begin() { return mTypes->begin(); } + // QList::iterator end() { return mTypes->end(); } + // QList::const_iterator begin() const { return mTypes->begin(); } + // QList::const_iterator end() const { return mTypes->end(); } private: + ScriptPropertyType *toScriptType(const PropertyType *type) const; + void applyPropertyChanges(); SharedPropertyTypes mTypes; }; From ab7edce9e91867b5c45599c9fbad01cc5fa0c5d9 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 14 Jun 2024 23:12:20 -0400 Subject: [PATCH 3/9] try adding iterator to tiled.project.propertyTypes. currently it throws a type error --- src/tiled/scriptpropertytypes.cpp | 9 ++++++++- src/tiled/scriptpropertytypes.h | 20 +++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/tiled/scriptpropertytypes.cpp b/src/tiled/scriptpropertytypes.cpp index a4dc877653..82cc4dacd2 100644 --- a/src/tiled/scriptpropertytypes.cpp +++ b/src/tiled/scriptpropertytypes.cpp @@ -19,7 +19,6 @@ */ #include "scriptpropertytypes.h" -#include "preferences.h" #include "project.h" #include "projectmanager.h" @@ -61,6 +60,7 @@ void ScriptPropertyTypes::removeByName(const QString &name) if (index < 0 ) return + // TODO the type isn't actually being deleted even when index >= 0 mTypes->removeAt(index); applyPropertyChanges(); } @@ -81,6 +81,13 @@ void ScriptPropertyTypes::applyPropertyChanges() Project &project = ProjectManager::instance()->project(); project.save(); } + +void ScriptPropertyTypes::propertyTypesChanged() +{ + mAllScriptTypes.clear(); + for (PropertyType *type : *mTypes) + mAllScriptTypes.append(toScriptType(type)); +} void registerPropertyTypes(QJSEngine *jsEngine) { jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), diff --git a/src/tiled/scriptpropertytypes.h b/src/tiled/scriptpropertytypes.h index 345526fc55..6244e4930f 100644 --- a/src/tiled/scriptpropertytypes.h +++ b/src/tiled/scriptpropertytypes.h @@ -20,6 +20,7 @@ #pragma once +#include "preferences.h" #include "propertytype.h" #include @@ -110,23 +111,28 @@ class ScriptPropertyTypes : public QObject public: ScriptPropertyTypes(SharedPropertyTypes sharedPropertyTypes) : mTypes(sharedPropertyTypes) - {} + { + connect(Preferences::instance(), &Preferences::propertyTypesChanged, this, &ScriptPropertyTypes::propertyTypesChanged); + propertyTypesChanged(); + } size_t count(); Q_INVOKABLE void removeByName(const QString &name); Q_INVOKABLE ScriptPropertyType *findByName(const QString &name); QVector all() const; - // TODO: when I don't have a list of ScriptPropertyType, - // how can i make this iterable? + // TODO: how to make this class iterable so you can loop through it to pull up + // each property type? // Enable easy iteration over objects with range-based for - // QList::iterator begin() { return mTypes->begin(); } - // QList::iterator end() { return mTypes->end(); } - // QList::const_iterator begin() const { return mTypes->begin(); } - // QList::const_iterator end() const { return mTypes->end(); } + QList::iterator begin() { return mAllScriptTypes.begin(); } + QList::iterator end() { return mAllScriptTypes.end(); } + QList::const_iterator begin() const { return mAllScriptTypes.begin(); } + QList::const_iterator end() const { return mAllScriptTypes.end(); } private: ScriptPropertyType *toScriptType(const PropertyType *type) const; void applyPropertyChanges(); + void propertyTypesChanged(); + QList mAllScriptTypes; SharedPropertyTypes mTypes; }; From f30dfdc708b30b7d8ec5b9a31c7d4cba8de6e3b5 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 15 Jun 2024 14:22:46 -0400 Subject: [PATCH 4/9] remove iterator from ScriptPropertyTypes (use tiled.project.propertyTypes.all instead) and add getter for class property members. getting members of class types does not work though --- src/tiled/scriptpropertytypes.cpp | 6 ------ src/tiled/scriptpropertytypes.h | 19 ++++--------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/tiled/scriptpropertytypes.cpp b/src/tiled/scriptpropertytypes.cpp index 82cc4dacd2..dcc30bd615 100644 --- a/src/tiled/scriptpropertytypes.cpp +++ b/src/tiled/scriptpropertytypes.cpp @@ -82,12 +82,6 @@ void ScriptPropertyTypes::applyPropertyChanges() project.save(); } -void ScriptPropertyTypes::propertyTypesChanged() -{ - mAllScriptTypes.clear(); - for (PropertyType *type : *mTypes) - mAllScriptTypes.append(toScriptType(type)); -} void registerPropertyTypes(QJSEngine *jsEngine) { jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), diff --git a/src/tiled/scriptpropertytypes.h b/src/tiled/scriptpropertytypes.h index 6244e4930f..654c87c299 100644 --- a/src/tiled/scriptpropertytypes.h +++ b/src/tiled/scriptpropertytypes.h @@ -83,13 +83,15 @@ class ScriptClassPropertyType : public ScriptPropertyType { Q_OBJECT Q_PROPERTY(QColor color READ color) - + Q_PROPERTY(QVariantMap members READ members) + public: ScriptClassPropertyType(const ClassPropertyType *propertyType) : mClassType(propertyType), ScriptPropertyType(propertyType) {} QColor color() const { return mClassType->color; } + QVariantMap members() const {return mClassType->members; } // TODO: " No viable overloaded '=' " // void setColor(const QColor &value) { mClassType->color = value; } @@ -111,28 +113,15 @@ class ScriptPropertyTypes : public QObject public: ScriptPropertyTypes(SharedPropertyTypes sharedPropertyTypes) : mTypes(sharedPropertyTypes) - { - connect(Preferences::instance(), &Preferences::propertyTypesChanged, this, &ScriptPropertyTypes::propertyTypesChanged); - propertyTypesChanged(); - } + {} size_t count(); Q_INVOKABLE void removeByName(const QString &name); Q_INVOKABLE ScriptPropertyType *findByName(const QString &name); QVector all() const; - // TODO: how to make this class iterable so you can loop through it to pull up - // each property type? - // Enable easy iteration over objects with range-based for - QList::iterator begin() { return mAllScriptTypes.begin(); } - QList::iterator end() { return mAllScriptTypes.end(); } - QList::const_iterator begin() const { return mAllScriptTypes.begin(); } - QList::const_iterator end() const { return mAllScriptTypes.end(); } - private: ScriptPropertyType *toScriptType(const PropertyType *type) const; void applyPropertyChanges(); - void propertyTypesChanged(); - QList mAllScriptTypes; SharedPropertyTypes mTypes; }; From 185c5ef243e5abb05ddb9f94df81b73245181bc7 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 15 Jun 2024 15:19:38 -0400 Subject: [PATCH 5/9] restructure the property types API to make tiled.project.propertyTypes a list of types and move the utility methods for custom types to tiled.project --- src/tiled/editableproject.cpp | 54 ++++++++++- src/tiled/editableproject.h | 13 ++- src/tiled/libtilededitor.qbs | 4 +- src/tiled/scriptmanager.cpp | 2 +- src/tiled/scriptpropertytype.cpp | 40 ++++++++ ...ptpropertytypes.h => scriptpropertytype.h} | 27 +----- src/tiled/scriptpropertytypes.cpp | 93 ------------------- 7 files changed, 102 insertions(+), 131 deletions(-) create mode 100644 src/tiled/scriptpropertytype.cpp rename src/tiled/{scriptpropertytypes.h => scriptpropertytype.h} (80%) delete mode 100644 src/tiled/scriptpropertytypes.cpp diff --git a/src/tiled/editableproject.cpp b/src/tiled/editableproject.cpp index fa73f836b9..3da7b08a40 100644 --- a/src/tiled/editableproject.cpp +++ b/src/tiled/editableproject.cpp @@ -20,8 +20,8 @@ */ #include "editableproject.h" - #include "projectdocument.h" +#include "projectmanager.h" namespace Tiled { @@ -51,10 +51,6 @@ QStringList EditableProject::folders() const return project()->folders(); } -ScriptPropertyTypes *EditableProject::propertyTypes() const -{ - return new ScriptPropertyTypes(project()->propertyTypes()); -} bool EditableProject::isReadOnly() const { @@ -68,6 +64,54 @@ QSharedPointer EditableProject::createDocument() return nullptr; } + +ScriptPropertyType *EditableProject::toScriptType(const PropertyType *type) const +{ + if (!type) + return nullptr; + + if (type->isEnum()) + return new ScriptEnumPropertyType(static_cast(type)); + + if (type->isClass()) + return new ScriptClassPropertyType(static_cast(type)); + + return new ScriptPropertyType(type); +} + +ScriptPropertyType *EditableProject::findTypeByName(const QString &name) +{ + const PropertyType *type = project()->propertyTypes()->findTypeByName(name); + return toScriptType(type); +} + +void EditableProject::removeTypeByName(const QString &name) +{ + int index = project()->propertyTypes()->findIndexByName(name); + if (index < 0 ) + return + + // TODO the type isn't actually being deleted even when index >= 0 + project()->propertyTypes()->removeAt(index); + applyPropertyChanges(); +} + +QVectorEditableProject::propertyTypes() const +{ + QVector scriptTypes; + for (const PropertyType *type : *project()->propertyTypes()) + scriptTypes.append(toScriptType(type)); + return scriptTypes; +} + +void EditableProject::applyPropertyChanges() +{ + emit Preferences::instance()->propertyTypesChanged(); + + Project &project = ProjectManager::instance()->project(); + project.save(); +} + } // namespace Tiled #include "moc_editableproject.cpp" diff --git a/src/tiled/editableproject.h b/src/tiled/editableproject.h index 15c0e2116c..19be670cf8 100644 --- a/src/tiled/editableproject.h +++ b/src/tiled/editableproject.h @@ -23,7 +23,7 @@ #include "editableasset.h" #include "project.h" -#include "scriptpropertytypes.h" +#include "scriptpropertytype.h" #include @@ -39,8 +39,7 @@ class EditableProject final : public EditableAsset Q_PROPERTY(QString automappingRulesFile READ automappingRulesFile) Q_PROPERTY(QString fileName READ fileName) Q_PROPERTY(QStringList folders READ folders) - Q_PROPERTY(ScriptPropertyTypes *propertyTypes READ propertyTypes) - + Q_PROPERTY(QVector propertyTypes READ propertyTypes) public: EditableProject(ProjectDocument *projectDocument, QObject *parent = nullptr); @@ -51,10 +50,16 @@ class EditableProject final : public EditableAsset QString automappingRulesFile() const; QString fileName() const; QStringList folders() const; - ScriptPropertyTypes *propertyTypes() const; Project *project() const; QSharedPointer createDocument() override; + + Q_INVOKABLE void removeTypeByName(const QString &name); + Q_INVOKABLE ScriptPropertyType *findTypeByName(const QString &name); + QVector propertyTypes() const; +private: + ScriptPropertyType *toScriptType(const PropertyType *type) const; + void applyPropertyChanges(); }; inline Project *EditableProject::project() const diff --git a/src/tiled/libtilededitor.qbs b/src/tiled/libtilededitor.qbs index d0ac26d075..022ccd8474 100644 --- a/src/tiled/libtilededitor.qbs +++ b/src/tiled/libtilededitor.qbs @@ -463,8 +463,8 @@ DynamicLibrary { "scriptmodule.h", "scriptprocess.cpp", "scriptprocess.h", - "scriptpropertytypes.cpp", - "scriptpropertytypes.h", + "scriptpropertytype.cpp", + "scriptpropertytype.h", "selectionrectangle.cpp", "selectionrectangle.h", "selectsametiletool.cpp", diff --git a/src/tiled/scriptmanager.cpp b/src/tiled/scriptmanager.cpp index f83bcb858a..1fd697b737 100644 --- a/src/tiled/scriptmanager.cpp +++ b/src/tiled/scriptmanager.cpp @@ -49,7 +49,7 @@ #include "scriptimage.h" #include "scriptmodule.h" #include "scriptprocess.h" -#include "scriptpropertytypes.h" +#include "scriptpropertytype.h" #include "tilecollisiondock.h" #include "tilelayer.h" #include "tilelayeredit.h" diff --git a/src/tiled/scriptpropertytype.cpp b/src/tiled/scriptpropertytype.cpp new file mode 100644 index 0000000000..7cba9e06fd --- /dev/null +++ b/src/tiled/scriptpropertytype.cpp @@ -0,0 +1,40 @@ +/* + * scriptimage.cpp + * Copyright 2020, Thorbjørn Lindeijer + * + * This file is part of Tiled. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "scriptpropertytype.h" +#include "project.h" +#include "projectmanager.h" + +namespace Tiled { + +QString ScriptPropertyType::name() const +{ + return mType->name; +} + +void registerPropertyTypes(QJSEngine *jsEngine) +{ + jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), + jsEngine->newQMetaObject()); +} + +} // namespace Tiled + +#include "moc_scriptpropertytype.cpp" diff --git a/src/tiled/scriptpropertytypes.h b/src/tiled/scriptpropertytype.h similarity index 80% rename from src/tiled/scriptpropertytypes.h rename to src/tiled/scriptpropertytype.h index 654c87c299..3d2712f88e 100644 --- a/src/tiled/scriptpropertytypes.h +++ b/src/tiled/scriptpropertytype.h @@ -84,7 +84,7 @@ class ScriptClassPropertyType : public ScriptPropertyType Q_OBJECT Q_PROPERTY(QColor color READ color) Q_PROPERTY(QVariantMap members READ members) - + public: ScriptClassPropertyType(const ClassPropertyType *propertyType) : mClassType(propertyType), @@ -101,34 +101,9 @@ class ScriptClassPropertyType : public ScriptPropertyType }; -/** - * Scripting engine wrapper for SharedPropertyTypes - */ -class ScriptPropertyTypes : public QObject -{ - Q_OBJECT - Q_PROPERTY(size_t count READ count) - Q_PROPERTY(QVector all READ all) - -public: - ScriptPropertyTypes(SharedPropertyTypes sharedPropertyTypes) - : mTypes(sharedPropertyTypes) - {} - size_t count(); - Q_INVOKABLE void removeByName(const QString &name); - Q_INVOKABLE ScriptPropertyType *findByName(const QString &name); - QVector all() const; - -private: - ScriptPropertyType *toScriptType(const PropertyType *type) const; - void applyPropertyChanges(); - SharedPropertyTypes mTypes; -}; - void registerPropertyTypes(QJSEngine *jsEngine); } // namespace Tiled -Q_DECLARE_METATYPE(Tiled::ScriptPropertyTypes*) Q_DECLARE_METATYPE(Tiled::ScriptPropertyType*) diff --git a/src/tiled/scriptpropertytypes.cpp b/src/tiled/scriptpropertytypes.cpp deleted file mode 100644 index dcc30bd615..0000000000 --- a/src/tiled/scriptpropertytypes.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * scriptimage.cpp - * Copyright 2020, Thorbjørn Lindeijer - * - * This file is part of Tiled. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include "scriptpropertytypes.h" -#include "project.h" -#include "projectmanager.h" - -namespace Tiled { - -QString ScriptPropertyType::name() const -{ - return mType->name; -} - -size_t ScriptPropertyTypes::count() -{ - return mTypes->count(); -} - -ScriptPropertyType *ScriptPropertyTypes::toScriptType(const PropertyType *type) const -{ - if (!type) - return nullptr; - - if (type->isEnum()) - return new ScriptEnumPropertyType(static_cast(type)); - - if (type->isClass()) - return new ScriptClassPropertyType(static_cast(type)); - - return new ScriptPropertyType(type); -} - -ScriptPropertyType *ScriptPropertyTypes::findByName(const QString &name) -{ - const PropertyType *type = mTypes->findTypeByName(name); - return toScriptType(type); -} - -void ScriptPropertyTypes::removeByName(const QString &name) -{ - int index = mTypes->findIndexByName(name); - if (index < 0 ) - return - - // TODO the type isn't actually being deleted even when index >= 0 - mTypes->removeAt(index); - applyPropertyChanges(); -} - -// TODO remove if we can implement an iterator -QVectorScriptPropertyTypes::all() const -{ - QVector scriptTypes; - for (const PropertyType *type : *mTypes) - scriptTypes.append(toScriptType(type)); - return scriptTypes; -} - -void ScriptPropertyTypes::applyPropertyChanges() -{ - emit Preferences::instance()->propertyTypesChanged(); - - Project &project = ProjectManager::instance()->project(); - project.save(); -} - -void registerPropertyTypes(QJSEngine *jsEngine) -{ - jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), - jsEngine->newQMetaObject()); -} - -} // namespace Tiled - -#include "moc_scriptpropertytypes.cpp" From a8fb617693bee4dabc6d301030ecebeb069b60f9 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 15 Jun 2024 23:26:00 -0400 Subject: [PATCH 6/9] add ClassPropertyType.ClassUsageFlag, classType.usageFlags to scripting --- src/tiled/scriptpropertytype.cpp | 2 ++ src/tiled/scriptpropertytype.h | 29 +++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/tiled/scriptpropertytype.cpp b/src/tiled/scriptpropertytype.cpp index 7cba9e06fd..a5c2768384 100644 --- a/src/tiled/scriptpropertytype.cpp +++ b/src/tiled/scriptpropertytype.cpp @@ -33,6 +33,8 @@ void registerPropertyTypes(QJSEngine *jsEngine) { jsEngine->globalObject().setProperty(QStringLiteral("EnumPropertyType"), jsEngine->newQMetaObject()); + jsEngine->globalObject().setProperty(QStringLiteral("ClassPropertyType"), + jsEngine->newQMetaObject()); } } // namespace Tiled diff --git a/src/tiled/scriptpropertytype.h b/src/tiled/scriptpropertytype.h index 3d2712f88e..bf3554acf1 100644 --- a/src/tiled/scriptpropertytype.h +++ b/src/tiled/scriptpropertytype.h @@ -84,16 +84,41 @@ class ScriptClassPropertyType : public ScriptPropertyType Q_OBJECT Q_PROPERTY(QColor color READ color) Q_PROPERTY(QVariantMap members READ members) + Q_PROPERTY(bool drawFill READ drawFill) + Q_PROPERTY(int usageFlags READ usageFlags) public: ScriptClassPropertyType(const ClassPropertyType *propertyType) : mClassType(propertyType), ScriptPropertyType(propertyType) {} + + // TODO: a way to avoid duplicating this again? + enum ClassUsageFlag { + PropertyValueType = 0x001, + + // Keep values synchronized with Object::TypeId + LayerClass = 0x002, + MapObjectClass = 0x004, + MapClass = 0x008, + TilesetClass = 0x010, + TileClass = 0x020, + WangSetClass = 0x040, + WangColorClass = 0x080, + ProjectClass = 0x100, + AnyUsage = 0xFFF, + AnyObjectClass = AnyUsage & ~PropertyValueType, + }; + Q_ENUM(ClassUsageFlag) + QColor color() const { return mClassType->color; } - QVariantMap members() const {return mClassType->members; } // TODO: " No viable overloaded '=' " - // void setColor(const QColor &value) { mClassType->color = value; } + // void setColor(QColor &value) { mClassType->color = value; } + QVariantMap members() const {return mClassType->members; } + bool drawFill() const { return mClassType->drawFill; } + // void setDrawFill(bool value) { mClassType->drawFill = value; } + int usageFlags() const { return mClassType->usageFlags; } + //void setUsageFlags(int value) { mClassType->setUsageFlags(value); } private: From 17fbc284d374747105accc3fdd91eb867a1ab021 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 16 Jun 2024 21:41:11 -0400 Subject: [PATCH 7/9] fix comments in propertytype.cpp --- src/libtiled/propertytype.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtiled/propertytype.cpp b/src/libtiled/propertytype.cpp index 4a92a4468b..d40dec78d3 100644 --- a/src/libtiled/propertytype.cpp +++ b/src/libtiled/propertytype.cpp @@ -537,8 +537,8 @@ const PropertyType *PropertyTypes::findTypeById(int typeId) const } /** - * Returns a pointer to the PropertyType matching the given \a typeId, or - * nullptr if it can't be found. + * Returns the index of the type of the given name, + * or -1 if no such type is found. */ const int PropertyTypes::findIndexByName(const QString &name) const { From fe5c55ab330b3c7190459f60559a9d16468c7917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 18 Jun 2024 15:57:03 +0200 Subject: [PATCH 8/9] Minor code style changes --- src/libtiled/propertytype.cpp | 31 +++++++++++++------------ src/libtiled/propertytype.h | 3 ++- src/tiled/editableproject.cpp | 39 +++++++++++++++++--------------- src/tiled/editableproject.h | 5 +++- src/tiled/scriptpropertytype.cpp | 8 +++---- src/tiled/scriptpropertytype.h | 17 ++++++-------- 6 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/libtiled/propertytype.cpp b/src/libtiled/propertytype.cpp index d40dec78d3..f6c0b0b102 100644 --- a/src/libtiled/propertytype.cpp +++ b/src/libtiled/propertytype.cpp @@ -524,6 +524,22 @@ void PropertyTypes::mergeObjectTypes(const QVector &objectTypes) } } +/** + * Returns the index of the type of the given name, or -1 if no such type is + * found. + */ +int PropertyTypes::findIndexByName(const QString &name) const +{ + if (name.isEmpty()) + return -1; + + for (int i = 0; i < mTypes.count(); i++) + if (mTypes[i]->name == name) + return i; + + return -1; +} + /** * Returns a pointer to the PropertyType matching the given \a typeId, or * nullptr if it can't be found. @@ -536,21 +552,6 @@ const PropertyType *PropertyTypes::findTypeById(int typeId) const return it == mTypes.end() ? nullptr : *it; } -/** - * Returns the index of the type of the given name, - * or -1 if no such type is found. - */ -const int PropertyTypes::findIndexByName(const QString &name) const -{ - if (name.isEmpty()) - return -1; - - for (int i =0; iname == name) - return i; - - return -1; -} /** * Returns a pointer to the PropertyType matching the given \a name and * \a usageFlags, or nullptr if it can't be found. diff --git a/src/libtiled/propertytype.h b/src/libtiled/propertytype.h index f5184a0bc8..ba3b16bdf4 100644 --- a/src/libtiled/propertytype.h +++ b/src/libtiled/propertytype.h @@ -199,8 +199,9 @@ class TILEDSHARED_EXPORT PropertyTypes void merge(PropertyTypes types); void mergeObjectTypes(const QVector &objectTypes); + int findIndexByName(const QString &name) const; + const PropertyType *findTypeById(int typeId) const; - const int findIndexByName(const QString &name) const; const PropertyType *findTypeByName(const QString &name, int usageFlags = ClassPropertyType::AnyUsage) const; const PropertyType *findPropertyValueType(const QString &name) const; const ClassPropertyType *findClassFor(const QString &name, const Object &object) const; diff --git a/src/tiled/editableproject.cpp b/src/tiled/editableproject.cpp index 3da7b08a40..ab0efcb9a6 100644 --- a/src/tiled/editableproject.cpp +++ b/src/tiled/editableproject.cpp @@ -20,6 +20,8 @@ */ #include "editableproject.h" + +#include "preferences.h" #include "projectdocument.h" #include "projectmanager.h" @@ -31,6 +33,11 @@ EditableProject::EditableProject(ProjectDocument *projectDocument, QObject *pare setDocument(projectDocument); } +bool EditableProject::isReadOnly() const +{ + return false; +} + QString EditableProject::extensionsPath() const { return project()->mExtensionsPath; @@ -51,10 +58,12 @@ QStringList EditableProject::folders() const return project()->folders(); } - -bool EditableProject::isReadOnly() const +QVectorEditableProject::propertyTypes() const { - return false; + QVector scriptTypes; + for (const PropertyType *type : *project()->propertyTypes()) + scriptTypes.append(toScriptType(type)); + return scriptTypes; } QSharedPointer EditableProject::createDocument() @@ -64,19 +73,21 @@ QSharedPointer EditableProject::createDocument() return nullptr; } - ScriptPropertyType *EditableProject::toScriptType(const PropertyType *type) const { if (!type) return nullptr; - if (type->isEnum()) - return new ScriptEnumPropertyType(static_cast(type)); - - if (type->isClass()) + switch (type->type) { + case PropertyType::PT_Invalid: + break; + case PropertyType::PT_Class: return new ScriptClassPropertyType(static_cast(type)); + case PropertyType::PT_Enum: + return new ScriptEnumPropertyType(static_cast(type)); + } - return new ScriptPropertyType(type); + return nullptr; } ScriptPropertyType *EditableProject::findTypeByName(const QString &name) @@ -88,7 +99,7 @@ ScriptPropertyType *EditableProject::findTypeByName(const QString &name) void EditableProject::removeTypeByName(const QString &name) { int index = project()->propertyTypes()->findIndexByName(name); - if (index < 0 ) + if (index < 0) return // TODO the type isn't actually being deleted even when index >= 0 @@ -96,14 +107,6 @@ void EditableProject::removeTypeByName(const QString &name) applyPropertyChanges(); } -QVectorEditableProject::propertyTypes() const -{ - QVector scriptTypes; - for (const PropertyType *type : *project()->propertyTypes()) - scriptTypes.append(toScriptType(type)); - return scriptTypes; -} - void EditableProject::applyPropertyChanges() { emit Preferences::instance()->propertyTypesChanged(); diff --git a/src/tiled/editableproject.h b/src/tiled/editableproject.h index 19be670cf8..3b8d30ec8f 100644 --- a/src/tiled/editableproject.h +++ b/src/tiled/editableproject.h @@ -40,6 +40,7 @@ class EditableProject final : public EditableAsset Q_PROPERTY(QString fileName READ fileName) Q_PROPERTY(QStringList folders READ folders) Q_PROPERTY(QVector propertyTypes READ propertyTypes) + public: EditableProject(ProjectDocument *projectDocument, QObject *parent = nullptr); @@ -50,13 +51,15 @@ class EditableProject final : public EditableAsset QString automappingRulesFile() const; QString fileName() const; QStringList folders() const; + QVector propertyTypes() const; + Project *project() const; QSharedPointer createDocument() override; Q_INVOKABLE void removeTypeByName(const QString &name); Q_INVOKABLE ScriptPropertyType *findTypeByName(const QString &name); - QVector propertyTypes() const; + private: ScriptPropertyType *toScriptType(const PropertyType *type) const; void applyPropertyChanges(); diff --git a/src/tiled/scriptpropertytype.cpp b/src/tiled/scriptpropertytype.cpp index a5c2768384..3dc21eb42a 100644 --- a/src/tiled/scriptpropertytype.cpp +++ b/src/tiled/scriptpropertytype.cpp @@ -1,6 +1,6 @@ /* - * scriptimage.cpp - * Copyright 2020, Thorbjørn Lindeijer + * scriptpropertytype.cpp + * Copyright 2024, chris * * This file is part of Tiled. * @@ -19,12 +19,10 @@ */ #include "scriptpropertytype.h" -#include "project.h" -#include "projectmanager.h" namespace Tiled { -QString ScriptPropertyType::name() const +const QString &ScriptPropertyType::name() const { return mType->name; } diff --git a/src/tiled/scriptpropertytype.h b/src/tiled/scriptpropertytype.h index bf3554acf1..456db69be2 100644 --- a/src/tiled/scriptpropertytype.h +++ b/src/tiled/scriptpropertytype.h @@ -1,6 +1,6 @@ /* - * scriptimage.h - * Copyright 2020, Thorbjørn Lindeijer + * scriptpropertytype.h + * Copyright 2024, chris * * This file is part of Tiled. * @@ -20,7 +20,6 @@ #pragma once -#include "preferences.h" #include "propertytype.h" #include @@ -44,7 +43,7 @@ class ScriptPropertyType : public QObject : mType(propertyType) {} - QString name() const; + const QString &name() const; bool isClass() const { return mType->isClass(); } bool isEnum() const { return mType->isEnum(); } QVariant defaultValue() { return mType->defaultValue(); } @@ -62,8 +61,8 @@ class ScriptEnumPropertyType : public ScriptPropertyType public: ScriptEnumPropertyType(const EnumPropertyType *propertyType) - : mEnumType(propertyType), - ScriptPropertyType(propertyType) + : ScriptPropertyType(propertyType) + , mEnumType(propertyType) {} // copied from propertytype.h enum StorageType { @@ -89,8 +88,8 @@ class ScriptClassPropertyType : public ScriptPropertyType public: ScriptClassPropertyType(const ClassPropertyType *propertyType) - : mClassType(propertyType), - ScriptPropertyType(propertyType) + : ScriptPropertyType(propertyType) + , mClassType(propertyType) {} // TODO: a way to avoid duplicating this again? @@ -121,7 +120,6 @@ class ScriptClassPropertyType : public ScriptPropertyType //void setUsageFlags(int value) { mClassType->setUsageFlags(value); } private: - const ClassPropertyType *mClassType; }; @@ -131,4 +129,3 @@ void registerPropertyTypes(QJSEngine *jsEngine); } // namespace Tiled Q_DECLARE_METATYPE(Tiled::ScriptPropertyType*) - From e80e00bb346e532085e2ee15bd1337b163e6dca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 18 Jun 2024 16:56:53 +0200 Subject: [PATCH 9/9] Fixed removal of types by name ;) --- src/tiled/editableproject.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tiled/editableproject.cpp b/src/tiled/editableproject.cpp index ab0efcb9a6..3b3cd616b3 100644 --- a/src/tiled/editableproject.cpp +++ b/src/tiled/editableproject.cpp @@ -100,9 +100,8 @@ void EditableProject::removeTypeByName(const QString &name) { int index = project()->propertyTypes()->findIndexByName(name); if (index < 0) - return + return; - // TODO the type isn't actually being deleted even when index >= 0 project()->propertyTypes()->removeAt(index); applyPropertyChanges(); }