From cb024a069680ade75e9ff54178866d7a58db1a09 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Wed, 3 Apr 2024 15:14:29 +0200 Subject: [PATCH 1/8] UI: Use connection with modeSwitch button --- UI/window-basic-main-transitions.cpp | 4 ++-- UI/window-basic-main.cpp | 6 ++++++ UI/window-basic-main.hpp | 9 +++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/UI/window-basic-main-transitions.cpp b/UI/window-basic-main-transitions.cpp index edf3baf9ffa08e..60d1943206fa43 100644 --- a/UI/window-basic-main-transitions.cpp +++ b/UI/window-basic-main-transitions.cpp @@ -976,7 +976,7 @@ int OBSBasic::GetTbarPosition() return tBar->value(); } -void OBSBasic::on_modeSwitch_clicked() +void OBSBasic::TogglePreviewProgramMode() { SetPreviewProgramMode(!IsPreviewProgramMode()); } @@ -1607,8 +1607,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) if (IsPreviewProgramMode() == enabled) return; - ui->modeSwitch->setChecked(enabled); os_atomic_set_bool(&previewProgramMode, enabled); + emit PreviewProgramModeChanged(enabled); if (IsPreviewProgramMode()) { if (!previewEnabled) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 9f72c621cfc4f9..798d71f634e7e2 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -334,6 +334,12 @@ OBSBasic::OBSBasic(QWidget *parent) ui->previewDisabledWidget->setVisible(false); ui->broadcastButton->setVisible(false); + /* Setup Studio Mode button connections */ + connect(this, &OBSBasic::PreviewProgramModeChanged, ui->modeSwitch, + &QAbstractButton::setChecked); + connect(ui->modeSwitch, &QAbstractButton::clicked, this, + &OBSBasic::TogglePreviewProgramMode); + startingDockLayout = saveState(); statsDock = new OBSDock(); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 64d237446f5b5c..9bbd58f049ec9b 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -1177,8 +1177,6 @@ private slots: void ShowTransitionProperties(); void HideTransitionProperties(); - void on_modeSwitch_clicked(); - // Source Context Buttons void on_sourcePropertiesButton_clicked(); void on_sourceFiltersButton_clicked(); @@ -1236,6 +1234,9 @@ private slots: void RepairOldExtraDockName(); void RepairCustomExtraDockName(); + /* Studio Mode toggle slot */ + void TogglePreviewProgramMode(); + public slots: void on_actionResetTransform_triggered(); @@ -1249,6 +1250,10 @@ public slots: void UpdateContextBarDeferred(bool force = false); void UpdateContextBarVisibility(); +signals: + /* Studio Mode signal */ + void PreviewProgramModeChanged(bool enabled); + private: std::unique_ptr ui; From 909327533616f5c981dd1908d6a8f0bb6c9915d7 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Wed, 3 Apr 2024 17:08:14 +0200 Subject: [PATCH 2/8] UI: Track recording state in OBSBasic Avoid using controls dock buttons for recording states. Use signals and OBSBasic member variables instead. --- UI/window-basic-main.cpp | 70 +++++++++++++++++++++++++++++++--------- UI/window-basic-main.hpp | 11 +++++++ 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 798d71f634e7e2..6878965609a9df 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -340,6 +340,30 @@ OBSBasic::OBSBasic(QWidget *parent) connect(ui->modeSwitch, &QAbstractButton::clicked, this, &OBSBasic::TogglePreviewProgramMode); + /* Set up recording connections */ + connect( + this, &OBSBasic::RecordingStarted, this, + [this]() { + this->recordingStarted = true; + this->recordingPaused = false; + }, + Qt::DirectConnection); + connect( + this, &OBSBasic::RecordingPaused, this, + [this]() { this->recordingPaused = true; }, + Qt::DirectConnection); + connect( + this, &OBSBasic::RecordingUnpaused, this, + [this]() { this->recordingPaused = false; }, + Qt::DirectConnection); + connect( + this, &OBSBasic::RecordingStopped, this, + [this]() { + this->recordingStarted = false; + this->recordingPaused = false; + }, + Qt::DirectConnection); + startingDockLayout = saveState(); statsDock = new OBSDock(); @@ -1994,6 +2018,8 @@ void OBSBasic::ResetOutputs() if (sysTrayReplayBuffer) sysTrayReplayBuffer->setEnabled( !!outputHandler->replayBuffer); + + UpdateIsRecordingPausable(); } else { outputHandler->Update(); } @@ -2802,10 +2828,10 @@ void OBSBasic::CreateHotkeys() "OBSBasic.StartRecording", Str("Basic.Main.StartRecording"), "OBSBasic.StopRecording", Str("Basic.Main.StopRecording"), MAKE_CALLBACK(!basic.outputHandler->RecordingActive() && - !basic.ui->recordButton->isChecked(), + !basic.recordingStarted, basic.StartRecording, "Starting recording"), MAKE_CALLBACK(basic.outputHandler->RecordingActive() && - basic.ui->recordButton->isChecked(), + basic.recordingStarted, basic.StopRecording, "Stopping recording"), this, this); LoadHotkeyPair(recordingHotkeys, "OBSBasic.StartRecording", @@ -2814,9 +2840,11 @@ void OBSBasic::CreateHotkeys() pauseHotkeys = obs_hotkey_pair_register_frontend( "OBSBasic.PauseRecording", Str("Basic.Main.PauseRecording"), "OBSBasic.UnpauseRecording", Str("Basic.Main.UnpauseRecording"), - MAKE_CALLBACK(basic.pause && !basic.pause->isChecked(), + MAKE_CALLBACK(basic.isRecordingPausable && + !basic.recordingPaused, basic.PauseRecording, "Pausing recording"), - MAKE_CALLBACK(basic.pause && basic.pause->isChecked(), + MAKE_CALLBACK(basic.isRecordingPausable && + basic.recordingPaused, basic.UnpauseRecording, "Unpausing recording"), this, this); LoadHotkeyPair(pauseHotkeys, "OBSBasic.PauseRecording", @@ -7795,6 +7823,7 @@ void OBSBasic::StopRecording() void OBSBasic::RecordingStart() { ui->statusbar->RecordingStarted(outputHandler->fileOutput); + emit RecordingStarted(); ui->recordButton->setText(QTStr("Basic.Main.StopRecording")); ui->recordButton->setChecked(true); @@ -7817,6 +7846,7 @@ void OBSBasic::RecordingStart() void OBSBasic::RecordingStop(int code, QString last_error) { ui->statusbar->RecordingStopped(); + emit RecordingStopped(); ui->recordButton->setText(QTStr("Basic.Main.StartRecording")); ui->recordButton->setChecked(false); @@ -10793,7 +10823,8 @@ void OBSBasic::UpdatePatronJson(const QString &text, const QString &error) void OBSBasic::PauseRecording() { - if (!pause || !outputHandler || !outputHandler->fileOutput || + if (!isRecordingPausable || !outputHandler || + !outputHandler->fileOutput || os_atomic_load_bool(&recording_paused)) return; @@ -10802,6 +10833,7 @@ void OBSBasic::PauseRecording() if (obs_output_pause(output, true)) { os_atomic_set_bool(&recording_paused, true); + emit RecordingPaused(); pause->setAccessibleName(QTStr("Basic.Main.UnpauseRecording")); pause->setToolTip(QTStr("Basic.Main.UnpauseRecording")); pause->blockSignals(true); @@ -10839,7 +10871,8 @@ void OBSBasic::PauseRecording() void OBSBasic::UnpauseRecording() { - if (!pause || !outputHandler || !outputHandler->fileOutput || + if (!isRecordingPausable || !outputHandler || + !outputHandler->fileOutput || !os_atomic_load_bool(&recording_paused)) return; @@ -10848,6 +10881,7 @@ void OBSBasic::UnpauseRecording() if (obs_output_pause(output, false)) { os_atomic_set_bool(&recording_paused, false); + emit RecordingUnpaused(); pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); pause->setToolTip(QTStr("Basic.Main.PauseRecording")); pause->blockSignals(true); @@ -10882,7 +10916,8 @@ void OBSBasic::UnpauseRecording() void OBSBasic::PauseToggled() { - if (!pause || !outputHandler || !outputHandler->fileOutput) + if (!isRecordingPausable || !outputHandler || + !outputHandler->fileOutput) return; obs_output_t *output = outputHandler->fileOutput; @@ -10894,16 +10929,11 @@ void OBSBasic::PauseToggled() UnpauseRecording(); } -void OBSBasic::UpdatePause(bool activate) +void OBSBasic::UpdateIsRecordingPausable() { - if (!activate || !outputHandler || !outputHandler->RecordingActive()) { - pause.reset(); - return; - } - const char *mode = config_get_string(basicConfig, "Output", "Mode"); bool adv = astrcmpi(mode, "Advanced") == 0; - bool shared; + bool shared = true; if (adv) { const char *recType = @@ -10923,7 +10953,17 @@ void OBSBasic::UpdatePause(bool activate) shared = strcmp(quality, "Stream") == 0; } - if (!shared) { + isRecordingPausable = !shared; +} + +void OBSBasic::UpdatePause(bool activate) +{ + if (!activate || !outputHandler || !outputHandler->RecordingActive()) { + pause.reset(); + return; + } + + if (isRecordingPausable) { pause.reset(new QPushButton()); pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); pause->setToolTip(QTStr("Basic.Main.PauseRecording")); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 9bbd58f049ec9b..0e3b514d6e729e 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -677,6 +677,10 @@ class OBSBasic : public OBSMainWindow { void UpdatePreviewOverflowSettings(); + bool recordingStarted = false; + bool isRecordingPausable = false; + bool recordingPaused = false; + bool restartingVCam = false; public slots: @@ -881,6 +885,7 @@ private slots: void AutoRemux(QString input, bool no_show = false); + void UpdateIsRecordingPausable(); void UpdatePause(bool activate = true); void UpdateReplayBuffer(bool activate = true); @@ -1251,6 +1256,12 @@ public slots: void UpdateContextBarVisibility(); signals: + /* Recording signals */ + void RecordingStarted(); + void RecordingPaused(); + void RecordingUnpaused(); + void RecordingStopped(); + /* Studio Mode signal */ void PreviewProgramModeChanged(bool enabled); From d23b65a2bf99922e3b377f292ab8e14e68268fa7 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Sat, 6 Apr 2024 15:37:34 +0200 Subject: [PATCH 3/8] UI: Track streaming state in OBSBasic Avoid using controls dock buttons for streaming state. Use signals and OBSBasic member variables instead. --- UI/window-basic-main.cpp | 25 +++++++++++++++++++++++-- UI/window-basic-main.hpp | 7 +++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 6878965609a9df..d7535e5b03b71b 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -340,6 +340,20 @@ OBSBasic::OBSBasic(QWidget *parent) connect(ui->modeSwitch, &QAbstractButton::clicked, this, &OBSBasic::TogglePreviewProgramMode); + /* Set up streaming connections */ + connect( + this, &OBSBasic::StreamingStarting, this, + [this] { this->streamingStarting = true; }, + Qt::DirectConnection); + connect( + this, &OBSBasic::StreamingStarted, this, + [this] { this->streamingStarting = false; }, + Qt::DirectConnection); + connect( + this, &OBSBasic::StreamingStopped, this, + [this] { this->streamingStarting = false; }, + Qt::DirectConnection); + /* Set up recording connections */ connect( this, &OBSBasic::RecordingStarted, this, @@ -2803,10 +2817,10 @@ void OBSBasic::CreateHotkeys() "OBSBasic.StartStreaming", Str("Basic.Main.StartStreaming"), "OBSBasic.StopStreaming", Str("Basic.Main.StopStreaming"), MAKE_CALLBACK(!basic.outputHandler->StreamingActive() && - basic.ui->streamButton->isEnabled(), + !basic.streamingStarting, basic.StartStreaming, "Starting stream"), MAKE_CALLBACK(basic.outputHandler->StreamingActive() && - basic.ui->streamButton->isEnabled(), + !basic.streamingStarting, basic.StopStreaming, "Stopping stream"), this, this); LoadHotkeyPair(streamingHotkeys, "OBSBasic.StartStreaming", @@ -6929,6 +6943,8 @@ void OBSBasic::DisplayStreamStartError() QString message = !outputHandler->lastError.empty() ? QTStr(outputHandler->lastError.c_str()) : QTStr("Output.StartFailedGeneric"); + + emit StreamingStopped(); ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(false); @@ -7089,6 +7105,7 @@ void OBSBasic::StartStreaming() sysTrayStream->setText(text); }; + emit StreamingStarting(); ui->streamButton->setEnabled(false); ui->streamButton->setChecked(false); ui->broadcastButton->setChecked(false); @@ -7481,6 +7498,7 @@ void OBSBasic::ForceStopStreaming() void OBSBasic::StreamDelayStarting(int sec) { + emit StreamingStarted(); ui->streamButton->setText(QTStr("Basic.Main.StopStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(true); @@ -7507,6 +7525,7 @@ void OBSBasic::StreamDelayStarting(int sec) void OBSBasic::StreamDelayStopping(int sec) { + emit StreamingStopped(); ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(false); @@ -7534,6 +7553,7 @@ void OBSBasic::StreamDelayStopping(int sec) void OBSBasic::StreamingStart() { + emit StreamingStarted(); OBSOutputAutoRelease output = obs_frontend_get_streaming_output(); ui->streamButton->setText(QTStr("Basic.Main.StopStreaming")); @@ -7638,6 +7658,7 @@ void OBSBasic::StreamingStop(int code, QString last_error) ui->statusbar->StreamStopped(); + emit StreamingStopped(); ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(false); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 0e3b514d6e729e..a478c49ff47548 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -677,6 +677,8 @@ class OBSBasic : public OBSMainWindow { void UpdatePreviewOverflowSettings(); + bool streamingStarting = false; + bool recordingStarted = false; bool isRecordingPausable = false; bool recordingPaused = false; @@ -1256,6 +1258,11 @@ public slots: void UpdateContextBarVisibility(); signals: + /* Streaming signals */ + void StreamingStarting(); + void StreamingStarted(); + void StreamingStopped(); + /* Recording signals */ void RecordingStarted(); void RecordingPaused(); From 178205257e8a31f43e243788b41d7c5531294621 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Sat, 6 Apr 2024 16:14:36 +0200 Subject: [PATCH 4/8] UI: Set system tray text explicitly Avoid using controls dock buttons as a source for text for system tray elements. --- UI/window-basic-main.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index d7535e5b03b71b..1e823b271be1c8 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -6950,7 +6950,7 @@ void OBSBasic::DisplayStreamStartError() ui->streamButton->setChecked(false); if (sysTrayStream) { - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); sysTrayStream->setEnabled(true); } @@ -7504,7 +7504,7 @@ void OBSBasic::StreamDelayStarting(int sec) ui->streamButton->setChecked(true); if (sysTrayStream) { - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StopStreaming")); sysTrayStream->setEnabled(true); } @@ -7531,7 +7531,7 @@ void OBSBasic::StreamDelayStopping(int sec) ui->streamButton->setChecked(false); if (sysTrayStream) { - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); sysTrayStream->setEnabled(true); } @@ -7562,7 +7562,7 @@ void OBSBasic::StreamingStart() ui->statusbar->StreamStarted(output); if (sysTrayStream) { - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StopStreaming")); sysTrayStream->setEnabled(true); } @@ -7601,7 +7601,7 @@ void OBSBasic::StreamStopping() ui->streamButton->setText(QTStr("Basic.Main.StoppingStreaming")); if (sysTrayStream) - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StoppingStreaming")); streamingStopping = true; if (api) @@ -7664,7 +7664,7 @@ void OBSBasic::StreamingStop(int code, QString last_error) ui->streamButton->setChecked(false); if (sysTrayStream) { - sysTrayStream->setText(ui->streamButton->text()); + sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); sysTrayStream->setEnabled(true); } @@ -7824,7 +7824,7 @@ void OBSBasic::RecordStopping() ui->recordButton->setText(QTStr("Basic.Main.StoppingRecording")); if (sysTrayRecord) - sysTrayRecord->setText(ui->recordButton->text()); + sysTrayRecord->setText(QTStr("Basic.Main.StoppingRecording")); recordingStopping = true; if (api) @@ -7849,7 +7849,7 @@ void OBSBasic::RecordingStart() ui->recordButton->setChecked(true); if (sysTrayRecord) - sysTrayRecord->setText(ui->recordButton->text()); + sysTrayRecord->setText(QTStr("Basic.Main.StopRecording")); recordingStopping = false; if (api) @@ -7872,7 +7872,7 @@ void OBSBasic::RecordingStop(int code, QString last_error) ui->recordButton->setChecked(false); if (sysTrayRecord) - sysTrayRecord->setText(ui->recordButton->text()); + sysTrayRecord->setText(QTStr("Basic.Main.StartRecording")); blog(LOG_INFO, RECORDING_STOP); @@ -8029,7 +8029,7 @@ void OBSBasic::ReplayBufferStopping() if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( - replayBufferButton->first()->text()); + QTStr("Basic.Main.StoppingReplayBuffer")); replayBufferStopping = true; if (api) @@ -8060,7 +8060,7 @@ void OBSBasic::ReplayBufferStart() if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( - replayBufferButton->first()->text()); + QTStr("Basic.Main.StopReplayBuffer")); replayBufferStopping = false; if (api) @@ -8121,7 +8121,7 @@ void OBSBasic::ReplayBufferStop(int code) if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( - replayBufferButton->first()->text()); + QTStr("Basic.Main.StartReplayBuffer")); blog(LOG_INFO, REPLAY_BUFFER_STOP); From eed5578e4c214833cd3c47af1df67b8cb7859a52 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Wed, 5 Jun 2024 08:35:21 +0200 Subject: [PATCH 5/8] UI: Remove setStreamText lambda Avoid tangling controls dock stream button to OBSBasic with a lambda. --- UI/window-basic-main.cpp | 116 +++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 1e823b271be1c8..130259883468a0 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -7099,12 +7099,6 @@ void OBSBasic::StartStreaming() } } - auto setStreamText = [&](const QString &text) { - ui->streamButton->setText(text); - if (sysTrayStream) - sysTrayStream->setText(text); - }; - emit StreamingStarting(); ui->streamButton->setEnabled(false); ui->streamButton->setChecked(false); @@ -7112,75 +7106,77 @@ void OBSBasic::StartStreaming() if (sysTrayStream) sysTrayStream->setEnabled(false); - setStreamText(QTStr("Basic.Main.PreparingStream")); + ui->streamButton->setText("Basic.Main.PreparingStream"); + if (sysTrayStream) + sysTrayStream->setText("Basic.Main.PreparingStream"); auto holder = outputHandler->SetupStreaming(service); - auto future = holder.future.then( - this, [&, setStreamText](bool setupStreamingResult) { - if (!setupStreamingResult) { - DisplayStreamStartError(); - return; - } + auto future = holder.future.then(this, [&](bool setupStreamingResult) { + if (!setupStreamingResult) { + DisplayStreamStartError(); + return; + } - if (api) - api->on_event( - OBS_FRONTEND_EVENT_STREAMING_STARTING); + if (api) + api->on_event(OBS_FRONTEND_EVENT_STREAMING_STARTING); - SaveProject(); + SaveProject(); - setStreamText(QTStr("Basic.Main.Connecting")); + ui->streamButton->setText("Basic.Main.Connecting"); + if (sysTrayStream) + sysTrayStream->setText("Basic.Main.Connecting"); - if (!outputHandler->StartStreaming(service)) { - DisplayStreamStartError(); - return; - } + if (!outputHandler->StartStreaming(service)) { + DisplayStreamStartError(); + return; + } - if (!autoStartBroadcast) { + if (!autoStartBroadcast) { + ui->broadcastButton->setText( + QTStr("Basic.Main.StartBroadcast")); + ui->broadcastButton->setProperty("broadcastState", + "ready"); + ui->broadcastButton->style()->unpolish( + ui->broadcastButton); + ui->broadcastButton->style()->polish( + ui->broadcastButton); + // well, we need to disable button while stream is not active + ui->broadcastButton->setEnabled(false); + } else { + if (!autoStopBroadcast) { ui->broadcastButton->setText( - QTStr("Basic.Main.StartBroadcast")); - ui->broadcastButton->setProperty( - "broadcastState", "ready"); - ui->broadcastButton->style()->unpolish( - ui->broadcastButton); - ui->broadcastButton->style()->polish( - ui->broadcastButton); - // well, we need to disable button while stream is not active - ui->broadcastButton->setEnabled(false); + QTStr("Basic.Main.StopBroadcast")); } else { - if (!autoStopBroadcast) { - ui->broadcastButton->setText(QTStr( - "Basic.Main.StopBroadcast")); - } else { - ui->broadcastButton->setText(QTStr( - "Basic.Main.AutoStopEnabled")); - ui->broadcastButton->setEnabled(false); - } - ui->broadcastButton->setProperty( - "broadcastState", "active"); - ui->broadcastButton->style()->unpolish( - ui->broadcastButton); - ui->broadcastButton->style()->polish( - ui->broadcastButton); - broadcastActive = true; + ui->broadcastButton->setText( + QTStr("Basic.Main.AutoStopEnabled")); + ui->broadcastButton->setEnabled(false); } + ui->broadcastButton->setProperty("broadcastState", + "active"); + ui->broadcastButton->style()->unpolish( + ui->broadcastButton); + ui->broadcastButton->style()->polish( + ui->broadcastButton); + broadcastActive = true; + } - bool recordWhenStreaming = config_get_bool( - GetGlobalConfig(), "BasicWindow", - "RecordWhenStreaming"); - if (recordWhenStreaming) - StartRecording(); + bool recordWhenStreaming = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "RecordWhenStreaming"); + if (recordWhenStreaming) + StartRecording(); - bool replayBufferWhileStreaming = config_get_bool( - GetGlobalConfig(), "BasicWindow", - "ReplayBufferWhileStreaming"); - if (replayBufferWhileStreaming) - StartReplayBuffer(); + bool replayBufferWhileStreaming = + config_get_bool(GetGlobalConfig(), "BasicWindow", + "ReplayBufferWhileStreaming"); + if (replayBufferWhileStreaming) + StartReplayBuffer(); #ifdef YOUTUBE_ENABLED - if (!autoStartBroadcast) - OBSBasic::ShowYouTubeAutoStartWarning(); + if (!autoStartBroadcast) + OBSBasic::ShowYouTubeAutoStartWarning(); #endif - }); + }); startStreamingFuture = {holder.cancelAll, future}; } From 511385891c7616b4e4680c6da4d624b2b68923f6 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Wed, 3 Apr 2024 14:35:10 +0200 Subject: [PATCH 6/8] UI: Separate controls dock from the main window --- UI/basic-controls.cpp | 329 +++++++++++++++++++++++++++++ UI/basic-controls.hpp | 72 +++++++ UI/cmake/legacy.cmake | 6 +- UI/cmake/ui-elements.cmake | 5 +- UI/cmake/ui-qt.cmake | 1 + UI/data/themes/Yami.obt | 8 + UI/forms/OBSBasic.ui | 243 --------------------- UI/forms/OBSBasicControls.ui | 397 ++++++++++++++++++++++++++++++++++ UI/noncheckable-button.hpp | 23 ++ UI/record-button.cpp | 159 -------------- UI/record-button.hpp | 39 ---- UI/window-basic-main.cpp | 399 ++++++++++------------------------- UI/window-basic-main.hpp | 64 ++++-- 13 files changed, 988 insertions(+), 757 deletions(-) create mode 100644 UI/basic-controls.cpp create mode 100644 UI/basic-controls.hpp create mode 100644 UI/forms/OBSBasicControls.ui create mode 100644 UI/noncheckable-button.hpp delete mode 100644 UI/record-button.cpp delete mode 100644 UI/record-button.hpp diff --git a/UI/basic-controls.cpp b/UI/basic-controls.cpp new file mode 100644 index 00000000000000..00145281cc1fe2 --- /dev/null +++ b/UI/basic-controls.cpp @@ -0,0 +1,329 @@ +#include "basic-controls.hpp" + +#include "window-basic-main.hpp" + +OBSBasicControls::OBSBasicControls(OBSBasic *main) + : QFrame(nullptr), + ui(new Ui::OBSBasicControls) +{ + /* Create UI elements */ + ui->setupUi(this); + + streamButtonMenu.reset(new QMenu()); + startStreamAction = + streamButtonMenu->addAction(QTStr("Basic.Main.StartStreaming")); + stopStreamAction = + streamButtonMenu->addAction(QTStr("Basic.Main.StopStreaming")); + QAction *forceStopStreamAction = streamButtonMenu->addAction( + QTStr("Basic.Main.ForceStopStreaming")); + + /* Transfer buttons signals as OBSBasicControls signals */ + connect( + ui->streamButton, &QPushButton::clicked, this, + [this]() { emit this->StreamButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->broadcastButton, &QPushButton::clicked, this, + [this]() { emit this->BroadcastButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->recordButton, &QPushButton::clicked, this, + [this]() { emit this->RecordButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->pauseRecordButton, &QPushButton::clicked, this, + [this]() { emit this->PauseRecordButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->replayBufferButton, &QPushButton::clicked, this, + [this]() { emit this->ReplayBufferButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->saveReplayButton, &QPushButton::clicked, this, + [this]() { emit this->SaveReplayBufferButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->virtualCamButton, &QPushButton::clicked, this, + [this]() { emit this->VirtualCamButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->virtualCamConfigButton, &QPushButton::clicked, this, + [this]() { emit this->VirtualCamConfigButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->modeSwitch, &QPushButton::clicked, this, + [this]() { emit this->StudioModeButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->settingsButton, &QPushButton::clicked, this, + [this]() { emit this->SettingsButtonClicked(); }, + Qt::DirectConnection); + connect( + ui->exitButton, &QPushButton::clicked, this, + [this]() { emit this->ExitButtonClicked(); }, + Qt::DirectConnection); + + /* Transfer menu actions signals as OBSBasicControls signals */ + connect( + startStreamAction.get(), &QAction::triggered, this, + [this]() { emit this->StartStreamMenuActionClicked(); }, + Qt::DirectConnection); + connect( + stopStreamAction.get(), &QAction::triggered, this, + [this]() { emit this->StopStreamMenuActionClicked(); }, + Qt::DirectConnection); + connect( + forceStopStreamAction, &QAction::triggered, this, + [this]() { emit this->ForceStopStreamMenuActionClicked(); }, + Qt::DirectConnection); + + /* Set up default visibilty */ + ui->broadcastButton->setVisible(false); + ui->pauseRecordButton->setVisible(false); + ui->replayBufferButton->setVisible(false); + ui->saveReplayButton->setVisible(false); + ui->virtualCamButton->setVisible(false); + ui->virtualCamConfigButton->setVisible(false); + + /* Set up state update connections */ + connect(main, &OBSBasic::StreamingPreparing, this, + &OBSBasicControls::StreamingPreparing); + connect(main, &OBSBasic::StreamingStarting, this, + &OBSBasicControls::StreamingStarting); + connect(main, &OBSBasic::StreamingStarted, this, + &OBSBasicControls::StreamingStarted); + connect(main, &OBSBasic::StreamingStopping, this, + &OBSBasicControls::StreamingStopping); + connect(main, &OBSBasic::StreamingStopped, this, + &OBSBasicControls::StreamingStopped); + + connect(main, &OBSBasic::BroadcastStreamReady, this, + &OBSBasicControls::BroadcastStreamReady); + connect(main, &OBSBasic::BroadcastStreamActive, this, + &OBSBasicControls::BroadcastStreamActive); + connect(main, &OBSBasic::BroadcastStreamStarted, this, + &OBSBasicControls::BroadcastStreamStarted); + + connect(main, &OBSBasic::RecordingStarted, this, + &OBSBasicControls::RecordingStarted); + connect(main, &OBSBasic::RecordingPaused, this, + &OBSBasicControls::RecordingPaused); + connect(main, &OBSBasic::RecordingUnpaused, this, + &OBSBasicControls::RecordingUnpaused); + connect(main, &OBSBasic::RecordingStopping, this, + &OBSBasicControls::RecordingStopping); + connect(main, &OBSBasic::RecordingStopped, this, + &OBSBasicControls::RecordingStopped); + + connect(main, &OBSBasic::ReplayBufStarted, this, + &OBSBasicControls::ReplayBufferStarted); + connect(main, &OBSBasic::ReplayBufferStopping, this, + &OBSBasicControls::ReplayBufferStopping); + connect(main, &OBSBasic::ReplayBufStopped, this, + &OBSBasicControls::ReplayBufferStopped); + + connect(main, &OBSBasic::VirtualCamStarted, this, + &OBSBasicControls::VirtualCamStarted); + connect(main, &OBSBasic::VirtualCamStopped, this, + &OBSBasicControls::VirtualCamStopped); + + connect(main, &OBSBasic::PreviewProgramModeChanged, this, + &OBSBasicControls::UpdateStudioModeState); + + /* Set up enablement connection */ + connect(main, &OBSBasic::BroadcastFlowEnabled, this, + &OBSBasicControls::EnableBroadcastFlow); + connect(main, &OBSBasic::ReplayBufEnabled, this, + &OBSBasicControls::EnableReplayBufferButtons); + connect(main, &OBSBasic::VirtualCamEnabled, this, + &OBSBasicControls::EnableVirtualCamButtons); +} + +void OBSBasicControls::StreamingPreparing() +{ + ui->streamButton->setEnabled(false); + ui->streamButton->setText(QTStr("Basic.Main.PreparingStream")); +} + +void OBSBasicControls::StreamingStarting(bool broadcastAutoStart) +{ + ui->streamButton->setText(QTStr("Basic.Main.Connecting")); + + if (!broadcastAutoStart) { + // well, we need to disable button while stream is not active + ui->broadcastButton->setEnabled(false); + + ui->broadcastButton->setText( + QTStr("Basic.Main.StartBroadcast")); + + ui->broadcastButton->setProperty("broadcastState", "ready"); + ui->broadcastButton->style()->unpolish(ui->broadcastButton); + ui->broadcastButton->style()->polish(ui->broadcastButton); + } +} + +void OBSBasicControls::StreamingStarted(bool withDelay) +{ + ui->streamButton->setEnabled(true); + ui->streamButton->setChecked(true); + ui->streamButton->setText(QTStr("Basic.Main.StopStreaming")); + + if (withDelay) { + ui->streamButton->setMenu(streamButtonMenu.get()); + startStreamAction->setVisible(false); + stopStreamAction->setVisible(true); + } +} + +void OBSBasicControls::StreamingStopping() +{ + ui->streamButton->setText(QTStr("Basic.Main.StoppingStreaming")); +} + +void OBSBasicControls::StreamingStopped(bool withDelay) +{ + ui->streamButton->setEnabled(true); + ui->streamButton->setChecked(false); + ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); + + if (withDelay) { + if (!ui->streamButton->menu()) + ui->streamButton->setMenu(streamButtonMenu.get()); + + startStreamAction->setVisible(true); + stopStreamAction->setVisible(false); + } else { + ui->streamButton->setMenu(nullptr); + } +} + +void OBSBasicControls::BroadcastStreamReady(bool ready) +{ + ui->broadcastButton->setChecked(ready); +} + +void OBSBasicControls::BroadcastStreamActive() +{ + ui->broadcastButton->setEnabled(true); +} + +void OBSBasicControls::BroadcastStreamStarted(bool autoStop) +{ + ui->broadcastButton->setText( + QTStr(autoStop ? "Basic.Main.AutoStopEnabled" + : "Basic.Main.StopBroadcast")); + if (autoStop) + ui->broadcastButton->setEnabled(false); + + ui->broadcastButton->setProperty("broadcastState", "active"); + ui->broadcastButton->style()->unpolish(ui->broadcastButton); + ui->broadcastButton->style()->polish(ui->broadcastButton); +} + +void OBSBasicControls::RecordingStarted(bool pausable) +{ + ui->recordButton->setChecked(true); + ui->recordButton->setText(QTStr("Basic.Main.StopRecording")); + + if (pausable) { + ui->pauseRecordButton->setVisible(pausable); + RecordingUnpaused(); + } +} + +void OBSBasicControls::RecordingPaused() +{ + QString text = QTStr("Basic.Main.UnpauseRecording"); + + ui->pauseRecordButton->setChecked(true); + ui->pauseRecordButton->setAccessibleName(text); + ui->pauseRecordButton->setToolTip(text); + + ui->saveReplayButton->setEnabled(false); +} + +void OBSBasicControls::RecordingUnpaused() +{ + QString text = QTStr("Basic.Main.PauseRecording"); + + ui->pauseRecordButton->setChecked(false); + ui->pauseRecordButton->setAccessibleName(text); + ui->pauseRecordButton->setToolTip(text); + + ui->saveReplayButton->setEnabled(true); +} + +void OBSBasicControls::RecordingStopping() +{ + ui->recordButton->setText(QTStr("Basic.Main.StoppingRecording")); +} + +void OBSBasicControls::RecordingStopped() +{ + ui->recordButton->setChecked(false); + ui->recordButton->setText(QTStr("Basic.Main.StartRecording")); + + ui->pauseRecordButton->setVisible(false); +} + +void OBSBasicControls::ReplayBufferStarted() +{ + ui->replayBufferButton->setChecked(true); + ui->replayBufferButton->setText(QTStr("Basic.Main.StopReplayBuffer")); + + ui->saveReplayButton->setVisible(true); +} + +void OBSBasicControls::ReplayBufferStopping() +{ + ui->replayBufferButton->setText( + QTStr("Basic.Main.StoppingReplayBuffer")); +} + +void OBSBasicControls::ReplayBufferStopped() +{ + ui->replayBufferButton->setChecked(false); + ui->replayBufferButton->setText(QTStr("Basic.Main.StartReplayBuffer")); + + ui->saveReplayButton->setVisible(false); +} + +void OBSBasicControls::VirtualCamStarted() +{ + ui->virtualCamButton->setChecked(true); + ui->virtualCamButton->setText(QTStr("Basic.Main.StopVirtualCam")); +} + +void OBSBasicControls::VirtualCamStopped() +{ + ui->virtualCamButton->setChecked(false); + ui->virtualCamButton->setText(QTStr("Basic.Main.StartVirtualCam")); +} + +void OBSBasicControls::UpdateStudioModeState(bool enabled) +{ + ui->modeSwitch->setChecked(enabled); +} + +void OBSBasicControls::EnableBroadcastFlow(bool enabled) +{ + ui->broadcastButton->setVisible(enabled); + ui->broadcastButton->setEnabled(enabled); + + ui->broadcastButton->setText(QTStr("Basic.Main.SetupBroadcast")); + + ui->broadcastButton->setProperty("broadcastState", "idle"); + ui->broadcastButton->style()->unpolish(ui->broadcastButton); + ui->broadcastButton->style()->polish(ui->broadcastButton); +} + +void OBSBasicControls::EnableReplayBufferButtons(bool enabled) +{ + ui->replayBufferButton->setVisible(enabled); +} + +void OBSBasicControls::EnableVirtualCamButtons() +{ + ui->virtualCamButton->setVisible(true); + ui->virtualCamConfigButton->setVisible(true); +} diff --git a/UI/basic-controls.hpp b/UI/basic-controls.hpp new file mode 100644 index 00000000000000..6aa6778028ce54 --- /dev/null +++ b/UI/basic-controls.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include + +#include +#include +#include + +class OBSBasic; + +#include "ui_OBSBasicControls.h" + +class OBSBasicControls : public QFrame { + Q_OBJECT + + std::unique_ptr ui; + + QScopedPointer streamButtonMenu; + QPointer startStreamAction; + QPointer stopStreamAction; + +private slots: + void StreamingPreparing(); + void StreamingStarting(bool broadcastAutoStart); + void StreamingStarted(bool withDelay); + void StreamingStopping(); + void StreamingStopped(bool withDelay); + + void BroadcastStreamReady(bool ready); + void BroadcastStreamActive(); + void BroadcastStreamStarted(bool autoStop); + + void RecordingStarted(bool pausable); + void RecordingPaused(); + void RecordingUnpaused(); + void RecordingStopping(); + void RecordingStopped(); + + void ReplayBufferStarted(); + void ReplayBufferStopping(); + void ReplayBufferStopped(); + + void VirtualCamStarted(); + void VirtualCamStopped(); + + void UpdateStudioModeState(bool enabled); + + void EnableBroadcastFlow(bool enabled); + void EnableReplayBufferButtons(bool enabled); + void EnableVirtualCamButtons(); + +public: + OBSBasicControls(OBSBasic *main); + inline ~OBSBasicControls() {} + +signals: + void StreamButtonClicked(); + void BroadcastButtonClicked(); + void RecordButtonClicked(); + void PauseRecordButtonClicked(); + void ReplayBufferButtonClicked(); + void SaveReplayBufferButtonClicked(); + void VirtualCamButtonClicked(); + void VirtualCamConfigButtonClicked(); + void StudioModeButtonClicked(); + void SettingsButtonClicked(); + void ExitButtonClicked(); + + void StartStreamMenuActionClicked(); + void StopStreamMenuActionClicked(); + void ForceStopStreamMenuActionClicked(); +}; diff --git a/UI/cmake/legacy.cmake b/UI/cmake/legacy.cmake index 5351f16f626d67..dc2800464ac60b 100644 --- a/UI/cmake/legacy.cmake +++ b/UI/cmake/legacy.cmake @@ -101,6 +101,7 @@ target_sources( forms/OBSAbout.ui forms/OBSAdvAudio.ui forms/OBSBasic.ui + forms/OBSBasicControls.ui forms/OBSBasicFilters.ui forms/OBSBasicInteraction.ui forms/OBSBasicProperties.ui @@ -167,6 +168,8 @@ target_sources( audio-encoders.cpp audio-encoders.hpp balance-slider.hpp + basic-controls.cpp + basic-controls.hpp clickable-label.hpp double-slider.cpp double-slider.hpp @@ -189,13 +192,12 @@ target_sources( menu-button.cpp menu-button.hpp mute-checkbox.hpp + noncheckable-button.hpp plain-text-edit.cpp plain-text-edit.hpp properties-view.cpp properties-view.hpp properties-view.moc.hpp - record-button.cpp - record-button.hpp remote-text.cpp remote-text.hpp scene-tree.cpp diff --git a/UI/cmake/ui-elements.cmake b/UI/cmake/ui-elements.cmake index 4b4ccb66e1f27f..d3f6f44ec29aac 100644 --- a/UI/cmake/ui-elements.cmake +++ b/UI/cmake/ui-elements.cmake @@ -38,6 +38,8 @@ target_sources( audio-encoders.cpp audio-encoders.hpp balance-slider.hpp + basic-controls.cpp + basic-controls.hpp context-bar-controls.cpp context-bar-controls.hpp focus-list.cpp @@ -55,8 +57,7 @@ target_sources( menu-button.cpp menu-button.hpp mute-checkbox.hpp - record-button.cpp - record-button.hpp + noncheckable-button.hpp remote-text.cpp remote-text.hpp scene-tree.cpp diff --git a/UI/cmake/ui-qt.cmake b/UI/cmake/ui-qt.cmake index 4989d2d1153a5d..6148fda8854924 100644 --- a/UI/cmake/ui-qt.cmake +++ b/UI/cmake/ui-qt.cmake @@ -34,6 +34,7 @@ set(_qt_sources forms/OBSAbout.ui forms/OBSAdvAudio.ui forms/OBSBasic.ui + forms/OBSBasicControls.ui forms/OBSBasicFilters.ui forms/OBSBasicInteraction.ui forms/OBSBasicProperties.ui diff --git a/UI/data/themes/Yami.obt b/UI/data/themes/Yami.obt index 91b48ddc4a2df9..f9bc6e07f088e9 100644 --- a/UI/data/themes/Yami.obt +++ b/UI/data/themes/Yami.obt @@ -990,6 +990,14 @@ QPushButton[themeID="replayBufferButton"], padding: var(--padding_large); } +#pauseRecordButton, +#saveReplayButton, +#virtualCamConfigButton { + padding: var(--padding_large) var(--padding_large); + width: var(--input_height); + max-width: var(--input_height); +} + /* Primary Control Button Checked Coloring */ #streamButton:!hover:!pressed:checked, #recordButton:!hover:!pressed:checked, diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui index a0313b2b4e6549..052d867350099b 100644 --- a/UI/forms/OBSBasic.ui +++ b/UI/forms/OBSBasic.ui @@ -1399,228 +1399,6 @@ - - - QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - Basic.Main.Controls - - - 8 - - - - - 0 - - - 1 - - - 0 - - - 1 - - - 1 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - true - - - - 0 - 0 - - - - - 150 - 0 - - - - Basic.Main.StartStreaming - - - true - - - - - - - true - - - - 0 - 0 - - - - - 150 - 0 - - - - Basic.Main.StartBroadcast - - - true - - - - - - - - - 2 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - - 0 - 0 - - - - Basic.Main.StartRecording - - - true - - - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - Basic.TogglePreviewProgramMode - - - true - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - Settings - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - Exit - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - @@ -2372,11 +2150,6 @@
window-dock.hpp
1 - - RecordButton - QPushButton -
record-button.hpp
-
@@ -2398,21 +2171,5 @@ - - exitButton - clicked() - OBSBasic - close() - - - 976 - 601 - - - 862 - -11 - - - diff --git a/UI/forms/OBSBasicControls.ui b/UI/forms/OBSBasicControls.ui new file mode 100644 index 00000000000000..c70df6142aa03f --- /dev/null +++ b/UI/forms/OBSBasicControls.ui @@ -0,0 +1,397 @@ + + + OBSBasicControls + + + + 0 + 0 + 318 + 213 + + + + + 0 + + + 1 + + + 0 + + + 1 + + + 1 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + true + + + + 0 + 0 + + + + + 150 + 0 + + + + Basic.Main.StartStreaming + + + true + + + + + + + true + + + + 0 + 0 + + + + + 150 + 0 + + + + Basic.Main.StartBroadcast + + + true + + + + + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Basic.Main.StartRecording + + + true + + + + + + + true + + + + 0 + 0 + + + + Basic.Main.PauseRecording + + + Basic.Main.PauseRecording + + + true + + + pauseIconSmall + + + + + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Basic.Main.StartReplayBuffer + + + true + + + replayBufferButton + + + + + + + true + + + + 0 + 0 + + + + Basic.Main.SaveReplay + + + Basic.Main.SaveReplay + + + replayIconSmall + + + + + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Basic.Main.StartVirtualCam + + + true + + + vcamButton + + + + + + + true + + + + 0 + 0 + + + + Basic.Main.VirtualCamConfig + + + Basic.Main.VirtualCamConfig + + + configIconSmall + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Basic.TogglePreviewProgramMode + + + true + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Settings + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Exit + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + NonCheckableButton + QPushButton +
noncheckable-button.hpp
+
+
+ + + + +
diff --git a/UI/noncheckable-button.hpp b/UI/noncheckable-button.hpp new file mode 100644 index 00000000000000..71d942ef31d3e0 --- /dev/null +++ b/UI/noncheckable-button.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +/* Button with its checked property not changed when clicked. + * Meant to be used in situations where manually changing the property + * is always preferred. */ +class NonCheckableButton : public QPushButton { + Q_OBJECT + + inline void nextCheckState() override {} + +public: + inline NonCheckableButton(QWidget *parent = nullptr) + : QPushButton(parent) + { + } + inline NonCheckableButton(const QString &text, + QWidget *parent = nullptr) + : QPushButton(text, parent) + { + } +}; diff --git a/UI/record-button.cpp b/UI/record-button.cpp deleted file mode 100644 index a33bbfdec9cbf7..00000000000000 --- a/UI/record-button.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "record-button.hpp" -#include "window-basic-main.hpp" - -void RecordButton::resizeEvent(QResizeEvent *event) -{ - OBSBasic *main = OBSBasic::Get(); - if (!main->pause) - return; - - QSize pauseSize = main->pause->size(); - int height = main->ui->recordButton->size().height(); - - if (pauseSize.height() != height || pauseSize.width() != height) { - main->pause->setMinimumSize(height, height); - main->pause->setMaximumSize(height, height); - } - - event->accept(); -} - -static QWidget *firstWidget(QLayoutItem *item) -{ - auto widget = item->widget(); - if (widget) - return widget; - - auto layout = item->layout(); - if (!layout) - return nullptr; - - auto n = layout->count(); - for (auto i = 0; i < n; i++) { - widget = firstWidget(layout->itemAt(i)); - if (widget) - return widget; - } - return nullptr; -} - -static QWidget *lastWidget(QLayoutItem *item) -{ - auto widget = item->widget(); - if (widget) - return widget; - - auto layout = item->layout(); - if (!layout) - return nullptr; - - for (auto i = layout->count(); i > 0; i--) { - widget = lastWidget(layout->itemAt(i - 1)); - if (widget) - return widget; - } - return nullptr; -} - -static QWidget *getNextWidget(QBoxLayout *container, QLayoutItem *item) -{ - for (auto i = 1, n = container->count(); i < n; i++) { - if (container->itemAt(i - 1) == item) - return firstWidget(container->itemAt(i)); - } - return nullptr; -} - -ControlsSplitButton::ControlsSplitButton(const QString &text, - const QVariant &themeID, - void (OBSBasic::*clicked)()) - : QHBoxLayout() -{ - button.reset(new QPushButton(text)); - button->setCheckable(true); - button->setProperty("themeID", themeID); - - button->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - button->installEventFilter(this); - - OBSBasic *main = OBSBasic::Get(); - connect(button.data(), &QPushButton::clicked, main, clicked); - - addWidget(button.data()); -} - -void ControlsSplitButton::addIcon(const QString &name, const QVariant &themeID, - void (OBSBasic::*clicked)()) -{ - icon.reset(new QPushButton()); - icon->setAccessibleName(name); - icon->setToolTip(name); - icon->setChecked(false); - icon->setProperty("themeID", themeID); - - QSizePolicy sp; - sp.setHeightForWidth(true); - icon->setSizePolicy(sp); - - OBSBasic *main = OBSBasic::Get(); - connect(icon.data(), &QAbstractButton::clicked, main, clicked); - - addWidget(icon.data()); - QWidget::setTabOrder(button.data(), icon.data()); - - auto next = getNextWidget(main->ui->buttonsVLayout, this); - if (next) - QWidget::setTabOrder(icon.data(), next); -} - -void ControlsSplitButton::removeIcon() -{ - icon.reset(); -} - -void ControlsSplitButton::insert(int index) -{ - OBSBasic *main = OBSBasic::Get(); - auto count = main->ui->buttonsVLayout->count(); - if (index < 0) - index = 0; - else if (index > count) - index = count; - - main->ui->buttonsVLayout->insertLayout(index, this); - - QWidget *prev = button.data(); - - if (index > 0) { - prev = lastWidget(main->ui->buttonsVLayout->itemAt(index - 1)); - if (prev) - QWidget::setTabOrder(prev, button.data()); - prev = button.data(); - } - - if (icon) { - QWidget::setTabOrder(button.data(), icon.data()); - prev = icon.data(); - } - - if (index < count) { - auto next = firstWidget( - main->ui->buttonsVLayout->itemAt(index + 1)); - if (next) - QWidget::setTabOrder(prev, next); - } -} - -bool ControlsSplitButton::eventFilter(QObject *obj, QEvent *event) -{ - if (event->type() == QEvent::Resize && icon) { - QSize iconSize = icon->size(); - int height = button->height(); - - if (iconSize.height() != height || iconSize.width() != height) { - icon->setMinimumSize(height, height); - icon->setMaximumSize(height, height); - } - } - return QObject::eventFilter(obj, event); -} diff --git a/UI/record-button.hpp b/UI/record-button.hpp deleted file mode 100644 index ea8d40c7de1aee..00000000000000 --- a/UI/record-button.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include - -class RecordButton : public QPushButton { - Q_OBJECT - -public: - inline RecordButton(QWidget *parent = nullptr) : QPushButton(parent) {} - - virtual void resizeEvent(QResizeEvent *event) override; -}; - -class OBSBasic; - -class ControlsSplitButton : public QHBoxLayout { - Q_OBJECT - -public: - ControlsSplitButton(const QString &text, const QVariant &themeID, - void (OBSBasic::*clicked)()); - - void addIcon(const QString &name, const QVariant &themeID, - void (OBSBasic::*clicked)()); - void removeIcon(); - void insert(int index); - - inline QPushButton *first() { return button.data(); } - inline QPushButton *second() { return icon.data(); } - -protected: - virtual bool eventFilter(QObject *obj, QEvent *event) override; - -private: - QScopedPointer button; - QScopedPointer icon; -}; diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 130259883468a0..74e07e540af94b 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -47,6 +47,7 @@ #include "platform.hpp" #include "visibility-item-widget.hpp" #include "item-widget-helpers.hpp" +#include "basic-controls.hpp" #include "window-basic-settings.hpp" #include "window-namedialog.hpp" #include "window-basic-auto-config.hpp" @@ -332,13 +333,6 @@ OBSBasic::OBSBasic(QWidget *parent) ui->setupUi(this); ui->previewDisabledWidget->setVisible(false); - ui->broadcastButton->setVisible(false); - - /* Setup Studio Mode button connections */ - connect(this, &OBSBasic::PreviewProgramModeChanged, ui->modeSwitch, - &QAbstractButton::setChecked); - connect(ui->modeSwitch, &QAbstractButton::clicked, this, - &OBSBasic::TogglePreviewProgramMode); /* Set up streaming connections */ connect( @@ -378,6 +372,52 @@ OBSBasic::OBSBasic(QWidget *parent) }, Qt::DirectConnection); + /* Add controls dock */ + OBSBasicControls *controls = new OBSBasicControls(this); + controlsDock = new OBSDock(this); + controlsDock->setObjectName(QString::fromUtf8("controlsDock")); + controlsDock->setWindowTitle(QTStr("Basic.Main.Controls")); + /* Parenting is done there so controls will be deleted alongside controlsDock */ + controlsDock->setWidget(controls); + addDockWidget(Qt::BottomDockWidgetArea, controlsDock); + + connect(controls, &OBSBasicControls::StreamButtonClicked, this, + &OBSBasic::StreamActionTriggered); + + connect(controls, &OBSBasicControls::StartStreamMenuActionClicked, this, + &OBSBasic::StartStreaming); + connect(controls, &OBSBasicControls::StopStreamMenuActionClicked, this, + &OBSBasic::StopStreaming); + connect(controls, &OBSBasicControls::ForceStopStreamMenuActionClicked, + this, &OBSBasic::ForceStopStreaming); + + connect(controls, &OBSBasicControls::BroadcastButtonClicked, this, + &OBSBasic::BroadcastButtonClicked); + + connect(controls, &OBSBasicControls::RecordButtonClicked, this, + &OBSBasic::RecordActionTriggered); + connect(controls, &OBSBasicControls::PauseRecordButtonClicked, this, + &OBSBasic::RecordPauseToggled); + + connect(controls, &OBSBasicControls::ReplayBufferButtonClicked, this, + &OBSBasic::ReplayBufferActionTriggered); + connect(controls, &OBSBasicControls::SaveReplayBufferButtonClicked, + this, &OBSBasic::ReplayBufferSave); + + connect(controls, &OBSBasicControls::VirtualCamButtonClicked, this, + &OBSBasic::VirtualCamActionTriggered); + connect(controls, &OBSBasicControls::VirtualCamConfigButtonClicked, + this, &OBSBasic::OpenVirtualCamConfig); + + connect(controls, &OBSBasicControls::StudioModeButtonClicked, this, + &OBSBasic::TogglePreviewProgramMode); + + connect(controls, &OBSBasicControls::SettingsButtonClicked, this, + &OBSBasic::on_action_Settings_triggered); + + connect(controls, &OBSBasicControls::ExitButtonClicked, this, + &QMainWindow::close); + startingDockLayout = saveState(); statsDock = new OBSDock(); @@ -518,7 +558,7 @@ OBSBasic::OBSBasic(QWidget *parent) SETUP_DOCK(ui->sourcesDock); SETUP_DOCK(ui->mixerDock); SETUP_DOCK(ui->transitionsDock); - SETUP_DOCK(ui->controlsDock); + SETUP_DOCK(controlsDock); SETUP_DOCK(statsDock); #undef SETUP_DOCK @@ -577,9 +617,6 @@ OBSBasic::OBSBasic(QWidget *parent) connect(ui->scenes, &SceneTree::scenesReordered, []() { OBSProjector::UpdateMultiviewProjectors(); }); - connect(ui->broadcastButton, &QPushButton::clicked, this, - &OBSBasic::BroadcastButtonClicked); - connect(App(), &OBSApp::StyleChanged, this, [this]() { if (api) api->on_event(OBS_FRONTEND_EVENT_THEME_CHANGED); @@ -1985,7 +2022,7 @@ void OBSBasic::InitPrimitives() obs_leave_graphics(); } -void OBSBasic::ReplayBufferClicked() +void OBSBasic::ReplayBufferActionTriggered() { if (outputHandler->ReplayBufferActive()) StopReplayBuffer(); @@ -1993,19 +2030,6 @@ void OBSBasic::ReplayBufferClicked() StartReplayBuffer(); }; -void OBSBasic::AddVCamButton() -{ - vcamButton = new ControlsSplitButton( - QTStr("Basic.Main.StartVirtualCam"), "vcamButton", - &OBSBasic::VCamButtonClicked); - vcamButton->addIcon(QTStr("Basic.Main.VirtualCamConfig"), - QStringLiteral("configIconSmall"), - &OBSBasic::VCamConfigButtonClicked); - vcamButton->insert(2); - vcamButton->first()->setSizePolicy(QSizePolicy::Minimum, - QSizePolicy::Minimum); -} - void OBSBasic::ResetOutputs() { ProfileScope("OBSBasic::ResetOutputs"); @@ -2019,15 +2043,7 @@ void OBSBasic::ResetOutputs() outputHandler.reset(advOut ? CreateAdvancedOutputHandler(this) : CreateSimpleOutputHandler(this)); - delete replayBufferButton; - - if (outputHandler->replayBuffer) { - replayBufferButton = new ControlsSplitButton( - QTStr("Basic.Main.StartReplayBuffer"), - "replayBufferButton", - &OBSBasic::ReplayBufferClicked); - replayBufferButton->insert(2); - } + emit ReplayBufEnabled(outputHandler->replayBuffer); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setEnabled( @@ -2169,7 +2185,7 @@ void OBSBasic::OBSInit() vcamEnabled = (obs_get_output_flags(VIRTUAL_CAM_ID) & OBS_OUTPUT_VIDEO) != 0; if (vcamEnabled) { - AddVCamButton(); + emit VirtualCamEnabled(); } InitBasicConfigDefaults2(); @@ -6945,9 +6961,6 @@ void OBSBasic::DisplayStreamStartError() : QTStr("Output.StartFailedGeneric"); emit StreamingStopped(); - ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); - ui->streamButton->setEnabled(true); - ui->streamButton->setChecked(false); if (sysTrayStream) { sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); @@ -6981,6 +6994,8 @@ void OBSBasic::YouTubeActionDialogOk(const QString &broadcast_id, autoStopBroadcast = autostop; broadcastReady = true; + emit BroadcastStreamReady(broadcastReady); + if (start_now) QMetaObject::invokeMethod(this, "StartStreaming"); } @@ -7023,9 +7038,7 @@ void OBSBasic::YoutubeStreamCheck(const std::string &key) auto item = json["items"][0]; auto status = item["status"]["streamStatus"].string_value(); if (status == "active") { - QMetaObject::invokeMethod(ui->broadcastButton, - "setEnabled", - Q_ARG(bool, true)); + emit BroadcastStreamActive(); break; } else { QThread::sleep(1); @@ -7077,8 +7090,6 @@ void OBSBasic::StartStreaming() if (auth && auth->broadcastFlow()) { if (!broadcastActive && !broadcastReady) { - ui->streamButton->setChecked(false); - QMessageBox no_broadcast(this); no_broadcast.setText(QTStr("Output.NoBroadcast.Text")); QPushButton *SetupBroadcast = no_broadcast.addButton( @@ -7099,16 +7110,12 @@ void OBSBasic::StartStreaming() } } - emit StreamingStarting(); - ui->streamButton->setEnabled(false); - ui->streamButton->setChecked(false); - ui->broadcastButton->setChecked(false); - if (sysTrayStream) - sysTrayStream->setEnabled(false); + emit StreamingPreparing(); - ui->streamButton->setText("Basic.Main.PreparingStream"); - if (sysTrayStream) + if (sysTrayStream) { + sysTrayStream->setEnabled(false); sysTrayStream->setText("Basic.Main.PreparingStream"); + } auto holder = outputHandler->SetupStreaming(service); auto future = holder.future.then(this, [&](bool setupStreamingResult) { @@ -7122,7 +7129,8 @@ void OBSBasic::StartStreaming() SaveProject(); - ui->streamButton->setText("Basic.Main.Connecting"); + emit StreamingStarting(autoStartBroadcast); + if (sysTrayStream) sysTrayStream->setText("Basic.Main.Connecting"); @@ -7131,32 +7139,8 @@ void OBSBasic::StartStreaming() return; } - if (!autoStartBroadcast) { - ui->broadcastButton->setText( - QTStr("Basic.Main.StartBroadcast")); - ui->broadcastButton->setProperty("broadcastState", - "ready"); - ui->broadcastButton->style()->unpolish( - ui->broadcastButton); - ui->broadcastButton->style()->polish( - ui->broadcastButton); - // well, we need to disable button while stream is not active - ui->broadcastButton->setEnabled(false); - } else { - if (!autoStopBroadcast) { - ui->broadcastButton->setText( - QTStr("Basic.Main.StopBroadcast")); - } else { - ui->broadcastButton->setText( - QTStr("Basic.Main.AutoStopEnabled")); - ui->broadcastButton->setEnabled(false); - } - ui->broadcastButton->setProperty("broadcastState", - "active"); - ui->broadcastButton->style()->unpolish( - ui->broadcastButton); - ui->broadcastButton->style()->polish( - ui->broadcastButton); + if (autoStartBroadcast) { + emit BroadcastStreamStarted(autoStopBroadcast); broadcastActive = true; } @@ -7185,8 +7169,6 @@ void OBSBasic::BroadcastButtonClicked() if (!broadcastReady || (!broadcastActive && !outputHandler->StreamingActive())) { SetupBroadcast(); - if (broadcastReady) - ui->broadcastButton->setChecked(true); return; } @@ -7210,7 +7192,6 @@ void OBSBasic::BroadcastButtonClicked() this, QTStr("Output.BroadcastStartFailed"), last_error, true); - ui->broadcastButton->setChecked(false); return; } } @@ -7218,18 +7199,7 @@ void OBSBasic::BroadcastButtonClicked() broadcastActive = true; autoStartBroadcast = true; // and clear the flag - if (!autoStopBroadcast) { - ui->broadcastButton->setText( - QTStr("Basic.Main.StopBroadcast")); - } else { - ui->broadcastButton->setText( - QTStr("Basic.Main.AutoStopEnabled")); - ui->broadcastButton->setEnabled(false); - } - - ui->broadcastButton->setProperty("broadcastState", "active"); - ui->broadcastButton->style()->unpolish(ui->broadcastButton); - ui->broadcastButton->style()->polish(ui->broadcastButton); + emit BroadcastStreamStarted(autoStopBroadcast); } else if (!autoStopBroadcast) { #ifdef YOUTUBE_ENABLED bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", @@ -7241,10 +7211,8 @@ void OBSBasic::BroadcastButtonClicked() QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (button == QMessageBox::No) { - ui->broadcastButton->setChecked(true); + if (button == QMessageBox::No) return; - } } std::shared_ptr ytAuth = @@ -7273,19 +7241,14 @@ void OBSBasic::BroadcastButtonClicked() autoStopBroadcast = true; QMetaObject::invokeMethod(this, "StopStreaming"); + emit BroadcastStreamReady(broadcastReady); SetBroadcastFlowEnabled(true); } } void OBSBasic::SetBroadcastFlowEnabled(bool enabled) { - ui->broadcastButton->setEnabled(enabled); - ui->broadcastButton->setVisible(enabled); - ui->broadcastButton->setChecked(broadcastReady); - ui->broadcastButton->setProperty("broadcastState", "idle"); - ui->broadcastButton->style()->unpolish(ui->broadcastButton); - ui->broadcastButton->style()->polish(ui->broadcastButton); - ui->broadcastButton->setText(QTStr("Basic.Main.SetupBroadcast")); + emit BroadcastFlowEnabled(enabled); } void OBSBasic::SetupBroadcast() @@ -7296,11 +7259,7 @@ void OBSBasic::SetupBroadcast() OBSYoutubeActions dialog(this, auth, broadcastReady); connect(&dialog, &OBSYoutubeActions::ok, this, &OBSBasic::YouTubeActionDialogOk); - int result = dialog.Valid() ? dialog.exec() : QDialog::Rejected; - if (result != QDialog::Accepted) { - if (!broadcastReady) - ui->broadcastButton->setChecked(false); - } + dialog.exec(); } #endif } @@ -7433,6 +7392,8 @@ void OBSBasic::StopStreaming() broadcastReady = false; } + emit BroadcastStreamReady(broadcastReady); + OnDeactivate(); bool recordWhenStreaming = config_get_bool( @@ -7473,6 +7434,8 @@ void OBSBasic::ForceStopStreaming() broadcastReady = false; } + emit BroadcastStreamReady(broadcastReady); + OnDeactivate(); bool recordWhenStreaming = config_get_bool( @@ -7494,26 +7457,13 @@ void OBSBasic::ForceStopStreaming() void OBSBasic::StreamDelayStarting(int sec) { - emit StreamingStarted(); - ui->streamButton->setText(QTStr("Basic.Main.StopStreaming")); - ui->streamButton->setEnabled(true); - ui->streamButton->setChecked(true); + emit StreamingStarted(true); if (sysTrayStream) { sysTrayStream->setText(QTStr("Basic.Main.StopStreaming")); sysTrayStream->setEnabled(true); } - if (!startStreamMenu.isNull()) - startStreamMenu->deleteLater(); - - startStreamMenu = new QMenu(); - startStreamMenu->addAction(QTStr("Basic.Main.StopStreaming"), this, - &OBSBasic::StopStreaming); - startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this, - &OBSBasic::ForceStopStreaming); - ui->streamButton->setMenu(startStreamMenu); - ui->statusbar->StreamDelayStarting(sec); OnActivate(); @@ -7521,26 +7471,13 @@ void OBSBasic::StreamDelayStarting(int sec) void OBSBasic::StreamDelayStopping(int sec) { - emit StreamingStopped(); - ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); - ui->streamButton->setEnabled(true); - ui->streamButton->setChecked(false); + emit StreamingStopped(true); if (sysTrayStream) { sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); sysTrayStream->setEnabled(true); } - if (!startStreamMenu.isNull()) - startStreamMenu->deleteLater(); - - startStreamMenu = new QMenu(); - startStreamMenu->addAction(QTStr("Basic.Main.StartStreaming"), this, - &OBSBasic::StartStreaming); - startStreamMenu->addAction(QTStr("Basic.Main.ForceStopStreaming"), this, - &OBSBasic::ForceStopStreaming); - ui->streamButton->setMenu(startStreamMenu); - ui->statusbar->StreamDelayStopping(sec); if (api) @@ -7551,10 +7488,6 @@ void OBSBasic::StreamingStart() { emit StreamingStarted(); OBSOutputAutoRelease output = obs_frontend_get_streaming_output(); - - ui->streamButton->setText(QTStr("Basic.Main.StopStreaming")); - ui->streamButton->setEnabled(true); - ui->streamButton->setChecked(true); ui->statusbar->StreamStarted(output); if (sysTrayStream) { @@ -7594,7 +7527,7 @@ void OBSBasic::StreamingStart() void OBSBasic::StreamStopping() { - ui->streamButton->setText(QTStr("Basic.Main.StoppingStreaming")); + emit StreamingStopping(); if (sysTrayStream) sysTrayStream->setText(QTStr("Basic.Main.StoppingStreaming")); @@ -7655,9 +7588,6 @@ void OBSBasic::StreamingStop(int code, QString last_error) ui->statusbar->StreamStopped(); emit StreamingStopped(); - ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); - ui->streamButton->setEnabled(true); - ui->streamButton->setChecked(false); if (sysTrayStream) { sysTrayStream->setText(QTStr("Basic.Main.StartStreaming")); @@ -7696,12 +7626,6 @@ void OBSBasic::StreamingStop(int code, QString last_error) QSystemTrayIcon::Warning); } - if (!startStreamMenu.isNull()) { - ui->streamButton->setMenu(nullptr); - startStreamMenu->deleteLater(); - startStreamMenu = nullptr; - } - // Reset broadcast button state/text if (!broadcastActive) SetBroadcastFlowEnabled(auth && auth->broadcastFlow()); @@ -7796,13 +7720,11 @@ void OBSBasic::StartRecording() if (!OutputPathValid()) { OutputPathInvalidMessage(); - ui->recordButton->setChecked(false); return; } if (!IsFFmpegOutputToURL() && LowDiskSpace()) { DiskSpaceMessage(); - ui->recordButton->setChecked(false); return; } @@ -7811,13 +7733,12 @@ void OBSBasic::StartRecording() SaveProject(); - if (!outputHandler->StartRecording()) - ui->recordButton->setChecked(false); + outputHandler->StartRecording(); } void OBSBasic::RecordStopping() { - ui->recordButton->setText(QTStr("Basic.Main.StoppingRecording")); + emit RecordingStopping(); if (sysTrayRecord) sysTrayRecord->setText(QTStr("Basic.Main.StoppingRecording")); @@ -7840,9 +7761,7 @@ void OBSBasic::StopRecording() void OBSBasic::RecordingStart() { ui->statusbar->RecordingStarted(outputHandler->fileOutput); - emit RecordingStarted(); - ui->recordButton->setText(QTStr("Basic.Main.StopRecording")); - ui->recordButton->setChecked(true); + emit RecordingStarted(isRecordingPausable); if (sysTrayRecord) sysTrayRecord->setText(QTStr("Basic.Main.StopRecording")); @@ -7855,7 +7774,6 @@ void OBSBasic::RecordingStart() diskFullTimer->start(1000); OnActivate(); - UpdatePause(); blog(LOG_INFO, RECORDING_START); } @@ -7864,8 +7782,6 @@ void OBSBasic::RecordingStop(int code, QString last_error) { ui->statusbar->RecordingStopped(); emit RecordingStopped(); - ui->recordButton->setText(QTStr("Basic.Main.StartRecording")); - ui->recordButton->setChecked(false); if (sysTrayRecord) sysTrayRecord->setText(QTStr("Basic.Main.StartRecording")); @@ -7935,7 +7851,6 @@ void OBSBasic::RecordingStop(int code, QString last_error) AutoRemux(outputHandler->lastRecordingPath.c_str()); OnDeactivate(); - UpdatePause(false); } void OBSBasic::RecordingFileChanged(QString lastRecordingPath) @@ -7986,20 +7901,16 @@ void OBSBasic::StartReplayBuffer() if (disableOutputsRef) return; - if (!UIValidation::NoSourcesConfirmation(this)) { - replayBufferButton->first()->setChecked(false); + if (!UIValidation::NoSourcesConfirmation(this)) return; - } if (!OutputPathValid()) { OutputPathInvalidMessage(); - replayBufferButton->first()->setChecked(false); return; } if (LowDiskSpace()) { DiskSpaceMessage(); - replayBufferButton->first()->setChecked(false); return; } @@ -8008,9 +7919,8 @@ void OBSBasic::StartReplayBuffer() SaveProject(); - if (!outputHandler->StartReplayBuffer()) { - replayBufferButton->first()->setChecked(false); - } else if (os_atomic_load_bool(&recording_paused)) { + if (outputHandler->StartReplayBuffer() && + os_atomic_load_bool(&recording_paused)) { ShowReplayBufferPauseWarning(); } } @@ -8020,8 +7930,7 @@ void OBSBasic::ReplayBufferStopping() if (!outputHandler || !outputHandler->replayBuffer) return; - replayBufferButton->first()->setText( - QTStr("Basic.Main.StoppingReplayBuffer")); + emit ReplayBufStopping(); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( @@ -8050,9 +7959,7 @@ void OBSBasic::ReplayBufferStart() if (!outputHandler || !outputHandler->replayBuffer) return; - replayBufferButton->first()->setText( - QTStr("Basic.Main.StopReplayBuffer")); - replayBufferButton->first()->setChecked(true); + emit ReplayBufStarted(); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( @@ -8063,7 +7970,6 @@ void OBSBasic::ReplayBufferStart() api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED); OnActivate(); - UpdateReplayBuffer(); blog(LOG_INFO, REPLAY_BUFFER_START); } @@ -8111,9 +8017,7 @@ void OBSBasic::ReplayBufferStop(int code) if (!outputHandler || !outputHandler->replayBuffer) return; - replayBufferButton->first()->setText( - QTStr("Basic.Main.StartReplayBuffer")); - replayBufferButton->first()->setChecked(false); + emit ReplayBufStopped(); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText( @@ -8151,7 +8055,6 @@ void OBSBasic::ReplayBufferStop(int code) api->on_event(OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED); OnDeactivate(); - UpdateReplayBuffer(false); } void OBSBasic::StartVirtualCam() @@ -8165,9 +8068,7 @@ void OBSBasic::StartVirtualCam() SaveProject(); - if (!outputHandler->StartVirtualCam()) { - vcamButton->first()->setChecked(false); - } + outputHandler->StartVirtualCam(); } void OBSBasic::StopVirtualCam() @@ -8188,10 +8089,10 @@ void OBSBasic::OnVirtualCamStart() if (!outputHandler || !outputHandler->virtualCam) return; - vcamButton->first()->setText(QTStr("Basic.Main.StopVirtualCam")); + emit VirtualCamStarted(); + if (sysTrayVirtualCam) sysTrayVirtualCam->setText(QTStr("Basic.Main.StopVirtualCam")); - vcamButton->first()->setChecked(true); if (api) api->on_event(OBS_FRONTEND_EVENT_VIRTUALCAM_STARTED); @@ -8206,10 +8107,10 @@ void OBSBasic::OnVirtualCamStop(int) if (!outputHandler || !outputHandler->virtualCam) return; - vcamButton->first()->setText(QTStr("Basic.Main.StartVirtualCam")); + emit VirtualCamStopped(); + if (sysTrayVirtualCam) sysTrayVirtualCam->setText(QTStr("Basic.Main.StartVirtualCam")); - vcamButton->first()->setChecked(false); if (api) api->on_event(OBS_FRONTEND_EVENT_VIRTUALCAM_STOPPED); @@ -8226,7 +8127,7 @@ void OBSBasic::OnVirtualCamStop(int) QTimer::singleShot(100, this, &OBSBasic::RestartingVirtualCam); } -void OBSBasic::on_streamButton_clicked() +void OBSBasic::StreamActionTriggered() { if (outputHandler->StreamingActive()) { bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", @@ -8241,10 +8142,8 @@ void OBSBasic::on_streamButton_clicked() QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (button == QMessageBox::No) { - ui->streamButton->setChecked(true); + if (button == QMessageBox::No) return; - } confirm = false; } @@ -8257,18 +8156,14 @@ void OBSBasic::on_streamButton_clicked() QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (button == QMessageBox::No) { - ui->streamButton->setChecked(true); + if (button == QMessageBox::No) return; - } } StopStreaming(); } else { - if (!UIValidation::NoSourcesConfirmation(this)) { - ui->streamButton->setChecked(false); + if (!UIValidation::NoSourcesConfirmation(this)) return; - } Auth *auth = GetAuth(); @@ -8282,10 +8177,8 @@ void OBSBasic::on_streamButton_clicked() break; case StreamSettingsAction::OpenSettings: on_action_Settings_triggered(); - ui->streamButton->setChecked(false); return; case StreamSettingsAction::Cancel: - ui->streamButton->setChecked(false); return; } @@ -8310,10 +8203,8 @@ void OBSBasic::on_streamButton_clicked() this, QTStr("ConfirmBWTest.Title"), QTStr("ConfirmBWTest.Text")); - if (button == QMessageBox::No) { - ui->streamButton->setChecked(false); + if (button == QMessageBox::No) return; - } } else if (confirm && isVisible()) { QMessageBox::StandardButton button = OBSMessageBox::question( @@ -8322,17 +8213,15 @@ void OBSBasic::on_streamButton_clicked() QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (button == QMessageBox::No) { - ui->streamButton->setChecked(false); + if (button == QMessageBox::No) return; - } } StartStreaming(); } } -void OBSBasic::on_recordButton_clicked() +void OBSBasic::RecordActionTriggered() { if (outputHandler->RecordingActive()) { bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", @@ -8346,37 +8235,31 @@ void OBSBasic::on_recordButton_clicked() QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (button == QMessageBox::No) { - ui->recordButton->setChecked(true); + if (button == QMessageBox::No) return; - } } StopRecording(); } else { - if (!UIValidation::NoSourcesConfirmation(this)) { - ui->recordButton->setChecked(false); + if (!UIValidation::NoSourcesConfirmation(this)) return; - } StartRecording(); } } -void OBSBasic::VCamButtonClicked() +void OBSBasic::VirtualCamActionTriggered() { if (outputHandler->VirtualCamActive()) { StopVirtualCam(); } else { - if (!UIValidation::NoSourcesConfirmation(this)) { - vcamButton->first()->setChecked(false); + if (!UIValidation::NoSourcesConfirmation(this)) return; - } StartVirtualCam(); } } -void OBSBasic::VCamConfigButtonClicked() +void OBSBasic::OpenVirtualCamConfig() { OBSBasicVCamConfig dialog(vcamConfig, outputHandler->VirtualCamActive(), this); @@ -8440,11 +8323,6 @@ void OBSBasic::RestartingVirtualCam() restartingVCam = false; } -void OBSBasic::on_settingsButton_clicked() -{ - on_action_Settings_triggered(); -} - void OBSBasic::on_actionHelpPortal_triggered() { QUrl url = QUrl("https://obsproject.com/help", QUrl::TolerantMode); @@ -9735,7 +9613,7 @@ void OBSBasic::on_resetDocks_triggered(bool force) QList docks{ui->scenesDock, ui->sourcesDock, ui->mixerDock, ui->transitionsDock, - ui->controlsDock}; + controlsDock}; QList sizes{cx22_5, cx22_5, mixerSize, cx5, cx21}; @@ -9743,7 +9621,7 @@ void OBSBasic::on_resetDocks_triggered(bool force) ui->sourcesDock->setVisible(true); ui->mixerDock->setVisible(true); ui->transitionsDock->setVisible(true); - ui->controlsDock->setVisible(true); + controlsDock->setVisible(true); statsDock->setVisible(false); statsDock->setFloating(true); @@ -9768,7 +9646,7 @@ void OBSBasic::on_lockDocks_toggled(bool lock) ui->sourcesDock->setFeatures(mainFeatures); ui->mixerDock->setFeatures(mainFeatures); ui->transitionsDock->setFeatures(mainFeatures); - ui->controlsDock->setFeatures(mainFeatures); + controlsDock->setFeatures(mainFeatures); statsDock->setFeatures(features); for (int i = extraDocks.size() - 1; i >= 0; i--) @@ -10071,13 +9949,13 @@ void OBSBasic::SystemTrayInit() &OBSBasic::IconActivated); connect(showHide, &QAction::triggered, this, &OBSBasic::ToggleShowHide); connect(sysTrayStream, &QAction::triggered, this, - &OBSBasic::on_streamButton_clicked); + &OBSBasic::StreamActionTriggered); connect(sysTrayRecord, &QAction::triggered, this, - &OBSBasic::on_recordButton_clicked); + &OBSBasic::RecordActionTriggered); connect(sysTrayReplayBuffer.data(), &QAction::triggered, this, - &OBSBasic::ReplayBufferClicked); + &OBSBasic::ReplayBufferActionTriggered); connect(sysTrayVirtualCam.data(), &QAction::triggered, this, - &OBSBasic::VCamButtonClicked); + &OBSBasic::VirtualCamActionTriggered); connect(exit, &QAction::triggered, this, &OBSBasic::close); } @@ -10851,11 +10729,6 @@ void OBSBasic::PauseRecording() os_atomic_set_bool(&recording_paused, true); emit RecordingPaused(); - pause->setAccessibleName(QTStr("Basic.Main.UnpauseRecording")); - pause->setToolTip(QTStr("Basic.Main.UnpauseRecording")); - pause->blockSignals(true); - pause->setChecked(true); - pause->blockSignals(false); ui->statusbar->RecordingPaused(); @@ -10873,11 +10746,6 @@ void OBSBasic::PauseRecording() trayIconFile)); } - auto replay = replayBufferButton ? replayBufferButton->second() - : nullptr; - if (replay) - replay->setEnabled(false); - if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_PAUSED); @@ -10899,11 +10767,6 @@ void OBSBasic::UnpauseRecording() os_atomic_set_bool(&recording_paused, false); emit RecordingUnpaused(); - pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); - pause->setToolTip(QTStr("Basic.Main.PauseRecording")); - pause->blockSignals(true); - pause->setChecked(false); - pause->blockSignals(false); ui->statusbar->RecordingUnpaused(); @@ -10921,17 +10784,12 @@ void OBSBasic::UnpauseRecording() trayIconFile)); } - auto replay = replayBufferButton ? replayBufferButton->second() - : nullptr; - if (replay) - replay->setEnabled(true); - if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_UNPAUSED); } } -void OBSBasic::PauseToggled() +void OBSBasic::RecordPauseToggled() { if (!isRecordingPausable || !outputHandler || !outputHandler->fileOutput) @@ -10973,47 +10831,6 @@ void OBSBasic::UpdateIsRecordingPausable() isRecordingPausable = !shared; } -void OBSBasic::UpdatePause(bool activate) -{ - if (!activate || !outputHandler || !outputHandler->RecordingActive()) { - pause.reset(); - return; - } - - if (isRecordingPausable) { - pause.reset(new QPushButton()); - pause->setAccessibleName(QTStr("Basic.Main.PauseRecording")); - pause->setToolTip(QTStr("Basic.Main.PauseRecording")); - pause->setCheckable(true); - pause->setChecked(false); - pause->setProperty("themeID", - QVariant(QStringLiteral("pauseIconSmall"))); - - QSizePolicy sp; - sp.setHeightForWidth(true); - pause->setSizePolicy(sp); - - connect(pause.data(), &QAbstractButton::clicked, this, - &OBSBasic::PauseToggled); - ui->recordingLayout->addWidget(pause.data()); - } else { - pause.reset(); - } -} - -void OBSBasic::UpdateReplayBuffer(bool activate) -{ - if (!activate || !outputHandler || - !outputHandler->ReplayBufferActive()) { - replayBufferButton->removeIcon(); - return; - } - - replayBufferButton->addIcon(QTStr("Basic.Main.SaveReplay"), - QStringLiteral("replayIconSmall"), - &OBSBasic::ReplayBufferSave); -} - #define MBYTE (1024ULL * 1024ULL) #define MBYTES_LEFT_STOP_REC 50ULL #define MAX_BYTES_LEFT (MBYTES_LEFT_STOP_REC * MBYTE) diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index a478c49ff47548..f68075ba3013ee 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -319,13 +319,8 @@ class OBSBasic : public OBSMainWindow { QPointer extraBrowsers; QPointer importer; - QPointer startStreamMenu; - QPointer transitionButton; - QPointer replayBufferButton; - QScopedPointer pause; - QPointer vcamButton; bool vcamEnabled = false; VCamConfig vcamConfig; @@ -546,8 +541,6 @@ class OBSBasic : public OBSMainWindow { void dragMoveEvent(QDragMoveEvent *event) override; void dropEvent(QDropEvent *event) override; - void ReplayBufferClicked(); - bool sysTrayMinimizeToTray(); void EnumDialogs(); @@ -888,8 +881,6 @@ private slots: void AutoRemux(QString input, bool no_show = false); void UpdateIsRecordingPausable(); - void UpdatePause(bool activate = true); - void UpdateReplayBuffer(bool activate = true); bool IsFFmpegOutputToURL() const; bool OutputPathValid(); @@ -933,7 +924,6 @@ private slots: int ResetVideo(); bool ResetAudio(); - void AddVCamButton(); void ResetOutputs(); void RefreshVolumeColors(); @@ -1132,11 +1122,6 @@ private slots: void on_actionScaleCanvas_triggered(); void on_actionScaleOutput_triggered(); - void on_streamButton_clicked(); - void on_recordButton_clicked(); - void VCamButtonClicked(); - void VCamConfigButtonClicked(); - void on_settingsButton_clicked(); void Screenshot(OBSSource source_ = nullptr); void ScreenshotSelectedSource(); void ScreenshotProgram(); @@ -1198,8 +1183,6 @@ private slots: void on_multiviewProjectorWindowed_triggered(); void on_sideDocks_toggled(bool side); - void PauseToggled(); - void logUploadFinished(const QString &text, const QString &error); void crashUploadFinished(const QString &text, const QString &error); void openLogDialog(const QString &text, const bool crash); @@ -1241,6 +1224,23 @@ private slots: void RepairOldExtraDockName(); void RepairCustomExtraDockName(); + /* Stream action (start/stop) slot */ + void StreamActionTriggered(); + + /* Record action (start/stop) slot */ + void RecordActionTriggered(); + + /* Record pause (pause/unpause) slot */ + void RecordPauseToggled(); + + /* Replay Buffer action (start/stop) slot */ + void ReplayBufferActionTriggered(); + + /* Virtual Cam action (start/stop) slots */ + void VirtualCamActionTriggered(); + + void OpenVirtualCamConfig(); + /* Studio Mode toggle slot */ void TogglePreviewProgramMode(); @@ -1259,22 +1259,44 @@ public slots: signals: /* Streaming signals */ - void StreamingStarting(); - void StreamingStarted(); - void StreamingStopped(); + void StreamingPreparing(); + void StreamingStarting(bool broadcastAutoStart); + void StreamingStarted(bool withDelay = false); + void StreamingStopping(); + void StreamingStopped(bool withDelay = false); + + /* Broadcast Flow signals */ + void BroadcastFlowEnabled(bool enabled); + void BroadcastStreamReady(bool ready); + void BroadcastStreamActive(); + void BroadcastStreamStarted(bool autoStop); /* Recording signals */ - void RecordingStarted(); + void RecordingStarted(bool pausable = false); void RecordingPaused(); void RecordingUnpaused(); + void RecordingStopping(); void RecordingStopped(); + /* Replay Buffer signals */ + void ReplayBufEnabled(bool enabled); + void ReplayBufStarted(); + void ReplayBufStopping(); + void ReplayBufStopped(); + + /* Virtual Camera signals */ + void VirtualCamEnabled(); + void VirtualCamStarted(); + void VirtualCamStopped(); + /* Studio Mode signal */ void PreviewProgramModeChanged(bool enabled); private: std::unique_ptr ui; + QPointer controlsDock; + public: /* `undo_s` needs to be declared after `ui` to prevent an uninitialized * warning for `ui` while initializing `undo_s`. */ From 3840ea0275ca27e3403830fe6eaf492e961c5726 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Sun, 21 Apr 2024 11:56:33 +0200 Subject: [PATCH 7/8] UI: Remove replayBufferButton and vcamButton theme IDs Those IDs were used on buttons that were programatically added to the controls dock, now those buttons are always present inside the UI file with their own object name. The use of theme IDs can be replaced by their object names. --- UI/data/themes/Yami.obt | 10 +++++----- UI/data/themes/Yami_Acri.ovt | 12 ++++++------ UI/forms/OBSBasicControls.ui | 6 ------ 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/UI/data/themes/Yami.obt b/UI/data/themes/Yami.obt index f9bc6e07f088e9..51e85a62a88532 100644 --- a/UI/data/themes/Yami.obt +++ b/UI/data/themes/Yami.obt @@ -985,7 +985,7 @@ QDoubleSpinBox::down-arrow { #streamButton, #recordButton, -QPushButton[themeID="replayBufferButton"], +#replayBufferButton, #broadcastButton { padding: var(--padding_large); } @@ -1001,8 +1001,8 @@ QPushButton[themeID="replayBufferButton"], /* Primary Control Button Checked Coloring */ #streamButton:!hover:!pressed:checked, #recordButton:!hover:!pressed:checked, -QPushButton[themeID="replayBufferButton"]:!hover:!pressed:checked, -QPushButton[themeID="vcamButton"]:!hover:!pressed:checked, +#replayBufferButton:!hover:!pressed:checked, +#virtualCamButton:!hover:!pressed:checked, #modeSwitch:!hover:!pressed:checked, #broadcastButton:!hover:!pressed:checked { background: var(--primary); @@ -1011,8 +1011,8 @@ QPushButton[themeID="vcamButton"]:!hover:!pressed:checked, /* Primary Control Button Hover Coloring */ #streamButton:hover:!pressed:checked, #recordButton:hover:!pressed:checked, -QPushButton[themeID="replayBufferButton"]:!pressed:checked, -QPushButton[themeID="vcamButton"]:!pressed:checked, +#replayBufferButton:!pressed:checked, +#virtualCamButton:!pressed:checked, #modeSwitch:hover:!pressed:checked, #broadcastButton:hover:!pressed:checked { background: var(--primary_light); diff --git a/UI/data/themes/Yami_Acri.ovt b/UI/data/themes/Yami_Acri.ovt index d727a804fc7f55..8f87eaebece9ba 100644 --- a/UI/data/themes/Yami_Acri.ovt +++ b/UI/data/themes/Yami_Acri.ovt @@ -147,8 +147,8 @@ QTabBar QToolButton { /* Primary Control Button Checked Coloring */ #streamButton:!hover:!pressed:checked, #recordButton:!hover:!pressed:checked, -QPushButton[themeID="replayBufferButton"]:!hover:!pressed:checked, -QPushButton[themeID="vcamButton"]:!hover:!pressed:checked, +#replayBufferButton:!hover:!pressed:checked, +#virtualCamButton:!hover:!pressed:checked, #modeSwitch:!hover:!pressed:checked, #broadcastButton:!hover:!pressed:checked { background: var(--button_bg_red); @@ -158,8 +158,8 @@ QPushButton[themeID="vcamButton"]:!hover:!pressed:checked, /* Primary Control Button Hover Coloring */ #streamButton:hover:!pressed:checked, #recordButton:hover:!pressed:checked, -QPushButton[themeID="replayBufferButton"]:!pressed:checked, -QPushButton[themeID="vcamButton"]:!pressed:checked, +#replayBufferButton:hover:!pressed:checked, +#virtualCamButton:hover:!pressed:checked, #modeSwitch:hover:!pressed:checked, #broadcastButton:hover:!pressed:checked { background: var(--button_bg_red_hover); @@ -168,8 +168,8 @@ QPushButton[themeID="vcamButton"]:!pressed:checked, /* Primary Control Button Checked + Pressed Coloring */ #streamButton:pressed:checked, #recordButton:pressed:checked, -QPushButton[themeID="replayBufferButton"]:pressed:checked, -QPushButton[themeID="vcamButton"]:pressed:checked, +#replayBufferButton:pressed:checked, +#virtualCamButton:pressed:checked, #modeSwitch:pressed:checked, #broadcastButton:pressed:checked { background: var(--button_bg_red_down); diff --git a/UI/forms/OBSBasicControls.ui b/UI/forms/OBSBasicControls.ui index c70df6142aa03f..1a4ab19103af59 100644 --- a/UI/forms/OBSBasicControls.ui +++ b/UI/forms/OBSBasicControls.ui @@ -207,9 +207,6 @@ true - - replayBufferButton - @@ -276,9 +273,6 @@ true - - vcamButton - From a2785b7c4049fb660ebbf8083d98bc35b3e5e431 Mon Sep 17 00:00:00 2001 From: Warchamp7 Date: Sun, 21 Apr 2024 15:57:37 -0400 Subject: [PATCH 8/8] UI: Add icons to Controls form buttons --- UI/forms/OBSBasicControls.ui | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/UI/forms/OBSBasicControls.ui b/UI/forms/OBSBasicControls.ui index 1a4ab19103af59..09ae9e500f8834 100644 --- a/UI/forms/OBSBasicControls.ui +++ b/UI/forms/OBSBasicControls.ui @@ -157,6 +157,10 @@ Basic.Main.PauseRecording + + + :/res/images/media-pause.svg:/res/images/media-pause.svg + true @@ -226,6 +230,10 @@ Basic.Main.SaveReplay + + + :/res/images/save.svg:/res/images/save.svg + replayIconSmall @@ -292,6 +300,10 @@ Basic.Main.VirtualCamConfig + + + :/settings/images/settings/general.svg:/settings/images/settings/general.svg + configIconSmall