From ce501bd972a8a14453e7c7a21efbfc01e9ccf9b4 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Tue, 2 Apr 2024 19:21:42 +0200 Subject: [PATCH] Move / add tabWidget related helper functions --- CMakeLists.txt | 2 + lib/advanced-scene-switcher.cpp | 8 +- lib/advanced-scene-switcher.hpp | 3 - lib/general.cpp | 122 +-------------------- lib/switcher-data.hpp | 1 - lib/utils/tab-helpers.cpp | 182 ++++++++++++++++++++++++++++++++ lib/utils/tab-helpers.hpp | 22 ++++ 7 files changed, 215 insertions(+), 125 deletions(-) create mode 100644 lib/utils/tab-helpers.cpp create mode 100644 lib/utils/tab-helpers.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 37195b73..a71c2052 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,6 +217,8 @@ target_sources( lib/utils/switch-button.hpp lib/utils/sync-helpers.cpp lib/utils/sync-helpers.hpp + lib/utils/tab-helpers.cpp + lib/utils/tab-helpers.hpp lib/utils/temp-variable.cpp lib/utils/temp-variable.hpp lib/utils/ui-helpers.cpp diff --git a/lib/advanced-scene-switcher.cpp b/lib/advanced-scene-switcher.cpp index ae7ae70a..ffee766f 100644 --- a/lib/advanced-scene-switcher.cpp +++ b/lib/advanced-scene-switcher.cpp @@ -11,6 +11,7 @@ #include "status-control.hpp" #include "switcher-data.hpp" #include "ui-helpers.hpp" +#include "tab-helpers.hpp" #include "utility.hpp" #include "version.h" @@ -44,7 +45,7 @@ AdvSceneSwitcher::~AdvSceneSwitcher() { if (switcher) { switcher->settingsWindowOpened = false; - switcher->lastOpenedTab = ui->tabWidget->currentIndex(); + SaveLastOpenedTab(ui->tabWidget); } } @@ -113,10 +114,11 @@ void AdvSceneSwitcher::LoadUI() SetupTriggerTab(); SetupMacroTab(); SetupVariableTab(); + SetupOtherTabs(ui->tabWidget); SetDeprecationWarnings(); - SetTabOrder(); - SetCurrentTab(); + SetTabOrder(ui->tabWidget); + SetCurrentTab(ui->tabWidget); RestoreWindowGeo(); CheckFirstTimeSetup(); diff --git a/lib/advanced-scene-switcher.hpp b/lib/advanced-scene-switcher.hpp index d84b8b7f..159c378d 100644 --- a/lib/advanced-scene-switcher.hpp +++ b/lib/advanced-scene-switcher.hpp @@ -34,8 +34,6 @@ public: void LoadUI(); - void SetTabOrder(); - void SetCurrentTab(); void RestoreWindowGeo(); void CheckFirstTimeSetup(); @@ -59,7 +57,6 @@ public slots: void on_autoStartEvent_currentIndexChanged(int index); void on_noMatchSwitchScene_currentTextChanged(const QString &text); void on_checkInterval_valueChanged(int value); - void on_tabMoved(int from, int to); void on_tabWidget_currentChanged(int index); void on_exportSettings_clicked(); void on_importSettings_clicked(); diff --git a/lib/general.cpp b/lib/general.cpp index 499905b8..40e8b83f 100644 --- a/lib/general.cpp +++ b/lib/general.cpp @@ -9,6 +9,7 @@ #include "splitter-helpers.hpp" #include "status-control.hpp" #include "switcher-data.hpp" +#include "tab-helpers.hpp" #include "ui-helpers.hpp" #include "utility.hpp" #include "variable.hpp" @@ -19,17 +20,6 @@ namespace advss { -static constexpr std::array tabNames = { - "generalTab", "macroTab", "variableTab", - "windowTitleTab", "executableTab", "screenRegionTab", - "mediaTab", "fileTab", "randomTab", - "timeTab", "idleTab", "sceneSequenceTab", - "audioTab", "videoTab", "networkTab", - "sceneGroupTab", "transitionsTab", "pauseTab", - "sceneTriggerTab"}; - -static std::vector tabOrder = std::vector(tabNames.size()); - void AdvSceneSwitcher::reject() { close(); @@ -244,14 +234,7 @@ void AdvSceneSwitcher::on_hideLegacyTabs_stateChanged(int state) for (int idx = 0; idx < ui->tabWidget->count(); idx++) { if (isLegacyTab(ui->tabWidget->tabText(idx))) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - // TODO: Switch to setTabVisible() once QT 5.15 is more wide spread - ui->tabWidget->setTabEnabled(idx, !state); - ui->tabWidget->setStyleSheet( - "QTabBar::tab::disabled {width: 0; height: 0; margin: 0; padding: 0; border: none;} "); -#else ui->tabWidget->setTabVisible(idx, !state); -#endif } } } @@ -363,67 +346,6 @@ void AdvSceneSwitcher::on_importSettings_clicked() } } -static int findTabIndex(QTabWidget *tabWidget, int pos) -{ - int at = -1; - QString tabName = tabNames.at(pos); - QWidget *page = tabWidget->findChild(tabName); - if (page) { - at = tabWidget->indexOf(page); - } - if (at == -1) { - blog(LOG_INFO, "failed to find tab %s", - tabName.toUtf8().constData()); - } - - return at; -} - -static bool tabWidgetOrderValid() -{ - auto tmp = std::vector(tabNames.size()); - std::iota(tmp.begin(), tmp.end(), 0); - - for (auto &p : tmp) { - auto it = std::find(tabOrder.begin(), tabOrder.end(), p); - if (it == tabOrder.end()) { - return false; - } - } - return true; -} - -static void resetTabWidgetOrder() -{ - tabOrder = std::vector(tabNames.size()); - std::iota(tabOrder.begin(), tabOrder.end(), 0); -} - -void AdvSceneSwitcher::SetTabOrder() -{ - if (!tabWidgetOrderValid()) { - resetTabWidgetOrder(); - } - - QTabBar *bar = ui->tabWidget->tabBar(); - for (int i = 0; i < bar->count(); ++i) { - int curPos = findTabIndex(ui->tabWidget, tabOrder[i]); - - if (i != curPos && curPos != -1) { - bar->moveTab(curPos, i); - } - } - - connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved); -} - -void AdvSceneSwitcher::SetCurrentTab() -{ - if (switcher->lastOpenedTab >= 0) { - ui->tabWidget->setCurrentIndex(switcher->lastOpenedTab); - } -} - static bool windowPosValid(QPoint pos) { return !!QGuiApplication::screenAt(pos); @@ -446,15 +368,6 @@ void AdvSceneSwitcher::CheckFirstTimeSetup() } } -void AdvSceneSwitcher::on_tabMoved(int from, int to) -{ - if (loading) { - return; - } - - std::swap(tabOrder[from], tabOrder[to]); -} - void AdvSceneSwitcher::on_tabWidget_currentChanged(int) { switcher->showFrame = false; @@ -537,7 +450,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj) RunPostLoadSteps(); // Reset on startup and scene collection change - switcher->lastOpenedTab = -1; + ResetLastOpenedTab(); startupLoadDone = true; } @@ -685,13 +598,7 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj) void SwitcherData::SaveUISettings(obs_data_t *obj) { - OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create(); - for (size_t i = 0; i < tabNames.size(); i++) { - OBSDataAutoRelease entry = obs_data_create(); - obs_data_set_int(entry, tabNames[i], tabOrder[i]); - obs_data_array_push_back(tabWidgetOrder, entry); - } - obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder); + SaveTabOrder(obj); obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo); obs_data_set_int(obj, "windowPosX", windowPos.x()); @@ -705,28 +612,7 @@ void SwitcherData::SaveUISettings(obs_data_t *obj) void SwitcherData::LoadUISettings(obs_data_t *obj) { - OBSDataArrayAutoRelease defaultTabWidgetOrder = obs_data_array_create(); - for (size_t i = 0; i < tabNames.size(); i++) { - OBSDataAutoRelease entry = obs_data_create(); - obs_data_set_default_int(entry, tabNames[i], i); - obs_data_array_push_back(defaultTabWidgetOrder, entry); - } - obs_data_set_default_array(obj, "tabWidgetOrder", - defaultTabWidgetOrder); - - tabOrder.clear(); - OBSDataArrayAutoRelease tabWidgetOrder = - obs_data_get_array(obj, "tabWidgetOrder"); - for (size_t i = 0; i < tabNames.size(); i++) { - OBSDataAutoRelease entry = - obs_data_array_item(tabWidgetOrder, i); - tabOrder.emplace_back( - (int)(obs_data_get_int(entry, tabNames[i]))); - } - - if (!tabWidgetOrderValid()) { - resetTabWidgetOrder(); - } + LoadTabOrder(obj); saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo"); windowPos = {(int)obs_data_get_int(obj, "windowPosX"), diff --git a/lib/switcher-data.hpp b/lib/switcher-data.hpp index 0d2e98a7..1c74e61f 100644 --- a/lib/switcher-data.hpp +++ b/lib/switcher-data.hpp @@ -171,7 +171,6 @@ public: /* --- Start of UI section --- */ bool settingsWindowOpened = false; - int lastOpenedTab = -1; std::string lastImportPath; QStringList loadFailureLibs; bool warnPluginLoadFailure = true; diff --git a/lib/utils/tab-helpers.cpp b/lib/utils/tab-helpers.cpp new file mode 100644 index 00000000..e0971e56 --- /dev/null +++ b/lib/utils/tab-helpers.cpp @@ -0,0 +1,182 @@ +#include "tab-helpers.hpp" +#include "log-helper.hpp" +#include "obs-module-helper.hpp" + +#include +#include +#include +#include +#include + +namespace advss { + +static std::vector tabNames = { + "generalTab", "macroTab", "windowTitleTab", + "executableTab", "screenRegionTab", "mediaTab", + "fileTab", "randomTab", "timeTab", + "idleTab", "sceneSequenceTab", "audioTab", + "videoTab", "networkTab", "sceneGroupTab", + "transitionsTab", "pauseTab", "sceneTriggerTab"}; + +static std::vector tabOrder = std::vector(tabNames.size()); + +namespace { +struct TabCallbacks { + std::function createWidget; + std::function setupTab; +}; +} // namespace + +static std::unordered_map createTabCallbacks; + +static int lastOpenedTab = -1; + +void SetTabVisibleByName(QTabWidget *tabWidget, bool visible, + const QString &name) +{ + for (int idx = 0; idx < tabWidget->count(); idx++) { + if (tabWidget->tabText(idx) != name) { + continue; + } + + tabWidget->setTabVisible(idx, visible); + } +} + +void AddSetupTabCallback(const char *tabName, + std::function createWidget, + std::function setupTab) +{ + if (std::find(tabNames.begin(), tabNames.end(), tabName) != + tabNames.end()) { + return; + } + tabNames.emplace_back(tabName); + TabCallbacks callbacks = {createWidget, setupTab}; + createTabCallbacks.emplace(tabName, callbacks); +} + +void SaveLastOpenedTab(QTabWidget *tabWidget) +{ + lastOpenedTab = tabWidget->currentIndex(); +} + +void ResetLastOpenedTab() +{ + lastOpenedTab = -1; +} + +void SaveTabOrder(obs_data_t *obj) +{ + OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create(); + for (size_t i = 0; i < tabNames.size(); i++) { + OBSDataAutoRelease entry = obs_data_create(); + obs_data_set_int(entry, tabNames[i].c_str(), tabOrder[i]); + obs_data_array_push_back(tabWidgetOrder, entry); + } + obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder); +} + +static bool tabWidgetOrderValid() +{ + auto tmp = std::vector(tabNames.size()); + std::iota(tmp.begin(), tmp.end(), 0); + + for (auto &p : tmp) { + auto it = std::find(tabOrder.begin(), tabOrder.end(), p); + if (it == tabOrder.end()) { + return false; + } + } + return true; +} + +static void resetTabWidgetOrder() +{ + tabOrder = std::vector(tabNames.size()); + std::iota(tabOrder.begin(), tabOrder.end(), 0); +} + +void LoadTabOrder(obs_data_t *obj) +{ + OBSDataArrayAutoRelease defaultTabWidgetOrder = obs_data_array_create(); + for (size_t i = 0; i < tabNames.size(); i++) { + OBSDataAutoRelease entry = obs_data_create(); + obs_data_set_default_int(entry, tabNames[i].c_str(), i); + obs_data_array_push_back(defaultTabWidgetOrder, entry); + } + obs_data_set_default_array(obj, "tabWidgetOrder", + defaultTabWidgetOrder); + + tabOrder.clear(); + OBSDataArrayAutoRelease tabWidgetOrder = + obs_data_get_array(obj, "tabWidgetOrder"); + for (size_t i = 0; i < tabNames.size(); i++) { + OBSDataAutoRelease entry = + obs_data_array_item(tabWidgetOrder, i); + tabOrder.emplace_back( + (int)(obs_data_get_int(entry, tabNames[i].c_str()))); + } + + if (!tabWidgetOrderValid()) { + resetTabWidgetOrder(); + } +} + +static int findTabIndex(QTabWidget *tabWidget, int pos) +{ + int at = -1; + QString tabName = QString::fromStdString(tabNames.at(pos)); + QWidget *page = tabWidget->findChild(tabName); + if (page) { + at = tabWidget->indexOf(page); + } + if (at == -1) { + blog(LOG_INFO, "failed to find tab %s", + tabName.toUtf8().constData()); + } + + return at; +} + +void SetTabOrder(QTabWidget *tabWidget) +{ + if (!tabWidgetOrderValid()) { + resetTabWidgetOrder(); + } + + auto bar = tabWidget->tabBar(); + for (int i = 0; i < bar->count(); ++i) { + int curPos = findTabIndex(tabWidget, tabOrder[i]); + + if (i != curPos && curPos != -1) { + bar->moveTab(curPos, i); + } + } + + QWidget::connect(bar, &QTabBar::tabMoved, [](int from, int to) { + std::swap(tabOrder[from], tabOrder[to]); + }); +} + +void SetCurrentTab(QTabWidget *tabWidget) +{ + if (lastOpenedTab >= 0) { + tabWidget->setCurrentIndex(lastOpenedTab); + } +} + +void SetupOtherTabs(QTabWidget *tabWidget) +{ + for (const auto &[name, callbacks] : createTabCallbacks) { + auto widget = callbacks.createWidget(); + widget->setObjectName(name); + auto tabText = obs_module_text( + (std::string("AdvSceneSwitcher.") + name + ".title") + .c_str()); + tabWidget->insertTab(0, widget, tabText); + callbacks.setupTab(tabWidget); + } +} + +} // namespace advss diff --git a/lib/utils/tab-helpers.hpp b/lib/utils/tab-helpers.hpp new file mode 100644 index 00000000..3dd5f2bd --- /dev/null +++ b/lib/utils/tab-helpers.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "export-symbol-helper.hpp" + +#include +#include + +namespace advss { + +EXPORT void AddSetupTabCallback(const char *tabName, + std::function createWidget, + std::function setupTab); +EXPORT void SetTabVisibleByName(QTabWidget *tabWidget, bool visible, + const QString &name); +void SaveLastOpenedTab(QTabWidget *tabWidget); +void ResetLastOpenedTab(); +void SetTabOrder(QTabWidget *tabWidget); +void SetCurrentTab(QTabWidget *tabWidget); +void SetupOtherTabs(QTabWidget *tabWidget); +void SaveTabOrder(obs_data_t *obj); +void LoadTabOrder(obs_data_t *obj); + +} // namespace advss