diff --git a/frontend/data/locale/en-US.ini b/frontend/data/locale/en-US.ini index f3cb18dc8..68c5b08cd 100644 --- a/frontend/data/locale/en-US.ini +++ b/frontend/data/locale/en-US.ini @@ -32,17 +32,17 @@ Browse="Browse" Mono="Mono" Stereo="Stereo" DroppedFrames="Dropped Frames %1 (%2%)" -StudioProgramProjector="Fullscreen Projector (Program)" -PreviewProjector="Fullscreen Projector (Preview)" -SceneProjector="Fullscreen Projector (Scene)" -SourceProjector="Fullscreen Projector (Source)" -StudioProgramWindow="Windowed Projector (Program)" -PreviewWindow="Windowed Projector (Preview)" -SceneWindow="Windowed Projector (Scene)" -SourceWindow="Windowed Projector (Source)" -MultiviewProjector="Multiview (Fullscreen)" -MultiviewWindowed="Multiview (Windowed)" -ResizeProjectorWindowToContent="Fit window to content" +Projector.Open.Program="Open Program Projector" +Projector.Open.Preview="Open Preview Projector" +Projector.Open.Scene="Open Scene Projector" +Projector.Open.Source="Open Source Projector" +Projector.Open.Multiview="Open Multiview" +Projector.Display="Display: %1" +Projector.Window="New window" +Projector.Title="Projector" +Projector.Title.Scene="Scene: %1" +Projector.Title.Source="Source: %1" +Projector.ResizeWindowToContent="Fit window to content" Clear="Clear" Revert="Revert" Show="Show" @@ -1135,10 +1135,10 @@ Basic.Settings.Output.SplitFile.Size="Split Size" # Screenshot Screenshot="Screenshot Output" Screenshot.SourceHotkey="Screenshot Selected Source" -Screenshot.StudioProgram="Screenshot (Program)" -Screenshot.Preview="Screenshot (Preview)" -Screenshot.Scene="Screenshot (Scene)" -Screenshot.Source="Screenshot (Source)" +Screenshot.StudioProgram="Save Program Screenshot" +Screenshot.Preview="Save Preview Screenshot" +Screenshot.Scene="Save Scene Screenshot" +Screenshot.Source="Save Source Screenshot" # basic mode 'output' settings - advanced section - recording subsection - completer FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z\n%FPS\n%CRES\n%ORES\n%VF" diff --git a/frontend/forms/OBSBasic.ui b/frontend/forms/OBSBasic.ui index 817645d11..e546c79d0 100644 --- a/frontend/forms/OBSBasic.ui +++ b/frontend/forms/OBSBasic.ui @@ -901,7 +901,7 @@ - MultiviewProjector + Projector.Open.Multiview @@ -929,7 +929,6 @@ - @@ -2163,11 +2162,6 @@ Basic.Stats - - - MultiviewWindowed - - Basic.MainMenu.Docks.ResetDocks diff --git a/frontend/widgets/OBSBasic.cpp b/frontend/widgets/OBSBasic.cpp index af0d38d7a..12ed07eab 100644 --- a/frontend/widgets/OBSBasic.cpp +++ b/frontend/widgets/OBSBasic.cpp @@ -1220,8 +1220,8 @@ void OBSBasic::OBSInit() ui->viewMenu->addSeparator(); - AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this, &OBSBasic::OpenMultiviewProjector); - connect(ui->viewMenu->menuAction(), &QAction::hovered, this, &OBSBasic::UpdateMultiviewProjectorMenu); + connect(ui->viewMenu->menuAction(), &QAction::hovered, this, &OBSBasic::updateMultiviewProjectorMenu); + OBSBasic::updateMultiviewProjectorMenu(); ui->sources->UpdateIcons(); diff --git a/frontend/widgets/OBSBasic.hpp b/frontend/widgets/OBSBasic.hpp index 26ba9ed02..df588a421 100644 --- a/frontend/widgets/OBSBasic.hpp +++ b/frontend/widgets/OBSBasic.hpp @@ -919,7 +919,7 @@ private: QPointer previewProjectorSource; QPointer previewProjectorMain; - void UpdateMultiviewProjectorMenu(); + void updateMultiviewProjectorMenu(); void ClearProjectors(); OBSProjector *OpenProjector(obs_source_t *source, int monitor, ProjectorType type); @@ -928,7 +928,6 @@ private: private slots: void OpenSavedProjector(SavedProjectorInfo *info); - void on_multiviewProjectorWindowed_triggered(); void OpenPreviewProjector(); void OpenSourceProjector(); @@ -938,6 +937,7 @@ private slots: void OpenPreviewWindow(); void OpenSourceWindow(); void OpenSceneWindow(); + void openMultiviewWindow(); public: void DeleteProjector(OBSProjector *projector); @@ -1437,6 +1437,7 @@ private: QPointer trayMenu; bool sysTrayMinimizeToTray(); + void updateSysTrayProjectorMenu(); private slots: void IconActivated(QSystemTrayIcon::ActivationReason reason); diff --git a/frontend/widgets/OBSBasic_Projectors.cpp b/frontend/widgets/OBSBasic_Projectors.cpp index 37213cf3f..68abf085c 100644 --- a/frontend/widgets/OBSBasic_Projectors.cpp +++ b/frontend/widgets/OBSBasic_Projectors.cpp @@ -80,10 +80,12 @@ void OBSBasic::LoadSavedProjectors(obs_data_array_t *array) } } -void OBSBasic::UpdateMultiviewProjectorMenu() +void OBSBasic::updateMultiviewProjectorMenu() { ui->multiviewProjectorMenu->clear(); AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this, &OBSBasic::OpenMultiviewProjector); + ui->multiviewProjectorMenu->addSeparator(); + ui->multiviewProjectorMenu->addAction(QTStr("Projector.Window"), this, &OBSBasic::openMultiviewWindow); } void OBSBasic::ClearProjectors() @@ -256,7 +258,7 @@ void OBSBasic::OpenSavedProjector(SavedProjectorInfo *info) } } -void OBSBasic::on_multiviewProjectorWindowed_triggered() +void OBSBasic::openMultiviewWindow() { OpenProjector(nullptr, -1, ProjectorType::Multiview); } diff --git a/frontend/widgets/OBSBasic_SceneItems.cpp b/frontend/widgets/OBSBasic_SceneItems.cpp index 682fa5c86..87646e3fe 100644 --- a/frontend/widgets/OBSBasic_SceneItems.cpp +++ b/frontend/widgets/OBSBasic_SceneItems.cpp @@ -573,6 +573,32 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) delete colorSelect; delete deinterlaceMenu; + OBSSceneItem sceneItem; + obs_source_t *source; + uint32_t flags; + bool isAsyncVideo = false; + bool hasAudio = false; + bool hasVideo = false; + + bool sourceSelected = idx != -1; + + if (sourceSelected) { + sceneItem = ui->sources->Get(idx); + source = obs_sceneitem_get_source(sceneItem); + flags = obs_source_get_output_flags(source); + isAsyncVideo = (flags & OBS_SOURCE_ASYNC_VIDEO) == OBS_SOURCE_ASYNC_VIDEO; + hasAudio = (flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO; + hasVideo = (flags & OBS_SOURCE_VIDEO) == OBS_SOURCE_VIDEO; + } + + // Add new source + QPointer addSourceMenu = CreateAddSourcePopupMenu(); + if (addSourceMenu) { + popup.addMenu(addSourceMenu); + popup.addSeparator(); + } + + // Preview menu entries if (preview) { QAction *action = popup.addAction(QTStr("Basic.Main.PreviewConextMenu.Enable"), this, &OBSBasic::TogglePreview); @@ -584,90 +610,60 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) popup.addAction(ui->actionLockPreview); popup.addMenu(ui->scalingMenu); - previewProjectorSource = new QMenu(QTStr("PreviewProjector")); + popup.addSeparator(); + } + + // Projector menu entries + if (preview) { + previewProjectorSource = new QMenu(QTStr("Projector.Open.Preview")); AddProjectorMenuMonitors(previewProjectorSource, this, &OBSBasic::OpenPreviewProjector); + previewProjectorSource->addSeparator(); + previewProjectorSource->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenPreviewWindow); popup.addMenu(previewProjectorSource); + } - QAction *previewWindow = popup.addAction(QTStr("PreviewWindow"), this, &OBSBasic::OpenPreviewWindow); + if (hasVideo) { + sourceProjector = new QMenu(QTStr("Projector.Open.Source")); + AddProjectorMenuMonitors(sourceProjector, this, &OBSBasic::OpenSourceProjector); + sourceProjector->addSeparator(); + sourceProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenSourceWindow); - popup.addAction(previewWindow); + popup.addMenu(sourceProjector); + } + popup.addSeparator(); + + // Screenshot menu entries + if (preview) { popup.addAction(QTStr("Screenshot.Preview"), this, &OBSBasic::ScreenshotScene); - - popup.addSeparator(); } - QPointer addSourceMenu = CreateAddSourcePopupMenu(); - if (addSourceMenu) - popup.addMenu(addSourceMenu); - - if (ui->sources->MultipleBaseSelected()) { - popup.addSeparator(); - popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources, &SourceTree::GroupSelectedItems); - - } else if (ui->sources->GroupsSelected()) { - popup.addSeparator(); - popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources, &SourceTree::UngroupSelectedGroups); + if (hasVideo) { + popup.addAction(QTStr("Screenshot.Source"), this, &OBSBasic::ScreenshotSelectedSource); } - popup.addSeparator(); - popup.addAction(ui->actionCopySource); - popup.addAction(ui->actionPasteRef); - popup.addAction(ui->actionPasteDup); popup.addSeparator(); - popup.addSeparator(); - popup.addAction(ui->actionCopyFilters); - popup.addAction(ui->actionPasteFilters); - popup.addSeparator(); + if (sourceSelected) { + // Sources list menu entries + if (!preview) { + colorMenu = new QMenu(QTStr("ChangeBG")); + colorWidgetAction = new QWidgetAction(colorMenu); + colorSelect = new ColorSelect(colorMenu); + popup.addMenu(AddBackgroundColorMenu(colorMenu, colorWidgetAction, colorSelect, sceneItem)); - if (idx != -1) { - if (addSourceMenu) - popup.addSeparator(); - - OBSSceneItem sceneItem = ui->sources->Get(idx); - obs_source_t *source = obs_sceneitem_get_source(sceneItem); - uint32_t flags = obs_source_get_output_flags(source); - bool isAsyncVideo = (flags & OBS_SOURCE_ASYNC_VIDEO) == OBS_SOURCE_ASYNC_VIDEO; - bool hasAudio = (flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO; - bool hasVideo = (flags & OBS_SOURCE_VIDEO) == OBS_SOURCE_VIDEO; - - colorMenu = new QMenu(QTStr("ChangeBG")); - colorWidgetAction = new QWidgetAction(colorMenu); - colorSelect = new ColorSelect(colorMenu); - popup.addMenu(AddBackgroundColorMenu(colorMenu, colorWidgetAction, colorSelect, sceneItem)); - popup.addAction(renameSource); - popup.addAction(ui->actionRemoveSource); - popup.addSeparator(); - - popup.addMenu(ui->orderMenu); - - if (hasVideo) - popup.addMenu(ui->transformMenu); - - popup.addSeparator(); - - if (hasAudio) { - QAction *actionHideMixer = - popup.addAction(QTStr("HideMixer"), this, &OBSBasic::ToggleHideMixer); - actionHideMixer->setCheckable(true); - actionHideMixer->setChecked(SourceMixerHidden(source)); + if (hasAudio) { + QAction *actionHideMixer = + popup.addAction(QTStr("HideMixer"), this, &OBSBasic::ToggleHideMixer); + actionHideMixer->setCheckable(true); + actionHideMixer->setChecked(SourceMixerHidden(source)); + } popup.addSeparator(); } - if (hasVideo) { - QAction *resizeOutput = popup.addAction(QTStr("ResizeOutputSizeOfSource"), this, - &OBSBasic::ResizeOutputSizeOfSource); - - int width = obs_source_get_width(source); - int height = obs_source_get_height(source); - - resizeOutput->setEnabled(!obs_video_active()); - - if (width < 32 || height < 32) - resizeOutput->setEnabled(false); - + // Scene item menu entries + if (hasVideo && source) { scaleFilteringMenu = new QMenu(QTStr("ScaleFiltering")); popup.addMenu(AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); blendingModeMenu = new QMenu(QTStr("BlendingMode")); @@ -679,29 +675,69 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) popup.addMenu(AddDeinterlacingMenu(deinterlaceMenu, source)); } - popup.addSeparator(); - popup.addMenu(CreateVisibilityTransitionMenu(true)); popup.addMenu(CreateVisibilityTransitionMenu(false)); + popup.addSeparator(); - sourceProjector = new QMenu(QTStr("SourceProjector")); - AddProjectorMenuMonitors(sourceProjector, this, &OBSBasic::OpenSourceProjector); - popup.addMenu(sourceProjector); - popup.addAction(QTStr("SourceWindow"), this, &OBSBasic::OpenSourceWindow); + QAction *resizeOutput = popup.addAction(QTStr("ResizeOutputSizeOfSource"), this, + &OBSBasic::ResizeOutputSizeOfSource); - popup.addAction(QTStr("Screenshot.Source"), this, &OBSBasic::ScreenshotSelectedSource); + int width = obs_source_get_width(source); + int height = obs_source_get_height(source); + + resizeOutput->setEnabled(!obs_video_active()); + + if (width < 32 || height < 32) + resizeOutput->setEnabled(false); } popup.addSeparator(); - if (flags & OBS_SOURCE_INTERACTION) + popup.addMenu(ui->orderMenu); + + if (hasVideo) { + popup.addMenu(ui->transformMenu); + } + + popup.addSeparator(); + + // Source grouping + if (ui->sources->MultipleBaseSelected()) { + popup.addSeparator(); + popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources, &SourceTree::GroupSelectedItems); + + } else if (ui->sources->GroupsSelected()) { + popup.addSeparator(); + popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources, &SourceTree::UngroupSelectedGroups); + } + popup.addSeparator(); + + popup.addAction(ui->actionCopySource); + popup.addAction(ui->actionPasteRef); + popup.addAction(ui->actionPasteDup); + popup.addSeparator(); + + if (hasVideo || hasAudio) { + popup.addAction(ui->actionCopyFilters); + popup.addAction(ui->actionPasteFilters); + popup.addSeparator(); + } + + popup.addAction(ui->actionRemoveSource); + popup.addAction(renameSource); + popup.addSeparator(); + + if (flags && flags & OBS_SOURCE_INTERACTION) popup.addAction(QTStr("Interact"), this, &OBSBasic::on_actionInteract_triggered); popup.addAction(QTStr("Filters"), this, [&]() { OpenFilters(); }); QAction *action = popup.addAction(QTStr("Properties"), this, &OBSBasic::on_actionSourceProperties_triggered); action->setEnabled(obs_source_configurable(source)); + } else { + popup.addAction(ui->actionPasteRef); + popup.addAction(ui->actionPasteDup); } popup.exec(QCursor::pos()); diff --git a/frontend/widgets/OBSBasic_Scenes.cpp b/frontend/widgets/OBSBasic_Scenes.cpp index ff18db68d..efb094255 100644 --- a/frontend/widgets/OBSBasic_Scenes.cpp +++ b/frontend/widgets/OBSBasic_Scenes.cpp @@ -546,13 +546,14 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) popup.addSeparator(); delete sceneProjectorMenu; - sceneProjectorMenu = new QMenu(QTStr("SceneProjector")); + sceneProjectorMenu = new QMenu(QTStr("Projector.Open.Scene")); AddProjectorMenuMonitors(sceneProjectorMenu, this, &OBSBasic::OpenSceneProjector); + sceneProjectorMenu->addSeparator(); + sceneProjectorMenu->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenSceneWindow); + popup.addMenu(sceneProjectorMenu); + popup.addSeparator(); - QAction *sceneWindow = popup.addAction(QTStr("SceneWindow"), this, &OBSBasic::OpenSceneWindow); - - popup.addAction(sceneWindow); popup.addAction(QTStr("Screenshot.Scene"), this, &OBSBasic::ScreenshotScene); popup.addSeparator(); popup.addAction(QTStr("Filters"), this, &OBSBasic::OpenSceneFilters); diff --git a/frontend/widgets/OBSBasic_StudioMode.cpp b/frontend/widgets/OBSBasic_StudioMode.cpp index f15c2e4c9..042c269c1 100644 --- a/frontend/widgets/OBSBasic_StudioMode.cpp +++ b/frontend/widgets/OBSBasic_StudioMode.cpp @@ -363,11 +363,14 @@ void OBSBasic::ProgramViewContextMenuRequested() QMenu popup(this); QPointer studioProgramProjector; - studioProgramProjector = new QMenu(QTStr("StudioProgramProjector")); + studioProgramProjector = new QMenu(QTStr("Projector.Open.Program")); AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector); + studioProgramProjector->addSeparator(); + studioProgramProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenStudioProgramWindow); popup.addMenu(studioProgramProjector); - popup.addAction(QTStr("StudioProgramWindow"), this, &OBSBasic::OpenStudioProgramWindow); + + popup.addSeparator(); popup.addAction(QTStr("Screenshot.StudioProgram"), this, &OBSBasic::ScreenshotProgram); popup.exec(QCursor::pos()); diff --git a/frontend/widgets/OBSBasic_SysTray.cpp b/frontend/widgets/OBSBasic_SysTray.cpp index ef74a2a4c..383fe6330 100644 --- a/frontend/widgets/OBSBasic_SysTray.cpp +++ b/frontend/widgets/OBSBasic_SysTray.cpp @@ -48,10 +48,11 @@ void OBSBasic::SystemTrayInit() exit = new QAction(QTStr("Exit"), trayIcon.data()); trayMenu = new QMenu; - previewProjector = new QMenu(QTStr("PreviewProjector")); - studioProgramProjector = new QMenu(QTStr("StudioProgramProjector")); - AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector); - AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector); + + previewProjector = new QMenu(QTStr("Projector.Open.Preview")); + studioProgramProjector = new QMenu(QTStr("Projector.Open.Program")); + OBSBasic::updateSysTrayProjectorMenu(); + trayMenu->addAction(showHide); trayMenu->addSeparator(); trayMenu->addMenu(previewProjector); @@ -85,11 +86,7 @@ void OBSBasic::SystemTrayInit() void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason) { - // Refresh projector list - previewProjector->clear(); - studioProgramProjector->clear(); - AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector); - AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector); + OBSBasic::updateSysTrayProjectorMenu(); #ifdef __APPLE__ UNUSED_PARAMETER(reason); @@ -145,3 +142,15 @@ bool OBSBasic::sysTrayMinimizeToTray() { return config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayMinimizeToTray"); } + +void OBSBasic::updateSysTrayProjectorMenu() +{ + previewProjector->clear(); + studioProgramProjector->clear(); + AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector); + previewProjector->addSeparator(); + previewProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenPreviewWindow); + AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector); + studioProgramProjector->addSeparator(); + studioProgramProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenStudioProgramWindow); +} diff --git a/frontend/widgets/OBSProjector.cpp b/frontend/widgets/OBSProjector.cpp index 32ce393be..f2982896f 100644 --- a/frontend/widgets/OBSProjector.cpp +++ b/frontend/widgets/OBSProjector.cpp @@ -263,7 +263,7 @@ void OBSProjector::mousePressEvent(QMouseEvent *event) popup.addAction(QTStr("Windowed"), this, &OBSProjector::OpenWindowedProjector); } else if (!this->isMaximized()) { - popup.addAction(QTStr("ResizeProjectorWindowToContent"), this, &OBSProjector::ResizeToContent); + popup.addAction(QTStr("Projector.ResizeWindowToContent"), this, &OBSProjector::ResizeToContent); } QAction *alwaysOnTopButton = new QAction(QTStr("Basic.MainMenu.View.AlwaysOnTop"), this); @@ -319,39 +319,22 @@ void OBSProjector::UpdateMultiview() void OBSProjector::UpdateProjectorTitle(QString name) { - bool window = (GetMonitor() == -1); - QString title = nullptr; switch (type) { case ProjectorType::Scene: - if (!window) - title = QTStr("SceneProjector") + " - " + name; - else - title = QTStr("SceneWindow") + " - " + name; + title = QTStr("Projector.Title") + " - " + QTStr("Projector.Title.Scene").arg(name); break; case ProjectorType::Source: - if (!window) - title = QTStr("SourceProjector") + " - " + name; - else - title = QTStr("SourceWindow") + " - " + name; + title = QTStr("Projector.Title") + " - " + QTStr("Projector.Title.Source").arg(name); break; case ProjectorType::Preview: - if (!window) - title = QTStr("PreviewProjector"); - else - title = QTStr("PreviewWindow"); + title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Preview"); break; case ProjectorType::StudioProgram: - if (!window) - title = QTStr("StudioProgramProjector"); - else - title = QTStr("StudioProgramWindow"); + title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Program"); break; case ProjectorType::Multiview: - if (!window) - title = QTStr("MultiviewProjector"); - else - title = QTStr("MultiviewWindowed"); + title = QTStr("Projector.Title") + " - " + QTStr("Multiview"); break; default: title = name;