Qt: Add volume reset button
This commit is contained in:
parent
7548113afd
commit
5e9a47f82b
|
@ -4821,10 +4821,10 @@ void FullscreenUI::DrawAudioSettingsPage()
|
||||||
|
|
||||||
DrawIntRangeSetting(bsi, FSUI_CSTR("Output Volume"),
|
DrawIntRangeSetting(bsi, FSUI_CSTR("Output Volume"),
|
||||||
FSUI_CSTR("Controls the volume of the audio played on the host."), "Audio", "OutputVolume", 100,
|
FSUI_CSTR("Controls the volume of the audio played on the host."), "Audio", "OutputVolume", 100,
|
||||||
0, 100, "%d%%");
|
0, 200, "%d%%");
|
||||||
DrawIntRangeSetting(bsi, FSUI_CSTR("Fast Forward Volume"),
|
DrawIntRangeSetting(bsi, FSUI_CSTR("Fast Forward Volume"),
|
||||||
FSUI_CSTR("Controls the volume of the audio played on the host when fast forwarding."), "Audio",
|
FSUI_CSTR("Controls the volume of the audio played on the host when fast forwarding."), "Audio",
|
||||||
"FastForwardVolume", 100, 0, 100, "%d%%");
|
"FastForwardVolume", 200, 0, 100, "%d%%");
|
||||||
DrawToggleSetting(bsi, FSUI_CSTR("Mute All Sound"),
|
DrawToggleSetting(bsi, FSUI_CSTR("Mute All Sound"),
|
||||||
FSUI_CSTR("Prevents the emulator from producing any audible sound."), "Audio", "OutputMuted",
|
FSUI_CSTR("Prevents the emulator from producing any audible sound."), "Audio", "OutputMuted",
|
||||||
false);
|
false);
|
||||||
|
|
|
@ -518,7 +518,7 @@ DEFINE_HOTKEY("AudioVolumeUp", TRANSLATE_NOOP("Hotkeys", "Audio"), TRANSLATE_NOO
|
||||||
{
|
{
|
||||||
g_settings.audio_output_muted = false;
|
g_settings.audio_output_muted = false;
|
||||||
|
|
||||||
const s32 volume = std::min<s32>(System::GetAudioOutputVolume() + 10, 100);
|
const s32 volume = std::min<s32>(System::GetAudioOutputVolume() + 10, 200);
|
||||||
g_settings.audio_output_volume = volume;
|
g_settings.audio_output_volume = volume;
|
||||||
g_settings.audio_fast_forward_volume = volume;
|
g_settings.audio_fast_forward_volume = volume;
|
||||||
SPU::GetOutputStream()->SetOutputVolume(volume);
|
SPU::GetOutputStream()->SetOutputVolume(volume);
|
||||||
|
|
|
@ -84,6 +84,8 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
|
||||||
tr("%"), "Audio", "FastForwardVolume", 100);
|
tr("%"), "Audio", "FastForwardVolume", 100);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.muted, "Audio", "OutputMuted", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.muted, "Audio", "OutputMuted", false);
|
||||||
}
|
}
|
||||||
|
connect(m_ui.resetVolume, &QToolButton::clicked, this, [this]() { resetVolume(false); });
|
||||||
|
connect(m_ui.resetFastForwardVolume, &QToolButton::clicked, this, [this]() { resetVolume(true); });
|
||||||
|
|
||||||
dialog->registerWidgetHelp(
|
dialog->registerWidgetHelp(
|
||||||
m_ui.audioBackend, tr("Audio Backend"), QStringLiteral("Cubeb"),
|
m_ui.audioBackend, tr("Audio Backend"), QStringLiteral("Cubeb"),
|
||||||
|
@ -117,6 +119,12 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
|
||||||
dialog->registerWidgetHelp(m_ui.stretchSettings, tr("Stretch Settings"), tr("N/A"),
|
dialog->registerWidgetHelp(m_ui.stretchSettings, tr("Stretch Settings"), tr("N/A"),
|
||||||
tr("These settings fine-tune the behavior of the SoundTouch audio time stretcher when "
|
tr("These settings fine-tune the behavior of the SoundTouch audio time stretcher when "
|
||||||
"running outside of 100% speed."));
|
"running outside of 100% speed."));
|
||||||
|
dialog->registerWidgetHelp(m_ui.resetVolume, tr("Reset Volume"), tr("N/A"),
|
||||||
|
m_dialog->isPerGameSettings() ? tr("Resets volume back to the global/inherited setting.") :
|
||||||
|
tr("Resets volume back to the default, i.e. full."));
|
||||||
|
dialog->registerWidgetHelp(m_ui.resetFastForwardVolume, tr("Reset Fast Forward Volume"), tr("N/A"),
|
||||||
|
m_dialog->isPerGameSettings() ? tr("Resets volume back to the global/inherited setting.") :
|
||||||
|
tr("Resets volume back to the default, i.e. full."));
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioSettingsWidget::~AudioSettingsWidget() = default;
|
AudioSettingsWidget::~AudioSettingsWidget() = default;
|
||||||
|
@ -478,4 +486,30 @@ void AudioSettingsWidget::onStretchSettingsClicked()
|
||||||
});
|
});
|
||||||
|
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioSettingsWidget::resetVolume(bool fast_forward)
|
||||||
|
{
|
||||||
|
const char* key = fast_forward ? "FastForwardVolume" : "OutputVolume";
|
||||||
|
QSlider* const slider = fast_forward ? m_ui.fastForwardVolume : m_ui.volume;
|
||||||
|
QLabel* const label = fast_forward ? m_ui.fastForwardVolumeLabel : m_ui.volumeLabel;
|
||||||
|
|
||||||
|
if (m_dialog->isPerGameSettings())
|
||||||
|
{
|
||||||
|
m_dialog->removeSettingValue("Audio", key);
|
||||||
|
|
||||||
|
const int value = m_dialog->getEffectiveIntValue("Audio", key, 100);
|
||||||
|
QSignalBlocker sb(slider);
|
||||||
|
slider->setValue(value);
|
||||||
|
label->setText(QStringLiteral("%1%2").arg(value).arg(tr("%")));
|
||||||
|
|
||||||
|
// remove bold font if it was previously overridden
|
||||||
|
QFont font(label->font());
|
||||||
|
font.setBold(false);
|
||||||
|
label->setFont(font);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slider->setValue(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ private:
|
||||||
AudioBackend getEffectiveBackend() const;
|
AudioBackend getEffectiveBackend() const;
|
||||||
AudioExpansionMode getEffectiveExpansionMode() const;
|
AudioExpansionMode getEffectiveExpansionMode() const;
|
||||||
u32 getEffectiveExpansionBlockSize() const;
|
u32 getEffectiveExpansionBlockSize() const;
|
||||||
|
void resetVolume(bool fast_forward);
|
||||||
|
|
||||||
Ui::AudioSettingsWidget m_ui;
|
Ui::AudioSettingsWidget m_ui;
|
||||||
SettingsWindow* m_dialog;
|
SettingsWindow* m_dialog;
|
||||||
|
|
|
@ -246,6 +246,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="resetVolume">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Stretch Settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="refresh-line"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
|
@ -285,6 +295,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="resetFastForwardVolume">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Stretch Settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="refresh-line"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
|
|
|
@ -34,7 +34,6 @@ namespace SettingWidgetBinder {
|
||||||
static constexpr const char* NULLABLE_PROPERTY = "SettingWidgetBinder_isNullable";
|
static constexpr const char* NULLABLE_PROPERTY = "SettingWidgetBinder_isNullable";
|
||||||
static constexpr const char* IS_NULL_PROPERTY = "SettingWidgetBinder_isNull";
|
static constexpr const char* IS_NULL_PROPERTY = "SettingWidgetBinder_isNull";
|
||||||
static constexpr const char* GLOBAL_VALUE_PROPERTY = "SettingWidgetBinder_globalValue";
|
static constexpr const char* GLOBAL_VALUE_PROPERTY = "SettingWidgetBinder_globalValue";
|
||||||
static constexpr const char* IS_UPDATING_PROPERTY = "SettingWidgetBinder_isUpdating";
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SettingAccessor
|
struct SettingAccessor
|
||||||
|
@ -351,39 +350,25 @@ struct SettingAccessor<QSlider>
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static void connectValueChanged(QSlider* widget, F func)
|
static void connectValueChanged(QSlider* widget, F func)
|
||||||
{
|
{
|
||||||
if (!isNullable(widget) || widget->contextMenuPolicy() == Qt::CustomContextMenu)
|
if (!isNullable(widget))
|
||||||
{
|
{
|
||||||
widget->connect(widget, &QSlider::valueChanged, func);
|
widget->connect(widget, &QSlider::valueChanged, func);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// How much do I hate this? A _lot_. We need to be able to run handlers (e.g. for labels), which get connected to
|
|
||||||
// valueChanged() above, but the user changing the control also triggers valueChanged()... so catch the recursion.
|
|
||||||
widget->setProperty(IS_UPDATING_PROPERTY, QVariant(false));
|
|
||||||
|
|
||||||
widget->setContextMenuPolicy(Qt::CustomContextMenu);
|
widget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
widget->connect(widget, &QSlider::customContextMenuRequested, widget, [widget, func](const QPoint& pt) {
|
widget->connect(widget, &QSlider::customContextMenuRequested, widget, [widget, func](const QPoint& pt) {
|
||||||
QMenu menu(widget);
|
QMenu menu(widget);
|
||||||
widget->connect(menu.addAction(qApp->translate("SettingWidgetBinder", "Reset")), &QAction::triggered, widget,
|
widget->connect(menu.addAction(qApp->translate("SettingWidgetBinder", "Reset")), &QAction::triggered, widget,
|
||||||
[widget, func = std::move(func)]() {
|
[widget, func = std::move(func)]() {
|
||||||
if (widget->property(IS_UPDATING_PROPERTY).toBool())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const bool old = widget->blockSignals(true);
|
const bool old = widget->blockSignals(true);
|
||||||
setNullableIntValue(widget, std::nullopt);
|
setNullableIntValue(widget, std::nullopt);
|
||||||
widget->blockSignals(old);
|
widget->blockSignals(old);
|
||||||
func();
|
func();
|
||||||
|
|
||||||
widget->setProperty(IS_UPDATING_PROPERTY, QVariant(true));
|
|
||||||
emit widget->valueChanged(widget->value());
|
|
||||||
widget->setProperty(IS_UPDATING_PROPERTY, QVariant(false));
|
|
||||||
});
|
});
|
||||||
menu.exec(widget->mapToGlobal(pt));
|
menu.exec(widget->mapToGlobal(pt));
|
||||||
});
|
});
|
||||||
widget->connect(widget, &QSlider::valueChanged, widget, [widget, func = std::move(func)]() {
|
widget->connect(widget, &QSlider::valueChanged, widget, [widget, func = std::move(func)]() {
|
||||||
if (widget->property(IS_UPDATING_PROPERTY).toBool())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (widget->property(IS_NULL_PROPERTY).toBool())
|
if (widget->property(IS_NULL_PROPERTY).toBool())
|
||||||
widget->setProperty(IS_NULL_PROPERTY, QVariant(false));
|
widget->setProperty(IS_NULL_PROPERTY, QVariant(false));
|
||||||
func();
|
func();
|
||||||
|
@ -786,42 +771,84 @@ static void BindWidgetToIntSetting(SettingsInterface* sif, WidgetType* widget, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename WidgetType>
|
||||||
static inline void BindWidgetAndLabelToIntSetting(SettingsInterface* sif, T* slider, QLabel* label,
|
static inline void BindWidgetAndLabelToIntSetting(SettingsInterface* sif, WidgetType* widget, QLabel* label,
|
||||||
const QString& label_suffix, std::string section, std::string key,
|
const QString& label_suffix, std::string section, std::string key,
|
||||||
s32 default_value)
|
int default_value, int option_offset = 0)
|
||||||
{
|
{
|
||||||
using Accessor = SettingAccessor<T>;
|
using Accessor = SettingAccessor<WidgetType>;
|
||||||
|
|
||||||
|
const s32 global_value =
|
||||||
|
Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), static_cast<s32>(default_value)) - option_offset;
|
||||||
|
|
||||||
BindWidgetToIntSetting(sif, slider, std::move(section), std::move(key), default_value);
|
|
||||||
if (sif)
|
if (sif)
|
||||||
{
|
{
|
||||||
QFont orig_font(label->font());
|
QFont orig_font(label->font());
|
||||||
QFont bold_font(orig_font);
|
QFont bold_font(orig_font);
|
||||||
bold_font.setBold(true);
|
bold_font.setBold(true);
|
||||||
|
|
||||||
Accessor::connectValueChanged(
|
Accessor::makeNullableInt(widget, global_value);
|
||||||
slider, [slider, label, label_suffix, bold_font = std::move(bold_font), orig_font = std::move(orig_font)]() {
|
|
||||||
std::optional<int> value = Accessor::getNullableIntValue(slider);
|
int sif_value;
|
||||||
if (value.has_value())
|
if (sif->GetIntValue(section.c_str(), key.c_str(), &sif_value))
|
||||||
|
{
|
||||||
|
Accessor::setNullableIntValue(widget, sif_value - option_offset);
|
||||||
|
if (label)
|
||||||
|
{
|
||||||
|
label->setText(QStringLiteral("%1%2").arg(sif_value).arg(label_suffix));
|
||||||
|
label->setFont(bold_font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Accessor::setNullableIntValue(widget, std::nullopt);
|
||||||
|
if (label)
|
||||||
|
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessor::connectValueChanged(widget, [sif, widget, label, label_suffix, section = std::move(section),
|
||||||
|
key = std::move(key), option_offset, global_value,
|
||||||
|
bold_font = std::move(bold_font), orig_font = std::move(orig_font)]() {
|
||||||
|
if (std::optional<int> new_value = Accessor::getNullableIntValue(widget); new_value.has_value())
|
||||||
|
{
|
||||||
|
sif->SetIntValue(section.c_str(), key.c_str(), new_value.value() + option_offset);
|
||||||
|
if (label)
|
||||||
{
|
{
|
||||||
label->setFont(bold_font);
|
label->setFont(bold_font);
|
||||||
label->setText(QStringLiteral("%1%2").arg(value.value()).arg(label_suffix));
|
label->setText(QStringLiteral("%1%2").arg(new_value.value()).arg(label_suffix));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sif->DeleteValue(section.c_str(), key.c_str());
|
||||||
|
if (label)
|
||||||
{
|
{
|
||||||
const int global_value = Accessor::getIntValue(slider);
|
|
||||||
label->setFont(orig_font);
|
label->setFont(orig_font);
|
||||||
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
sif->Save();
|
||||||
|
g_emu_thread->reloadGameSettings();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Accessor::connectValueChanged(slider, [slider, label, label_suffix]() {
|
Accessor::setIntValue(widget, static_cast<int>(global_value));
|
||||||
const int global_value = Accessor::getIntValue(slider);
|
|
||||||
|
if (label)
|
||||||
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
||||||
});
|
|
||||||
|
Accessor::connectValueChanged(
|
||||||
|
widget, [widget, label, label_suffix, section = std::move(section), key = std::move(key), option_offset]() {
|
||||||
|
const int new_value = Accessor::getIntValue(widget);
|
||||||
|
Host::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
|
||||||
|
Host::CommitBaseSettingChanges();
|
||||||
|
g_emu_thread->applySettings();
|
||||||
|
|
||||||
|
if (label)
|
||||||
|
label->setText(QStringLiteral("%1%2").arg(new_value).arg(label_suffix));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue