diff --git a/src/Gui/QSint/actionpanel/actiongroup.cpp b/src/Gui/QSint/actionpanel/actiongroup.cpp index a1007600ea..559c72c627 100644 --- a/src/Gui/QSint/actionpanel/actiongroup.cpp +++ b/src/Gui/QSint/actionpanel/actiongroup.cpp @@ -4,82 +4,85 @@ * License: LGPL * * * ***************************************************************************/ - #include "actiongroup.h" #include "taskheader_p.h" #include "taskgroup_p.h" #include - +#include +#include namespace QSint { - ActionGroup::ActionGroup(QWidget *parent) - : QWidget(parent) + : QWidget(parent), + myHeader(new TaskHeader(QPixmap(), "", false, this)) { - myHeader = new TaskHeader(QPixmap(), "", false, this); myHeader->setVisible(false); init(false); } ActionGroup::ActionGroup(const QString &title, bool expandable, QWidget *parent) - : QWidget(parent) + : QWidget(parent), + myHeader(new TaskHeader(QPixmap(), title, expandable, this)) { - myHeader = new TaskHeader(QPixmap(), title, expandable, this); init(true); } ActionGroup::ActionGroup(const QPixmap &icon, const QString &title, bool expandable, QWidget *parent) - : QWidget(parent) + : QWidget(parent), + myHeader(new TaskHeader(icon, title, expandable, this)) { - myHeader = new TaskHeader(icon, title, expandable, this); init(true); } -void ActionGroup::init(bool header) +ActionGroup::~ActionGroup() { - m_foldStep = 0; - - myScheme = ActionPanelScheme::defaultScheme(); - - QVBoxLayout *vbl = new QVBoxLayout(); - vbl->setContentsMargins(0, 0, 0, 0); - vbl->setSpacing(0); - setLayout(vbl); - - vbl->addWidget(myHeader); - - myGroup = new TaskGroup(this, header); - vbl->addWidget(myGroup); - - myDummy = new QWidget(this); - vbl->addWidget(myDummy); - myDummy->hide(); - - connect(myHeader, &TaskHeader::activated, this, &ActionGroup::showHide); + delete myHeader; + delete myGroup; + delete myDummy; } -void ActionGroup::setScheme(ActionPanelScheme *pointer) +void ActionGroup::init(bool hasHeader) { - myScheme = pointer; - myHeader->setScheme(pointer); - myGroup->setScheme(pointer); - update(); + m_foldStep = 0; + myScheme = ActionPanelScheme::defaultScheme(); + + auto *layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + layout->addWidget(myHeader); + + myGroup = new TaskGroup(this, hasHeader); + layout->addWidget(myGroup); + + myDummy = new QWidget(this); + layout->addWidget(myDummy); + myDummy->hide(); + + connect(myHeader, &TaskHeader::activated, this, &ActionGroup::showHide); +} + +void ActionGroup::setScheme(ActionPanelScheme *scheme) +{ + myScheme = scheme; + myHeader->setScheme(scheme); + myGroup->setScheme(scheme); + update(); } QBoxLayout* ActionGroup::groupLayout() { - return myGroup->groupLayout(); + return myGroup->groupLayout(); } ActionLabel* ActionGroup::addAction(QAction *action, bool addToLayout, bool addStretch) { - if (!action) - return nullptr; + if (!action) return nullptr; - ActionLabel* label = new ActionLabel(action, this); + auto *label = new ActionLabel(action, this); myGroup->addActionLabel(label, addToLayout, addStretch); return label; @@ -87,11 +90,9 @@ ActionLabel* ActionGroup::addAction(QAction *action, bool addToLayout, bool addS ActionLabel* ActionGroup::addActionLabel(ActionLabel *label, bool addToLayout, bool addStretch) { - if (!label) - return nullptr; + if (!label) return nullptr; myGroup->addActionLabel(label, addToLayout, addStretch); - return label; } @@ -102,121 +103,101 @@ bool ActionGroup::addWidget(QWidget *widget, bool addToLayout, bool addStretch) void ActionGroup::showHide() { - if (m_foldStep) - return; + if (m_foldStep || !myHeader->expandable()) return; - if (!myHeader->expandable()) - return; + if (myGroup->isVisible()) + { + m_foldPixmap = myGroup->transparentRender(); + m_tempHeight = m_fullHeight = myGroup->height(); + m_foldDelta = m_fullHeight / myScheme->groupFoldSteps; + m_foldStep = myScheme->groupFoldSteps; + m_foldDirection = -1; - if (myGroup->isVisible()) - { - m_foldPixmap = myGroup->transparentRender(); -// m_foldPixmap = QPixmap::grabWidget(myGroup, myGroup->rect()); + myGroup->hide(); + myDummy->setFixedSize(myGroup->size()); + myDummy->show(); - m_tempHeight = m_fullHeight = myGroup->height(); - m_foldDelta = m_fullHeight / myScheme->groupFoldSteps; - m_foldStep = myScheme->groupFoldSteps; - m_foldDirection = -1; + QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processHide); + } + else + { + m_foldStep = myScheme->groupFoldSteps; + m_foldDirection = 1; + m_tempHeight = 0; - myGroup->hide(); - myDummy->setFixedSize(myGroup->size()); - myDummy->show(); - - QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processHide); - } - else - { - m_foldStep = myScheme->groupFoldSteps; - m_foldDirection = 1; - m_tempHeight = 0; - - QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processShow); - } - - myDummy->show(); + QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processShow); + } } void ActionGroup::processHide() { - if (!--m_foldStep) { - myDummy->setFixedHeight(0); - myDummy->hide(); - myHeader->setFold(false); - setFixedHeight(myHeader->height()); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - return; - } + if (--m_foldStep == 0) + { + myDummy->hide(); + myHeader->setFold(false); + setFixedHeight(myHeader->height()); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + return; + } - setUpdatesEnabled(false); + m_tempHeight -= m_foldDelta; + myDummy->setFixedHeight(m_tempHeight); + setFixedHeight(myDummy->height() + myHeader->height()); - m_tempHeight -= m_foldDelta; - myDummy->setFixedHeight(m_tempHeight); - setFixedHeight(myDummy->height()+myHeader->height()); - - QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processHide); - - setUpdatesEnabled(true); + QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processHide); } void ActionGroup::processShow() { - if (!--m_foldStep) { - myDummy->hide(); - m_foldPixmap = QPixmap(); - myGroup->show(); - myHeader->setFold(true); - setFixedHeight(m_fullHeight+myHeader->height()); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - setMaximumHeight(QWIDGETSIZE_MAX); - setMinimumHeight(0); - return; - } - - setUpdatesEnabled(false); - - m_tempHeight += m_foldDelta; - myDummy->setFixedHeight(m_tempHeight); - setFixedHeight(myDummy->height()+myHeader->height()); - - QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processShow); - - setUpdatesEnabled(true); -} - -void ActionGroup::paintEvent ( QPaintEvent * event ) -{ - Q_UNUSED(event); - QPainter p(this); - - if (myDummy->isVisible()) { - if (myScheme->groupFoldThaw) { - if (m_foldDirection < 0) - p.setOpacity((double)m_foldStep / myScheme->groupFoldSteps); - else - p.setOpacity((double)(myScheme->groupFoldSteps-m_foldStep) / myScheme->groupFoldSteps); - } - - switch (myScheme->groupFoldEffect) + if (--m_foldStep == 0) { - case ActionPanelScheme::ShrunkFolding: - p.drawPixmap(myDummy->pos(), m_foldPixmap.scaled(myDummy->size()) ); - break; - - case ActionPanelScheme::SlideFolding: - p.drawPixmap(myDummy->pos(), m_foldPixmap, - QRect(0, m_foldPixmap.height()-myDummy->height(), - m_foldPixmap.width(), myDummy->width() - ) ); - break; - - default: - p.drawPixmap(myDummy->pos(), m_foldPixmap); + myDummy->hide(); + m_foldPixmap = QPixmap(); + myGroup->show(); + myHeader->setFold(true); + setFixedHeight(m_fullHeight + myHeader->height()); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + setMaximumHeight(QWIDGETSIZE_MAX); + return; } - return; - } + m_tempHeight += m_foldDelta; + myDummy->setFixedHeight(m_tempHeight); + setFixedHeight(myDummy->height() + myHeader->height()); + + QTimer::singleShot(myScheme->groupFoldDelay, this, &ActionGroup::processShow); } +void ActionGroup::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter p(this); + + if (myDummy->isVisible()) + { + if (myScheme->groupFoldThaw) + { + double opacity = (m_foldDirection < 0) + ? static_cast(m_foldStep) / myScheme->groupFoldSteps + : static_cast(myScheme->groupFoldSteps - m_foldStep) / myScheme->groupFoldSteps; + p.setOpacity(opacity); + } + + switch (myScheme->groupFoldEffect) + { + case ActionPanelScheme::ShrunkFolding: + p.drawPixmap(myDummy->pos(), m_foldPixmap.scaled(myDummy->size())); + break; + case ActionPanelScheme::SlideFolding: + p.drawPixmap(myDummy->pos(), m_foldPixmap, + QRect(0, m_foldPixmap.height() - myDummy->height(), + m_foldPixmap.width(), myDummy->width())); + break; + default: + p.drawPixmap(myDummy->pos(), m_foldPixmap); + } + } +} bool ActionGroup::isExpandable() const { @@ -243,21 +224,19 @@ QString ActionGroup::headerText() const return myHeader->myTitle->text(); } -void ActionGroup::setHeaderText(const QString & headerText) +void ActionGroup::setHeaderText(const QString &headerText) { myHeader->myTitle->setText(headerText); } -void ActionGroup::setHeaderIcon(const QPixmap& icon) +void ActionGroup::setHeaderIcon(const QPixmap &icon) { myHeader->myTitle->setIcon(icon); } - QSize ActionGroup::minimumSizeHint() const { - return {200,65}; + return {200, 65}; } - -} +} // namespace diff --git a/src/Gui/QSint/actionpanel/actiongroup.h b/src/Gui/QSint/actionpanel/actiongroup.h index cb36abbf09..c9aab1bba3 100644 --- a/src/Gui/QSint/actionpanel/actiongroup.h +++ b/src/Gui/QSint/actionpanel/actiongroup.h @@ -8,9 +8,9 @@ #ifndef ACTIONGROUP_H #define ACTIONGROUP_H +#include #include #include -#include #include "qsint_global.h" @@ -20,157 +20,128 @@ namespace QSint class ActionLabel; class ActionPanelScheme; - +class TaskHeader; +class TaskGroup; /** - \brief Class representing a single group of actions similar to Windows XP task panels. - \since 0.2 - - \image html ActionGroup.png An example of ActionGroup - - ActionGroup consists from optional header and set of actions represented by ActionLabel. - It can contain arbitrary widgets as well. -*/ - + * @brief A collapsible group widget for organizing actions + * + * ActionGroup consists of an optional header and a collection of actions represented by ActionLabel. + * It can also contain arbitrary widgets. + * + */ class QSINT_EXPORT ActionGroup : public QWidget { Q_OBJECT - Q_PROPERTY(bool expandable READ isExpandable WRITE setExpandable) // clazy:exclude=qproperty-without-notify - Q_PROPERTY(bool header READ hasHeader WRITE setHeader) // clazy:exclude=qproperty-without-notify - Q_PROPERTY(QString headerText READ headerText WRITE setHeaderText) // clazy:exclude=qproperty-without-notify + Q_PROPERTY(bool expandable READ isExpandable WRITE setExpandable) + Q_PROPERTY(bool header READ hasHeader WRITE setHeader) + Q_PROPERTY(QString headerText READ headerText WRITE setHeaderText) public: - /** Constructor. Creates ActionGroup without header. - */ explicit ActionGroup(QWidget *parent = nullptr); - - /** Constructor. Creates ActionGroup with header's - text set to \a title, but with no icon. - - If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. - */ - explicit ActionGroup(const QString& title, - bool expandable = true, - QWidget *parent = nullptr); - - /** Constructor. Creates ActionGroup with header's - text set to \a title and icon set to \a icon. - - If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. - */ - explicit ActionGroup(const QPixmap& icon, - const QString& title, - bool expandable = true, - QWidget *parent = nullptr); - - /** Creates action item from the \a action and returns it. - - If \a addToLayout is set to \a true (default), - the action is added to the default vertical layout, i.e. subsequent - calls of this function will create several ActionLabels arranged vertically, - one below another. - - Set \a addToLayout to \a false if you want to add the action to the specified layout manually. - This allows one to do custom actions arrangements, i.e. horizontal etc. - - If \a addStretch is set to \a true (default), - ActionLabel will be automatically aligned to the left side of the ActionGroup. - Set \a addStretch to \a false if you want ActionLabel to occupy all the horizontal space. - */ + explicit ActionGroup(const QString& title, bool expandable = true, QWidget *parent = nullptr); + explicit ActionGroup(const QPixmap& icon, const QString& title, bool expandable = true, QWidget *parent = nullptr); + ~ActionGroup() override; + /** + * @brief Creates an action item from the given `action` and returns it. + * + * If `addToLayout` is `true` (default), the action is added to the default vertical layout, meaning + * subsequent calls will arrange multiple `ActionLabel`s vertically, one below another. + * + * If `addToLayout` is `false`, the action must be added to a layout manually. + * This allows for custom arrangements, such as horizontal layouts. + * + * If `addStretch` is `true` (default),`ActionLabel` will be automatically aligned to the left side. + * if `addStretch` is `false` `ActionLabel` will occupy all available horizontal space. + */ ActionLabel* addAction(QAction *action, bool addToLayout = true, bool addStretch = true); - /** Adds \a label to the group. - - \sa addAction() for the description. - */ + /** + * @brief Adds an `ActionLabel` to the group. + * See `addAction()` for parameter details. + */ ActionLabel* addActionLabel(ActionLabel *label, bool addToLayout = true, bool addStretch = true); - /** Adds \a widget to the group. Returns \a true if it has been added successfully. - - \sa addAction() for the description. - */ + /** + * @brief Adds a `QWidget` to the group. Returns `true` if added successfully. + * See `addAction()` for parameter details. + */ bool addWidget(QWidget *widget, bool addToLayout = true, bool addStretch = true); - /** Returns group's layout (QVBoxLayout by default). - */ + /** + * @brief Returns the group's layout (QVBoxLayout by default). + */ QBoxLayout* groupLayout(); - /** Sets the scheme of the panel and all the child groups to \a scheme. - By default, ActionPanelScheme::defaultScheme() is used. - */ - void setScheme(ActionPanelScheme *pointer); + /** + * @brief Sets the scheme for the panel and all its child groups. + * + * By default, `ActionPanelScheme::defaultScheme()` is used. + */ + void setScheme(ActionPanelScheme *scheme); - /** Returns \a true if the group is expandable. - - \sa setExpandable(). - */ + /** + * @brief Checks if the group can collapse or expand. + */ bool isExpandable() const; - /** Returns \a true if the group has header. + /** + * @brief Makes the group expandable or not. + */ + void setExpandable(bool expandable); - \sa setHeader(). - */ + /** + * @brief Checks if the group has a header. + */ bool hasHeader() const; - /** Returns text of the header. - Only valid if the group has header (see hasHeader()). + /** + * @brief Enables or disables the group's header. + */ + void setHeader(bool enable); - \sa setHeaderText(). - */ + /** + * @brief Returns the text of the header. + */ QString headerText() const; + /** + * @brief Sets the text of the header. + */ + void setHeaderText(const QString &text); + /** + * @brief Sets the icon of the header. + */ + void setHeaderIcon(const QPixmap &icon); QSize minimumSizeHint() const override; public Q_SLOTS: - /** Expands/collapses the group. - Only valid if the group has header (see hasHeader()). - */ void showHide(); - /** Makes the group expandable if \a expandable is set to \a true. - - \sa isExpandable(). - */ - void setExpandable(bool expandable = true); - - /** Enables/disables group's header according to \a enable. - - \sa hasHeader(). - */ - void setHeader(bool enable = true); - - /** Sets text of the header to \a title. - Only valid if the group has header (see hasHeader()). - - \sa headerText(). - */ - void setHeaderText(const QString & title); - void setHeaderIcon(const QPixmap& icon); - protected Q_SLOTS: void processHide(); void processShow(); protected: - void init(bool header); + void paintEvent(QPaintEvent *event) override; + void init(bool hasHeader); - void paintEvent ( QPaintEvent * event ) override; - - double m_foldStep, m_foldDelta, m_fullHeight, m_tempHeight; - int m_foldDirection; + double m_foldStep = 0; + double m_foldDelta = 0; + double m_fullHeight = 0; + double m_tempHeight = 0; + int m_foldDirection = 0; QPixmap m_foldPixmap; - class TaskHeader *myHeader; - class TaskGroup *myGroup; - QWidget *myDummy; - - ActionPanelScheme *myScheme; + TaskHeader *myHeader = nullptr; + TaskGroup *myGroup = nullptr; + QWidget *myDummy = nullptr; + ActionPanelScheme *myScheme = nullptr; }; - -} // namespace +} // namespace QSint #endif // ACTIONGROUP_H