-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVolumeSlider.cs
141 lines (128 loc) · 3.5 KB
/
VolumeSlider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System.ComponentModel;
using System.Globalization;
namespace ToneGenerator
{
/// <summary>
/// Tweaked volume slider that is double buffered and fixes divide by 0 bug on Windows XP.
/// </summary>
public class VolumeSlider : UserControl
{
/// <summary>
/// Creates a new VolumeSlider control.
/// </summary>
public VolumeSlider()
{
Name = "VolumeSlider";
Size = new Size(96, 16);
}
/// <summary>
/// The volume for this control.
/// </summary>
private float volume = 1f;
[DefaultValue(1f)]
public float Volume
{
get { return volume; }
set
{
if (value < 0f)
value = 0f;
if (value > Utilities.DbToMag(maximumDB))
value = Utilities.DbToMag(maximumDB);
if (volume != value)
{
volume = value;
if (VolumeChanged != null)
VolumeChanged(this, EventArgs.Empty);
Invalidate();
}
}
}
private float minimumDB = -60;
/// <summary>
/// Gets or sets the minimum decibel volume for the control.
/// </summary>
public float MinimumDB
{
get { return minimumDB; }
set
{
minimumDB = value;
Invalidate();
}
}
private float maximumDB = 0;
/// <summary>
/// Gets or sets the minimum decibel volume for the control.
/// </summary>
public float MaximumDB
{
get { return maximumDB; }
set
{
maximumDB = value;
Invalidate();
}
}
/// <summary>
/// Volume changed event
/// </summary>
public event EventHandler? VolumeChanged;
/// <summary>
/// Raises the <see cref="HandleCreated"/> event.
/// </summary>
/// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
DoubleBuffered = true;
}
/// <summary>
/// <see cref="M:System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)" />
/// </summary>
protected override void OnMouseDown(MouseEventArgs e)
{
SetVolumeFromMouse(e.X);
base.OnMouseDown(e);
}
/// <summary>
/// <see cref="M:System.Windows.Forms.Control.OnMouseMove(System.Windows.Forms.MouseEventArgs)" />
/// </summary>
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
SetVolumeFromMouse(e.X);
base.OnMouseMove(e);
}
/// <summary>
/// Raises the <see cref="Resize"/> event.
/// </summary>
/// <param name="e">An System.EventArgs that contains the event data.</param>
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
Invalidate();
}
/// <summary>
/// Raises the <see cref="Paint"/> event.
/// </summary>
/// <param name="pe">A <see cref="PaintEventArgs"/> that contains the event data.</param>
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.DrawRectangle(Pens.Black, 0, 0, Width - 1, Height - 1);
float db = Utilities.MagToDb(volume);
float fraction = 1f - (db - maximumDB) / (minimumDB - maximumDB);
int width = (int)((Width - 2) * fraction);
pe.Graphics.FillRectangle(Brushes.LightGreen, 1, 1, Math.Max(0, width), Height - 2);
using (var stringFormat = new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center })
{
pe.Graphics.DrawString(string.Format(CultureInfo.CurrentCulture, "{0:F2} dB", db), Font, Brushes.Black, ClientRectangle, stringFormat);
}
}
private void SetVolumeFromMouse(int x)
{
Volume = x <= 0 ? 0f : Utilities.DbToMag(maximumDB + (1f - (float)x / (Width - 2)) * (minimumDB - maximumDB));
}
}
}