Move / add tabWidget related helper functions

This commit is contained in:
WarmUpTill 2024-04-02 19:21:42 +02:00 committed by WarmUpTill
parent ec5944f53c
commit ce501bd972
7 changed files with 215 additions and 125 deletions

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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<const char *, 19> tabNames = {
"generalTab", "macroTab", "variableTab",
"windowTitleTab", "executableTab", "screenRegionTab",
"mediaTab", "fileTab", "randomTab",
"timeTab", "idleTab", "sceneSequenceTab",
"audioTab", "videoTab", "networkTab",
"sceneGroupTab", "transitionsTab", "pauseTab",
"sceneTriggerTab"};
static std::vector<int> tabOrder = std::vector<int>(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<QWidget *>(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<int>(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<int>(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"),

View File

@ -171,7 +171,6 @@ public:
/* --- Start of UI section --- */
bool settingsWindowOpened = false;
int lastOpenedTab = -1;
std::string lastImportPath;
QStringList loadFailureLibs;
bool warnPluginLoadFailure = true;

182
lib/utils/tab-helpers.cpp Normal file
View File

@ -0,0 +1,182 @@
#include "tab-helpers.hpp"
#include "log-helper.hpp"
#include "obs-module-helper.hpp"
#include <obs.hpp>
#include <QTabBar>
#include <string>
#include <unordered_map>
#include <vector>
namespace advss {
static std::vector<std::string> tabNames = {
"generalTab", "macroTab", "windowTitleTab",
"executableTab", "screenRegionTab", "mediaTab",
"fileTab", "randomTab", "timeTab",
"idleTab", "sceneSequenceTab", "audioTab",
"videoTab", "networkTab", "sceneGroupTab",
"transitionsTab", "pauseTab", "sceneTriggerTab"};
static std::vector<int> tabOrder = std::vector<int>(tabNames.size());
namespace {
struct TabCallbacks {
std::function<QWidget *()> createWidget;
std::function<void(QTabWidget *)> setupTab;
};
} // namespace
static std::unordered_map<const char *, TabCallbacks> 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<QWidget *()> createWidget,
std::function<void(QTabWidget *)> 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<int>(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<int>(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<QWidget *>(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

22
lib/utils/tab-helpers.hpp Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "export-symbol-helper.hpp"
#include <obs-data.h>
#include <QTabWidget>
namespace advss {
EXPORT void AddSetupTabCallback(const char *tabName,
std::function<QWidget *()> createWidget,
std::function<void(QTabWidget *)> 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