diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index b7a01d854..78a0c0b23 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -429,6 +429,7 @@ Basic.Main.AddSourceHelp.Text="You need to have at least 1 scene to add a source # basic mode main window Basic.Main.Scenes="Scenes" Basic.Main.Sources="Sources" +Basic.Main.Controls="Controls" Basic.Main.Connecting="Connecting..." Basic.Main.StartRecording="Start Recording" Basic.Main.StartReplayBuffer="Start Replay Buffer" @@ -487,6 +488,9 @@ Basic.MainMenu.Edit.AdvAudio="&Advanced Audio Properties" # basic mode view menu Basic.MainMenu.View="&View" Basic.MainMenu.View.Toolbars="&Toolbars" +Basic.MainMenu.View.Docks="Docks" +Basic.MainMenu.View.Docks.ResetUI="Reset UI" +Basic.MainMenu.View.Docks.LockUI="Lock UI" Basic.MainMenu.View.Toolbars.Listboxes="&Listboxes" Basic.MainMenu.View.SceneTransitions="S&cene Transitions" Basic.MainMenu.View.StatusBar="&Status Bar" diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui index 53998458a..cb11bb446 100644 --- a/UI/forms/OBSBasic.ui +++ b/UI/forms/OBSBasic.ui @@ -7,8 +7,8 @@ 0 0 - 1110 - 724 + 1079 + 730 @@ -34,238 +34,40 @@ - + - - - Qt::Vertical - - - false - - - + + + + + + 0 + 0 + + + + Qt::CustomContextMenu + + + Basic.Main.PreviewDisabled + + + Qt::AlignCenter + + + + + + + 2 + - + - 2 + 4 - - - 4 - - - - - - 0 - 0 - - - - - 32 - 32 - - - - Qt::ClickFocus - - - Qt::CustomContextMenu - - - - - - - - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - Basic.Main.PreviewDisabled - - - Qt::AlignCenter - - - - - - - - - - - 2 - - - - - true - - - - 0 - 0 - - - - Basic.Main.StartStreaming - - - false - - - - - - - true - - - - 0 - 0 - - - - - 130 - 0 - - - - Basic.Main.StartRecording - - - - - - - Basic.TogglePreviewProgramMode - - - true - - - - - - - - 0 - 0 - - - - Settings - - - - - - - - 0 - 0 - - - - Exit - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - 220 - 0 - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 215 - 16 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - - - + 0 @@ -274,537 +76,23 @@ - 160 - 0 + 32 + 32 - - - 260 - 16777215 - + + Qt::ClickFocus - - QFrame::StyledPanel + + Qt::CustomContextMenu - - QFrame::Sunken - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - QFrame::NoFrame - - - QFrame::Plain - - - true - - - true - - - QAbstractItemView::InternalMove - - - Qt::TargetMoveAction - - - - - - - - - 16 - 16 - - - - false - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 150 - 0 - - - - - - - - - Basic.Main.Sources - - - - - - - 2 - - - - - - 0 - 0 - - - - Mixer - - - - - - - - 0 - 0 - - - - - 22 - 22 - - - - Basic.AdvAudio - - - - - - - :/res/images/configuration21_16.png:/res/images/configuration21_16.png - - - true - - - configIconSmall - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - 0 - - - - - - 0 - 0 - - - - - 160 - 0 - - - - - 260 - 16777215 - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - QFrame::NoFrame - - - true - - - true - - - QAbstractItemView::InternalMove - - - Qt::TargetMoveAction - - - QAbstractItemView::ExtendedSelection - - - - - - - - - 16 - 16 - - - - false - - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 150 - 0 - - - - - - - - - - - - - Basic.Main.Scenes - - - - - - - Basic.SceneTransitions - - - - - - - - 4 - - - 1 - - - 1 - - - 1 - - - 2 - - - - - - 120 - 0 - - - - Transition - - - - - - - 4 - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 22 - 22 - - - - Basic.AddTransition - - - Basic.AddTransition - - - - - - - :/res/images/add.png:/res/images/add.png - - - true - - - addIconSmall - - - - - - - - 0 - 0 - - - - - 22 - 22 - - - - Basic.RemoveTransition - - - Basic.RemoveTransition - - - - - - - :/res/images/list_remove.png:/res/images/list_remove.png - - - true - - - removeIconSmall - - - - - - - - 0 - 0 - - - - - 22 - 22 - - - - Basic.TransitionProperties - - - Basic.TransitionProperties - - - - - - - :/res/images/configuration21_16.png:/res/images/configuration21_16.png - - - true - - - configIconSmall - - - - - - - - - 4 - - - - - - 0 - 0 - - - - Basic.TransitionDuration - - - transitionDuration - - - - - - - Basic.TransitionDuration - - - ms - - - 2 - - - 10000 - - - 50 - - - 300 - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - + + @@ -813,7 +101,7 @@ 0 0 - 1110 + 1079 21 @@ -978,18 +266,31 @@ - - - - F11 + + + Basic.MainMenu.View.Docks + + + + + + + + + + Basic.MainMenu.View.Fullscreen.Interface + + F11 + + + - @@ -1010,6 +311,773 @@ + + + QDockWidget::AllDockWidgetFeatures + + + Basic.Main.Scenes + + + 8 + + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + + 160 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Qt::CustomContextMenu + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + true + + + QAbstractItemView::InternalMove + + + Qt::TargetMoveAction + + + + + + + + 16 + 16 + + + + false + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 150 + 0 + + + + + + + + + + + + + QDockWidget::AllDockWidgetFeatures + + + Basic.Main.Sources + + + 8 + + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + + 160 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Qt::CustomContextMenu + + + QFrame::NoFrame + + + true + + + true + + + QAbstractItemView::InternalMove + + + Qt::TargetMoveAction + + + QAbstractItemView::ExtendedSelection + + + + + + + + 16 + 16 + + + + false + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 150 + 0 + + + + + + + + + + + + + QDockWidget::AllDockWidgetFeatures + + + Mixer + + + 8 + + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 220 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 230 + 16 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 2 + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.AdvAudio + + + + + + + :/res/images/configuration21_16.png:/res/images/configuration21_16.png + + + true + + + configIconSmall + + + + + + + + + + + QDockWidget::AllDockWidgetFeatures + + + Basic.SceneTransitions + + + 8 + + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 4 + + + 1 + + + 1 + + + 1 + + + 2 + + + + + + 120 + 0 + + + + Transition + + + + + + + 4 + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.AddTransition + + + Basic.AddTransition + + + + + + + :/res/images/add.png:/res/images/add.png + + + true + + + addIconSmall + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.RemoveTransition + + + Basic.RemoveTransition + + + + + + + :/res/images/list_remove.png:/res/images/list_remove.png + + + true + + + removeIconSmall + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + Basic.TransitionProperties + + + Basic.TransitionProperties + + + + + + + :/res/images/configuration21_16.png:/res/images/configuration21_16.png + + + true + + + configIconSmall + + + + + + + + + 4 + + + + + + 0 + 0 + + + + Basic.TransitionDuration + + + transitionDuration + + + + + + + Basic.TransitionDuration + + + ms + + + 2 + + + 10000 + + + 50 + + + 300 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + QDockWidget::AllDockWidgetFeatures + + + Basic.Main.Controls + + + 8 + + + + + 2 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + true + + + + 0 + 0 + + + + Basic.Main.StartStreaming + + + false + + + + + + + true + + + + 0 + 0 + + + + + 130 + 0 + + + + Basic.Main.StartRecording + + + + + + + Basic.TogglePreviewProgramMode + + + true + + + + + + + + 0 + 0 + + + + Settings + + + + + + + + 0 + 0 + + + + Exit + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + @@ -1414,17 +1482,6 @@ Basic.MainMenu.View.Toolbars.Listboxes - - - true - - - true - - - Basic.MainMenu.View.SceneTransitions - - true @@ -1488,6 +1545,77 @@ Basic.Stats + + + Basic.MainMenu.View.Docks.ResetUI + + + + + true + + + true + + + Basic.MainMenu.View.Docks.LockUI + + + + + true + + + true + + + Basic.Main.Scenes + + + + + true + + + true + + + Basic.Main.Sources + + + + + true + + + true + + + Mixer + + + + + true + + + true + + + Basic.SceneTransitions + + + + + true + + + true + + + Basic.Main.Controls + + @@ -1540,12 +1668,12 @@ close() - 838 - 272 + 976 + 601 - 902 - -10 + 862 + -11 diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 055179cd0..65b680b77 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -145,6 +145,8 @@ OBSBasic::OBSBasic(QWidget *parent) ui->setupUi(this); ui->previewDisabledLabel->setVisible(false); + startingDockLayout = saveState(); + copyActionsDynamicProperties(); ui->sources->setItemDelegate(new VisibilityItemDelegate(ui->sources)); @@ -257,6 +259,33 @@ OBSBasic::OBSBasic(QWidget *parent) addNudge(Qt::Key_Down, SLOT(NudgeDown())); addNudge(Qt::Key_Left, SLOT(NudgeLeft())); addNudge(Qt::Key_Right, SLOT(NudgeRight())); + + auto assignDockToggle = [this](QDockWidget *dock, QAction *action) + { + auto handleWindowToggle = [action] (bool vis) + { + action->blockSignals(true); + action->setChecked(vis); + action->blockSignals(false); + }; + auto handleMenuToggle = [dock] (bool check) + { + dock->blockSignals(true); + dock->setVisible(check); + dock->blockSignals(false); + }; + + dock->connect(dock->toggleViewAction(), &QAction::toggled, + handleWindowToggle); + dock->connect(action, &QAction::toggled, + handleMenuToggle); + }; + + assignDockToggle(ui->scenesDock, ui->toggleScenes); + assignDockToggle(ui->sourcesDock, ui->toggleSources); + assignDockToggle(ui->mixerDock, ui->toggleMixer); + assignDockToggle(ui->transitionsDock, ui->toggleTransitions); + assignDockToggle(ui->controlsDock, ui->toggleControls); } static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent, @@ -1355,7 +1384,6 @@ void OBSBasic::OBSInit() } \ } while (false) - SET_VISIBILITY("ShowTransitions", toggleSceneTransitions); SET_VISIBILITY("ShowListboxToolbars", toggleListboxToolbars); SET_VISIBILITY("ShowStatusBar", toggleStatusBar); #undef SET_VISIBILITY @@ -1419,24 +1447,26 @@ void OBSBasic::OBSInit() show(); #endif - QList defSizes; - - int top = config_get_int(App()->GlobalConfig(), "BasicWindow", - "splitterTop"); - int bottom = config_get_int(App()->GlobalConfig(), "BasicWindow", - "splitterBottom"); - - if (!top || !bottom) { - defSizes = ui->mainSplitter->sizes(); - int total = defSizes[0] + defSizes[1]; - defSizes[0] = total * 75 / 100; - defSizes[1] = total - defSizes[0]; + const char *dockStateStr = config_get_string(App()->GlobalConfig(), + "BasicWindow", "DockState"); + if (!dockStateStr) { + on_resetUI_triggered(); } else { - defSizes.push_back(top); - defSizes.push_back(bottom); + QByteArray dockState = + QByteArray::fromBase64(QByteArray(dockStateStr)); + if (!restoreState(dockState)) + on_resetUI_triggered(); } - ui->mainSplitter->setSizes(defSizes); + config_set_default_bool(App()->GlobalConfig(), "BasicWindow", + "DocksLocked", true); + + bool docksLocked = config_get_bool(App()->GlobalConfig(), + "BasicWindow", "DocksLocked"); + on_lockUI_toggled(docksLocked); + ui->lockUI->blockSignals(true); + ui->lockUI->setChecked(docksLocked); + ui->lockUI->blockSignals(false); SystemTray(true); @@ -1758,13 +1788,8 @@ OBSBasic::~OBSBasic() config_set_int(App()->GlobalConfig(), "General", "LastVersion", LIBOBS_API_VER); - QList splitterSizes = ui->mainSplitter->sizes(); bool alwaysOnTop = IsAlwaysOnTop(this); - config_set_int(App()->GlobalConfig(), "BasicWindow", "splitterTop", - splitterSizes[0]); - config_set_int(App()->GlobalConfig(), "BasicWindow", "splitterBottom", - splitterSizes[1]); config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewEnabled", previewEnabled); config_set_bool(App()->GlobalConfig(), "BasicWindow", "AlwaysOnTop", @@ -1777,6 +1802,8 @@ OBSBasic::~OBSBasic() "EditPropertiesMode", editPropertiesMode); config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewProgramMode", IsPreviewProgramMode()); + config_set_bool(App()->GlobalConfig(), "BasicWindow", + "DocksLocked", ui->lockUI->isChecked()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); #ifdef _WIN32 @@ -2981,6 +3008,10 @@ void OBSBasic::closeEvent(QCloseEvent *event) "BasicWindow", "geometry", saveGeometry().toBase64().constData()); + config_set_string(App()->GlobalConfig(), + "BasicWindow", "DockState", + saveState().toBase64().constData()); + if (outputHandler && outputHandler->Active()) { SetShowing(true); @@ -5253,13 +5284,57 @@ int OBSBasic::GetProfilePath(char *path, size_t size, const char *file) const return snprintf(path, size, "%s/%s/%s", profiles_path, profile, file); } -void OBSBasic::on_toggleSceneTransitions_toggled(bool visible) +void OBSBasic::on_resetUI_triggered() { - ui->sceneTransitionsLabel->setVisible(visible); - ui->transitionsContainer->setVisible(visible); + restoreState(startingDockLayout); - config_set_bool(App()->GlobalConfig(), "BasicWindow", - "ShowTransitions", visible); + int cx = width(); + int cy = height(); + + int cx22_5 = cx * 225 / 1000; + int cx5 = cx * 5 / 100; + + cy = cy * 225 / 1000; + + int mixerSize = cx - (cx22_5 * 2 + cx5 * 2); + + QList docks { + ui->scenesDock, + ui->sourcesDock, + ui->mixerDock, + ui->transitionsDock, + ui->controlsDock + }; + + QList sizes { + cx22_5, + cx22_5, + mixerSize, + cx5, + cx5 + }; + + ui->scenesDock->setVisible(true); + ui->sourcesDock->setVisible(true); + ui->mixerDock->setVisible(true); + ui->transitionsDock->setVisible(true); + ui->controlsDock->setVisible(true); + + resizeDocks(docks, {cy, cy, cy, cy, cy}, Qt::Vertical); + resizeDocks(docks, sizes, Qt::Horizontal); +} + +void OBSBasic::on_lockUI_toggled(bool lock) +{ + QDockWidget::DockWidgetFeatures features = lock + ? QDockWidget::NoDockWidgetFeatures + : QDockWidget::AllDockWidgetFeatures; + + ui->scenesDock->setFeatures(features); + ui->sourcesDock->setFeatures(features); + ui->mixerDock->setFeatures(features); + ui->transitionsDock->setFeatures(features); + ui->controlsDock->setFeatures(features); } void OBSBasic::on_toggleListboxToolbars_toggled(bool visible) diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index d34b74d0f..85e804600 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -348,6 +348,8 @@ private: QList visDlgPositions; + QByteArray startingDockLayout; + obs_data_array_t *SaveProjectors(); void LoadSavedProjectors(obs_data_array_t *savedProjectors); @@ -615,7 +617,6 @@ private slots: void on_actionAlwaysOnTop_triggered(); - void on_toggleSceneTransitions_toggled(bool visible); void on_toggleListboxToolbars_toggled(bool visible); void on_toggleStatusBar_toggled(bool visible); @@ -629,6 +630,9 @@ private slots: void on_autoConfigure_triggered(); void on_stats_triggered(); + void on_resetUI_triggered(); + void on_lockUI_toggled(bool lock); + void logUploadFinished(const QString &text, const QString &error); void updateCheckFinished();