Skip to content

Commit

Permalink
Introduced ListEdit widget for the Properties view
Browse files Browse the repository at this point in the history
* VariantPropertyManager now displays the number of list items.

* VariantEditorFactory now instantiates a ListEdit widget when a list
  value is selected, which features a button to add an item to the list
  (currently just "0" integer values).
  • Loading branch information
bjorn committed Jul 10, 2024
1 parent 7ca8cc9 commit b93cb06
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 74 deletions.
8 changes: 0 additions & 8 deletions src/tiled/custompropertieshelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@ QtVariantProperty *CustomPropertiesHelper::createPropertyInternal(const QString
}
}
}
} else if (type == QMetaType::QVariantList) {
// In case of list values, we need an expandable property with the list
// values as subproperties (though creation of such properties will
// only be done once the value is set)

// todo: lists probably need their own type here, such that a widget
// can be created that allows for adding elements
type = VariantPropertyManager::unstyledGroupTypeId();
}

if (type == objectRefTypeId())
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/libtilededitor.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ DynamicLibrary {
"layermodel.h",
"layeroffsettool.cpp",
"layeroffsettool.h",
"listedit.cpp",
"listedit.h",
"locatorwidget.cpp",
"locatorwidget.h",
"magicwandtool.h",
Expand Down
88 changes: 88 additions & 0 deletions src/tiled/listedit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* listedit.h
* Copyright 2024, Thorbjørn Lindeijer <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

#include "listedit.h"

#include "utils.h"

#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>

namespace Tiled {

ListEdit::ListEdit(QWidget *parent)
: QWidget{parent}
{
QHBoxLayout *layout = new QHBoxLayout{this};
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);

mLabel = new QLabel{this};
mLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));

QToolButton *addButton = new QToolButton{this};
addButton->setIcon(QIcon(QStringLiteral(":/images/22/add.png")));
Utils::setThemeIcon(addButton, "add");

QToolButton *editButton = new QToolButton{this};
editButton->setSizePolicy(QSizePolicy{QSizePolicy::Fixed, QSizePolicy::Preferred});
editButton->setText(tr("Edit..."));
layout->addWidget(mLabel);
layout->addWidget(addButton);
layout->addWidget(editButton);

setFocusProxy(editButton);
setFocusPolicy(Qt::StrongFocus);

connect(addButton, &QToolButton::clicked,
this, &ListEdit::addButtonClicked);
connect(editButton, &QToolButton::clicked,
this, &ListEdit::editButtonClicked);
}

void ListEdit::setValue(const QVariantList &value)
{
mValue = value;
mLabel->setText(valueText(value));
}

QString ListEdit::valueText(const QVariantList &value)
{
return value.isEmpty() ? tr("<empty>")
: tr("%1 items").arg(value.count());
}

void ListEdit::addButtonClicked()
{
// todo: spawn a kind of "add property" dialog, but without a name field?
// or maybe add button is a dropdown with the available types?
mValue.append(0);
emit valueChanged(mValue);
}

void ListEdit::editButtonClicked()
{
// todo: spawn list edit dialog
}

} // namespace Tiled

#include "moc_listedit.cpp"
56 changes: 56 additions & 0 deletions src/tiled/listedit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* listedit.h
* Copyright 2024, Thorbjørn Lindeijer <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <QWidget>

class QLabel;

namespace Tiled {

/**
* The widget that enables the user to edit a list property.
*/
class ListEdit final : public QWidget
{
Q_OBJECT
Q_PROPERTY(QVariantList value READ value WRITE setValue NOTIFY valueChanged FINAL)

public:
explicit ListEdit(QWidget *parent = nullptr);

const QVariantList &value() const { return mValue; }
void setValue(const QVariantList &value);

static QString valueText(const QVariantList &value);

signals:
void valueChanged(const QVariantList &value);

private:
void addButtonClicked();
void editButtonClicked();

QLabel *mLabel;
QVariantList mValue;
};

} // namespace Tiled
1 change: 0 additions & 1 deletion src/tiled/objectrefedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#pragma once

#include "properties.h"
#include "variantpropertymanager.h"

#include <QWidget>
Expand Down
114 changes: 55 additions & 59 deletions src/tiled/varianteditorfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "varianteditorfactory.h"

#include "fileedit.h"
#include "listedit.h"
#include "objectrefedit.h"
#include "textpropertyedit.h"
#include "tilesetdocument.h"
Expand Down Expand Up @@ -89,6 +90,7 @@ VariantEditorFactory::~VariantEditorFactory()
qDeleteAll(mTextPropertyEditToProperty.keys());
qDeleteAll(mObjectRefEditToProperty.keys());
qDeleteAll(mComboBoxToProperty.keys());
qDeleteAll(mListEditToProperty.keys());
}

void VariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
Expand Down Expand Up @@ -145,6 +147,18 @@ QWidget *VariantEditorFactory::createEditor(QtVariantPropertyManager *manager,
this, &VariantEditorFactory::slotEditorDestroyed);

editor = tilesetEdit;
} else if (type == QMetaType::QVariantList) {
auto listEdit = new ListEdit(parent);
listEdit->setValue(manager->value(property).toList());
mCreatedListEdits[property].append(listEdit);
mListEditToProperty[listEdit] = property;

connect(listEdit, &ListEdit::valueChanged,
this, &VariantEditorFactory::listEditValueChanged);
connect(listEdit, &QObject::destroyed,
this, &VariantEditorFactory::slotEditorDestroyed);

editor = listEdit;
} else if (type == QMetaType::QString) {
bool multiline = manager->attributeValue(property, QLatin1String("multiline")).toBool();
QStringList suggestions = manager->attributeValue(property, QLatin1String("suggestions")).toStringList();
Expand Down Expand Up @@ -227,6 +241,10 @@ void VariantEditorFactory::slotPropertyChanged(QtProperty *property,
for (ObjectRefEdit *objectRefEdit : std::as_const(mCreatedObjectRefEdits)[property])
objectRefEdit->setValue(value.value<DisplayObjectRef>());
}
else if (mCreatedListEdits.contains(property)) {
for (ListEdit *listEdit : std::as_const(mCreatedListEdits)[property])
listEdit->setValue(value.toList());
}
}

void VariantEditorFactory::slotPropertyAttributeChanged(QtProperty *property,
Expand Down Expand Up @@ -304,72 +322,50 @@ void VariantEditorFactory::objectRefEditValueChanged(const DisplayObjectRef &val
}
}

void VariantEditorFactory::slotEditorDestroyed(QObject *object)
void VariantEditorFactory::listEditValueChanged(const QVariantList &value)
{
// Check if it was an ObjectRefEdit
{
auto objectRefEdit = static_cast<ObjectRefEdit*>(object);

if (QtProperty *property = mObjectRefEditToProperty.value(objectRefEdit)) {
mObjectRefEditToProperty.remove(objectRefEdit);
mCreatedObjectRefEdits[property].removeAll(objectRefEdit);
if (mCreatedObjectRefEdits[property].isEmpty())
mCreatedObjectRefEdits.remove(property);
return;
}
}

// Check if it was a FileEdit
{
auto fileEdit = static_cast<FileEdit*>(object);

if (QtProperty *property = mFileEditToProperty.value(fileEdit)) {
mFileEditToProperty.remove(fileEdit);
mCreatedFileEdits[property].removeAll(fileEdit);
if (mCreatedFileEdits[property].isEmpty())
mCreatedFileEdits.remove(property);
return;
}
}

// Check if it was a TilesetParametersEdit
{
auto tilesetEdit = static_cast<TilesetParametersEdit*>(object);

if (QtProperty *property = mTilesetEditToProperty.value(tilesetEdit)) {
mTilesetEditToProperty.remove(tilesetEdit);
mCreatedTilesetEdits[property].removeAll(tilesetEdit);
if (mCreatedTilesetEdits[property].isEmpty())
mCreatedTilesetEdits.remove(property);
auto listEdit = qobject_cast<ListEdit*>(sender());
Q_ASSERT(listEdit);
if (QtProperty *property = mListEditToProperty.value(listEdit)) {
QtVariantPropertyManager *manager = propertyManager(property);
if (!manager)
return;
}
manager->setValue(property, value);
}
}

// Check if it was a TextPropertyEdit
{
auto textPropertyEdit = static_cast<TextPropertyEdit*>(object);

if (QtProperty *property = mTextPropertyEditToProperty.value(textPropertyEdit)) {
mTextPropertyEditToProperty.remove(textPropertyEdit);
mCreatedTextPropertyEdits[property].removeAll(textPropertyEdit);
if (mCreatedTextPropertyEdits[property].isEmpty())
mCreatedTextPropertyEdits.remove(property);
return;
}
template <typename T>
static bool removeEditor(QMap<QtProperty *, QList<T *> > &map,
QMap<T *, QtProperty *> &reverseMap,
QObject *object)
{
T *editor = static_cast<T*>(object);

if (QtProperty *property = reverseMap.value(editor)) {
map[property].removeAll(editor);
if (map[property].isEmpty())
map.remove(property);
reverseMap.remove(editor);
return true;
}

// Check if it was a QComboBox
{
auto comboBox = static_cast<QComboBox*>(object);
return false;
}

if (QtProperty *property = mComboBoxToProperty.value(comboBox)) {
mComboBoxToProperty.remove(comboBox);
mCreatedComboBoxes[property].removeAll(comboBox);
if (mCreatedComboBoxes[property].isEmpty())
mCreatedComboBoxes.remove(property);
return;
}
}
void VariantEditorFactory::slotEditorDestroyed(QObject *object)
{
if (removeEditor(mCreatedObjectRefEdits, mObjectRefEditToProperty, object))
return;
if (removeEditor(mCreatedFileEdits, mFileEditToProperty, object))
return;
if (removeEditor(mCreatedTilesetEdits, mTilesetEditToProperty, object))
return;
if (removeEditor(mCreatedTextPropertyEdits, mTextPropertyEditToProperty, object))
return;
if (removeEditor(mCreatedComboBoxes, mComboBoxToProperty, object))
return;
if (removeEditor(mCreatedListEdits, mListEditToProperty, object))
return;
}

} // namespace Tiled
Expand Down
5 changes: 5 additions & 0 deletions src/tiled/varianteditorfactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace Tiled {

class DisplayObjectRef;
class FileEdit;
class ListEdit;
class ObjectRefEdit;
class TextPropertyEdit;
class TilesetParametersEdit;
Expand Down Expand Up @@ -71,6 +72,7 @@ class VariantEditorFactory : public QtVariantEditorFactory
void textPropertyEditTextChanged(const QString &value);
void comboBoxPropertyEditTextChanged(const QString &value);
void objectRefEditValueChanged(const DisplayObjectRef &value);
void listEditValueChanged(const QVariantList &value);
void slotEditorDestroyed(QObject *object);

QMap<QtProperty *, QList<FileEdit *> > mCreatedFileEdits;
Expand All @@ -87,6 +89,9 @@ class VariantEditorFactory : public QtVariantEditorFactory

QMap<QtProperty *, QList<ObjectRefEdit *> > mCreatedObjectRefEdits;
QMap<ObjectRefEdit *, QtProperty *> mObjectRefEditToProperty;

QMap<QtProperty *, QList<ListEdit *> > mCreatedListEdits;
QMap<ListEdit *, QtProperty *> mListEditToProperty;
};

} // namespace Tiled
Loading

0 comments on commit b93cb06

Please sign in to comment.