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