Skip to content

Commit 0a9a77c

Browse files
committed
Qt: Move OSD and Capture settings to their own sections
1 parent 83b3a2e commit 0a9a77c

22 files changed

+1161
-971
lines changed

src/duckstation-qt/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ set(SRCS
2828
biossettingswidget.ui
2929
colorpickerbutton.cpp
3030
colorpickerbutton.h
31+
capturesettingswidget.cpp
32+
capturesettingswidget.h
33+
capturesettingswidget.ui
3134
consolesettingswidget.cpp
3235
consolesettingswidget.h
3336
consolesettingswidget.ui
@@ -126,6 +129,9 @@ set(SRCS
126129
memoryscannerwindow.ui
127130
memoryviewwidget.cpp
128131
memoryviewwidget.h
132+
osdsettingswidget.cpp
133+
osdsettingswidget.h
134+
osdsettingswidget.ui
129135
postprocessingsettingswidget.cpp
130136
postprocessingsettingswidget.h
131137
postprocessingchainconfigwidget.ui
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
2+
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3+
4+
#include "capturesettingswidget.h"
5+
#include "qtutils.h"
6+
#include "settingswindow.h"
7+
#include "settingwidgetbinder.h"
8+
9+
#include "util/media_capture.h"
10+
11+
#include "common/error.h"
12+
13+
#include "moc_capturesettingswidget.cpp"
14+
15+
CaptureSettingsWidget::CaptureSettingsWidget(SettingsWindow* dialog, QWidget* parent)
16+
: QWidget(parent), m_dialog(dialog)
17+
{
18+
SettingsInterface* sif = dialog->getSettingsInterface();
19+
20+
m_ui.setupUi(this);
21+
22+
SettingWidgetBinder::BindWidgetToEnumSetting(
23+
sif, m_ui.screenshotSize, "Display", "ScreenshotMode", &Settings::ParseDisplayScreenshotMode,
24+
&Settings::GetDisplayScreenshotModeName, &Settings::GetDisplayScreenshotModeDisplayName,
25+
Settings::DEFAULT_DISPLAY_SCREENSHOT_MODE, DisplayScreenshotMode::Count);
26+
SettingWidgetBinder::BindWidgetToEnumSetting(
27+
sif, m_ui.screenshotFormat, "Display", "ScreenshotFormat", &Settings::ParseDisplayScreenshotFormat,
28+
&Settings::GetDisplayScreenshotFormatName, &Settings::GetDisplayScreenshotFormatDisplayName,
29+
Settings::DEFAULT_DISPLAY_SCREENSHOT_FORMAT, DisplayScreenshotFormat::Count);
30+
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.screenshotQuality, "Display", "ScreenshotQuality",
31+
Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY);
32+
33+
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.mediaCaptureBackend, "MediaCapture", "Backend",
34+
&MediaCapture::ParseBackendName, &MediaCapture::GetBackendName,
35+
&MediaCapture::GetBackendDisplayName,
36+
Settings::DEFAULT_MEDIA_CAPTURE_BACKEND, MediaCaptureBackend::MaxCount);
37+
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCapture, "MediaCapture", "VideoCapture", true);
38+
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureWidth, "MediaCapture", "VideoWidth",
39+
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_WIDTH);
40+
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureHeight, "MediaCapture", "VideoHeight",
41+
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_HEIGHT);
42+
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.videoCaptureResolutionAuto, "MediaCapture", "VideoAutoSize",
43+
false);
44+
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.videoCaptureBitrate, "MediaCapture", "VideoBitrate",
45+
Settings::DEFAULT_MEDIA_CAPTURE_VIDEO_BITRATE);
46+
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture",
47+
"VideoCodecUseArgs", false);
48+
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureArguments, "MediaCapture", "AudioCodecArgs");
49+
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableAudioCapture, "MediaCapture", "AudioCapture", true);
50+
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.audioCaptureBitrate, "MediaCapture", "AudioBitrate",
51+
Settings::DEFAULT_MEDIA_CAPTURE_AUDIO_BITRATE);
52+
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "MediaCapture",
53+
"VideoCodecUseArgs", false);
54+
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.audioCaptureArguments, "MediaCapture", "AudioCodecArgs");
55+
56+
connect(m_ui.mediaCaptureBackend, &QComboBox::currentIndexChanged, this,
57+
&CaptureSettingsWidget::onMediaCaptureBackendChanged);
58+
connect(m_ui.enableVideoCapture, &QCheckBox::checkStateChanged, this,
59+
&CaptureSettingsWidget::onMediaCaptureVideoEnabledChanged);
60+
connect(m_ui.videoCaptureResolutionAuto, &QCheckBox::checkStateChanged, this,
61+
&CaptureSettingsWidget::onMediaCaptureVideoAutoResolutionChanged);
62+
connect(m_ui.enableAudioCapture, &QCheckBox::checkStateChanged, this,
63+
&CaptureSettingsWidget::onMediaCaptureAudioEnabledChanged);
64+
65+
// Init all dependent options.
66+
onMediaCaptureBackendChanged();
67+
onMediaCaptureAudioEnabledChanged();
68+
onMediaCaptureVideoEnabledChanged();
69+
70+
dialog->registerWidgetHelp(m_ui.screenshotSize, tr("Screenshot Size"), tr("Screen Resolution"),
71+
tr("Determines the resolution at which screenshots will be saved. Internal resolutions "
72+
"preserve more detail at the cost of file size."));
73+
dialog->registerWidgetHelp(
74+
m_ui.screenshotFormat, tr("Screenshot Format"), tr("PNG"),
75+
tr("Selects the format which will be used to save screenshots. JPEG produces smaller files, but loses detail."));
76+
dialog->registerWidgetHelp(m_ui.screenshotQuality, tr("Screenshot Quality"),
77+
QStringLiteral("%1%").arg(Settings::DEFAULT_DISPLAY_SCREENSHOT_QUALITY),
78+
tr("Selects the quality at which screenshots will be compressed. Higher values preserve "
79+
"more detail for JPEG, and reduce file size for PNG."));
80+
dialog->registerWidgetHelp(
81+
m_ui.mediaCaptureBackend, tr("Backend"),
82+
QString::fromUtf8(MediaCapture::GetBackendDisplayName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND)),
83+
tr("Selects the framework that is used to encode video/audio."));
84+
dialog->registerWidgetHelp(m_ui.captureContainer, tr("Container"), tr("MP4"),
85+
tr("Determines the file format used to contain the captured audio/video."));
86+
dialog->registerWidgetHelp(m_ui.enableVideoCapture, tr("Capture Video"), tr("Checked"),
87+
tr("Captures video to the chosen file when media capture is started. If unchecked, the "
88+
"file will only contain audio."));
89+
dialog->registerWidgetHelp(
90+
m_ui.videoCaptureCodec, tr("Video Codec"), tr("Default"),
91+
tr("Selects which Video Codec to be used for media capture. <b>If unsure, leave it on default.<b>"));
92+
dialog->registerWidgetHelp(m_ui.videoCaptureBitrate, tr("Video Bitrate"), tr("6000 kbps"),
93+
tr("Sets the video bitrate to be used. Larger bitrate generally yields better video "
94+
"quality at the cost of larger resulting file size."));
95+
dialog->registerWidgetHelp(
96+
m_ui.videoCaptureResolutionAuto, tr("Automatic Resolution"), tr("Unchecked"),
97+
tr("When checked, the video capture resolution will follows the internal resolution of the running "
98+
"game. <b>Be careful when using this setting especially when you are upscaling, as higher internal "
99+
"resolutions (above 4x) can cause system slowdown.</b>"));
100+
dialog->registerWidgetHelp(m_ui.enableVideoCaptureArguments, tr("Enable Extra Video Arguments"), tr("Unchecked"),
101+
tr("Allows you to pass arguments to the selected video codec."));
102+
dialog->registerWidgetHelp(
103+
m_ui.videoCaptureArguments, tr("Extra Video Arguments"), tr("Empty"),
104+
tr("Parameters passed to the selected video codec.<br><b>You must use '=' to separate key from value and ':' to "
105+
"separate two pairs from each other.</b><br>For example: \"crf = 21 : preset = veryfast\""));
106+
dialog->registerWidgetHelp(m_ui.enableAudioCapture, tr("Capture Audio"), tr("Checked"),
107+
tr("Captures audio to the chosen file when media capture is started. If unchecked, the "
108+
"file will only contain video."));
109+
dialog->registerWidgetHelp(
110+
m_ui.audioCaptureCodec, tr("Audio Codec"), tr("Default"),
111+
tr("Selects which Audio Codec to be used for media capture. <b>If unsure, leave it on default.<b>"));
112+
dialog->registerWidgetHelp(m_ui.audioCaptureBitrate, tr("Audio Bitrate"), tr("128 kbps"),
113+
tr("Sets the audio bitrate to be used."));
114+
dialog->registerWidgetHelp(m_ui.enableAudioCaptureArguments, tr("Enable Extra Audio Arguments"), tr("Unchecked"),
115+
tr("Allows you to pass arguments to the selected audio codec."));
116+
dialog->registerWidgetHelp(
117+
m_ui.audioCaptureArguments, tr("Extra Audio Arguments"), tr("Empty"),
118+
tr("Parameters passed to the selected audio codec.<br><b>You must use '=' to separate key from value and ':' to "
119+
"separate two pairs from each other.</b><br>For example: \"compression_level = 4 : joint_stereo = 1\""));
120+
}
121+
122+
CaptureSettingsWidget::~CaptureSettingsWidget() = default;
123+
124+
void CaptureSettingsWidget::onMediaCaptureBackendChanged()
125+
{
126+
SettingsInterface* const sif = m_dialog->getSettingsInterface();
127+
const MediaCaptureBackend backend =
128+
MediaCapture::ParseBackendName(
129+
m_dialog
130+
->getEffectiveStringValue("MediaCapture", "Backend",
131+
MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND))
132+
.c_str())
133+
.value_or(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND);
134+
135+
{
136+
SettingWidgetBinder::DisconnectWidget(m_ui.captureContainer);
137+
m_ui.captureContainer->clear();
138+
139+
for (const auto& [name, display_name] : MediaCapture::GetContainerList(backend))
140+
{
141+
const QString qname = QString::fromStdString(name);
142+
m_ui.captureContainer->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname);
143+
}
144+
145+
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.captureContainer, "MediaCapture", "Container",
146+
Settings::DEFAULT_MEDIA_CAPTURE_CONTAINER);
147+
connect(m_ui.captureContainer, &QComboBox::currentIndexChanged, this,
148+
&CaptureSettingsWidget::onMediaCaptureContainerChanged);
149+
}
150+
151+
onMediaCaptureContainerChanged();
152+
}
153+
154+
void CaptureSettingsWidget::onMediaCaptureContainerChanged()
155+
{
156+
SettingsInterface* const sif = m_dialog->getSettingsInterface();
157+
const MediaCaptureBackend backend =
158+
MediaCapture::ParseBackendName(
159+
m_dialog
160+
->getEffectiveStringValue("MediaCapture", "Backend",
161+
MediaCapture::GetBackendName(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND))
162+
.c_str())
163+
.value_or(Settings::DEFAULT_MEDIA_CAPTURE_BACKEND);
164+
const std::string container = m_dialog->getEffectiveStringValue("MediaCapture", "Container", "mp4");
165+
166+
{
167+
SettingWidgetBinder::DisconnectWidget(m_ui.videoCaptureCodec);
168+
m_ui.videoCaptureCodec->clear();
169+
m_ui.videoCaptureCodec->addItem(tr("Default"), QVariant(QString()));
170+
171+
for (const auto& [name, display_name] : MediaCapture::GetVideoCodecList(backend, container.c_str()))
172+
{
173+
const QString qname = QString::fromStdString(name);
174+
m_ui.videoCaptureCodec->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname);
175+
}
176+
177+
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureCodec, "MediaCapture", "VideoCodec");
178+
}
179+
180+
{
181+
SettingWidgetBinder::DisconnectWidget(m_ui.audioCaptureCodec);
182+
m_ui.audioCaptureCodec->clear();
183+
m_ui.audioCaptureCodec->addItem(tr("Default"), QVariant(QString()));
184+
185+
for (const auto& [name, display_name] : MediaCapture::GetAudioCodecList(backend, container.c_str()))
186+
{
187+
const QString qname = QString::fromStdString(name);
188+
m_ui.audioCaptureCodec->addItem(tr("%1 (%2)").arg(QString::fromStdString(display_name)).arg(qname), qname);
189+
}
190+
191+
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.audioCaptureCodec, "MediaCapture", "AudioCodec");
192+
}
193+
}
194+
195+
void CaptureSettingsWidget::onMediaCaptureVideoEnabledChanged()
196+
{
197+
const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoCapture", true);
198+
m_ui.videoCaptureCodecLabel->setEnabled(enabled);
199+
m_ui.videoCaptureCodec->setEnabled(enabled);
200+
m_ui.videoCaptureBitrateLabel->setEnabled(enabled);
201+
m_ui.videoCaptureBitrate->setEnabled(enabled);
202+
m_ui.videoCaptureResolutionLabel->setEnabled(enabled);
203+
m_ui.videoCaptureResolutionAuto->setEnabled(enabled);
204+
m_ui.enableVideoCaptureArguments->setEnabled(enabled);
205+
m_ui.videoCaptureArguments->setEnabled(enabled);
206+
onMediaCaptureVideoAutoResolutionChanged();
207+
}
208+
209+
void CaptureSettingsWidget::onMediaCaptureVideoAutoResolutionChanged()
210+
{
211+
const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoCapture", true);
212+
const bool auto_enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "VideoAutoSize", false);
213+
m_ui.videoCaptureWidth->setEnabled(enabled && !auto_enabled);
214+
m_ui.xLabel->setEnabled(enabled && !auto_enabled);
215+
m_ui.videoCaptureHeight->setEnabled(enabled && !auto_enabled);
216+
}
217+
218+
void CaptureSettingsWidget::onMediaCaptureAudioEnabledChanged()
219+
{
220+
const bool enabled = m_dialog->getEffectiveBoolValue("MediaCapture", "AudioCapture", true);
221+
m_ui.audioCaptureCodecLabel->setEnabled(enabled);
222+
m_ui.audioCaptureCodec->setEnabled(enabled);
223+
m_ui.audioCaptureBitrateLabel->setEnabled(enabled);
224+
m_ui.audioCaptureBitrate->setEnabled(enabled);
225+
m_ui.enableAudioCaptureArguments->setEnabled(enabled);
226+
m_ui.audioCaptureArguments->setEnabled(enabled);
227+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
2+
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3+
4+
#pragma once
5+
6+
#include <QtWidgets/QWidget>
7+
8+
#include "ui_capturesettingswidget.h"
9+
10+
class SettingsWindow;
11+
12+
class CaptureSettingsWidget : public QWidget
13+
{
14+
Q_OBJECT
15+
16+
public:
17+
CaptureSettingsWidget(SettingsWindow* dialog, QWidget* parent);
18+
~CaptureSettingsWidget();
19+
20+
private:
21+
void onMediaCaptureBackendChanged();
22+
void onMediaCaptureContainerChanged();
23+
void onMediaCaptureVideoEnabledChanged();
24+
void onMediaCaptureVideoAutoResolutionChanged();
25+
void onMediaCaptureAudioEnabledChanged();
26+
27+
Ui::CaptureSettingsWidget m_ui;
28+
29+
SettingsWindow* m_dialog;
30+
};

0 commit comments

Comments
 (0)