Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn committed Oct 10, 2024
1 parent d5b54cf commit bf0c1cf
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 110 deletions.
209 changes: 158 additions & 51 deletions src/tiled/propertieswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,9 @@ class VariantMapProperty : public GroupProperty
: GroupProperty(name, parent)
{}

void setValue(const QVariantMap &value, const QVariantMap &suggestions = {});
void setValue(const QVariantMap &value,
const QVariantMap &suggestions = {});

const QVariantMap &value() const { return mValue; }

signals:
Expand All @@ -430,6 +432,7 @@ class VariantMapProperty : public GroupProperty
Document *mDocument = nullptr;

private:
Property *createProperty(const QString &name, const QVariant &value);
Property *createProperty(const QStringList &path,
std::function<QVariant ()> get,
std::function<void (const QVariant &)> set);
Expand All @@ -439,6 +442,9 @@ class VariantMapProperty : public GroupProperty
const ClassPropertyType &classType,
std::function<QVariant ()> get);

void removeMember(const QString &name);
void addMember(const QString &name, const QVariant &value);

void updateModifiedRecursively(Property *property, const QVariant &value);
void emitValueChangedRecursively(Property *property);

Expand Down Expand Up @@ -2261,70 +2267,86 @@ void VariantMapProperty::setValue(const QVariantMap &value,
QVariantMap allProperties = mSuggestions;
mergeProperties(allProperties, mValue);

clear();
// First, delete all properties that are not in allProperties
for (auto it = mPropertyMap.begin(); it != mPropertyMap.end();) {
if (!allProperties.contains(it.key())) {
deleteProperty(it.value());
it = mPropertyMap.erase(it);
} else {
++it;
}
}

QMapIterator<QString, QVariant> it(allProperties);
while (it.hasNext()) {
it.next();
const QString &name = it.key();

auto get = [=] {
return mValue.value(name, mSuggestions.value(name));
};
auto set = [=] (const QVariant &value) {
mValue.insert(name, value);
emit memberValueChanged({ name }, value);
emit valueChanged();
};
// const auto newValue = mSuggestions.value(name);

// if (auto property = mPropertyMap.value(name)) {
// if (isSameType(oldValue, newValue)) {
// updateModifiedRecursively(property, newValue);
// } else {
// // Delete and re-create the property
// const int index = indexOfProperty(property);
// deleteProperty(property);
// mPropertyMap.remove(name);
// property = createProperty(name, newValue);
// if (property) {
// insertProperty(index, property);
// mPropertyMap.insert(name, property);
// }
// }

// if (property) {
// property->setEnabled(false);
// property->setActions(Property::Action::Add);
// emitValueChangedRecursively(property);
// }
// }

if (auto property = createProperty(it.key(), it.value())) {
addProperty(property);
mPropertyMap.insert(it.key(), property);
}
}

if (auto property = createProperty({ name }, std::move(get), std::move(set))) {
if (mValue.contains(name)) {
property->setActions(Property::Action::Remove);
} else {
property->setEnabled(false);
property->setActions(Property::Action::Add);
}
emit valueChanged();
}

updateModifiedRecursively(property, it.value());
Property *VariantMapProperty::createProperty(const QString &name, const QVariant &value)
{
auto get = [=] {
return mValue.value(name, mSuggestions.value(name));
};
auto set = [=] (const QVariant &value) {
mValue.insert(name, value);
emit memberValueChanged({ name }, value);
emit valueChanged();
};

addProperty(property);
mPropertyMap.insert(name, property);

connect(property, &Property::removeRequested, this, [=] {
mValue.remove(name);

if (!mSuggestions.contains(name)) {
if (auto property = mPropertyMap.take(name))
deleteProperty(property);
} else {
if (auto property = mPropertyMap.value(name)) {
property->setEnabled(false);
property->setActions(Property::Action::Add);
emitValueChangedRecursively(property);
updateModifiedRecursively(property, mSuggestions.value(name));
}
}
if (auto property = createProperty({ name }, std::move(get), std::move(set))) {
if (mValue.contains(name)) {
property->setActions(Property::Action::Remove);
} else {
property->setEnabled(false);
property->setActions(Property::Action::Add);
}

emit memberValueChanged({ name }, QVariant());
emit valueChanged();
});
updateModifiedRecursively(property, value);

connect(property, &Property::addRequested, this, [=] {
const auto memberValue = mSuggestions.value(name);
mValue.insert(name, memberValue);
connect(property, &Property::removeRequested, this, [=] {
removeMember(name);
});

if (auto property = mPropertyMap.value(name)) {
property->setEnabled(true);
property->setActions(Property::Action::Remove);
}
connect(property, &Property::addRequested, this, [=] {
addMember(name, mSuggestions.value(name));
});

emit memberValueChanged({ name }, memberValue);
emit valueChanged();
});
}
return property;
}

emit valueChanged();
return nullptr;
}

Property *VariantMapProperty::createProperty(const QStringList &path,
Expand Down Expand Up @@ -2432,6 +2454,91 @@ void VariantMapProperty::createClassMembers(const QStringList &path,
}
}

static bool isSameType(const QVariant &a, const QVariant &b)
{
if (a.userType() != b.userType())
return false;

// Two PropertyValue values might still have different types
if (a.userType() == propertyValueId()) {
auto aTypeId = a.value<PropertyValue>().typeId;
auto bTypeId = b.value<PropertyValue>().typeId;
if (aTypeId != bTypeId)
return false;
}

return true;
}

void VariantMapProperty::removeMember(const QString &name)
{
if (!mValue.contains(name))
return;

const auto oldValue = mValue.take(name);

if (!mSuggestions.contains(name)) {
if (auto property = mPropertyMap.take(name))
deleteProperty(property);
} else {
const auto newValue = mSuggestions.value(name);

if (auto property = mPropertyMap.value(name)) {
if (isSameType(oldValue, newValue)) {
updateModifiedRecursively(property, newValue);
} else {
// Delete and re-create the property
const int index = indexOfProperty(property);
deleteProperty(property);
mPropertyMap.remove(name);
property = createProperty(name, newValue);
if (property) {
insertProperty(index, property);
mPropertyMap.insert(name, property);
}
}

if (property) {
property->setEnabled(false);
property->setActions(Property::Action::Add);
emitValueChangedRecursively(property);
}
}
}

emit memberValueChanged({ name }, QVariant());
emit valueChanged();
}

void VariantMapProperty::addMember(const QString &name, const QVariant &value)
{
const auto oldValue = mValue.value(name, mSuggestions.value(name));

mValue.insert(name, value);

if (auto property = mPropertyMap.value(name)) {
if (!isSameType(oldValue, value)) {
// Delete and re-create the property
const int index = indexOfProperty(property);
deleteProperty(property);
mPropertyMap.remove(name);
property = createProperty(name, value);
if (property) {
insertProperty(index, property);
mPropertyMap.insert(name, property);
}
}

if (property) {
property->setEnabled(true);
property->setActions(Property::Action::Remove);
}
}

emit memberValueChanged({ name }, value);
emit valueChanged();
}

void VariantMapProperty::updateModifiedRecursively(Property *property,
const QVariant &value)
{
Expand Down
36 changes: 28 additions & 8 deletions src/tiled/propertyeditorwidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,11 +501,7 @@ PropertyLabel::PropertyLabel(int level, QWidget *parent)
void PropertyLabel::setLevel(int level)
{
m_level = level;

const int spacing = Utils::dpiScaled(3);
const int branchIndicatorWidth = Utils::dpiScaled(14);
setContentsMargins(spacing + branchIndicatorWidth * std::max(m_level, 1),
spacing, spacing, spacing);
updateContentMargins();
}

void PropertyLabel::setHeader(bool header)
Expand All @@ -517,6 +513,7 @@ void PropertyLabel::setHeader(bool header)
setBackgroundRole(header ? QPalette::Dark : QPalette::NoRole);
setForegroundRole(header ? QPalette::BrightText : QPalette::NoRole);
setAutoFillBackground(header);
updateContentMargins();
}

void PropertyLabel::setExpandable(bool expandable)
Expand Down Expand Up @@ -588,12 +585,35 @@ void PropertyLabel::paintEvent(QPaintEvent *event)
}
}

void PropertyLabel::updateContentMargins()
{
const int spacing = Utils::dpiScaled(3);
const int branchIndicatorWidth = Utils::dpiScaled(14);
const int verticalSpacing = m_header ? spacing : 0;
setContentsMargins(spacing + branchIndicatorWidth * std::max(m_level, 1),
verticalSpacing, spacing, verticalSpacing);

}

/**
* To fit better alongside other widgets without vertical centering, the size
* hint is adjusted to match that of a QLineEdit.
*/
QSize PropertyLabel::sizeHint() const
{
auto hint = ElidingLabel::sizeHint();
hint.setHeight(m_lineEdit.sizeHint().height());
return hint;
constexpr int QLineEditPrivate_verticalMargin = 1;
constexpr int QLineEditPrivate_horizontalMargin = 2;

auto fm = fontMetrics();
auto cm = contentsMargins();
const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2 * QLineEditPrivate_verticalMargin
+ cm.top() + cm.bottom();
int w = fm.horizontalAdvance(u'x') * 17 + 2 * QLineEditPrivate_horizontalMargin
+ cm.left() + cm.right();
QStyleOptionFrame opt;
initStyleOption(&opt);
return style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h), this);
}

} // namespace Tiled
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/propertyeditorwidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ class PropertyLabel : public ElidingLabel
void paintEvent(QPaintEvent *) override;

private:
void updateContentMargins();

QLineEdit m_lineEdit;
int m_level = 0;
bool m_header = false;
Expand Down
Loading

0 comments on commit bf0c1cf

Please sign in to comment.