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