Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume controls in Game Options window #8943

Merged
merged 4 commits into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 11 additions & 34 deletions src/music_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "settings_gui.h"
#include "widgets/dropdown_func.h"
#include "widgets/dropdown_type.h"
#include "widgets/slider_func.h"

#include "widgets/music_widget.h"

Expand Down Expand Up @@ -643,8 +644,6 @@ static void ShowMusicTrackSelection()
}

struct MusicWindow : public Window {
static const int slider_width = 3;

MusicWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
{
this->InitNested(number);
Expand Down Expand Up @@ -740,27 +739,13 @@ struct MusicWindow : public Window {
break;
}

case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: {
/* Draw a wedge indicating low to high volume level. */
const int ha = (r.bottom - r.top) / 5;
int wx1 = r.left, wx2 = r.right;
if (_current_text_dir == TD_RTL) std::swap(wx1, wx2);
const uint shadow = _colour_gradient[COLOUR_GREY][3];
const uint fill = _colour_gradient[COLOUR_GREY][6];
const uint light = _colour_gradient[COLOUR_GREY][7];
const std::vector<Point> wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} };
GfxFillPolygon(wedge, fill);
GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light);
GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light);
GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow);
/* Draw a slider handle indicating current volume level. */
const int sw = ScaleGUITrad(slider_width);
byte volume = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
if (_current_text_dir == TD_RTL) volume = 127 - volume;
const int x = r.left + (volume * (r.right - r.left - sw) / 127);
DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE);
case WID_M_MUSIC_VOL:
DrawVolumeSliderWidget(r, _settings_client.music.music_vol);
break;

case WID_M_EFFECT_VOL:
DrawVolumeSliderWidget(r, _settings_client.music.effect_vol);
break;
}
}
}

Expand Down Expand Up @@ -801,19 +786,11 @@ struct MusicWindow : public Window {
break;

case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders
int x = pt.x - this->GetWidget<NWidgetBase>(widget)->pos_x;

byte *vol = (widget == WID_M_MUSIC_VOL) ? &_settings_client.music.music_vol : &_settings_client.music.effect_vol;

byte new_vol = Clamp(x * 127 / (int)this->GetWidget<NWidgetBase>(widget)->current_x, 0, 127);
if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol;
/* Clamp to make sure min and max are properly settable */
if (new_vol > 124) new_vol = 127;
if (new_vol < 3) new_vol = 0;
if (new_vol != *vol) {
*vol = new_vol;
if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(new_vol);
byte &vol = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
if (ClickVolumeSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, vol)) {
if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(vol);
this->SetDirty();
SetWindowClassesDirty(WC_GAME_OPTIONS);
}

if (click_count > 0) this->mouse_capture_widget = widget;
Expand Down
41 changes: 38 additions & 3 deletions src/settings_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "string_func.h"
#include "widgets/dropdown_type.h"
#include "widgets/dropdown_func.h"
#include "widgets/slider_func.h"
#include "highscore.h"
#include "base_media_base.h"
#include "company_base.h"
Expand All @@ -36,6 +37,7 @@
#include "fontcache.h"
#include "zoom_func.h"
#include "video/video_driver.hpp"
#include "music/music_driver.hpp"

#include <vector>
#include <iterator>
Expand Down Expand Up @@ -335,6 +337,14 @@ struct GameOptionsWindow : Window {
SetDParamStr(0, BaseMusic::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode()));
DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING);
break;

case WID_GO_BASE_SFX_VOLUME:
DrawVolumeSliderWidget(r, _settings_client.music.effect_vol);
break;

case WID_GO_BASE_MUSIC_VOLUME:
DrawVolumeSliderWidget(r, _settings_client.music.music_vol);
break;
}
}

Expand Down Expand Up @@ -387,6 +397,16 @@ struct GameOptionsWindow : Window {
}
break;

case WID_GO_BASE_SFX_VOLUME:
case WID_GO_BASE_MUSIC_VOLUME:
size->width = ScaleGUITrad(67);
size->height = ScaleGUITrad(12);
resize->width = 0;
resize->height = 0;
fill->width = 0;
fill->height = 0;
break;

default: {
int selected;
DropDownList list = this->BuildDropDownList(widget, &selected);
Expand Down Expand Up @@ -441,6 +461,19 @@ struct GameOptionsWindow : Window {
this->SetDirty();
break;

case WID_GO_BASE_SFX_VOLUME:
case WID_GO_BASE_MUSIC_VOLUME: {
byte &vol = (widget == WID_GO_BASE_MUSIC_VOLUME) ? _settings_client.music.music_vol : _settings_client.music.effect_vol;
if (ClickVolumeSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, vol)) {
if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol);
this->SetDirty();
SetWindowClassesDirty(WC_MUSIC_WINDOW);
}

if (click_count > 0) this->mouse_capture_widget = widget;
break;
}

default: {
int selected;
DropDownList list = this->BuildDropDownList(widget, &selected);
Expand Down Expand Up @@ -645,9 +678,10 @@ static const NWidgetPart _nested_game_options_widgets[] = {
EndContainer(),

NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPadding(0, 10, 0, 10),
NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(150, 12), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_BASE_SFX_VOLUME), SetMinimalSize(67, 12), SetMinimalTextLines(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
EndContainer(),
NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
Expand All @@ -658,9 +692,10 @@ static const NWidgetPart _nested_game_options_widgets[] = {
EndContainer(),

NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPadding(0, 10, 0, 10),
NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP),
NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 12), SetMinimalTextLines(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
EndContainer(),
NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
Expand Down
4 changes: 2 additions & 2 deletions src/table/settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3522,7 +3522,7 @@ cat = SC_BASIC
var = music.music_vol
type = SLE_UINT8
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = 127
def = 50
min = 0
max = 127
interval = 1
Expand All @@ -3532,7 +3532,7 @@ cat = SC_BASIC
var = music.effect_vol
type = SLE_UINT8
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = 127
def = 100
min = 0
max = 127
interval = 1
Expand Down
10 changes: 10 additions & 0 deletions src/widget_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ class NWidgetBase : public ZeroedMemoryAllocator {
virtual void Draw(const Window *w) = 0;
virtual void SetDirty(const Window *w) const;

Rect GetCurrentRect() const
{
Rect r;
r.left = this->pos_x;
r.top = this->pos_y;
r.right = this->pos_x + this->current_x;
r.bottom = this->pos_y + this->current_y;
return r;
}

WidgetType type; ///< Type of the widget / nested widget.
uint fill_x; ///< Horizontal fill stepsize (from initial size, \c 0 means not resizable).
uint fill_y; ///< Vertical fill stepsize (from initial size, \c 0 means not resizable).
Expand Down
2 changes: 2 additions & 0 deletions src/widgets/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ add_files(
screenshot_widget.h
settings_widget.h
sign_widget.h
slider.cpp
slider_func.h
smallmap_widget.h
station_widget.h
statusbar_widget.h
Expand Down
2 changes: 2 additions & 0 deletions src/widgets/settings_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ enum GameOptionsWidgets {
WID_GO_BASE_GRF_TEXTFILE, ///< Open base GRF readme, changelog (+1) or license (+2).
WID_GO_BASE_GRF_DESCRIPTION = WID_GO_BASE_GRF_TEXTFILE + TFT_END, ///< Description of selected base GRF.
WID_GO_BASE_SFX_DROPDOWN, ///< Use to select a base SFX.
WID_GO_BASE_SFX_VOLUME, ///< Change sound effects volume.
WID_GO_BASE_SFX_TEXTFILE, ///< Open base SFX readme, changelog (+1) or license (+2).
WID_GO_BASE_SFX_DESCRIPTION = WID_GO_BASE_SFX_TEXTFILE + TFT_END, ///< Description of selected base SFX.
WID_GO_BASE_MUSIC_DROPDOWN, ///< Use to select a base music set.
WID_GO_BASE_MUSIC_VOLUME, ///< Change music volume.
WID_GO_BASE_MUSIC_STATUS, ///< Info about corrupted files etc.
WID_GO_BASE_MUSIC_TEXTFILE, ///< Open base music readme, changelog (+1) or license (+2).
WID_GO_BASE_MUSIC_DESCRIPTION = WID_GO_BASE_MUSIC_TEXTFILE + TFT_END, ///< Description of selected base music set.
Expand Down
70 changes: 70 additions & 0 deletions src/widgets/slider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is part of OpenTTD.
* OpenTTD 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, version 2.
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file slider.cpp Implementation of the horizontal slider widget. */

#include "../stdafx.h"
#include "../window_gui.h"
#include "../window_func.h"
#include "../strings_func.h"
#include "../zoom_func.h"
#include "slider_func.h"

#include "../safeguards.h"


/**
* Draw a volume slider widget with know at given value
* @param r Rectangle to draw the widget in
* @param value Value to put the slider at
*/
void DrawVolumeSliderWidget(Rect r, byte value)
{
static const int slider_width = 3;

/* Draw a wedge indicating low to high volume level. */
const int ha = (r.bottom - r.top) / 5;
int wx1 = r.left, wx2 = r.right;
if (_current_text_dir == TD_RTL) std::swap(wx1, wx2);
const uint shadow = _colour_gradient[COLOUR_GREY][3];
const uint fill = _colour_gradient[COLOUR_GREY][6];
const uint light = _colour_gradient[COLOUR_GREY][7];
const std::vector<Point> wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} };
GfxFillPolygon(wedge, fill);
GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light);
GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light);
GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow);

/* Draw a slider handle indicating current volume level. */
const int sw = ScaleGUITrad(slider_width);
if (_current_text_dir == TD_RTL) value = 127 - value;
const int x = r.left + (value * (r.right - r.left - sw) / 127);
DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE);
}

/**
* Handle click on a volume slider widget to change the value
* @param r Rectangle of the widget
* @param pt Clicked point
* @param value[in,out] Volume value to modify
* @return True if the volume setting was modified
*/
bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value)
{
byte new_vol = Clamp((pt.x - r.left) * 127 / (r.right - r.left), 0, 127);
if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol;

/* Clamp to make sure min and max are properly settable */
if (new_vol > 124) new_vol = 127;
if (new_vol < 3) new_vol = 0;
if (new_vol != value) {
value = new_vol;
return true;
}

return false;
}
21 changes: 21 additions & 0 deletions src/widgets/slider_func.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* This file is part of OpenTTD.
* OpenTTD 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, version 2.
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file slider_type.h Types related to the horizontal slider widget. */

#ifndef WIDGETS_SLIDER_TYPE_H
#define WIDGETS_SLIDER_TYPE_H

#include "../window_type.h"
#include "../gfx_func.h"


void DrawVolumeSliderWidget(Rect r, byte value);
bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value);


#endif /* WIDGETS_SLIDER_TYPE_H */