diff --git a/examples/examples.tiled-project b/examples/examples.tiled-project index 339734ee6c..ecfeddc2a1 100644 --- a/examples/examples.tiled-project +++ b/examples/examples.tiled-project @@ -10,7 +10,6 @@ "objectTypesFile": "objecttypes.xml", "propertyTypes": [ { - "color": "#a0a0a4", "id": 1, "name": "BodyType", "values": [ @@ -19,7 +18,6 @@ ] }, { - "color": "#a0a0a4", "id": 2, "name": "EnemyType", "values": [ @@ -29,7 +27,6 @@ ] }, { - "color": "#a0a0a4", "id": 3, "name": "State", "values": [ diff --git a/src/libtiled/containerhelpers.h b/src/libtiled/containerhelpers.h index 9e9fed140c..ea4012a0f7 100644 --- a/src/libtiled/containerhelpers.h +++ b/src/libtiled/containerhelpers.h @@ -51,3 +51,11 @@ inline bool contains(const Container &container, Value value) container.end(), value) != container.end(); } + +template +inline bool contains_where(const Container &container, Pred pred) +{ + return std::find_if(container.begin(), + container.end(), + pred) != container.end(); +} diff --git a/src/libtiled/propertytype.cpp b/src/libtiled/propertytype.cpp index 600e8577fa..e320a545e2 100644 --- a/src/libtiled/propertytype.cpp +++ b/src/libtiled/propertytype.cpp @@ -68,7 +68,6 @@ QVariantHash PropertyType::toVariant() const { QStringLiteral("id"), id }, { QStringLiteral("name"), name }, { QStringLiteral("values"), values }, - { QStringLiteral("color"), color }, }; } @@ -80,7 +79,6 @@ PropertyType PropertyType::fromVariant(const QVariant &variant) propertyType.id = hash.value(QStringLiteral("id")).toInt(); propertyType.name = hash.value(QStringLiteral("name")).toString(); propertyType.values = hash.value(QStringLiteral("values")).toStringList(); - propertyType.color = hash.value(QStringLiteral("color")).toString(); nextId = std::max(nextId, propertyType.id); diff --git a/src/libtiled/propertytype.h b/src/libtiled/propertytype.h index 4893250c94..89550e855f 100644 --- a/src/libtiled/propertytype.h +++ b/src/libtiled/propertytype.h @@ -39,18 +39,15 @@ namespace Tiled { /** - * Defines a custom property type. + * Defines a custom property type. Currently this includes only enums. */ class TILEDSHARED_EXPORT PropertyType { public: int id = 0; QString name; - QColor color = Qt::gray; QStringList values; - int valueType = QMetaType::Int; - static int nextId; QVariant wrap(const QVariant &value) const; diff --git a/src/tiled/mainwindow.cpp b/src/tiled/mainwindow.cpp index faaf55d87c..59cb726f90 100644 --- a/src/tiled/mainwindow.cpp +++ b/src/tiled/mainwindow.cpp @@ -798,7 +798,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) mShowObjectTypesEditor = new QAction(tr("Object Types Editor"), this); mShowObjectTypesEditor->setCheckable(true); - mShowPropertyTypesEditor = new QAction(tr("Property Types Editor"), this); + mShowPropertyTypesEditor = new QAction(tr("Enums Editor"), this); mShowPropertyTypesEditor->setCheckable(true); mUi->menuView->insertAction(mUi->actionShowGrid, mViewsAndToolbarsAction); @@ -2345,7 +2345,7 @@ void MainWindow::retranslateUi() mResetToDefaultLayout->setText(tr("Reset to Default Layout")); mLockLayout->setText(tr("Lock Layout")); mShowObjectTypesEditor->setText(tr("Object Types Editor")); - mShowPropertyTypesEditor->setText(tr("Property Types Editor")); + mShowPropertyTypesEditor->setText(tr("Enums Editor")); mActionHandler->retranslateUi(); CommandManager::instance()->retranslateUi(); } diff --git a/src/tiled/objecttypeseditor.cpp b/src/tiled/objecttypeseditor.cpp index fcf7318fc3..a8c633592d 100644 --- a/src/tiled/objecttypeseditor.cpp +++ b/src/tiled/objecttypeseditor.cpp @@ -44,6 +44,19 @@ namespace Tiled { +class ColorDelegate : public QStyledItemDelegate +{ +public: + explicit ColorDelegate(QObject *parent = nullptr) + : QStyledItemDelegate(parent) + { } + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &, + const QModelIndex &) const override; +}; void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, diff --git a/src/tiled/objecttypeseditor.h b/src/tiled/objecttypeseditor.h index 016b722156..a20815f042 100644 --- a/src/tiled/objecttypeseditor.h +++ b/src/tiled/objecttypeseditor.h @@ -36,21 +36,6 @@ class QtVariantPropertyManager; namespace Tiled { -class ColorDelegate : public QStyledItemDelegate -{ -public: - explicit ColorDelegate(QObject *parent = nullptr) - : QStyledItemDelegate(parent) - { } - - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; - - QSize sizeHint(const QStyleOptionViewItem &, - const QModelIndex &) const override; -}; - - class ObjectTypesModel; class ObjectTypesEditor : public QDialog diff --git a/src/tiled/propertytypeseditor.cpp b/src/tiled/propertytypeseditor.cpp index 7a3d9b7c63..22dc3cd354 100644 --- a/src/tiled/propertytypeseditor.cpp +++ b/src/tiled/propertytypeseditor.cpp @@ -21,9 +21,6 @@ #include "propertytypeseditor.h" #include "ui_propertytypeseditor.h" -// for colordelegate. -#include "objecttypeseditor.h" - #include "propertytypesmodel.h" #include "object.h" #include "preferences.h" @@ -34,7 +31,6 @@ #include "variantpropertymanager.h" #include -#include #include #include #include @@ -44,40 +40,19 @@ namespace Tiled { -class PropertyTypeValuesModel : public QStringListModel -{ - Q_OBJECT - -public: - using QStringListModel::QStringListModel; - - QVariant headerData(int section, Qt::Orientation orientation, int role) const override - { - if (section == 0 && orientation == Qt::Horizontal && role == Qt::DisplayRole) - return PropertyTypesEditor::tr("Values"); - return QStringListModel::headerData(section, orientation, role); - } -}; - PropertyTypesEditor::PropertyTypesEditor(QWidget *parent) : QDialog(parent) , mUi(new Ui::PropertyTypesEditor) , mPropertyTypesModel(new PropertyTypesModel(this)) - , mDetailsModel(new PropertyTypeValuesModel(this)) + , mValuesModel(new QStringListModel(this)) { mUi->setupUi(this); resize(Utils::dpiScaled(size())); - mUi->propertyTypesTable->setModel(mPropertyTypesModel); - mUi->propertyTypesTable->setItemDelegateForColumn(1, new Tiled::ColorDelegate(this)); - - QHeaderView *horizontalHeader = mUi->propertyTypesTable->horizontalHeader(); - horizontalHeader->setSectionResizeMode(0, QHeaderView::Stretch); - horizontalHeader->setSectionResizeMode(1, QHeaderView::Fixed); - horizontalHeader->resizeSection(1, Utils::dpiScaled(50)); + mUi->propertyTypesView->setModel(mPropertyTypesModel); - mUi->detailsTable->setModel(mDetailsModel); - mUi->detailsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); + mUi->valuesView->setModel(mValuesModel); + mUi->valuesView->setSelectionMode(QAbstractItemView::ExtendedSelection); mAddPropertyTypeAction = new QAction(this); mRemovePropertyTypeAction = new QAction(this); @@ -87,12 +62,14 @@ PropertyTypesEditor::PropertyTypesEditor(QWidget *parent) mRemovePropertyTypeAction->setEnabled(false); mAddValueAction->setEnabled(false); mRemoveValueAction->setEnabled(false); + mRemoveValueAction->setPriority(QAction::LowPriority); QIcon addIcon(QLatin1String(":/images/22/add.png")); QIcon removeIcon(QLatin1String(":/images/22/remove.png")); mAddPropertyTypeAction->setIcon(addIcon); mRemovePropertyTypeAction->setIcon(removeIcon); + mRemovePropertyTypeAction->setPriority(QAction::LowPriority); mAddValueAction->setIcon(addIcon); mRemoveValueAction->setIcon(removeIcon); @@ -105,11 +82,13 @@ PropertyTypesEditor::PropertyTypesEditor(QWidget *parent) stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QToolBar *propertyTypesToolBar = new QToolBar(this); + propertyTypesToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); propertyTypesToolBar->setIconSize(Utils::smallIconSize()); propertyTypesToolBar->addAction(mAddPropertyTypeAction); propertyTypesToolBar->addAction(mRemovePropertyTypeAction); QToolBar *propertiesToolBar = new QToolBar(this); + propertiesToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); propertiesToolBar->setIconSize(Utils::smallIconSize()); propertiesToolBar->addAction(mAddValueAction); propertiesToolBar->addAction(mRemoveValueAction); @@ -117,14 +96,12 @@ PropertyTypesEditor::PropertyTypesEditor(QWidget *parent) mUi->propertyTypesLayout->addWidget(propertyTypesToolBar); mUi->typeDetailsLayout->addWidget(propertiesToolBar); - connect(mUi->propertyTypesTable->selectionModel(), &QItemSelectionModel::selectionChanged, + connect(mUi->propertyTypesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PropertyTypesEditor::selectedPropertyTypesChanged); - connect(mUi->detailsTable->selectionModel(), &QItemSelectionModel::selectionChanged, + connect(mUi->valuesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PropertyTypesEditor::updateActions); connect(mPropertyTypesModel, &PropertyTypesModel::modelReset, this, &PropertyTypesEditor::selectFirstPropertyType); - connect(mUi->propertyTypesTable, &QAbstractItemView::doubleClicked, - this, &PropertyTypesEditor::propertyTypeIndexClicked); connect(mAddPropertyTypeAction, &QAction::triggered, this, &PropertyTypesEditor::addPropertyType); @@ -136,23 +113,28 @@ PropertyTypesEditor::PropertyTypesEditor(QWidget *parent) connect(mRemoveValueAction, &QAction::triggered, this, &PropertyTypesEditor::removeValues); - connect(mPropertyTypesModel, &PropertyTypesModel::dataChanged, + connect(mPropertyTypesModel, &PropertyTypesModel::nameChanged, + this, &PropertyTypesEditor::propertyTypeNameChanged); + connect(mPropertyTypesModel, &QAbstractItemModel::dataChanged, this, &PropertyTypesEditor::applyPropertyTypes); - connect(mPropertyTypesModel, &PropertyTypesModel::rowsInserted, + connect(mPropertyTypesModel, &QAbstractItemModel::rowsInserted, this, &PropertyTypesEditor::applyPropertyTypes); - connect(mPropertyTypesModel, &PropertyTypesModel::rowsRemoved, + connect(mPropertyTypesModel, &QAbstractItemModel::rowsRemoved, this, &PropertyTypesEditor::applyPropertyTypes); - connect(mDetailsModel, &QAbstractItemModel::dataChanged, + connect(mValuesModel, &QAbstractItemModel::dataChanged, this, &PropertyTypesEditor::valuesChanged); - connect(mDetailsModel, &QAbstractTableModel::rowsInserted, + connect(mValuesModel, &QAbstractItemModel::rowsInserted, this, &PropertyTypesEditor::valuesChanged); - connect(mDetailsModel, &QAbstractTableModel::rowsRemoved, + connect(mValuesModel, &QAbstractItemModel::rowsRemoved, this, &PropertyTypesEditor::valuesChanged); + connect(mUi->nameEdit, &QLineEdit::textEdited, + this, &PropertyTypesEditor::nameChanged); Preferences *prefs = Preferences::instance(); mPropertyTypesModel->setPropertyTypes(Object::propertyTypes()); - connect(prefs, &Preferences::propertyTypesChanged, this, &PropertyTypesEditor::propertyTypesChanged); + connect(prefs, &Preferences::propertyTypesChanged, + this, &PropertyTypesEditor::propertyTypesChanged); retranslateUi(); } @@ -183,8 +165,8 @@ void PropertyTypesEditor::changeEvent(QEvent *e) void PropertyTypesEditor::retranslateUi() { - mAddPropertyTypeAction->setText(tr("Add Property Type")); - mRemovePropertyTypeAction->setText(tr("Remove Property Type")); + mAddPropertyTypeAction->setText(tr("Add Enum")); + mRemovePropertyTypeAction->setText(tr("Remove Enum")); mAddValueAction->setText(tr("Add Value")); mRemoveValueAction->setText(tr("Remove Value")); @@ -195,35 +177,50 @@ void PropertyTypesEditor::addPropertyType() const QModelIndex newIndex = mPropertyTypesModel->addNewPropertyType(); // Select and focus the new row and ensure it is visible - QItemSelectionModel *sm = mUi->propertyTypesTable->selectionModel(); + QItemSelectionModel *sm = mUi->propertyTypesView->selectionModel(); sm->select(newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); sm->setCurrentIndex(newIndex, QItemSelectionModel::Current); - mUi->propertyTypesTable->edit(newIndex); + mUi->propertyTypesView->edit(newIndex); } void PropertyTypesEditor::selectedPropertyTypesChanged() { - const QItemSelectionModel *sm = mUi->propertyTypesTable->selectionModel(); + const QItemSelectionModel *sm = mUi->propertyTypesView->selectionModel(); mRemovePropertyTypeAction->setEnabled(sm->hasSelection()); updateValues(); } void PropertyTypesEditor::removeSelectedPropertyTypes() { - const QItemSelectionModel *sm = mUi->propertyTypesTable->selectionModel(); + // Cancel potential editor first, since letting it apply can cause + // reordering of the types in setData, which would cause the wrong types to + // get removed. + mUi->propertyTypesView->closePersistentEditor(mUi->propertyTypesView->currentIndex()); + + const QItemSelectionModel *sm = mUi->propertyTypesView->selectionModel(); mPropertyTypesModel->removePropertyTypes(sm->selectedRows()); } -void PropertyTypesEditor::propertyTypeIndexClicked(const QModelIndex &index) +/** + * Returns the index of the currently selected property type, or an invalid + * index if no or multiple property types are selected. + */ +QModelIndex PropertyTypesEditor::selectedPropertyTypeIndex() const { - if (index.column() == 1) { - QColor color = mPropertyTypesModel->propertyTypes().at(index.row()).color; - QColor newColor = QColorDialog::getColor(color, this); - if (newColor.isValid()) - mPropertyTypesModel->setPropertyTypeColor(index.row(), newColor); - } + const auto selectionModel = mUi->propertyTypesView->selectionModel(); + const QModelIndexList selectedRows = selectionModel->selectedRows(); + return selectedRows.size() == 1 ? selectedRows.first() : QModelIndex(); +} + +void PropertyTypesEditor::propertyTypeNameChanged(const QModelIndex &index, const PropertyType &type) +{ + if (mSettingName) + return; + + if (index == selectedPropertyTypeIndex()) + mUi->nameEdit->setText(type.name); } void PropertyTypesEditor::applyPropertyTypes() @@ -265,58 +262,51 @@ static QString nextValueText(const PropertyType &propertyType) void PropertyTypesEditor::addValue() { - const auto selectionModel = mUi->propertyTypesTable->selectionModel(); - const QModelIndexList selectedRows = selectionModel->selectedRows(); - if (selectedRows.size() != 1) + const auto selectedTypeIndex = selectedPropertyTypeIndex(); + if (!selectedTypeIndex.isValid()) return; - const int row = mDetailsModel->rowCount(); - if (!mDetailsModel->insertRow(row)) + const int row = mValuesModel->rowCount(); + if (!mValuesModel->insertRow(row)) return; - const PropertyType propertyType = mPropertyTypesModel->propertyTypeAt(selectedRows.first()); + const PropertyType propertyType = mPropertyTypesModel->propertyTypeAt(selectedTypeIndex); const QString valueText = nextValueText(propertyType); - const auto valueIndex = mDetailsModel->index(row); - mUi->detailsTable->setCurrentIndex(valueIndex); - mDetailsModel->setData(valueIndex, valueText, Qt::DisplayRole); - mUi->detailsTable->edit(valueIndex); + const auto valueIndex = mValuesModel->index(row); + mUi->valuesView->setCurrentIndex(valueIndex); + mValuesModel->setData(valueIndex, valueText, Qt::DisplayRole); + mUi->valuesView->edit(valueIndex); } void PropertyTypesEditor::removeValues() { - const QItemSelection selection = mUi->detailsTable->selectionModel()->selection(); + const QItemSelection selection = mUi->valuesView->selectionModel()->selection(); for (const QItemSelectionRange &range : selection) - mDetailsModel->removeRows(range.top(), range.height()); + mValuesModel->removeRows(range.top(), range.height()); } void PropertyTypesEditor::updateValues() { - const auto selectionModel = mUi->propertyTypesTable->selectionModel(); - const auto selectedRows = selectionModel->selectedRows(); - - QScopedValueRollback touchingValues(mTouchingValues, true); - // again.. should just be one. Maybe a more elegant way to do this ? - if (selectedRows.size() == 1) { - const QModelIndex &index = selectedRows.first(); - const PropertyType propertyType = mPropertyTypesModel->propertyTypeAt(index); - mDetailsModel->setStringList(propertyType.values); - } else { - mDetailsModel->setStringList({}); - } + const auto selectedTypeIndex = selectedPropertyTypeIndex(); + const PropertyType propertyType = mPropertyTypesModel->propertyTypeAt(selectedTypeIndex); + + QScopedValueRollback touchingValues(mUpdatingValues, true); + + mValuesModel->setStringList(propertyType.values); + mUi->nameEdit->setText(propertyType.name); + mUi->nameEdit->setEnabled(selectedTypeIndex.isValid()); updateActions(); } void PropertyTypesEditor::updateActions() { - const auto typesSelectionModel = mUi->propertyTypesTable->selectionModel(); - const auto selectedTypes = typesSelectionModel->selectedRows(); - - const auto valuesSelectionModel = mUi->detailsTable->selectionModel(); + const auto selectedTypeIndex = selectedPropertyTypeIndex(); + const auto valuesSelectionModel = mUi->valuesView->selectionModel(); const auto selectedValues = valuesSelectionModel->selectedRows(); - mAddValueAction->setEnabled(selectedTypes.size() == 1); + mAddValueAction->setEnabled(selectedTypeIndex.isValid()); mRemoveValueAction->setEnabled(!selectedValues.isEmpty()); } @@ -324,37 +314,40 @@ void PropertyTypesEditor::selectFirstPropertyType() { const QModelIndex firstIndex = mPropertyTypesModel->index(0, 0); if (firstIndex.isValid()) { - mUi->propertyTypesTable->selectionModel()->select(firstIndex, - QItemSelectionModel::ClearAndSelect | - QItemSelectionModel::Rows); + mUi->propertyTypesView->selectionModel()->select(firstIndex, + QItemSelectionModel::ClearAndSelect | + QItemSelectionModel::Rows); } else { // make sure the properties view is empty updateValues(); } } -void PropertyTypesEditor::recalculateValues() +void PropertyTypesEditor::valuesChanged() { - const auto selectionModel = mUi->propertyTypesTable->selectionModel(); - const auto selectedRows = selectionModel->selectedRows(); - - // there should be just one for editing. if more than one - don't do anything - if (selectedRows.size() == 1) { - const QModelIndex &index = selectedRows.first(); - const QStringList newValues = mDetailsModel->stringList(); - mPropertyTypesModel->setPropertyTypeValues(index.row(), newValues); - } + if (mUpdatingValues) + return; + + const auto index = selectedPropertyTypeIndex(); + if (!index.isValid()) + return; + + const QStringList newValues = mValuesModel->stringList(); + mPropertyTypesModel->setPropertyTypeValues(index.row(), newValues); + + applyPropertyTypes(); } -void PropertyTypesEditor::valuesChanged() +void PropertyTypesEditor::nameChanged(const QString &name) { - if (!mTouchingValues) { - recalculateValues(); - applyPropertyTypes(); - } + const auto index = selectedPropertyTypeIndex(); + if (!index.isValid()) + return; + + QScopedValueRollback settingName(mSettingName, true); + mPropertyTypesModel->setPropertyTypeName(index.row(), name); } } // namespace Tiled -#include "propertytypeseditor.moc" #include "moc_propertytypeseditor.cpp" diff --git a/src/tiled/propertytypeseditor.h b/src/tiled/propertytypeseditor.h index d85353c2c9..910e7b7db8 100644 --- a/src/tiled/propertytypeseditor.h +++ b/src/tiled/propertytypeseditor.h @@ -53,7 +53,10 @@ class PropertyTypesEditor : public QDialog void addPropertyType(); void selectedPropertyTypesChanged(); void removeSelectedPropertyTypes(); - void propertyTypeIndexClicked(const QModelIndex &index); + QModelIndex selectedPropertyTypeIndex() const; + + void propertyTypeNameChanged(const QModelIndex &index, + const PropertyType &type); void applyPropertyTypes(); void propertyTypesChanged(); @@ -65,18 +68,17 @@ class PropertyTypesEditor : public QDialog void selectFirstPropertyType(); void valuesChanged(); + void nameChanged(const QString &name); - void recalculateValues(); void retranslateUi(); - void createValue(int row, const QString &name); - Ui::PropertyTypesEditor *mUi; PropertyTypesModel *mPropertyTypesModel; - QStringListModel *mDetailsModel; + QStringListModel *mValuesModel; bool mSettingPrefPropertyTypes = false; - bool mTouchingValues = false; + bool mSettingName = false; + bool mUpdatingValues = false; QAction *mAddPropertyTypeAction; QAction *mRemovePropertyTypeAction; diff --git a/src/tiled/propertytypeseditor.ui b/src/tiled/propertytypeseditor.ui index b2fc3167ec..4a82009bff 100644 --- a/src/tiled/propertytypeseditor.ui +++ b/src/tiled/propertytypeseditor.ui @@ -6,83 +6,100 @@ 0 0 - 652 - 398 + 650 + 326 - Property Types Editor + Enums Editor true - + - - - Qt::Horizontal + + + Enums - - - - 0 - - - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - - - - - - - - 0 - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - false - - - Qt::LeftToRight - - - false - - - false - - - true - - - - - + + + + + 0 + + + + + + 0 + 0 + + + + QAbstractItemView::SelectRows + + + false + + + true + + + true + + + + + + + + + + + Name + + + nameEdit + + + + + + + + + + Values + + + valuesView + + + + + + + 0 + + + + + false + + + true + + + true + + + + + + + + diff --git a/src/tiled/propertytypesmodel.cpp b/src/tiled/propertytypesmodel.cpp index df5aaa955f..c8ded940eb 100644 --- a/src/tiled/propertytypesmodel.cpp +++ b/src/tiled/propertytypesmodel.cpp @@ -20,11 +20,13 @@ #include "propertytypesmodel.h" +#include "containerhelpers.h" + using namespace Tiled; static bool propertyTypeLessThan(const PropertyType &a, const PropertyType &b) { - return a.name.toLower() < b.name.toLower(); + return QString::localeAwareCompare(a.name, b.name) < 0; } void PropertyTypesModel::setPropertyTypes(const PropertyTypes &propertyTypes) @@ -48,31 +50,6 @@ int PropertyTypesModel::rowCount(const QModelIndex &parent) const return parent.isValid() ? 0 : mPropertyTypes.size(); } -int PropertyTypesModel::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : 2; -} - -QVariant PropertyTypesModel::headerData(int section, - Qt::Orientation orientation, - int role) const -{ - if (orientation == Qt::Horizontal) { - if (role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Type"); - case 1: - return tr("Color"); - } - } else if (role == Qt::TextAlignmentRole) { - return Qt::AlignLeft; - } - } - - return QVariant(); -} - QVariant PropertyTypesModel::data(const QModelIndex &index, int role) const { // QComboBox requests data for an invalid index when the model is empty @@ -85,9 +62,6 @@ QVariant PropertyTypesModel::data(const QModelIndex &index, int role) const if (index.column() == 0) return propertyType.name; - if (role == ColorRole && index.column() == 1) - return propertyType.color; - return QVariant(); } @@ -96,30 +70,7 @@ bool PropertyTypesModel::setData(const QModelIndex &index, int role) { if (role == Qt::EditRole && index.column() == 0) { - const int oldRow = index.row(); - - PropertyType propertyType = mPropertyTypes.at(oldRow); - propertyType.name = value.toString().trimmed(); - - auto nextPropertyType = std::lower_bound(mPropertyTypes.constBegin(), - mPropertyTypes.constEnd(), - propertyType, - propertyTypeLessThan); - - const int newRow = nextPropertyType - mPropertyTypes.constBegin(); - // QVector::move works differently from beginMoveRows - const int moveToRow = newRow > oldRow ? newRow - 1 : newRow; - - mPropertyTypes[oldRow].name = propertyType.name; - emit dataChanged(index, index); - - if (moveToRow != oldRow) { - Q_ASSERT(newRow != oldRow); - Q_ASSERT(newRow != oldRow + 1); - beginMoveRows(QModelIndex(), oldRow, oldRow, QModelIndex(), newRow); - mPropertyTypes.move(oldRow, moveToRow); - endMoveRows(); - } + setPropertyTypeName(index.row(), value.toString()); return true; } return false; @@ -127,24 +78,44 @@ bool PropertyTypesModel::setData(const QModelIndex &index, Qt::ItemFlags PropertyTypesModel::flags(const QModelIndex &index) const { - Qt::ItemFlags f = QAbstractTableModel::flags(index); + Qt::ItemFlags f = QAbstractListModel::flags(index); if (index.column() == 0) f |= Qt::ItemIsEditable; return f; } -void PropertyTypesModel::setPropertyTypeColor(int objectIndex, const QColor &color) +void PropertyTypesModel::setPropertyTypeName(int row, const QString &name) { - mPropertyTypes[objectIndex].color = color; - - const QModelIndex mi = index(objectIndex, 1); - emit dataChanged(mi, mi); + PropertyType propertyType = mPropertyTypes.at(row); + propertyType.name = name.trimmed(); + + auto nextPropertyType = std::lower_bound(mPropertyTypes.constBegin(), + mPropertyTypes.constEnd(), + propertyType, + propertyTypeLessThan); + + const int newRow = nextPropertyType - mPropertyTypes.constBegin(); + // QVector::move works differently from beginMoveRows + const int moveToRow = newRow > row ? newRow - 1 : newRow; + + mPropertyTypes[row].name = propertyType.name; + const auto index = this->index(row); + emit nameChanged(index, mPropertyTypes[row]); + emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole }); + + if (moveToRow != row) { + Q_ASSERT(newRow != row); + Q_ASSERT(newRow != row + 1); + beginMoveRows(QModelIndex(), row, row, QModelIndex(), newRow); + mPropertyTypes.move(row, moveToRow); + endMoveRows(); + } } -void PropertyTypesModel::setPropertyTypeValues(int objectIndex, +void PropertyTypesModel::setPropertyTypeValues(int index, const QStringList &values) { - mPropertyTypes[objectIndex].values = values; + mPropertyTypes[index].values = values; } void PropertyTypesModel::removePropertyTypes(const QModelIndexList &indexes) @@ -165,12 +136,29 @@ void PropertyTypesModel::removePropertyTypes(const QModelIndexList &indexes) QModelIndex PropertyTypesModel::addNewPropertyType() { - beginInsertRows(QModelIndex(), 0, 0); + const int row = mPropertyTypes.size(); + beginInsertRows(QModelIndex(), row, row); PropertyType propertyType; propertyType.id = ++PropertyType::nextId; - mPropertyTypes.prepend(propertyType); + propertyType.name = nextPropertyTypeName(); + mPropertyTypes.append(propertyType); endInsertRows(); - return index(0, 0); + return index(row, 0); +} + +QString PropertyTypesModel::nextPropertyTypeName() const +{ + const auto baseText = tr("Enum"); + + // Search for a unique value, starting from the current count + int number = mPropertyTypes.count(); + QString name; + do { + name = baseText + QString::number(number++); + } while (contains_where(mPropertyTypes, + [&] (const PropertyType &type) { return type.name == name; })); + + return name; } diff --git a/src/tiled/propertytypesmodel.h b/src/tiled/propertytypesmodel.h index 30cd0b1bed..72f6ec7c5b 100644 --- a/src/tiled/propertytypesmodel.h +++ b/src/tiled/propertytypesmodel.h @@ -20,24 +20,22 @@ #pragma once -#include - -#include "propertytype.h" -#include "properties.h" #include "object.h" -#include +#include "properties.h" +#include "propertytype.h" + +#include +#include namespace Tiled { -class PropertyTypesModel : public QAbstractTableModel +class PropertyTypesModel : public QAbstractListModel { Q_OBJECT public: - enum { ColorRole = Qt::UserRole }; - PropertyTypesModel(QObject *parent = nullptr) - : QAbstractTableModel(parent) + : QAbstractListModel(parent) { } @@ -47,23 +45,24 @@ class PropertyTypesModel : public QAbstractTableModel PropertyType propertyTypeAt(const QModelIndex &index) const; int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - - QVariant headerData(int section, Qt::Orientation orientation, - int role) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role) override; Qt::ItemFlags flags(const QModelIndex &index) const override; - void setPropertyTypeColor(int objectIndex, const QColor &color); - void setPropertyTypeValues(int objectIndex, const QStringList &values); + void setPropertyTypeName(int row, const QString &name); + void setPropertyTypeValues(int index, const QStringList &values); void removePropertyTypes(const QModelIndexList &indexes); +signals: + void nameChanged(const QModelIndex &index, const PropertyType &type); + public slots: QModelIndex addNewPropertyType(); private: + QString nextPropertyTypeName() const; + PropertyTypes mPropertyTypes; };