diff --git a/doomsday/client/client.pro b/doomsday/client/client.pro index 0c393bedd8..fc247070b1 100644 --- a/doomsday/client/client.pro +++ b/doomsday/client/client.pro @@ -352,6 +352,7 @@ DENG_HEADERS += \ include/ui/dd_input.h \ include/ui/dd_ui.h \ include/ui/dialogs/aboutdialog.h \ + include/ui/dialogs/audiosettingsdialog.h \ include/ui/dialogs/coloradjustmentdialog.h \ include/ui/dialogs/messagedialog.h \ include/ui/dialogs/videosettingsdialog.h \ @@ -397,6 +398,7 @@ DENG_HEADERS += \ include/ui/widgets/consolecommandwidget.h \ include/ui/widgets/consolewidget.h \ include/ui/widgets/cvarsliderwidget.h \ + include/ui/widgets/cvartogglewidget.h \ include/ui/widgets/dialogwidget.h \ include/ui/widgets/documentwidget.h \ include/ui/widgets/gameselectionwidget.h \ @@ -680,6 +682,7 @@ SOURCES += \ src/ui/clientwindow.cpp \ src/ui/dd_input.cpp \ src/ui/dialogs/aboutdialog.cpp \ + src/ui/dialogs/audiosettingsdialog.cpp \ src/ui/dialogs/coloradjustmentdialog.cpp \ src/ui/dialogs/messagedialog.cpp \ src/ui/dialogs/videosettingsdialog.cpp \ @@ -718,6 +721,7 @@ SOURCES += \ src/ui/widgets/consolecommandwidget.cpp \ src/ui/widgets/consolewidget.cpp \ src/ui/widgets/cvarsliderwidget.cpp \ + src/ui/widgets/cvartogglewidget.cpp \ src/ui/widgets/dialogwidget.cpp \ src/ui/widgets/documentwidget.cpp \ src/ui/widgets/gameselectionwidget.cpp \ diff --git a/doomsday/client/include/ui/dialogs/audiosettingsdialog.h b/doomsday/client/include/ui/dialogs/audiosettingsdialog.h new file mode 100644 index 0000000000..1b575ce194 --- /dev/null +++ b/doomsday/client/include/ui/dialogs/audiosettingsdialog.h @@ -0,0 +1,41 @@ +/** @file audiosettingsdialog.h Dialog for audio settings. + * + * @authors Copyright (c) 2013 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_AUDIOSETTINGSDIALOG_H +#define DENG_CLIENT_AUDIOSETTINGSDIALOG_H + +#include "ui/widgets/dialogwidget.h" + +/** + * Dialog for modifying video settings. + */ +class AudioSettingsDialog : public DialogWidget +{ + Q_OBJECT + +public: + AudioSettingsDialog(de::String const &name = "audiosettings"); + +public slots: + void resetToDefaults(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_AUDIOSETTINGSDIALOG_H diff --git a/doomsday/client/include/ui/widgets/cvarsliderwidget.h b/doomsday/client/include/ui/widgets/cvarsliderwidget.h index 92cf714151..61f6bf06fd 100644 --- a/doomsday/client/include/ui/widgets/cvarsliderwidget.h +++ b/doomsday/client/include/ui/widgets/cvarsliderwidget.h @@ -31,7 +31,7 @@ class CVarSliderWidget : public SliderWidget public: CVarSliderWidget(char const *cvarPath); -public: +public slots: void updateFromCVar(); protected slots: diff --git a/doomsday/client/include/ui/widgets/cvartogglewidget.h b/doomsday/client/include/ui/widgets/cvartogglewidget.h new file mode 100644 index 0000000000..b558302c28 --- /dev/null +++ b/doomsday/client/include/ui/widgets/cvartogglewidget.h @@ -0,0 +1,44 @@ +/** @file cvartogglewidget.h Console variable toggle. + * + * @authors Copyright (c) 2013 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_CVARTOGGLEWIDGET_H +#define DENG_CLIENT_CVARTOGGLEWIDGET_H + +#include "togglewidget.h" + +/** + * Console variable toggle for on/off type of cvars (value 0 or 1). + */ +class CVarToggleWidget : public ToggleWidget +{ + Q_OBJECT + +public: + CVarToggleWidget(char const *cvarPath); + +public slots: + void updateFromCVar(); + +protected slots: + void setCVarValueFromWidget(); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_CVARTOGGLEWIDGET_H diff --git a/doomsday/client/include/ui/widgets/taskbarwidget.h b/doomsday/client/include/ui/widgets/taskbarwidget.h index 8a32f6c600..6a815ea4bb 100644 --- a/doomsday/client/include/ui/widgets/taskbarwidget.h +++ b/doomsday/client/include/ui/widgets/taskbarwidget.h @@ -60,6 +60,7 @@ public slots: void showAbout(); void showUpdaterSettings(); void showVideoSettings(); + void showAudioSettings(); signals: void opened(); diff --git a/doomsday/client/include/ui/widgets/togglewidget.h b/doomsday/client/include/ui/widgets/togglewidget.h index 34ab522490..4d2d8ddd0d 100644 --- a/doomsday/client/include/ui/widgets/togglewidget.h +++ b/doomsday/client/include/ui/widgets/togglewidget.h @@ -27,6 +27,8 @@ */ class ToggleWidget : public ButtonWidget { + Q_OBJECT + public: enum ToggleState { Active, @@ -54,6 +56,10 @@ class ToggleWidget : public ButtonWidget bool isActive() const { return toggleState() == Active; } bool isInactive() const { return toggleState() == Inactive; } +signals: + void stateChanged(ToggleWidget::ToggleState active); + void stateChangedByUser(ToggleWidget::ToggleState active); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/src/audio/s_main.cpp b/doomsday/client/src/audio/s_main.cpp index d85448f5e7..bc60832461 100644 --- a/doomsday/client/src/audio/s_main.cpp +++ b/doomsday/client/src/audio/s_main.cpp @@ -102,7 +102,7 @@ void S_Register(void) C_VAR_INT("sound-rate", &sfxSampleRate, 0, 11025, 44100); C_VAR_INT("sound-16bit", &sfx16Bit, 0, 0, 1); C_VAR_INT("sound-3d", &sfx3D, 0, 0, 1); - C_VAR_FLOAT2("sound-reverb-volume", &sfxReverbStrength, 0, 0, 10, S_ReverbVolumeChanged); + C_VAR_FLOAT2("sound-reverb-volume", &sfxReverbStrength, 0, 0, 1.5f, S_ReverbVolumeChanged); // Ccmds C_CMD_FLAGS("playsound", NULL, PlaySound, CMDF_NO_DEDICATED); diff --git a/doomsday/client/src/ui/dialogs/audiosettingsdialog.cpp b/doomsday/client/src/ui/dialogs/audiosettingsdialog.cpp new file mode 100644 index 0000000000..9e66b2da5e --- /dev/null +++ b/doomsday/client/src/ui/dialogs/audiosettingsdialog.cpp @@ -0,0 +1,131 @@ +/** @file audiosettingsdialog.cpp Dialog for audio settings. + * + * @authors Copyright (c) 2013 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/dialogs/audiosettingsdialog.h" +#include "ui/widgets/cvarsliderwidget.h" +#include "ui/widgets/cvartogglewidget.h" +#include "ui/widgets/choicewidget.h" + +#include "con_main.h" +#include "SignalAction" + +using namespace de; +using namespace ui; + +DENG_GUI_PIMPL(AudioSettingsDialog) +{ + CVarSliderWidget *sfxVolume; + CVarSliderWidget *musicVolume; + CVarSliderWidget *reverbVolume; + CVarToggleWidget *sound3D; + CVarToggleWidget *sound16bit; + ChoiceWidget *sampleRate; + CVarToggleWidget *soundInfo; + + Instance(Public *i) : Base(i) + { + ScrollAreaWidget &area = self.area(); + + area.add(sfxVolume = new CVarSliderWidget("sound-volume")); + area.add(musicVolume = new CVarSliderWidget("music-volume")); + area.add(reverbVolume = new CVarSliderWidget("sound-reverb-volume")); + area.add(sound3D = new CVarToggleWidget("sound-3d")); + area.add(sound16bit = new CVarToggleWidget("sound-16bit")); + area.add(sampleRate = new ChoiceWidget); + area.add(soundInfo = new CVarToggleWidget("sound-info")); + } + + void fetch() + { + sfxVolume->updateFromCVar(); + musicVolume->updateFromCVar(); + reverbVolume->updateFromCVar(); + sound3D->updateFromCVar(); + sound16bit->updateFromCVar(); + soundInfo->updateFromCVar(); + + // Update the selected sample rate. + sampleRate->setSelected(sampleRate->items().findData(Con_GetInteger("sound-rate"))); + } +}; + +AudioSettingsDialog::AudioSettingsDialog(String const &name) + : DialogWidget(name, WithHeading), d(new Instance(this)) +{ + heading().setText(tr("Audio Settings")); + + LabelWidget *sfxVolLabel = new LabelWidget; + sfxVolLabel->setText(tr("SFX Volume:")); + area().add(sfxVolLabel); + + LabelWidget *musicVolLabel = new LabelWidget; + musicVolLabel->setText(tr("Music Volume:")); + area().add(musicVolLabel); + + LabelWidget *rvbVolLabel = new LabelWidget; + rvbVolLabel->setText(tr("Reverb Volume:")); + area().add(rvbVolLabel); + + d->sound3D->setText(tr("3D Effects & Reverb")); + d->sound16bit->setText(tr("16-bit Resampling")); + + LabelWidget *rateLabel = new LabelWidget; + rateLabel->setText(tr("Resampling:")); + area().add(rateLabel); + + d->sampleRate->items() + << new ChoiceItem(tr("1x @ 11025 Hz"), 11025) + << new ChoiceItem(tr("2x @ 22050 Hz"), 22050) + << new ChoiceItem(tr("4x @ 44100 Hz"), 44100); + + d->soundInfo->setText(tr("Developer Info")); + + // Layout. + GridLayout layout(area().contentRule().left(), area().contentRule().top()); + layout.setGridSize(2, 0); + layout.setColumnAlignment(0, ui::AlignRight); + layout << *sfxVolLabel << *d->sfxVolume + << *musicVolLabel << *d->musicVolume + << *rvbVolLabel << *d->reverbVolume + << Const(0) << *d->sound3D + << *rateLabel << *d->sampleRate + << Const(0) << *d->sound16bit + << Const(0) << *d->soundInfo; + + area().setContentSize(layout.width(), layout.height()); + + buttons().items() + << new DialogButtonItem(DialogWidget::Default | DialogWidget::Accept, tr("Close")) + << new DialogButtonItem(DialogWidget::Action, tr("Reset to Defaults"), + new SignalAction(this, SLOT(resetToDefaults()))); + + d->fetch(); +} + +void AudioSettingsDialog::resetToDefaults() +{ + Con_SetInteger("sound-volume", 255 ); + Con_SetInteger("music-volume", 255 ); + Con_SetFloat ("sound-reverb-volume", 0.5f ); + Con_SetInteger("sound-info", 0 ); + Con_SetInteger("sound-rate", 11025); + Con_SetInteger("sound-16bit", 0 ); + Con_SetInteger("sound-3d", 0 ); + + d->fetch(); +} diff --git a/doomsday/client/src/ui/widgets/cvarsliderwidget.cpp b/doomsday/client/src/ui/widgets/cvarsliderwidget.cpp index 763fb45a9f..7e9ddadd21 100644 --- a/doomsday/client/src/ui/widgets/cvarsliderwidget.cpp +++ b/doomsday/client/src/ui/widgets/cvarsliderwidget.cpp @@ -48,12 +48,28 @@ void CVarSliderWidget::updateFromCVar() float step = 0; cvar_t *var = d->var(); - setRange(Rangef(var->min, var->max), step); - setValue(CVar_Float(var)); - setPrecision(2); + if(var->type == CVT_FLOAT) + { + setRange(Rangef(var->min, var->max), step); + setValue(CVar_Float(var)); + setPrecision(2); + } + else + { + setRange(Rangei(var->min, var->max)); + setValue(CVar_Integer(var)); + } } void CVarSliderWidget::setCVarValueFromWidget() { - CVar_SetFloat(d->var(), value()); + cvar_t *var = d->var(); + if(var->type == CVT_FLOAT) + { + CVar_SetFloat(d->var(), value()); + } + else + { + CVar_SetInteger(d->var(), round(value())); + } } diff --git a/doomsday/client/src/ui/widgets/cvartogglewidget.cpp b/doomsday/client/src/ui/widgets/cvartogglewidget.cpp new file mode 100644 index 0000000000..034b1399c1 --- /dev/null +++ b/doomsday/client/src/ui/widgets/cvartogglewidget.cpp @@ -0,0 +1,54 @@ +/** @file cvartogglewidget.cpp Console variable toggle. + * + * @authors Copyright (c) 2013 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/widgets/cvartogglewidget.h" +#include "con_main.h" + +using namespace de; +using namespace ui; + +DENG2_PIMPL_NOREF(CVarToggleWidget) +{ + char const *cvar; + + cvar_t *var() const + { + cvar_t *cv = Con_FindVariable(cvar); + DENG2_ASSERT(cv != 0); + return cv; + } +}; + +CVarToggleWidget::CVarToggleWidget(char const *cvarPath) : d(new Instance) +{ + d->cvar = cvarPath; + updateFromCVar(); + + connect(this, SIGNAL(stateChangedByUser(ToggleWidget::ToggleState)), + this, SLOT(setCVarValueFromWidget())); +} + +void CVarToggleWidget::updateFromCVar() +{ + setActive(CVar_Integer(d->var()) != 0); +} + +void CVarToggleWidget::setCVarValueFromWidget() +{ + CVar_SetInteger(d->var(), isActive()? 1 : 0); +} diff --git a/doomsday/client/src/ui/widgets/sliderwidget.cpp b/doomsday/client/src/ui/widgets/sliderwidget.cpp index 5be8305485..06324637bc 100644 --- a/doomsday/client/src/ui/widgets/sliderwidget.cpp +++ b/doomsday/client/src/ui/widgets/sliderwidget.cpp @@ -425,9 +425,12 @@ DENG_GUI_PIMPL(SliderWidget) SliderWidget::SliderWidget(String const &name) : GuiWidget(name), d(new Instance(this)) { + /* + // Testing. setRange(Rangef(0, 1)); setPrecision(2); setValue(.5f); + */ // Default size. rule().setInput(Rule::Width, style().rules().rule("slider.width")) diff --git a/doomsday/client/src/ui/widgets/taskbarwidget.cpp b/doomsday/client/src/ui/widgets/taskbarwidget.cpp index 648dd83784..9d3ee140ef 100644 --- a/doomsday/client/src/ui/widgets/taskbarwidget.cpp +++ b/doomsday/client/src/ui/widgets/taskbarwidget.cpp @@ -24,6 +24,7 @@ #include "ui/widgets/blurwidget.h" #include "ui/dialogs/aboutdialog.h" #include "ui/dialogs/videosettingsdialog.h" +#include "ui/dialogs/audiosettingsdialog.h" #include "GuiRootWidget" #include "CommandAction" #include "SignalAction" @@ -51,7 +52,8 @@ static uint POS_PANEL = 0; static uint POS_UNLOAD = 1; static uint POS_GAME_SEPARATOR = 2; static uint POS_VIDEO_SETTINGS = 3; -static uint POS_UPDATER_SETTINGS = 4; +static uint POS_AUDIO_SETTINGS = 4; +static uint POS_UPDATER_SETTINGS = 5; DENG_GUI_PIMPL(TaskBarWidget), public IGameChangeObserver @@ -156,6 +158,19 @@ public IGameChangeObserver status->setText(tr("No game loaded")); } } + + void setupItemSubDialog(ui::Data::Pos item, DialogWidget *dlg) + { + dlg->setDeleteAfterDismissed(true); + if(mainMenu->isOpen()) + { + dlg->setAnchorAndOpeningDirection(mainMenu->menu().organizer(). + itemWidget(item)->hitRule(), + ui::Left); + + connect(mainMenu, SIGNAL(closed()), dlg, SLOT(close())); + } + } }; TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) @@ -191,7 +206,6 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) // DE logo. d->logo = new ButtonWidget; - //d->logo->setAction(new CommandAction("panel")); d->logo->setImage(style().images().image("logo.px128")); d->logo->setImageScale(.475f); d->logo->setImageFit(FitToHeight | OriginalAspectRatio); @@ -255,6 +269,8 @@ TaskBarWidget::TaskBarWidget() : GuiWidget("taskbar"), d(new Instance(this)) << new ui::Item(ui::Item::Separator) << new ui::ActionItem(ui::Item::ShownAsButton, tr("Video Settings"), new SignalAction(this, SLOT(showVideoSettings()))) + << new ui::ActionItem(ui::Item::ShownAsButton, tr("Audio Settings"), + new SignalAction(this, SLOT(showAudioSettings()))) << new ui::ActionItem(ui::Item::ShownAsButton, tr("Updater Settings"), new SignalAction(this, SLOT(showUpdaterSettings()))) << new ui::Item(ui::Item::Separator) @@ -492,28 +508,22 @@ void TaskBarWidget::showAbout() void TaskBarWidget::showUpdaterSettings() { UpdaterSettingsDialog *dlg = new UpdaterSettingsDialog(UpdaterSettingsDialog::WithApplyAndCheckButton); - dlg->setDeleteAfterDismissed(true); - if(d->mainMenu->isOpen()) - { - dlg->setAnchorAndOpeningDirection(d->mainMenu->menu().organizer(). - itemWidget(POS_UPDATER_SETTINGS)->hitRule(), - ui::Left); - } + d->setupItemSubDialog(POS_UPDATER_SETTINGS, dlg); dlg->exec(root()); } void TaskBarWidget::showVideoSettings() { VideoSettingsDialog *dlg = new VideoSettingsDialog; - dlg->setDeleteAfterDismissed(true); - if(d->mainMenu->isOpen()) - { - dlg->setAnchorAndOpeningDirection(d->mainMenu->menu().organizer(). - itemWidget(POS_VIDEO_SETTINGS)->hitRule(), - ui::Left); + d->setupItemSubDialog(POS_VIDEO_SETTINGS, dlg); + root().add(dlg); + dlg->open(); +} - connect(d->mainMenu, SIGNAL(closed()), dlg, SLOT(close())); - } +void TaskBarWidget::showAudioSettings() +{ + AudioSettingsDialog *dlg = new AudioSettingsDialog; + d->setupItemSubDialog(POS_AUDIO_SETTINGS, dlg); root().add(dlg); dlg->open(); } diff --git a/doomsday/client/src/ui/widgets/togglewidget.cpp b/doomsday/client/src/ui/widgets/togglewidget.cpp index 1c5edb2552..93e58826d4 100644 --- a/doomsday/client/src/ui/widgets/togglewidget.cpp +++ b/doomsday/client/src/ui/widgets/togglewidget.cpp @@ -118,6 +118,8 @@ DENG2_OBSERVES(ButtonWidget, Press) { // Toggle the state. self.setActive(self.isInactive()); + + emit self.stateChangedByUser(self.toggleState()); } }; @@ -138,6 +140,7 @@ void ToggleWidget::setToggleState(ToggleState state, bool notify) { DENG2_FOR_AUDIENCE(Toggle, i) i->toggleStateChanged(*this); } + emit stateChanged(state); } }