2 // System.Windows.Forms.TrackBar.cs
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 // Jordi Mas i Hernandez, jordi@ximian.com
27 // - The AutoSize functionality seems quite broken for vertical controls in .Net 1.1. Not
28 // sure if we are implementing it the right way.
30 // Copyright (C) Novell Inc., 2004
35 // $Log: TrackBar.cs,v $
36 // Revision 1.10 2004/08/13 20:55:20 jordi
37 // change from wndproc to events
39 // Revision 1.9 2004/08/13 18:46:26 jordi
40 // adds timer and grap window
42 // Revision 1.8 2004/08/12 20:29:01 jordi
43 // Trackbar enhancement, fix mouse problems, highli thumb, etc
45 // Revision 1.7 2004/08/10 23:27:12 jordi
46 // add missing methods, properties, and restructure to hide extra ones
48 // Revision 1.6 2004/08/10 15:47:11 jackson
49 // Allow control to handle buffering
51 // Revision 1.5 2004/08/07 23:32:26 jordi
52 // throw exceptions of invalid enums values
54 // Revision 1.4 2004/08/06 23:18:06 pbartok
55 // - Fixed some rounding issues with float/int
57 // Revision 1.3 2004/07/27 15:53:02 jordi
58 // fixes trackbar events, def classname, methods signature
60 // Revision 1.2 2004/07/26 17:42:03 jordi
63 // Revision 1.1 2004/07/15 09:38:02 jordi
64 // Horizontal and Vertical TrackBar control implementation
70 using System.ComponentModel;
72 using System.Drawing.Imaging;
73 using System.Drawing.Drawing2D;
76 namespace System.Windows.Forms
78 public class TrackBar : Control, ISupportInitialize
82 private int tickFrequency;
83 private bool autosize;
85 private int smallChange;
86 private int largeChange;
87 private Orientation orientation;
88 private TickStyle tickStyle;
89 private Rectangle paint_area = new Rectangle ();
90 private Rectangle thumb_pos = new Rectangle (); /* Current position and size of the thumb */
91 private Rectangle thumb_area = new Rectangle (); /* Area where the thumb can scroll */
92 private bool thumb_pressed = false;
93 private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
94 private int thumb_mouseclick;
95 private bool mouse_clickmove;
98 public event EventHandler Scroll;
99 public event EventHandler ValueChanged;
104 orientation = Orientation.Horizontal;
110 tickStyle = TickStyle.BottomRight;
115 mouse_clickmove = false;
116 SizeChanged += new System.EventHandler (OnResizeTB);
117 MouseDown += new MouseEventHandler (OnMouseDownTB);
118 MouseUp += new MouseEventHandler (OnMouseUpTB);
120 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
121 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
124 #region Public Properties
126 public bool AutoSize {
127 get { return autosize; }
128 set { autosize = value;}
131 [EditorBrowsable (EditorBrowsableState.Never)]
132 public override Image BackgroundImage {
133 get { return base.BackgroundImage; }
134 set { base.BackgroundImage = value; }
137 protected override CreateParams CreateParams {
139 CreateParams createParams = base.CreateParams;
140 createParams.ClassName = XplatUI.DefaultClassName;
142 createParams.Style = (int) (
143 WindowStyles.WS_CHILD |
144 WindowStyles.WS_VISIBLE);
150 protected override ImeMode DefaultImeMode {
151 get {return ImeMode.Disable; }
154 protected override Size DefaultSize {
155 get { return new System.Drawing.Size (104, 42); }
158 [EditorBrowsable (EditorBrowsableState.Never)]
159 public override Font Font {
160 get { return base.Font; }
161 set { base.Font = value; }
164 [EditorBrowsable (EditorBrowsableState.Never)]
165 public override Color ForeColor {
166 get { return base.ForeColor; }
167 set { base.ForeColor = value; }
170 public int LargeChange {
171 get { return largeChange; }
174 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
182 get { return maximum; }
184 if (maximum != value) {
187 if (maximum < minimum)
196 get { return minimum; }
199 if (Minimum != value) {
202 if (minimum > maximum)
210 public Orientation Orientation {
211 get { return orientation; }
213 if (!Enum.IsDefined (typeof (Orientation), value))
214 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Orientation", value));
216 /* Orientation can be changed once the control has been created */
217 if (orientation != value) {
220 int old_witdh = Width;
228 public int SmallChange {
229 get { return smallChange;}
232 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
234 if (smallChange != value) {
241 [EditorBrowsable (EditorBrowsableState.Never)]
242 public override string Text {
243 get { return base.Text; }
244 set { base.Text = value; }
248 public int TickFrequency {
249 get { return tickFrequency; }
252 tickFrequency = value;
258 public TickStyle TickStyle {
259 get { return tickStyle; }
261 if (!Enum.IsDefined (typeof (TickStyle), value))
262 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for TickStyle", value));
264 if (tickStyle != value) {
272 get { return position; }
274 if (value < Minimum || value > Maximum)
275 throw new ArgumentException(
276 string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
278 if (position != value) {
281 if (ValueChanged != null)
282 ValueChanged (this, new EventArgs ());
289 #endregion //Public Properties
291 #region Public Methods
293 public virtual void BeginInit ()
298 protected override void CreateHandle ()
300 base.CreateHandle ();
304 public virtual void EndInit ()
309 protected override bool IsInputKey (Keys keyData)
314 protected override void OnBackColorChanged (EventArgs e)
319 protected override void OnHandleCreated (EventArgs e)
322 if (Orientation == Orientation.Horizontal)
323 Size = new Size (Width, 40);
325 Size = new Size (50, Height);
328 CreateBuffers (Width, Height);
329 UpdatePos (Value, true);
332 protected override void OnMouseWheel (MouseEventArgs e)
334 if (!Enabled) return;
343 protected virtual void OnScroll (EventArgs e)
349 protected virtual void OnValueChanged (EventArgs e)
351 if (ValueChanged != null)
352 ValueChanged (this, e);
355 public void SetRange (int minValue, int maxValue)
363 public override string ToString()
365 return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
366 Minimum, Maximum, Value);
371 protected override void WndProc (ref Message m)
375 switch ((Msg) m.Msg) {
378 case Msg.WM_MOUSEMOVE:
379 OnMouseMoveTB (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
381 LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
386 PaintEventArgs paint_event;
388 paint_event = XplatUI.PaintEventStart (Handle);
389 OnPaintTB (paint_event);
390 XplatUI.PaintEventEnd (Handle);
395 OnKeyDownTB (new KeyEventArgs ((Keys)m.WParam.ToInt32 ()));
398 case Msg.WM_ERASEBKGND:
399 m.Result = (IntPtr) 1; /* Disable background painting to avoid flickering */
406 base.WndProc (ref m);
409 #endregion Public Methods
411 #region Private Methods
413 private void UpdateArea ()
415 paint_area.X = paint_area.Y = 0;
416 paint_area.Width = Width;
417 paint_area.Height = Height;
420 private void UpdatePos (int newPos, bool update_trumbpos)
424 if (newPos < minimum)
427 if (newPos > maximum)
433 private void LargeIncrement ()
435 UpdatePos (position + LargeChange, true);
437 OnScroll (new EventArgs ());
440 private void LargeDecrement ()
442 UpdatePos (position - LargeChange, true);
444 OnScroll (new EventArgs ());
447 private void SmallIncrement ()
449 UpdatePos (position + SmallChange, true);
451 OnScroll (new EventArgs ());
454 private void SmallDecrement ()
456 UpdatePos (position - SmallChange, true);
458 OnScroll (new EventArgs ());
463 float ticks = (Maximum - Minimum) / tickFrequency; /* N of ticks draw*/
466 ThemeEngine.Current.DrawTrackBar (DeviceContext, paint_area, this,
467 ref thumb_pos, ref thumb_area, thumb_pressed, ticks, thumb_mouseclick, true);
469 ThemeEngine.Current.DrawTrackBar (DeviceContext, paint_area, this,
470 ref thumb_pos, ref thumb_area, thumb_pressed, ticks, Value - Minimum, false);
474 private void OnMouseUpTB (object sender, MouseEventArgs e)
476 if (!Enabled) return;
478 if (thumb_pressed == true || mouse_clickmove == true) {
479 thumb_pressed = false;
480 holdclick_timer.Enabled = false;
481 XplatUI.ReleaseWindow (Handle);
486 private void OnMouseDownTB (object sender, MouseEventArgs e)
488 if (!Enabled) return;
490 bool fire_timer = false;
492 Point point = new Point (e.X, e.Y);
494 if (orientation == Orientation.Horizontal) {
496 if (thumb_pos.Contains (point)) {
497 XplatUI.GrabWindow (Handle);
498 thumb_pressed = true;
499 thumb_mouseclick = e.X;
503 if (paint_area.Contains (point)) {
504 if (e.X > thumb_pos.X + thumb_pos.Width)
511 mouse_clickmove = true;
516 if (thumb_pos.Contains (point)) {
517 XplatUI.GrabWindow (Handle);
518 thumb_pressed = true;
519 thumb_mouseclick = e.Y;
524 if (paint_area.Contains (point)) {
525 if (e.Y > thumb_pos.Y + thumb_pos.Height)
532 mouse_clickmove = true;
538 holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
\r
539 holdclick_timer.Interval = 300;
\r
540 holdclick_timer.Enabled = true;
544 private void OnMouseMoveTB (MouseEventArgs e)
546 if (!Enabled) return;
548 Point pnt = new Point (e.X, e.Y);
550 /* Moving the thumb */
553 if (orientation == Orientation.Horizontal){
554 if (paint_area.Contains (e.X, thumb_pos.Y))
555 thumb_mouseclick = e.X;
558 if (paint_area.Contains (thumb_pos.X, e.Y))
559 thumb_mouseclick = e.Y;
563 OnScroll (new EventArgs ());
567 private void OnResizeTB (object sender, System.EventArgs e)
569 if (Width <= 0 || Height <= 0)
573 CreateBuffers (Width, Height);
576 private void OnPaintTB (PaintEventArgs pevent)
578 if (Width <= 0 || Height <= 0 || Visible == false)
581 /* Copies memory drawing buffer to screen*/
584 pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
587 private void OnKeyDownTB (KeyEventArgs e)
\r
589 switch (e.KeyCode) {
\r
605 private void OnFirstClickTimer (Object source, ElapsedEventArgs e)
\r
608 pnt = PointToClient (MousePosition);
\r
610 if (thumb_area.Contains (pnt)) {
\r
611 if (orientation == Orientation.Horizontal) {
\r
612 if (pnt.X > thumb_pos.X + thumb_pos.Width)
615 if (pnt.X < thumb_pos.X)
616 LargeDecrement ();
\r
619 if (pnt.Y > thumb_pos.Y + thumb_pos.Height)
622 if (pnt.Y < thumb_pos.Y)
631 #endregion // Private Methods