1 |
/* |
2 |
* BTrackBar.cs |
3 |
* Copyright (c) 2009 kbinani |
4 |
* |
5 |
* This file is part of Boare.Lib.AppUtil. |
6 |
* |
7 |
* Boare.Lib.AppUtil is free software; you can redistribute it and/or |
8 |
* modify it under the terms of the BSD License. |
9 |
* |
10 |
* Boare.Lib.AppUtil is distributed in the hope that it will be useful, |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
13 |
*/ |
14 |
//#define BENCH |
15 |
using System; |
16 |
using System.Windows.Forms; |
17 |
using System.Reflection; |
18 |
|
19 |
namespace Boare.Lib.AppUtil { |
20 |
|
21 |
/// <summary> |
22 |
/// Valueの型を変えられるTrackBar |
23 |
/// </summary> |
24 |
public class BTrackBar<T> : UserControl where T : struct, IComparable<T> { |
25 |
const int _MAX = 10000; |
26 |
private T m_value; |
27 |
private T m_min; |
28 |
private T m_max; |
29 |
private T m_tick_frequency; |
30 |
private MethodInfo m_parser = null; |
31 |
private ValueType m_value_type = ValueType.int_; |
32 |
private TrackBarEx m_track_bar; |
33 |
private Type m_type = typeof( int ); |
34 |
|
35 |
private enum ValueType { |
36 |
sbyte_, |
37 |
byte_, |
38 |
shoft_, |
39 |
ushort_, |
40 |
int_, |
41 |
uint_, |
42 |
long_, |
43 |
ulong_, |
44 |
} |
45 |
|
46 |
public event EventHandler ValueChanged; |
47 |
|
48 |
private static void test() { |
49 |
System.Windows.Forms.TrackBar tb = new System.Windows.Forms.TrackBar(); |
50 |
BTrackBar<int> tb2 = new BTrackBar<int>(); |
51 |
} |
52 |
|
53 |
public BTrackBar() { |
54 |
InitializeComponent(); |
55 |
T value_type = new T(); |
56 |
if ( value_type is byte ) { |
57 |
m_value_type = BTrackBar<T>.ValueType.byte_; |
58 |
} else if ( value_type is sbyte ) { |
59 |
m_value_type = BTrackBar<T>.ValueType.sbyte_; |
60 |
} else if ( value_type is short ) { |
61 |
m_value_type = BTrackBar<T>.ValueType.shoft_; |
62 |
} else if ( value_type is ushort ) { |
63 |
m_value_type = BTrackBar<T>.ValueType.ushort_; |
64 |
} else if ( value_type is int ) { |
65 |
m_value_type = BTrackBar<T>.ValueType.int_; |
66 |
} else if ( value_type is uint ) { |
67 |
m_value_type = BTrackBar<T>.ValueType.uint_; |
68 |
} else if ( value_type is long ) { |
69 |
m_value_type = BTrackBar<T>.ValueType.long_; |
70 |
} else if ( value_type is ulong ) { |
71 |
m_value_type = BTrackBar<T>.ValueType.ulong_; |
72 |
} else { |
73 |
throw new NotSupportedException( "generic type T must be byte, sbyte, short, ushort, int, uint, long or ulong" ); |
74 |
} |
75 |
m_type = value_type.GetType(); |
76 |
m_parser = typeof( T ).GetMethod( "Parse", new Type[] { typeof( string ) } ); |
77 |
if ( m_parser == null ) { |
78 |
throw new ApplicationException( "this error never occurs; m_type=" + m_value_type ); |
79 |
} |
80 |
#if BENCH |
81 |
// Benchmark1: string parser |
82 |
int _COUNT = 100000; |
83 |
MethodInfo parser_double = typeof( double ).GetMethod( "Parse", new Type[] { typeof( string ) } ); |
84 |
Console.WriteLine( "parsed \"123.456\" = " + ((double)parser_double.Invoke( typeof( double ), new object[] { "123.456" } )) ); |
85 |
DateTime start = DateTime.Now; |
86 |
for ( int i = 0; i < _COUNT; i++ ) { |
87 |
double v = (double)parser_double.Invoke( typeof( double ), new object[] { "123.456" } ); |
88 |
} |
89 |
Console.WriteLine( "Benchmark1; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); |
90 |
|
91 |
// Benchmark2: BinaryFormatter |
92 |
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); |
93 |
System.IO.MemoryStream ms = new System.IO.MemoryStream( 64 ); |
94 |
const double cdbbl = 123.456; |
95 |
bf.Serialize( ms, cdbbl ); |
96 |
_COUNT = 10000; |
97 |
ms.Seek( 0, System.IO.SeekOrigin.Begin ); |
98 |
Console.WriteLine( "deserilized = " + ((double)bf.Deserialize( ms )) ); |
99 |
start = DateTime.Now; |
100 |
for ( int i = 0; i < _COUNT; i++ ) { |
101 |
ms.Seek( 0, System.IO.SeekOrigin.Begin ); |
102 |
double v = (double)bf.Deserialize( ms ); |
103 |
} |
104 |
Console.WriteLine( "Benchmark2; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); |
105 |
|
106 |
// Benchmark3: Convert class |
107 |
object obj = cdbbl; |
108 |
Console.WriteLine( "Converted = " + Convert.ToDouble( obj ) ); |
109 |
_COUNT = 100000; |
110 |
start = DateTime.Now; |
111 |
for ( int i = 0; i < _COUNT; i++ ) { |
112 |
double v = Convert.ToDouble( obj ); |
113 |
} |
114 |
Console.WriteLine( "Benchmark3; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); |
115 |
#endif |
116 |
} |
117 |
|
118 |
public T Maximum { |
119 |
get { |
120 |
return m_max; |
121 |
} |
122 |
set { |
123 |
if ( value.CompareTo( m_min ) < 0 ) { |
124 |
throw new ArgumentOutOfRangeException( "Maximum" ); |
125 |
} |
126 |
m_max = value; |
127 |
if ( m_max.CompareTo( m_value ) < 0 ) { |
128 |
Value = m_max; |
129 |
} |
130 |
} |
131 |
} |
132 |
|
133 |
public T Minimum { |
134 |
get { |
135 |
return m_min; |
136 |
} |
137 |
set { |
138 |
if ( value.CompareTo( m_max ) > 0 ) { |
139 |
throw new ArgumentOutOfRangeException( "Minimum" ); |
140 |
} |
141 |
m_min = value; |
142 |
if ( m_min.CompareTo( m_value ) > 0 ) { |
143 |
Value = m_min; |
144 |
} |
145 |
} |
146 |
} |
147 |
|
148 |
public TickStyle TickStyle { |
149 |
get { |
150 |
return m_track_bar.TickStyle; |
151 |
} |
152 |
set { |
153 |
m_track_bar.TickStyle = value; |
154 |
} |
155 |
} |
156 |
|
157 |
public T TickFrequency { |
158 |
get { |
159 |
return m_tick_frequency; |
160 |
} |
161 |
set { |
162 |
m_tick_frequency = value; |
163 |
double max = asDouble( m_max ); |
164 |
double min = asDouble( m_min ); |
165 |
double stride = asDouble( m_tick_frequency ); |
166 |
double rate = (max - min) / stride; |
167 |
Console.WriteLine( "BTrackBar+set__TickFrequency" ); |
168 |
Console.WriteLine( " rate=" + rate ); |
169 |
int freq = (int)(_MAX / rate); |
170 |
Console.WriteLine( " freq=" + freq ); |
171 |
Console.WriteLine( " m_track_bar.Maximum=" + m_track_bar.Maximum ); |
172 |
m_track_bar.TickFrequency = freq; |
173 |
} |
174 |
} |
175 |
|
176 |
public T Value { |
177 |
get { |
178 |
return m_value; |
179 |
} |
180 |
set { |
181 |
if ( value.CompareTo( m_max ) > 0 ) { |
182 |
throw new ArgumentOutOfRangeException( "Value" ); |
183 |
} |
184 |
if ( value.CompareTo( m_min ) < 0 ) { |
185 |
throw new ArgumentOutOfRangeException( "Value" ); |
186 |
} |
187 |
T old = m_value; |
188 |
m_value = value; |
189 |
if ( old.CompareTo( m_value ) != 0 && ValueChanged != null ) { |
190 |
ValueChanged( this, new EventArgs() ); |
191 |
} |
192 |
} |
193 |
} |
194 |
|
195 |
private double asDouble( T value ) { |
196 |
object o = value; |
197 |
return Convert.ToDouble( o ); |
198 |
} |
199 |
|
200 |
private T add( T value1, T value2 ) { |
201 |
object o1 = value1; |
202 |
object o2 = value2; |
203 |
switch ( m_value_type ) { |
204 |
case BTrackBar<T>.ValueType.sbyte_: |
205 |
sbyte sb1 = Convert.ToSByte( o1 ); |
206 |
sbyte sb2 = Convert.ToSByte( o2 ); |
207 |
object sb_r = (sb1 + sb2); |
208 |
return (T)sb_r; |
209 |
case BTrackBar<T>.ValueType.byte_: |
210 |
byte b1 = Convert.ToByte( o1 ); |
211 |
byte b2 = Convert.ToByte( o2 ); |
212 |
object b_r = (b1 + b2); |
213 |
return (T)b_r; |
214 |
case BTrackBar<T>.ValueType.shoft_: |
215 |
short s1 = Convert.ToInt16( o1 ); |
216 |
short s2 = Convert.ToInt16( o2 ); |
217 |
object s_r = (s1 + s2); |
218 |
return (T)s_r; |
219 |
case BTrackBar<T>.ValueType.ushort_: |
220 |
ushort us1 = Convert.ToUInt16( o1 ); |
221 |
ushort us2 = Convert.ToUInt16( o2 ); |
222 |
object us_r = (us1 + us2); |
223 |
return (T)us_r; |
224 |
case BTrackBar<T>.ValueType.int_: |
225 |
int i1 = Convert.ToInt32( o1 ); |
226 |
int i2 = Convert.ToInt32( o2 ); |
227 |
object i_r = (i1 + i2); |
228 |
return (T)i_r; |
229 |
case BTrackBar<T>.ValueType.uint_: |
230 |
uint ui1 = Convert.ToUInt32( o1 ); |
231 |
uint ui2 = Convert.ToUInt32( o2 ); |
232 |
object ui_r = ui1 + ui2; |
233 |
return (T)ui_r; |
234 |
case BTrackBar<T>.ValueType.long_: |
235 |
long l1 = Convert.ToInt64( o1 ); |
236 |
long l2 = Convert.ToInt64( o2 ); |
237 |
object l_r = l1 + l2; |
238 |
return (T)l_r; |
239 |
case BTrackBar<T>.ValueType.ulong_: |
240 |
ulong ul1 = Convert.ToUInt64( o1 ); |
241 |
ulong ul2 = Convert.ToUInt64( o2 ); |
242 |
object ul_r = ul1 + ul2; |
243 |
return (T)ul_r; |
244 |
} |
245 |
return new T(); |
246 |
} |
247 |
|
248 |
private void InitializeComponent() { |
249 |
this.m_track_bar = new TrackBarEx(); |
250 |
((System.ComponentModel.ISupportInitialize)(this.m_track_bar)).BeginInit(); |
251 |
this.SuspendLayout(); |
252 |
// |
253 |
// trackBar |
254 |
// |
255 |
this.m_track_bar.Dock = System.Windows.Forms.DockStyle.Fill; |
256 |
this.m_track_bar.Location = new System.Drawing.Point( 0, 0 ); |
257 |
this.m_track_bar.Name = "trackBar"; |
258 |
this.m_track_bar.Size = new System.Drawing.Size( 286, 55 ); |
259 |
this.m_track_bar.TabIndex = 0; |
260 |
this.m_track_bar.Maximum = _MAX; |
261 |
this.m_track_bar.Minimum = 0; |
262 |
this.m_track_bar.TickFrequency = 1; |
263 |
this.m_track_bar.SmallChange = 1; |
264 |
this.m_track_bar.m_wheel_direction = false; |
265 |
// |
266 |
// BTrackBar |
267 |
// |
268 |
this.Controls.Add( this.m_track_bar ); |
269 |
this.Name = "BTrackBar"; |
270 |
this.Size = new System.Drawing.Size( 286, 55 ); |
271 |
((System.ComponentModel.ISupportInitialize)(this.m_track_bar)).EndInit(); |
272 |
this.ResumeLayout( false ); |
273 |
this.PerformLayout(); |
274 |
} |
275 |
} |
276 |
|
277 |
internal class TrackBarEx : TrackBar { |
278 |
public bool m_wheel_direction = true; |
279 |
|
280 |
protected override void OnMouseWheel( MouseEventArgs e ) { |
281 |
if ( m_wheel_direction ) { |
282 |
base.OnMouseWheel( new MouseEventArgs( e.Button, e.Clicks, e.X, e.Y, e.Delta ) ); |
283 |
} else { |
284 |
base.OnMouseWheel( new MouseEventArgs( e.Button, e.Clicks, e.X, e.Y, -e.Delta ) ); |
285 |
} |
286 |
} |
287 |
} |
288 |
|
289 |
} |