From b036736547cdf027ba2da05d45477c1542947659 Mon Sep 17 00:00:00 2001 From: WarmUpTill <19472752+WarmUpTill@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:51:25 +0200 Subject: [PATCH] Refactor MacroSegmentList rework to support nested macros --- lib/macro/macro-segment-list.cpp | 83 ++++++++++++++++++++++++-------- lib/macro/macro-segment-list.hpp | 55 +++++++++++++-------- 2 files changed, 99 insertions(+), 39 deletions(-) diff --git a/lib/macro/macro-segment-list.cpp b/lib/macro/macro-segment-list.cpp index 03320590..991a265f 100644 --- a/lib/macro/macro-segment-list.cpp +++ b/lib/macro/macro-segment-list.cpp @@ -17,27 +17,39 @@ bool MacroSegmentList::_useCache = true; MacroSegmentList::MacroSegmentList(QWidget *parent) : QScrollArea(parent), + _stackedWidget(new QStackedWidget(this)), _layout(new QVBoxLayout), _contentLayout(new QVBoxLayout), - _helpMsg(new QLabel) + _helpMsg(new QLabel(this)) { _helpMsg->setWordWrap(true); _helpMsg->setAlignment(Qt::AlignCenter); + auto helpWidget = new QWidget(this); + auto helpLayout = new QVBoxLayout(helpWidget); + helpLayout->addWidget(_helpMsg); + helpLayout->setAlignment(Qt::AlignCenter); + + auto contentWidget = new QWidget(this); + contentWidget->setLayout(_contentLayout); _contentLayout->setSpacing(0); - auto helperLayout = new QGridLayout(); - helperLayout->addWidget(_helpMsg, 0, 0, - Qt::AlignHCenter | Qt::AlignVCenter); - helperLayout->addLayout(_contentLayout, 0, 0); - helperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); - _layout->addLayout(helperLayout, 10); - _layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, - QSizePolicy::Expanding)); - auto wrapper = new QWidget; - wrapper->setLayout(_layout); - setWidget(wrapper); + + auto contentWrapper = new QWidget(this); + auto wrapperLayout = new QVBoxLayout(contentWrapper); + wrapperLayout->setContentsMargins(0, 0, 0, 0); + wrapperLayout->addWidget(contentWidget); + // Move macro segments to the top of the list + wrapperLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, + QSizePolicy::Expanding)); + + _stackedWidget->addWidget(helpWidget); + _stackedWidget->addWidget(contentWrapper); + + setWidget(_stackedWidget); setWidgetResizable(true); setAcceptDrops(true); + SetHelpMsgVisible(true); + connect(verticalScrollBar(), &QScrollBar::valueChanged, this, [this]() { SetupVisibleMacroSegmentWidgets(); }); } @@ -107,9 +119,11 @@ void MacroSegmentList::SetHelpMsg(const QString &msg) const _helpMsg->setText(msg); } -void MacroSegmentList::SetHelpMsgVisible(bool visible) const +void MacroSegmentList::SetHelpMsgVisible(bool visible) { - _helpMsg->setVisible(visible); + _stackedWidget->setCurrentIndex(visible ? 0 : 1); + adjustSize(); + updateGeometry(); } void MacroSegmentList::Insert(int idx, QWidget *widget) @@ -117,23 +131,33 @@ void MacroSegmentList::Insert(int idx, QWidget *widget) widget->installEventFilter(this); _contentLayout->insertWidget(idx, widget); SetupVisibleMacroSegmentWidgets(); + SetHelpMsgVisible(false); + adjustSize(); + updateGeometry(); } void MacroSegmentList::Add(QWidget *widget) { - widget->installEventFilter(this); - _contentLayout->addWidget(widget); - SetupVisibleMacroSegmentWidgets(); + Insert(_contentLayout->count(), widget); } -void MacroSegmentList::Remove(int idx) const +void MacroSegmentList::Remove(int idx) { DeleteLayoutItemWidget(_contentLayout->takeAt(idx)); + adjustSize(); + updateGeometry(); + if (IsEmpty()) { + SetHelpMsgVisible(true); + } } -void MacroSegmentList::Clear(int idx) const +void MacroSegmentList::Clear(int idx) { ClearLayout(_contentLayout, idx); + adjustSize(); + updateGeometry(); + + SetHelpMsgVisible(true); } void MacroSegmentList::SetCachingEnabled(bool enable) @@ -178,6 +202,8 @@ bool MacroSegmentList::PopulateWidgetsFromCache(const Macro *macro) widget->show(); } + adjustSize(); + updateGeometry(); return true; } @@ -411,6 +437,24 @@ void MacroSegmentList::SetVisibilityCheckEnable(bool enable) } } +bool MacroSegmentList::IsEmpty() const +{ + return _contentLayout->count() == 0; +} + +QSize MacroSegmentList::minimumSizeHint() const +{ + return _stackedWidget->currentWidget()->minimumSizeHint(); +} + +QSize MacroSegmentList::sizeHint() const +{ + const auto contentSize = _stackedWidget->currentWidget()->sizeHint(); + const auto hint = + QSize(width(), contentSize.height() + 2 * frameWidth()); + return hint; +} + void MacroSegmentList::SetupVisibleMacroSegmentWidgets() { if (!_checkVisibility) { @@ -428,6 +472,7 @@ void MacroSegmentList::SetupVisibleMacroSegmentWidgets() segment->SetupWidgets(); } + updateGeometry(); } int MacroSegmentList::GetSegmentIndexFromPos(const QPoint &pos) const diff --git a/lib/macro/macro-segment-list.hpp b/lib/macro/macro-segment-list.hpp index 95988c71..13ef7a4a 100644 --- a/lib/macro/macro-segment-list.hpp +++ b/lib/macro/macro-segment-list.hpp @@ -1,12 +1,14 @@ #pragma once #include "macro-segment.hpp" -#include -#include -#include -#include #include +#include +#include +#include +#include +#include + namespace advss { class Macro; @@ -17,51 +19,63 @@ class MacroSegmentList : public QScrollArea { public: MacroSegmentList(QWidget *parent = nullptr); ~MacroSegmentList(); + void SetHelpMsg(const QString &msg) const; - void SetHelpMsgVisible(bool visible) const; + void SetHelpMsgVisible(bool visible); + MacroSegmentEdit *WidgetAt(int idx) const; MacroSegmentEdit *WidgetAt(const QPoint &) const; + int IndexAt(const QPoint &) const; void Insert(int idx, QWidget *widget); void Add(QWidget *widget); - void Remove(int idx) const; - void Clear(int idx = 0) const; // Clear all elements >= idx + void Remove(int idx); + void Clear(int idx = 0); // Clear all elements >= idx + bool IsEmpty() const; + static void SetCachingEnabled(bool enable); void CacheCurrentWidgetsFor(const Macro *); bool PopulateWidgetsFromCache(const Macro *); void ClearWidgetsFromCacheFor(const Macro *); + void SetVisibilityCheckEnable(bool enable); + void Highlight(int idx, QColor color = QColor(Qt::green)); + void SetCollapsed(bool) const; void SetSelection(int idx) const; QVBoxLayout *ContentLayout() const { return _contentLayout; } - void SetVisibilityCheckEnable(bool enable); + + QSize minimumSizeHint() const override; + QSize sizeHint() const override; signals: void SelectionChanged(int idx); void Reorder(int source, int target); protected: - bool eventFilter(QObject *object, QEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void dragLeaveEvent(QDragLeaveEvent *event); - void dragEnterEvent(QDragEnterEvent *event); - void dragMoveEvent(QDragMoveEvent *event); - void dropEvent(QDropEvent *event); - void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *object, QEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void dragLeaveEvent(QDragLeaveEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + void resizeEvent(QResizeEvent *event) override; private: void SetupVisibleMacroSegmentWidgets(); + void ClearWidgetCache(); + int GetSegmentIndexFromPos(const QPoint &) const; + bool IsInListArea(const QPoint &) const; + QRect GetContentItemRectWithPadding(int idx) const; + int GetDragIndex(const QPoint &) const; int GetDropIndex(const QPoint &) const; void CheckScroll() const; void CheckDropLine(const QPoint &); - bool IsInListArea(const QPoint &) const; - QRect GetContentItemRectWithPadding(int idx) const; void HideLastDropLine(); - void ClearWidgetCache(); int _dragPosition = -1; int _dropLineIdx = -1; @@ -69,6 +83,7 @@ private: std::thread _autoScrollThread; std::atomic_bool _autoScroll{false}; + QStackedWidget *_stackedWidget; QVBoxLayout *_layout; QVBoxLayout *_contentLayout; QLabel *_helpMsg;