diff --git a/lib/macro/macro-segment-list.cpp b/lib/macro/macro-segment-list.cpp index cdbbc371..abc0e11d 100644 --- a/lib/macro/macro-segment-list.cpp +++ b/lib/macro/macro-segment-list.cpp @@ -46,6 +46,17 @@ MacroSegmentList::~MacroSegmentList() _autoScroll = false; _autoScrollThread.join(); } + + const auto clearWidgetVector = + [](const std::vector &widgets) { + for (auto widget : widgets) { + widget->deleteLater(); + } + }; + + for (const auto &[_, widgets] : _widgetCache) { + clearWidgetVector(widgets); + } } static bool posIsInScrollbar(const QScrollBar *scrollbar, const QPoint &pos) @@ -125,6 +136,38 @@ void MacroSegmentList::Clear(int idx) const ClearLayout(_contentLayout, idx); } +void MacroSegmentList::CacheCurrentWidgetsFor(const Macro *macro) +{ + std::vector result; + int idx = 0; + QLayoutItem *item; + while ((item = _contentLayout->takeAt(idx))) { + if (!item || !item->widget()) { + continue; + } + auto widget = item->widget(); + widget->hide(); + result.emplace_back(widget); + } + + _widgetCache[macro] = result; +} + +bool MacroSegmentList::PopulateWidgetsFromCache(const Macro *macro) +{ + auto it = _widgetCache.find(macro); + if (it == _widgetCache.end()) { + return false; + } + + for (auto widget : it->second) { + _contentLayout->addWidget(widget); + widget->show(); + } + + return true; +} + void MacroSegmentList::Highlight(int idx, QColor color) { auto item = _contentLayout->itemAt(idx); diff --git a/lib/macro/macro-segment-list.hpp b/lib/macro/macro-segment-list.hpp index 3c7c8e91..46773c45 100644 --- a/lib/macro/macro-segment-list.hpp +++ b/lib/macro/macro-segment-list.hpp @@ -9,12 +9,14 @@ namespace advss { +class Macro; + class MacroSegmentList : public QScrollArea { Q_OBJECT public: MacroSegmentList(QWidget *parent = nullptr); - virtual ~MacroSegmentList(); + ~MacroSegmentList(); void SetHelpMsg(const QString &msg) const; void SetHelpMsgVisible(bool visible) const; MacroSegmentEdit *WidgetAt(int idx) const; @@ -24,6 +26,8 @@ public: void Add(QWidget *widget); void Remove(int idx) const; void Clear(int idx = 0) const; // Clear all elements >= idx + void CacheCurrentWidgetsFor(const Macro *); + bool PopulateWidgetsFromCache(const Macro *); void Highlight(int idx, QColor color = QColor(Qt::green)); void SetCollapsed(bool) const; void SetSelection(int idx) const; @@ -67,6 +71,8 @@ private: QLabel *_helpMsg; bool _checkVisibility = true; + + std::unordered_map> _widgetCache; }; } // namespace advss diff --git a/lib/macro/macro-tab.cpp b/lib/macro/macro-tab.cpp index 76e7e287..34ef26c7 100644 --- a/lib/macro/macro-tab.cpp +++ b/lib/macro/macro-tab.cpp @@ -537,6 +537,11 @@ void AdvSceneSwitcher::on_runMacroOnChange_stateChanged(int value) const void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx) { auto &actions = m.Actions(); + ui->actionsList->SetHelpMsgVisible(actions.size() == 0); + + if (ui->actionsList->PopulateWidgetsFromCache(&m)) { + return; + } // The layout system has not completed geometry propagation yet, so we // can skip those checks for now @@ -547,7 +552,6 @@ void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx) actions[afterIdx]->GetId()); ui->actionsList->Add(newEntry); } - ui->actionsList->SetHelpMsgVisible(actions.size() == 0); // Give the layout system time before enabling the visibility checks and // fully constructing the visible macro segments @@ -559,6 +563,11 @@ void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx) void AdvSceneSwitcher::PopulateMacroElseActions(Macro &m, uint32_t afterIdx) { auto &actions = m.ElseActions(); + ui->elseActionsList->SetHelpMsgVisible(actions.size() == 0); + + if (ui->elseActionsList->PopulateWidgetsFromCache(&m)) { + return; + } // The layout system has not completed geometry propagation yet, so we // can skip those checks for now @@ -569,7 +578,6 @@ void AdvSceneSwitcher::PopulateMacroElseActions(Macro &m, uint32_t afterIdx) actions[afterIdx]->GetId()); ui->elseActionsList->Add(newEntry); } - ui->elseActionsList->SetHelpMsgVisible(actions.size() == 0); // Give the layout system time before enabling the visibility checks and // fully constructing the visible macro segments @@ -582,6 +590,11 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx) { bool root = afterIdx == 0; auto &conditions = m.Conditions(); + ui->conditionsList->SetHelpMsgVisible(conditions.size() == 0); + + if (ui->conditionsList->PopulateWidgetsFromCache(&m)) { + return; + } // The layout system has not completed geometry propagation yet, so we // can skip those checks for now @@ -594,7 +607,6 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx) ui->conditionsList->Add(newEntry); root = false; } - ui->conditionsList->SetHelpMsgVisible(conditions.size() == 0); // Give the layout system time before enabling the visibility checks and // fully constructing the visible macro segments @@ -779,6 +791,10 @@ void AdvSceneSwitcher::MacroSelectionAboutToChange() const } macro->SetElseActionSplitterPosition( ui->macroElseActionSplitter->sizes()); + + ui->conditionsList->CacheCurrentWidgetsFor(macro); + ui->actionsList->CacheCurrentWidgetsFor(macro); + ui->elseActionsList->CacheCurrentWidgetsFor(macro); } void AdvSceneSwitcher::MacroSelectionChanged()