From c195699476b4bf09f20855319ba20300bc77da11 Mon Sep 17 00:00:00 2001 From: netnazgul Date: Tue, 9 Jan 2018 23:37:47 +0300 Subject: [PATCH] Implement a slider widget for volume control that returns an exponentially scaled value --- AUTHORS | 1 + OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Widgets/ExponentialSliderWidget.cs | 53 +++++++++++++++++++ OpenRA.Mods.Common/Widgets/SliderWidget.cs | 4 +- mods/cnc/chrome/lobby-music.yaml | 4 +- mods/cnc/chrome/music.yaml | 4 +- mods/cnc/chrome/settings.yaml | 12 ++--- mods/common/chrome/lobby-music.yaml | 4 +- mods/common/chrome/musicplayer.yaml | 4 +- mods/common/chrome/settings.yaml | 12 ++--- 10 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 OpenRA.Mods.Common/Widgets/ExponentialSliderWidget.cs diff --git a/AUTHORS b/AUTHORS index 5fc8566520..1b8ac15ae8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -109,6 +109,7 @@ Also thanks to: * Muh * Mustafa Alperen Seki (MustaphaTR) * Neil Shivkar (havok13888) + * Nikolay Fomin (netnazgul) * Nooze * Nukem * Okunev Yu Dmitry (xaionaro) diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index ce0c752af5..b526c76c85 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -619,6 +619,7 @@ + diff --git a/OpenRA.Mods.Common/Widgets/ExponentialSliderWidget.cs b/OpenRA.Mods.Common/Widgets/ExponentialSliderWidget.cs new file mode 100644 index 0000000000..07cc597b08 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/ExponentialSliderWidget.cs @@ -0,0 +1,53 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Drawing; +using OpenRA.Graphics; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets +{ + public class ExponentialSliderWidget : SliderWidget + { + // Values are according to https://www.dr-lex.be/info-stuff/volumecontrols.html + public double ExpA = 1.0e-3; + public double ExpB = 6.908; + + public ExponentialSliderWidget() : + base() { } + public ExponentialSliderWidget(ExponentialSliderWidget other) : + base(other) { } + + float ExpFromLinear(float x) + { + if (x <= 0) + return 0; + + return (float)(ExpA * Math.Exp(ExpB * x)).Clamp(0.0, 1.0); + } + + float LinearFromExp(float x) + { + return (float)(Math.Log(x / ExpA) / ExpB).Clamp(0.0, 1.0); + } + + protected override float ValueFromPx(int x) + { + return MinimumValue + (MaximumValue - MinimumValue) * ExpFromLinear((x - 0.5f * RenderBounds.Height) / (RenderBounds.Width - RenderBounds.Height)); + } + + protected override int PxFromValue(float x) + { + return (int)(0.5f * RenderBounds.Height + (RenderBounds.Width - RenderBounds.Height) * LinearFromExp((x - MinimumValue) / (MaximumValue - MinimumValue))); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/SliderWidget.cs b/OpenRA.Mods.Common/Widgets/SliderWidget.cs index 243298278b..7f578cbda6 100644 --- a/OpenRA.Mods.Common/Widgets/SliderWidget.cs +++ b/OpenRA.Mods.Common/Widgets/SliderWidget.cs @@ -84,12 +84,12 @@ namespace OpenRA.Mods.Common.Widgets return ThumbRect.Contains(mi.Location); } - float ValueFromPx(int x) + protected virtual float ValueFromPx(int x) { return MinimumValue + (MaximumValue - MinimumValue) * (x - 0.5f * RenderBounds.Height) / (RenderBounds.Width - RenderBounds.Height); } - protected int PxFromValue(float x) + protected virtual int PxFromValue(float x) { return (int)(0.5f * RenderBounds.Height + (RenderBounds.Width - RenderBounds.Height) * (x - MinimumValue) / (MaximumValue - MinimumValue)); } diff --git a/mods/cnc/chrome/lobby-music.yaml b/mods/cnc/chrome/lobby-music.yaml index cdc4e2a673..850ba465e1 100644 --- a/mods/cnc/chrome/lobby-music.yaml +++ b/mods/cnc/chrome/lobby-music.yaml @@ -138,12 +138,12 @@ Container@LOBBY_MUSIC_BIN: Height: 25 Align: Right Text: Volume: - Slider@MUSIC_SLIDER: + ExponentialSlider@MUSIC_SLIDER: X: 70 Y: 186 Width: PARENT_RIGHT - 80 Height: 20 - Ticks: 5 + Ticks: 7 ScrollPanel@MUSIC_LIST: X: 307 Width: PARENT_RIGHT - 307 diff --git a/mods/cnc/chrome/music.yaml b/mods/cnc/chrome/music.yaml index 0899cb52d4..ce0c1c86f5 100644 --- a/mods/cnc/chrome/music.yaml +++ b/mods/cnc/chrome/music.yaml @@ -128,12 +128,12 @@ Container@MUSIC_PANEL: Height: 16 ImageCollection: music ImageName: next - Slider@MUSIC_SLIDER: + ExponentialSlider@MUSIC_SLIDER: X: 145 Y: 3 Width: 185 Height: 20 - Ticks: 5 + Ticks: 7 Label@TIME_LABEL: X: (PARENT_RIGHT - WIDTH) / 2 Y: 315 diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index 1fdb7e5f4d..161c7d194c 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -277,12 +277,12 @@ Container@SETTINGS_PANEL: Height: 25 Align: Right Text: Sound Volume: - Slider@SOUND_VOLUME: + ExponentialSlider@SOUND_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 43 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Checkbox@CASH_TICKS: X: 15 Y: 40 @@ -304,12 +304,12 @@ Container@SETTINGS_PANEL: Height: 25 Align: Right Text: Music Volume: - Slider@MUSIC_VOLUME: + ExponentialSlider@MUSIC_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 73 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Label@VIDEO_LABEL: X: PARENT_RIGHT - WIDTH - 270 Y: 97 @@ -317,12 +317,12 @@ Container@SETTINGS_PANEL: Height: 25 Align: Right Text: Video Volume: - Slider@VIDEO_VOLUME: + ExponentialSlider@VIDEO_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 103 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Label@AUDIO_DEVICE_LABEL: X: 190 - WIDTH - 5 Y: 244 diff --git a/mods/common/chrome/lobby-music.yaml b/mods/common/chrome/lobby-music.yaml index feca8d0a01..4e4bc2a15e 100644 --- a/mods/common/chrome/lobby-music.yaml +++ b/mods/common/chrome/lobby-music.yaml @@ -128,12 +128,12 @@ Container@LOBBY_MUSIC_BIN: Height: 25 Align: Right Text: Volume: - Slider@MUSIC_SLIDER: + ExponentialSlider@MUSIC_SLIDER: X: 70 Y: 186 Width: PARENT_RIGHT - 80 Height: 20 - Ticks: 5 + Ticks: 7 ScrollPanel@MUSIC_LIST: X: 268 Width: PARENT_RIGHT - 268 diff --git a/mods/common/chrome/musicplayer.yaml b/mods/common/chrome/musicplayer.yaml index 6dac81459a..8dedd634a3 100644 --- a/mods/common/chrome/musicplayer.yaml +++ b/mods/common/chrome/musicplayer.yaml @@ -116,12 +116,12 @@ Background@MUSIC_PANEL: Height: 25 ImageCollection: music ImageName: next - Slider@MUSIC_SLIDER: + ExponentialSlider@MUSIC_SLIDER: X: 145 Y: 3 Width: 175 Height: 20 - Ticks: 5 + Ticks: 7 Label@TIME_LABEL: X: (PARENT_RIGHT - WIDTH) / 2 Y: 330 diff --git a/mods/common/chrome/settings.yaml b/mods/common/chrome/settings.yaml index 91fca369d2..e816c1a541 100644 --- a/mods/common/chrome/settings.yaml +++ b/mods/common/chrome/settings.yaml @@ -285,12 +285,12 @@ Background@SETTINGS_PANEL: Height: 25 Align: Right Text: Sound Volume: - Slider@SOUND_VOLUME: + ExponentialSlider@SOUND_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 43 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Checkbox@CASH_TICKS: X: 15 Y: 40 @@ -312,12 +312,12 @@ Background@SETTINGS_PANEL: Height: 25 Align: Right Text: Music Volume: - Slider@MUSIC_VOLUME: + ExponentialSlider@MUSIC_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 73 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Label@VIDEO_LABEL: X: PARENT_RIGHT - WIDTH - 270 Y: 97 @@ -325,12 +325,12 @@ Background@SETTINGS_PANEL: Height: 25 Align: Right Text: Video Volume: - Slider@VIDEO_VOLUME: + ExponentialSlider@VIDEO_VOLUME: X: PARENT_RIGHT - WIDTH - 15 Y: 103 Width: 250 Height: 20 - Ticks: 5 + Ticks: 7 Label@AUDIO_DEVICE_LABEL: X: 190 - WIDTH - 5 Y: 244