frontend: Reorganize Preview/Source context menu

This commit is contained in:
Warchamp7 2024-11-04 12:33:14 -05:00 • committed by Ryan Foster
commit 69ecfcd9f6
10 changed files with 170 additions and 141 deletions

View file

@ -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"

View file

@ -901,7 +901,7 @@
</widget>
<widget class="QMenu" name="multiviewProjectorMenu">
<property name="title">
<string>MultiviewProjector</string>
<string>Projector.Open.Multiview</string>
</property>
</widget>
<action name="resetUI">
@ -929,7 +929,6 @@
<addaction name="stats"/>
<addaction name="separator"/>
<addaction name="multiviewProjectorMenu"/>
<addaction name="multiviewProjectorWindowed"/>
<addaction name="separator"/>
<addaction name="actionAlwaysOnTop"/>
</widget>
@ -2163,11 +2162,6 @@
<string>Basic.Stats</string>
</property>
</action>
<action name="multiviewProjectorWindowed">
<property name="text">
<string>MultiviewWindowed</string>
</property>
</action>
<action name="resetDocks">
<property name="text">
<string>Basic.MainMenu.Docks.ResetDocks</string>

View file

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

View file

@ -919,7 +919,7 @@ private:
QPointer<QMenu> previewProjectorSource;
QPointer<QMenu> 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<QMenu> trayMenu;
bool sysTrayMinimizeToTray();
void updateSysTrayProjectorMenu();
private slots:
void IconActivated(QSystemTrayIcon::ActivationReason reason);

View file

@ -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);
}

View file

@ -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<QMenu> 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<QMenu> 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());

View file

@ -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);

View file

@ -363,11 +363,14 @@ void OBSBasic::ProgramViewContextMenuRequested()
QMenu popup(this);
QPointer<QMenu> 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());

View file

@ -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);
}

View file

@ -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;