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.15 2004/10/05 04:56:12 jackson
37 // Let the base Control handle the buffers, derived classes should not have to CreateBuffers themselves.
39 // Revision 1.14 2004/09/28 18:44:25 pbartok
40 // - Streamlined Theme interfaces:
41 // * Each DrawXXX method for a control now is passed the object for the
42 // control to be drawn in order to allow accessing any state the theme
45 // * ControlPaint methods for the theme now have a CP prefix to avoid
46 // name clashes with the Draw methods for controls
48 // * Every control now retrieves it's DefaultSize from the current theme
50 // Revision 1.13 2004/08/23 20:10:03 jordi
51 // fixes properties and methods
53 // Revision 1.12 2004/08/21 20:21:48 pbartok
54 // - Replaced direct XplatUI calls with their Control counterpart
56 // Revision 1.11 2004/08/20 19:45:50 jordi
57 // fixes timer, new properties and methods
59 // Revision 1.10 2004/08/13 20:55:20 jordi
60 // change from wndproc to events
62 // Revision 1.9 2004/08/13 18:46:26 jordi
63 // adds timer and grap window
65 // Revision 1.8 2004/08/12 20:29:01 jordi
66 // Trackbar enhancement, fix mouse problems, highli thumb, etc
68 // Revision 1.7 2004/08/10 23:27:12 jordi
69 // add missing methods, properties, and restructure to hide extra ones
71 // Revision 1.6 2004/08/10 15:47:11 jackson
72 // Allow control to handle buffering
74 // Revision 1.5 2004/08/07 23:32:26 jordi
75 // throw exceptions of invalid enums values
77 // Revision 1.4 2004/08/06 23:18:06 pbartok
78 // - Fixed some rounding issues with float/int
80 // Revision 1.3 2004/07/27 15:53:02 jordi
81 // fixes trackbar events, def classname, methods signature
83 // Revision 1.2 2004/07/26 17:42:03 jordi
86 // Revision 1.1 2004/07/15 09:38:02 jordi
87 // Horizontal and Vertical TrackBar control implementation
93 using System.ComponentModel;
95 using System.Drawing.Imaging;
96 using System.Drawing.Drawing2D;
99 namespace System.Windows.Forms
102 [DefaultEvent ("Scroll")]
103 public class TrackBar : Control, ISupportInitialize
107 internal int tickFrequency;
108 private bool autosize;
109 private int position;
110 private int smallChange;
111 private int largeChange;
112 private Orientation orientation;
113 private TickStyle tickStyle;
114 internal Rectangle paint_area = new Rectangle ();
115 private Rectangle thumb_pos = new Rectangle (); /* Current position and size of the thumb */
116 private Rectangle thumb_area = new Rectangle (); /* Area where the thumb can scroll */
117 internal bool thumb_pressed = false;
118 private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
119 internal int thumb_mouseclick;
120 private bool mouse_clickmove;
123 public event EventHandler Scroll;
124 public event EventHandler ValueChanged;
125 public new event EventHandler ImeModeChanged;
126 public new event EventHandler ForeColorChanged;
127 public new event EventHandler TextChanged;
128 public new event EventHandler BackgroundImageChanged;
133 orientation = Orientation.Horizontal;
139 tickStyle = TickStyle.BottomRight;
144 mouse_clickmove = false;
145 SizeChanged += new System.EventHandler (OnResizeTB);
146 MouseDown += new MouseEventHandler (OnMouseDownTB);
147 MouseUp += new MouseEventHandler (OnMouseUpTB);
148 MouseMove += new MouseEventHandler (OnMouseMoveTB);
149 holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
151 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
152 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
155 #region Private & Internal Properties
156 internal Rectangle ThumbPos {
166 internal Rectangle ThumbArea {
175 #endregion // Private & Internal Properties
177 #region Public Properties
179 [DefaultValue (true)]
180 public bool AutoSize {
181 get { return autosize; }
182 set { autosize = value;}
185 [EditorBrowsable (EditorBrowsableState.Never)]
186 public override Image BackgroundImage {
187 get { return base.BackgroundImage; }
189 if (base.BackgroundImage == value)
192 if (BackgroundImageChanged != null)
193 BackgroundImageChanged (this, EventArgs.Empty);
195 base.BackgroundImage = value;
199 protected override CreateParams CreateParams {
201 CreateParams createParams = base.CreateParams;
202 createParams.ClassName = XplatUI.DefaultClassName;
204 createParams.Style = (int) (
205 WindowStyles.WS_CHILD |
206 WindowStyles.WS_VISIBLE);
212 protected override ImeMode DefaultImeMode {
213 get {return ImeMode.Disable; }
216 protected override Size DefaultSize {
217 get { return ThemeEngine.Current.TrackBarDefaultSize; }
220 [EditorBrowsable (EditorBrowsableState.Never)]
221 public override Font Font {
222 get { return base.Font; }
223 set { base.Font = value; }
226 [EditorBrowsable (EditorBrowsableState.Never)]
227 public override Color ForeColor {
228 get { return base.ForeColor; }
230 if (value == base.ForeColor)
233 if (ForeColorChanged != null)
234 ForeColorChanged (this, EventArgs.Empty);
240 [EditorBrowsable (EditorBrowsableState.Never)]
241 public new ImeMode ImeMode {
242 get { return base.ImeMode; }
244 if (value == base.ImeMode)
247 base.ImeMode = value;
248 if (ImeModeChanged != null)
249 ImeModeChanged (this, EventArgs.Empty);
254 public int LargeChange
\r
256 get { return largeChange; }
259 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
267 [RefreshProperties (RefreshProperties.All)]
269 get { return maximum; }
271 if (maximum != value) {
274 if (maximum < minimum)
283 [RefreshProperties (RefreshProperties.All)]
285 get { return minimum; }
288 if (Minimum != value) {
291 if (minimum > maximum)
299 [DefaultValue (Orientation.Horizontal)]
301 public Orientation Orientation {
302 get { return orientation; }
304 if (!Enum.IsDefined (typeof (Orientation), value))
305 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Orientation", value));
307 /* Orientation can be changed once the control has been created */
308 if (orientation != value) {
311 int old_witdh = Width;
320 public int SmallChange {
321 get { return smallChange;}
324 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
326 if (smallChange != value) {
333 [EditorBrowsable (EditorBrowsableState.Never)]
335 public override string Text {
336 get { return base.Text; }
338 if (value == base.Text)
341 if (TextChanged != null)
342 TextChanged (this, EventArgs.Empty);
349 public int TickFrequency {
350 get { return tickFrequency; }
353 tickFrequency = value;
359 [DefaultValue (TickStyle.BottomRight)]
360 public TickStyle TickStyle {
361 get { return tickStyle; }
363 if (!Enum.IsDefined (typeof (TickStyle), value))
364 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for TickStyle", value));
366 if (tickStyle != value) {
376 get { return position; }
378 if (value < Minimum || value > Maximum)
379 throw new ArgumentException(
380 string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
382 if (position != value) {
385 if (ValueChanged != null)
386 ValueChanged (this, new EventArgs ());
393 #endregion //Public Properties
395 #region Public Methods
397 public virtual void BeginInit ()
402 protected override void CreateHandle ()
404 base.CreateHandle ();
408 public virtual void EndInit ()
413 protected override bool IsInputKey (Keys keyData)
418 protected override void OnBackColorChanged (EventArgs e)
423 protected override void OnHandleCreated (EventArgs e)
426 if (Orientation == Orientation.Horizontal)
427 Size = new Size (Width, 40);
429 Size = new Size (50, Height);
432 UpdatePos (Value, true);
435 [EditorBrowsable (EditorBrowsableState.Advanced)]
436 protected override void OnMouseWheel (MouseEventArgs e)
438 if (!Enabled) return;
445 base.OnMouseWheel (e);
449 protected virtual void OnScroll (EventArgs e)
455 protected virtual void OnValueChanged (EventArgs e)
457 if (ValueChanged != null)
458 ValueChanged (this, e);
461 public void SetRange (int minValue, int maxValue)
469 public override string ToString()
471 return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
472 Minimum, Maximum, Value);
476 protected override void WndProc (ref Message m)
478 switch ((Msg) m.Msg) {
481 PaintEventArgs paint_event;
483 paint_event = XplatUI.PaintEventStart (Handle);
484 OnPaintTB (paint_event);
485 XplatUI.PaintEventEnd (Handle);
490 OnKeyDownTB (new KeyEventArgs ((Keys)m.WParam.ToInt32 ()));
493 case Msg.WM_ERASEBKGND:
494 m.Result = (IntPtr) 1; /* Disable background painting to avoid flickering */
501 base.WndProc (ref m);
504 #endregion Public Methods
506 #region Private Methods
508 private void UpdateArea ()
510 paint_area.X = paint_area.Y = 0;
511 paint_area.Width = Width;
512 paint_area.Height = Height;
515 private void UpdatePos (int newPos, bool update_trumbpos)
519 if (newPos < minimum)
522 if (newPos > maximum)
528 private void LargeIncrement ()
530 UpdatePos (position + LargeChange, true);
532 OnScroll (new EventArgs ());
535 private void LargeDecrement ()
537 UpdatePos (position - LargeChange, true);
539 OnScroll (new EventArgs ());
542 private void SmallIncrement ()
544 UpdatePos (position + SmallChange, true);
546 OnScroll (new EventArgs ());
549 private void SmallDecrement ()
551 UpdatePos (position - SmallChange, true);
553 OnScroll (new EventArgs ());
558 float ticks = (Maximum - Minimum) / tickFrequency; /* N of ticks draw*/
560 ThemeEngine.Current.DrawTrackBar(DeviceContext, this.ClientRectangle, this);
563 private void OnMouseUpTB (object sender, MouseEventArgs e)
565 if (!Enabled) return;
567 if (thumb_pressed == true || mouse_clickmove == true) {
568 thumb_pressed = false;
569 holdclick_timer.Enabled = false;
570 this.Capture = false;
575 private void OnMouseDownTB (object sender, MouseEventArgs e)
577 if (!Enabled) return;
579 bool fire_timer = false;
581 Point point = new Point (e.X, e.Y);
583 if (orientation == Orientation.Horizontal) {
585 if (thumb_pos.Contains (point)) {
587 thumb_pressed = true;
588 thumb_mouseclick = e.X;
592 if (paint_area.Contains (point)) {
593 if (e.X > thumb_pos.X + thumb_pos.Width)
600 mouse_clickmove = true;
605 if (thumb_pos.Contains (point)) {
607 thumb_pressed = true;
608 thumb_mouseclick = e.Y;
613 if (paint_area.Contains (point)) {
614 if (e.Y > thumb_pos.Y + thumb_pos.Height)
621 mouse_clickmove = true;
627 holdclick_timer.Interval = 300;
\r
628 holdclick_timer.Enabled = true;
632 private void OnMouseMoveTB (object sender, MouseEventArgs e)
634 if (!Enabled) return;
636 Point pnt = new Point (e.X, e.Y);
638 /* Moving the thumb */
641 if (orientation == Orientation.Horizontal){
642 if (paint_area.Contains (e.X, thumb_pos.Y))
643 thumb_mouseclick = e.X;
646 if (paint_area.Contains (thumb_pos.X, e.Y))
647 thumb_mouseclick = e.Y;
651 OnScroll (new EventArgs ());
655 private void OnResizeTB (object sender, System.EventArgs e)
657 if (Width <= 0 || Height <= 0)
663 private void OnPaintTB (PaintEventArgs pevent)
665 if (Width <= 0 || Height <= 0 || Visible == false)
668 /* Copies memory drawing buffer to screen*/
671 pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
674 private void OnKeyDownTB (KeyEventArgs e)
\r
676 switch (e.KeyCode) {
\r
692 private void OnFirstClickTimer (Object source, ElapsedEventArgs e)
\r
695 pnt = PointToClient (MousePosition);
\r
697 if (thumb_area.Contains (pnt)) {
\r
698 if (orientation == Orientation.Horizontal) {
\r
699 if (pnt.X > thumb_pos.X + thumb_pos.Width)
702 if (pnt.X < thumb_pos.X)
703 LargeDecrement ();
\r
706 if (pnt.Y > thumb_pos.Y + thumb_pos.Height)
709 if (pnt.Y < thumb_pos.Y)
718 protected override void SetBoundsCore (int x, int y,int width, int height, BoundsSpecified specified)
720 base.SetBoundsCore (x, y,width, height, specified);
724 #endregion // Private Methods