From d2c03f771b2e15367cc1f7fdad6533c839aef0c4 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 14 Nov 2023 15:52:55 +0100 Subject: [PATCH] Utils: Add ToggleAspect Change-Id: I2de41811c0c039cd52d48aab98e0c65706d21a74 Reviewed-by: hjk --- src/libs/utils/aspects.cpp | 140 +++++++++++++++++++++++++++++++++++++ src/libs/utils/aspects.h | 37 +++++++++- 2 files changed, 176 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 43fc9d9bcc4..0452cf2a9c3 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -287,6 +287,11 @@ void BaseAspect::setIcon(const QIcon &icon) d->m_action->setIcon(icon); } +QIcon BaseAspect::icon() const +{ + return d->m_icon; +} + /*! Returns the current text for the separate label in the visual representation of this aspect. @@ -697,6 +702,17 @@ public: UndoableValue m_undoable; }; +class ToggleAspectPrivate +{ +public: + struct Data + { + QIcon icon; + QString tooltip; + QString text; + } on, off; +}; + class ColorAspectPrivate { public: @@ -1731,6 +1747,130 @@ void ColorAspect::bufferToGui() d->m_colorButton->setColor(m_buffer); } +static void updateToggleAction(ToggleAspect &aspect, + const std::unique_ptr &d) +{ + if (!aspect.hasAction()) + return; + + QAction *action = aspect.action(); + + Internal::ToggleAspectPrivate::Data data = aspect.value() ? d->on : d->off; + if (data.icon.isNull()) + data.icon = aspect() ? aspect.icon() : d->on.icon; + if (data.text.isEmpty()) + data.text = aspect() ? aspect.toolTip() : d->on.text; + if (data.tooltip.isEmpty()) + data.tooltip = aspect() ? aspect.toolTip() : d->on.tooltip; + + action->setIcon(data.icon); + action->setText(data.text); + action->setToolTip(data.tooltip); +} + +/*! + \class Utils::ToggleAspect + \inmodule QtCreator + + \brief A toggle aspect is a boolean property of some object, together with + a description of its behavior for common operations like visualizing or + persisting. It also contains independent tooltips, icons and text for the action() + according to the on / off state of the aspect. + + The aspect is displayed using a QCheckBox. + + The visual representation often contains a label in front or after + the display of the actual checkmark. +*/ + +ToggleAspect::ToggleAspect(AspectContainer *container) + : BoolAspect(container) + , d(std::make_unique()) +{} + +ToggleAspect::~ToggleAspect() {} + +void ToggleAspect::setOffIcon(const QIcon &icon) +{ + d->off.icon = icon; + updateToggleAction(*this, d); +} + +void ToggleAspect::setOffTooltip(const QString &tooltip) +{ + d->off.tooltip = tooltip; + updateToggleAction(*this, d); +} + +void ToggleAspect::setOnTooltip(const QString &tooltip) +{ + d->on.tooltip = tooltip; + updateToggleAction(*this, d); +} + +void ToggleAspect::setOnIcon(const QIcon &icon) +{ + d->on.icon = icon; + updateToggleAction(*this, d); +} + +QString ToggleAspect::onTooltip() const +{ + return d->on.tooltip; +} + +QIcon ToggleAspect::onIcon() const +{ + return d->on.icon; +} + +QString ToggleAspect::offTooltip() const +{ + return d->off.tooltip; +} + +QIcon ToggleAspect::offIcon() const +{ + return d->off.icon; +} + +void ToggleAspect::setOnText(const QString &text) +{ + d->on.text = text; +} + +QString ToggleAspect::onText() const +{ + return d->on.text; +} + +void ToggleAspect::setOffText(const QString &text) +{ + d->off.text = text; +} +QString ToggleAspect::offText() const +{ + return d->off.text; +} + +void ToggleAspect::announceChanges(Changes changes, Announcement howToAnnounce) +{ + if (changes.internalFromBuffer || changes.internalFromOutside) + updateToggleAction(*this, d); + BoolAspect::announceChanges(changes, howToAnnounce); +} + +QAction *ToggleAspect::action() +{ + if (hasAction()) + return BoolAspect::action(); + + QAction *a = BoolAspect::action(); + updateToggleAction(*this, d); + + return a; +} + /*! \class Utils::BoolAspect \inmodule QtCreator diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index 0d3d18171d1..ffc2906d879 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -39,6 +39,7 @@ class CheckableDecider; namespace Internal { class AspectContainerPrivate; class BaseAspectPrivate; +class ToggleAspectPrivate; class BoolAspectPrivate; class ColorAspectPrivate; class DoubleAspectPrivate; @@ -107,6 +108,7 @@ public: void setLabelText(const QString &labelText); void setLabelPixmap(const QPixmap &labelPixmap); void setIcon(const QIcon &labelIcon); + QIcon icon() const; using ConfigWidgetCreator = std::function; void setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator); @@ -149,7 +151,7 @@ public: unsigned bufferFromGui : 1; }; - void announceChanges(Changes changes, Announcement howToAnnounce = DoEmit); + virtual void announceChanges(Changes changes, Announcement howToAnnounce = DoEmit); class QTCREATOR_UTILS_EXPORT Data { @@ -448,6 +450,39 @@ private: std::unique_ptr d; }; +class QTCREATOR_UTILS_EXPORT ToggleAspect : public BoolAspect +{ +public: + ToggleAspect(AspectContainer *container = nullptr); + ~ToggleAspect(); + + void setOffIcon(const QIcon &icon); + QIcon offIcon() const; + + void setOffTooltip(const QString &tooltip); + QString offTooltip() const; + + void setOnIcon(const QIcon &icon); + QIcon onIcon() const; + + void setOnTooltip(const QString &tooltip); + QString onTooltip() const; + + void setOnText(const QString &text); + QString onText() const; + + void setOffText(const QString &text); + QString offText() const; + + QAction *action() override; + +protected: + void announceChanges(Changes changes, Announcement howToAnnounce = DoEmit) override; + +private: + std::unique_ptr d; +}; + class QTCREATOR_UTILS_EXPORT ColorAspect : public TypedAspect { Q_OBJECT