Skip to content

Commit

Permalink
Allow expanding the child properties for any GroupProperty
Browse files Browse the repository at this point in the history
Also when it isn't displayed as a header. Also introduced a "level"
member of VariantEditor which is passed on to the PropertyLabel, which
is used to indent expanded child properties.
  • Loading branch information
bjorn committed Sep 18, 2024
1 parent f77fb26 commit 036f68c
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 89 deletions.
14 changes: 7 additions & 7 deletions src/tiled/propertieswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ class TilesetProperties : public ObjectProperties
push(new ChangeTilesetTransformationFlags(tilesetDocument(), value));
});

// todo: sub-properties are not displayed yet and image file name doesn't update in the TilesetParametersEdit
// todo: image file name doesn't update in the TilesetParametersEdit
mTilesetImageProperty = new TilesetImageProperty(document, this);

mImageProperty = new UrlProperty(
Expand All @@ -1302,6 +1302,12 @@ class TilesetProperties : public ObjectProperties
mMarginProperty->setSuffix(tr(" px"));
mTileSpacingProperty->setSuffix(tr(" px"));

mImageProperty->setEnabled(false);
mTransparentColorProperty->setEnabled(false);
mTileSizeProperty->setEnabled(false);
mMarginProperty->setEnabled(false);
mTileSpacingProperty->setEnabled(false);

mTilesetImageProperty->addProperty(mImageProperty);
mTilesetImageProperty->addProperty(mTransparentColorProperty);
mTilesetImageProperty->addProperty(mTileSizeProperty);
Expand Down Expand Up @@ -1379,12 +1385,6 @@ class TilesetProperties : public ObjectProperties
void updateEnabledState()
{
const bool collection = tileset()->isCollection();
mTilesetImageProperty->setEnabled(!collection);
mImageProperty->setEnabled(!collection);
mTransparentColorProperty->setEnabled(!collection);
mTileSizeProperty->setEnabled(!collection);
mMarginProperty->setEnabled(!collection);
mTileSpacingProperty->setEnabled(!collection);
mColumnCountProperty->setEnabled(collection);
}

Expand Down
63 changes: 49 additions & 14 deletions src/tiled/propertyeditorwidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,38 +491,73 @@ void ElidingLabel::paintEvent(QPaintEvent *)
}


HeaderWidget::HeaderWidget(const QString &text, QWidget *parent)
: ElidingLabel(text, parent)
PropertyLabel::PropertyLabel(int level, QWidget *parent)
: ElidingLabel(parent)
{
setBackgroundRole(QPalette::Dark);
setForegroundRole(QPalette::BrightText);
setAutoFillBackground(true);
setMinimumWidth(Utils::dpiScaled(50));
setLevel(level);
}

void PropertyLabel::setLevel(int level)
{
m_level = level;

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

void HeaderWidget::mousePressEvent(QMouseEvent *event)
void PropertyLabel::setHeader(bool header)
{
if (m_header == header)
return;

m_header = header;
setBackgroundRole(header ? QPalette::Dark : QPalette::NoRole);
setForegroundRole(header ? QPalette::BrightText : QPalette::NoRole);
setAutoFillBackground(header);
}

void PropertyLabel::setExpandable(bool expandable)
{
if (m_expandable == expandable)
return;

m_expandable = expandable;
update();
}

void PropertyLabel::setExpanded(bool expanded)
{
if (m_expanded == expanded)
return;

m_expanded = expanded;
update();
emit toggled(m_expanded);
}

void PropertyLabel::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_checked = !m_checked;
emit toggled(m_checked);
if (m_expandable && event->button() == Qt::LeftButton) {
setExpanded(!m_expanded);
return;
}

ElidingLabel::mousePressEvent(event);
}

void HeaderWidget::paintEvent(QPaintEvent *event)
void PropertyLabel::paintEvent(QPaintEvent *event)
{
ElidingLabel::paintEvent(event);

QStyleOption branchOption;
branchOption.initFrom(this);
branchOption.rect = QRect(0, 0, contentsMargins().left(), height());
branchOption.state = QStyle::State_Children;
if (m_checked)
if (m_expandable)
branchOption.state |= QStyle::State_Children;
if (m_expanded)
branchOption.state |= QStyle::State_Open;

QStylePainter p(this);
Expand Down
40 changes: 19 additions & 21 deletions src/tiled/propertyeditorwidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,40 +274,38 @@ class ElidingLabel : public QLabel
};

/**
* A header widget that can be toggled.
* A property label widget, which can be a header or just be expandable.
*/
class HeaderWidget : public ElidingLabel
class PropertyLabel : public ElidingLabel
{
Q_OBJECT

public:
HeaderWidget(const QString &text, QWidget *parent = nullptr);
PropertyLabel(int level, QWidget *parent = nullptr);

signals:
void toggled(bool checked);
void setLevel(int level);

protected:
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *) override;
void setHeader(bool header);
bool isHeader() const { return m_header; }

private:
bool m_checked = true;
};
void setExpandable(bool expandable);
bool isExpandable() const { return m_expandable; }

/**
* A label that matches its preferred height with that of a line edit.
*/
class LineEditLabel : public ElidingLabel
{
Q_OBJECT
void setExpanded(bool expanded);
bool isExpanded() const { return m_expanded; }

public:
using ElidingLabel::ElidingLabel;
signals:
void toggled(bool expanded);

QSize sizeHint() const override;
protected:
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *) override;

private:
QLineEdit m_lineEdit;
int m_level = 0;
bool m_header = false;
bool m_expandable = false;
bool m_expanded = false;
};

} // namespace Tiled
82 changes: 37 additions & 45 deletions src/tiled/varianteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,31 +502,30 @@ void VariantEditor::addSeparator()

void VariantEditor::addProperty(Property *property)
{
const int spacing = m_layout->spacing();
const int branchIndicatorWidth = Utils::dpiScaled(14);
const auto displayMode = property->displayMode();

switch (property->displayMode()) {
case Property::DisplayMode::Default:
case Property::DisplayMode::NoLabel: {
if (displayMode == Property::DisplayMode::Separator) {
addSeparator();
return;
}

auto label = new PropertyLabel(m_level, this);

if (displayMode != Property::DisplayMode::NoLabel) {
label->setText(property->name());
label->setToolTip(property->toolTip());
label->setEnabled(property->isEnabled());
connect(property, &Property::toolTipChanged, label, &QWidget::setToolTip);
connect(property, &Property::enabledChanged, label, &QWidget::setEnabled);
}

if (displayMode == Property::DisplayMode::Header) {
label->setHeader(true);
m_layout->addWidget(label);
} else {
auto propertyLayout = new QHBoxLayout;
propertyLayout->setContentsMargins(0, 0, spacing, 0);

// Property label indentation, which shrinks when there is very little space
propertyLayout->addSpacerItem(new QSpacerItem(spacing + branchIndicatorWidth, 0,
QSizePolicy::Maximum));
propertyLayout->setStretch(0, 1);

if (property->displayMode() == Property::DisplayMode::Default) {
auto label = new LineEditLabel(property->name(), this);
label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
label->setToolTip(property->toolTip());
label->setEnabled(property->isEnabled());
connect(property, &Property::toolTipChanged, label, &QWidget::setToolTip);
connect(property, &Property::enabledChanged, label, &QWidget::setEnabled);
propertyLayout->addWidget(label, LabelStretch, Qt::AlignTop);
} else {
propertyLayout->addStretch(LabelStretch);
}
propertyLayout->setContentsMargins(0, 0, m_layout->spacing(), 0);
propertyLayout->addWidget(label, LabelStretch, Qt::AlignTop);

if (auto editor = createEditor(property)) {
editor->setToolTip(property->toolTip());
Expand All @@ -537,34 +536,26 @@ void VariantEditor::addProperty(Property *property)
}

m_layout->addLayout(propertyLayout);

break;
}
case Property::DisplayMode::Header: {
auto headerWidget = new HeaderWidget(property->name(), this);
m_layout->addWidget(headerWidget);

if (auto groupProperty = dynamic_cast<GroupProperty *>(property)) {
auto editor = new VariantEditor(this);
for (auto property : groupProperty->subProperties())
editor->addProperty(property);
if (auto groupProperty = dynamic_cast<GroupProperty *>(property)) {
label->setExpandable(true);
label->setExpanded(label->isHeader());

connect(headerWidget, &HeaderWidget::toggled,
editor, [this, editor](bool checked) {
editor->setVisible(checked);
auto editor = new VariantEditor(this);
editor->setLevel(m_level + 1);
editor->setVisible(label->isExpanded());
for (auto property : groupProperty->subProperties())
editor->addProperty(property);

// needed to avoid flickering when hiding the editor
layout()->activate();
});
connect(label, &PropertyLabel::toggled, editor, [=](bool expanded) {
editor->setVisible(expanded);

m_layout->addWidget(editor);
}
// needed to avoid flickering when hiding the editor
layout()->activate();
});

break;
}
case Property::DisplayMode::Separator:
addSeparator();
break;
m_layout->addWidget(editor);
}
}

Expand Down Expand Up @@ -600,6 +591,7 @@ void VariantEditor::addValue(const QVariant &value)
QWidget *VariantEditor::createEditor(Property *property)
{
if (const auto editor = property->createEditor(this)) {
editor->setMinimumWidth(Utils::dpiScaled(70));
editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
return editor;
} else {
Expand Down
7 changes: 5 additions & 2 deletions src/tiled/varianteditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class QVBoxLayout;

namespace Tiled {

class HeaderWidget;
class PropertyLabel;

/**
* A property represents a named value that can create its own edit widget.
Expand Down Expand Up @@ -133,7 +133,7 @@ class PropertyTemplate : public Property
{}

Type value() const { return m_get(); }
void setValue(const Type &value) { m_set(value); }
void setValue(const Type &value) { if (m_set) m_set(value); }

private:
std::function<Type()> m_get;
Expand Down Expand Up @@ -409,6 +409,8 @@ class VariantEditor : public QWidget
void addProperty(Property *property);
// void addValue(const QVariant &value);

void setLevel(int level) { m_level = level; }

private:
QWidget *createEditor(Property *property);

Expand All @@ -418,6 +420,7 @@ class VariantEditor : public QWidget
};

QVBoxLayout *m_layout;
int m_level = 0;
};

} // namespace Tiled

0 comments on commit 036f68c

Please sign in to comment.