From 7f85cdb50021371b690c94db6343da116c6a7bee Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Thu, 15 Oct 2020 20:59:59 +0200 Subject: [PATCH] update UI of window tab --- forms/advanced-scene-switcher.ui | 77 +---- src/general.cpp | 2 +- src/headers/advanced-scene-switcher.hpp | 12 +- src/headers/switch-window.hpp | 48 ++- src/headers/switcher-data-structs.hpp | 2 +- src/switch-window.cpp | 397 ++++++++++++------------ src/switcher-data-structs.cpp | 2 +- 7 files changed, 238 insertions(+), 302 deletions(-) diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index 41f0e557..a70f3020 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -1161,74 +1161,7 @@ - - - - - true - - - 20 - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - - - - if fullscreen - - - - - - - if maximized - - - - - - - if focused - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + 0 @@ -1246,7 +1179,7 @@ 4 - + 22 @@ -1262,7 +1195,7 @@ - + 22 @@ -1317,7 +1250,7 @@ - + 22 @@ -1340,7 +1273,7 @@ - + 22 diff --git a/src/general.cpp b/src/general.cpp index b92e1b5a..eb98eda8 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -246,7 +246,7 @@ void SceneSwitcher::on_verboseLogging_stateChanged(int state) switcher->verbose = state; } -void SceneSwitcher::on_uiHints_stateChanged(int state) +void SceneSwitcher::on_uiHintsDisable_stateChanged(int state) { if (loading) return; diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 68879f66..94a09e76 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -33,7 +33,6 @@ public: void SetStarted(); void SetStopped(); - int FindByData(const QString &window); int ScreenRegionFindByData(const QString ®ion); int PauseScenesFindByData(const QString &scene); int PauseWindowsFindByData(const QString &window); @@ -87,11 +86,10 @@ public: bool listMoveDown(QListWidget *list); public slots: - void on_switches_currentRowChanged(int idx); - void on_up_clicked(); - void on_down_clicked(); - void on_add_clicked(); - void on_remove_clicked(); + void on_windowUp_clicked(); + void on_windowDown_clicked(); + void on_windowAdd_clicked(); + void on_windowRemove_clicked(); void on_noMatchDontSwitch_clicked(); void on_noMatchSwitch_clicked(); void on_noMatchRandomSwitch_clicked(); @@ -136,7 +134,7 @@ public slots: void on_autoStartScenes_currentTextChanged(const QString &text); void on_verboseLogging_stateChanged(int state); - void on_uiHints_stateChanged(int state); + void on_uiHintsDisable_stateChanged(int state); void on_exportSettings_clicked(); void on_importSettings_clicked(); diff --git a/src/headers/switch-window.hpp b/src/headers/switch-window.hpp index 16b91702..e0ebb89c 100644 --- a/src/headers/switch-window.hpp +++ b/src/headers/switch-window.hpp @@ -1,22 +1,22 @@ #pragma once -#include #include "utility.hpp" #include "switch-generic.hpp" constexpr auto window_title_func = 5; constexpr auto default_priority_5 = window_title_func; -struct WindowSceneSwitch : SceneSwitcherEntry { - std::string window; - bool fullscreen; - bool maximized; - bool focus; +struct WindowSwitch : SceneSwitcherEntry { + std::string window = ""; + bool fullscreen = false; + bool maximized = false; + bool focus = true; const char *getType() { return "window"; } - inline WindowSceneSwitch(OBSWeakSource scene_, const char *window_, - OBSWeakSource transition_, bool fullscreen_, - bool maximized_, bool focus_) + inline WindowSwitch() {} + inline WindowSwitch(OBSWeakSource scene_, const char *window_, + OBSWeakSource transition_, bool fullscreen_, + bool maximized_, bool focus_) : SceneSwitcherEntry(scene_, transition_), window(window_), fullscreen(fullscreen_), @@ -26,8 +26,28 @@ struct WindowSceneSwitch : SceneSwitcherEntry { } }; -static inline QString MakeWindowSwitchName(const QString &scene, - const QString &value, - const QString &transition, - bool fullscreen, bool maximized, - bool focus); +class WindowSwitchWidget : public SwitchWidget { + Q_OBJECT + +public: + WindowSwitchWidget(WindowSwitch *s); + WindowSwitch *getSwitchData(); + void setSwitchData(WindowSwitch *s); + + static void swapSwitchData(WindowSwitchWidget *s1, + WindowSwitchWidget *s2); + +private slots: + void WindowChanged(const QString &text); + void FullscreenChanged(int state); + void MaximizedChanged(int state); + void FocusChanged(int state); + +private: + QComboBox *windows; + QCheckBox *fullscreen; + QCheckBox *maximized; + QCheckBox *focused; + + WindowSwitch *switchData; +}; diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 2c58ddbf..25c56b87 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -59,7 +59,7 @@ struct SwitcherData { NoMatch switchIfNotMatching = NO_SWITCH; StartupBehavior startupBehavior = PERSIST; - std::vector windowSwitches; + std::deque windowSwitches; std::vector ignoreIdleWindows; std::string lastTitle; diff --git a/src/switch-window.cpp b/src/switch-window.cpp index 476ef8cd..5ea87a24 100644 --- a/src/switch-window.cpp +++ b/src/switch-window.cpp @@ -1,141 +1,76 @@ #include "headers/advanced-scene-switcher.hpp" -bool isRunning(std::string &title) +static QMetaObject::Connection addPulse; + +void SceneSwitcher::on_windowAdd_clicked() { - QStringList windows; + ui->windowAdd->disconnect(addPulse); - GetWindowList(windows); - // True if switch is running (direct) - bool equals = windows.contains(QString::fromStdString(title)); - // True if switch is running (regex) - bool matches = (windows.indexOf(QRegularExpression( - QString::fromStdString(title))) != -1); + std::lock_guard lock(switcher->m); + switcher->windowSwitches.emplace_back(); - return (equals || matches); + QListWidgetItem *item; + item = new QListWidgetItem(ui->windowSwitches); + ui->windowSwitches->addItem(item); + WindowSwitchWidget *sw = + new WindowSwitchWidget(&switcher->windowSwitches.back()); + item->setSizeHint(sw->minimumSizeHint()); + ui->windowSwitches->setItemWidget(item, sw); } -bool isFocused(std::string &title) +void SceneSwitcher::on_windowRemove_clicked() { - std::string current; - - GetCurrentWindowTitle(current); - // True if switch equals current window - bool equals = (title == current); - // True if switch matches current window - bool matches = QString::fromStdString(current).contains( - QRegularExpression(QString::fromStdString(title))); - - return (equals || matches); -} - -void SceneSwitcher::on_up_clicked() -{ - int index = ui->switches->currentRow(); - if (index != -1 && index != 0) { - ui->switches->insertItem(index - 1, - ui->switches->takeItem(index)); - ui->switches->setCurrentRow(index - 1); - - std::lock_guard lock(switcher->m); - - iter_swap(switcher->windowSwitches.begin() + index, - switcher->windowSwitches.begin() + index - 1); - } -} - -void SceneSwitcher::on_down_clicked() -{ - int index = ui->switches->currentRow(); - if (index != -1 && index != ui->switches->count() - 1) { - ui->switches->insertItem(index + 1, - ui->switches->takeItem(index)); - ui->switches->setCurrentRow(index + 1); - - std::lock_guard lock(switcher->m); - - iter_swap(switcher->windowSwitches.begin() + index, - switcher->windowSwitches.begin() + index + 1); - } -} - -void SceneSwitcher::on_add_clicked() -{ - QString sceneName = ui->scenes->currentText(); - QString windowName = ui->windows->currentText(); - QString transitionName = ui->transitions->currentText(); - bool fullscreen = ui->fullscreenCheckBox->isChecked(); - bool maximized = ui->maximizedCheckBox->isChecked(); - bool focus = ui->focusCheckBox->isChecked(); - - if (windowName.isEmpty() || sceneName.isEmpty()) - return; - - OBSWeakSource source = GetWeakSourceByQString(sceneName); - OBSWeakSource transition = GetWeakTransitionByQString(transitionName); - QVariant v = QVariant::fromValue(windowName); - - QString text = MakeWindowSwitchName(sceneName, windowName, - transitionName, fullscreen, - maximized, focus); - - int idx = FindByData(windowName); - - if (idx == -1) { - std::lock_guard lock(switcher->m); - switcher->windowSwitches.emplace_back( - source, windowName.toUtf8().constData(), transition, - fullscreen, maximized, focus); - - QListWidgetItem *item = new QListWidgetItem(text, ui->switches); - item->setData(Qt::UserRole, v); - } else { - QListWidgetItem *item = ui->switches->item(idx); - item->setText(text); - - std::string window = windowName.toUtf8().constData(); - - { - std::lock_guard lock(switcher->m); - for (auto &s : switcher->windowSwitches) { - if (s.window == window) { - s.scene = source; - s.transition = transition; - s.fullscreen = fullscreen; - s.maximized = maximized; - s.focus = focus; - break; - } - } - } - } -} - -void SceneSwitcher::on_remove_clicked() -{ - QListWidgetItem *item = ui->switches->currentItem(); + QListWidgetItem *item = ui->windowSwitches->currentItem(); if (!item) return; - std::string window = - item->data(Qt::UserRole).toString().toUtf8().constData(); - { std::lock_guard lock(switcher->m); + int idx = ui->windowSwitches->currentRow(); auto &switches = switcher->windowSwitches; - - for (auto it = switches.begin(); it != switches.end(); ++it) { - auto &s = *it; - - if (s.window == window) { - switches.erase(it); - break; - } - } + switches.erase(switches.begin() + idx); } delete item; } +void SceneSwitcher::on_windowUp_clicked() +{ + int index = ui->windowSwitches->currentRow(); + if (!listMoveUp(ui->windowSwitches)) + return; + + WindowSwitchWidget *s1 = (WindowSwitchWidget *)ui->windowSwitches->itemWidget( + ui->windowSwitches->item(index)); + WindowSwitchWidget *s2 = (WindowSwitchWidget *)ui->windowSwitches->itemWidget( + ui->windowSwitches->item(index - 1)); + WindowSwitchWidget::swapSwitchData(s1, s2); + + std::lock_guard lock(switcher->m); + + std::swap(switcher->windowSwitches[index], + switcher->windowSwitches[index - 1]); +} + +void SceneSwitcher::on_windowDown_clicked() +{ + int index = ui->windowSwitches->currentRow(); + + if (!listMoveDown(ui->windowSwitches)) + return; + + WindowSwitchWidget *s1 = (WindowSwitchWidget *)ui->windowSwitches->itemWidget( + ui->windowSwitches->item(index)); + WindowSwitchWidget *s2 = (WindowSwitchWidget *)ui->windowSwitches->itemWidget( + ui->windowSwitches->item(index + 1)); + WindowSwitchWidget::swapSwitchData(s1, s2); + + std::lock_guard lock(switcher->m); + + std::swap(switcher->windowSwitches[index], + switcher->windowSwitches[index + 1]); +} + void SceneSwitcher::on_ignoreWindowsAdd_clicked() { QString windowName = ui->ignoreWindowsWindows->currentText(); @@ -184,24 +119,6 @@ void SceneSwitcher::on_ignoreWindowsRemove_clicked() delete item; } -int SceneSwitcher::FindByData(const QString &window) -{ - int count = ui->switches->count(); - int idx = -1; - - for (int i = 0; i < count; i++) { - QListWidgetItem *item = ui->switches->item(i); - QString itemWindow = item->data(Qt::UserRole).toString(); - - if (itemWindow == window) { - idx = i; - break; - } - } - - return idx; -} - int SceneSwitcher::IgnoreWindowsFindByData(const QString &window) { int count = ui->ignoreWindows->count(); @@ -220,34 +137,6 @@ int SceneSwitcher::IgnoreWindowsFindByData(const QString &window) return idx; } -void SceneSwitcher::on_switches_currentRowChanged(int idx) -{ - if (loading) - return; - if (idx == -1) - return; - - QListWidgetItem *item = ui->switches->item(idx); - - QString window = item->data(Qt::UserRole).toString(); - - std::lock_guard lock(switcher->m); - for (auto &s : switcher->windowSwitches) { - if (window.compare(s.window.c_str()) == 0) { - std::string name = GetWeakSourceName(s.scene); - std::string transitionName = - GetWeakSourceName(s.transition); - ui->scenes->setCurrentText(name.c_str()); - ui->windows->setCurrentText(window); - ui->transitions->setCurrentText(transitionName.c_str()); - ui->fullscreenCheckBox->setChecked(s.fullscreen); - ui->maximizedCheckBox->setChecked(s.maximized); - ui->focusCheckBox->setChecked(s.focus); - break; - } - } -} - void SceneSwitcher::on_ignoreWindows_currentRowChanged(int idx) { if (loading) @@ -268,6 +157,34 @@ void SceneSwitcher::on_ignoreWindows_currentRowChanged(int idx) } } +bool isRunning(std::string &title) +{ + QStringList windows; + + GetWindowList(windows); + // True if switch is running (direct) + bool equals = windows.contains(QString::fromStdString(title)); + // True if switch is running (regex) + bool matches = (windows.indexOf(QRegularExpression( + QString::fromStdString(title))) != -1); + + return (equals || matches); +} + +bool isFocused(std::string &title) +{ + std::string current; + + GetCurrentWindowTitle(current); + // True if switch equals current window + bool equals = (title == current); + // True if switch matches current window + bool matches = QString::fromStdString(current).contains( + QRegularExpression(QString::fromStdString(title))); + + return (equals || matches); +} + void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { @@ -293,7 +210,7 @@ void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene, lastTitle = title; // Check for match - for (WindowSceneSwitch &s : windowSwitches) { + for (WindowSwitch &s : windowSwitches) { // True if fullscreen is disabled OR current window is fullscreen bool fullscreen = (!s.fullscreen || isFullscreen(s.window)); // True if maximized is disabled OR current window is maximized @@ -324,7 +241,7 @@ void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene, void SwitcherData::saveWindowTitleSwitches(obs_data_t *obj) { obs_data_array_t *windowTitleArray = obs_data_array_create(); - for (WindowSceneSwitch &s : switcher->windowSwitches) { + for (WindowSwitch &s : switcher->windowSwitches) { obs_data_t *array_obj = obs_data_create(); obs_source_t *source = obs_weak_source_get_source(s.scene); @@ -422,24 +339,20 @@ void SwitcherData::loadWindowTitleSwitches(obs_data_t *obj) void SceneSwitcher::setupTitleTab() { - populateSceneSelection(ui->scenes, false); - populateTransitionSelection(ui->transitions); - populateWindowSelection(ui->windows); - populateWindowSelection(ui->ignoreWindowsWindows); - for (auto &s : switcher->windowSwitches) { - std::string sceneName = GetWeakSourceName(s.scene); - std::string transitionName = GetWeakSourceName(s.transition); - QString text = MakeWindowSwitchName(sceneName.c_str(), - s.window.c_str(), - transitionName.c_str(), - s.fullscreen, s.maximized, - s.focus); - - QListWidgetItem *item = new QListWidgetItem(text, ui->switches); - item->setData(Qt::UserRole, s.window.c_str()); + QListWidgetItem *item; + item = new QListWidgetItem(ui->windowSwitches); + ui->windowSwitches->addItem(item); + WindowSwitchWidget *sw = new WindowSwitchWidget(&s); + item->setSizeHint(sw->minimumSizeHint()); + ui->windowSwitches->setItemWidget(item, sw); } + if (switcher->windowSwitches.size() == 0) + addPulse = PulseWidget(ui->windowAdd, QColor(Qt::green)); + + populateWindowSelection(ui->ignoreWindowsWindows); + for (auto &window : switcher->ignoreWindowsSwitches) { QString text = QString::fromStdString(window); @@ -447,36 +360,108 @@ void SceneSwitcher::setupTitleTab() new QListWidgetItem(text, ui->ignoreWindows); item->setData(Qt::UserRole, text); } +} + +WindowSwitchWidget::WindowSwitchWidget(WindowSwitch *s) : SwitchWidget(s, false) +{ + windows = new QComboBox(); + fullscreen = new QCheckBox("if fullscreen"); + maximized = new QCheckBox("if maximized"); + focused = new QCheckBox("if focused"); + + QWidget::connect(windows, SIGNAL(currentTextChanged(const QString &)), + this, SLOT(WindowChanged(const QString &))); + QWidget::connect(fullscreen, SIGNAL(stateChanged(int)), this, + SLOT(FullscreenChanged(int))); + QWidget::connect(maximized, SIGNAL(stateChanged(int)), this, + SLOT(MaximizedChanged(int))); + QWidget::connect(focused, SIGNAL(stateChanged(int)), this, + SLOT(FocusChanged(int))); + + SceneSwitcher::populateWindowSelection(windows); #if __APPLE__ // TODO: // not implemented on MacOS as I cannot test it - ui->maximizedCheckBox->setDisabled(true); - ui->maximizedCheckBox->setVisible(false); + maximized->setDisabled(true); + maximized->setVisible(false); #endif -} -static inline QString MakeWindowSwitchName(const QString &scene, - const QString &value, - const QString &transition, - bool fullscreen, bool maximized, - bool focus) -{ - QString name = QStringLiteral("[") + scene + QStringLiteral(", ") + - transition + QStringLiteral("]: ") + value; - - if (fullscreen || maximized || focus) { - name += QStringLiteral(" (only if"); - - if (fullscreen) - name += QStringLiteral(" fullscreen "); - if (maximized) - name += QStringLiteral(" maximized "); - if (focus) - name += QStringLiteral(" focused"); - - name += QStringLiteral(")"); + if (s) { + windows->setCurrentText(s->window.c_str()); + fullscreen->setChecked(s->fullscreen); + maximized->setChecked(s->maximized); + focused->setChecked(s->focus); } - return name; + setStyleSheet("* { background-color: transparent; }"); + + QHBoxLayout *mainLayout = new QHBoxLayout; + + mainLayout->addWidget(windows); + mainLayout->addWidget(scenes); + mainLayout->addWidget(transitions); + mainLayout->addWidget(scenes); + mainLayout->addWidget(fullscreen); + mainLayout->addWidget(maximized); + mainLayout->addWidget(focused); + mainLayout->addStretch(); + + setLayout(mainLayout); + + switchData = s; + + loading = false; +} + +WindowSwitch *WindowSwitchWidget::getSwitchData() +{ + return switchData; +} + +void WindowSwitchWidget::setSwitchData(WindowSwitch *s) +{ + switchData = s; +} + +void WindowSwitchWidget::swapSwitchData(WindowSwitchWidget *s1, + WindowSwitchWidget *s2) +{ + SwitchWidget::swapSwitchData(s1, s2); + + WindowSwitch *t = s1->getSwitchData(); + s1->setSwitchData(s2->getSwitchData()); + s2->setSwitchData(t); +} + +void WindowSwitchWidget::WindowChanged(const QString &text) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->window = text.toStdString(); +} + +void WindowSwitchWidget::FullscreenChanged(int state) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->fullscreen = state; +} + +void WindowSwitchWidget::MaximizedChanged(int state) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->maximized = state; +} + +void WindowSwitchWidget::FocusChanged(int state) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->focus = state; } diff --git a/src/switcher-data-structs.cpp b/src/switcher-data-structs.cpp index 95b2ed8f..e2555917 100644 --- a/src/switcher-data-structs.cpp +++ b/src/switcher-data-structs.cpp @@ -4,7 +4,7 @@ void SwitcherData::Prune() { for (size_t i = 0; i < windowSwitches.size(); i++) { - WindowSceneSwitch &s = windowSwitches[i]; + WindowSwitch &s = windowSwitches[i]; if (!s.valid()) windowSwitches.erase(windowSwitches.begin() + i--); }