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 // Copyright (c) 2004-2005 Novell, Inc.
27 // Jordi Mas i Hernandez, jordi@ximian.com
30 // - The AutoSize functionality seems quite broken for vertical controls in .Net 1.1. Not
31 // sure if we are implementing it the right way.
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
40 using System.Drawing.Imaging;
41 using System.Drawing.Drawing2D;
44 namespace System.Windows.Forms
46 [Designer("System.Windows.Forms.Design.TrackBarDesigner, " + Consts.AssemblySystem_Design)]
47 [DefaultEvent ("Scroll")]
48 [DefaultProperty("Value")]
49 public class TrackBar : Control, ISupportInitialize
53 internal int tickFrequency;
54 private bool autosize;
56 private int smallChange;
57 private int largeChange;
58 private Orientation orientation;
59 private TickStyle tickStyle;
60 private Rectangle thumb_pos = new Rectangle (); /* Current position and size of the thumb */
61 private Rectangle thumb_area = new Rectangle (); /* Area where the thumb can scroll */
62 internal bool thumb_pressed = false;
63 private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
64 internal int thumb_mouseclick;
65 private bool mouse_clickmove;
69 [EditorBrowsable (EditorBrowsableState.Never)]
70 public new event EventHandler BackgroundImageChanged;
73 [EditorBrowsable (EditorBrowsableState.Never)]
74 public new event EventHandler Click;
77 [EditorBrowsable (EditorBrowsableState.Never)]
78 public new event EventHandler DoubleClick;
81 [EditorBrowsable (EditorBrowsableState.Never)]
82 public new event EventHandler FontChanged;
85 [EditorBrowsable (EditorBrowsableState.Never)]
86 public new event EventHandler ForeColorChanged;
89 [EditorBrowsable (EditorBrowsableState.Never)]
90 public new event EventHandler ImeModeChanged;
93 [EditorBrowsable (EditorBrowsableState.Never)]
94 public new event PaintEventHandler Paint;
96 public event EventHandler Scroll;
99 [EditorBrowsable (EditorBrowsableState.Never)]
100 public new event EventHandler TextChanged;
101 public event EventHandler ValueChanged;
107 orientation = Orientation.Horizontal;
113 tickStyle = TickStyle.BottomRight;
116 mouse_clickmove = false;
117 MouseDown += new MouseEventHandler (OnMouseDownTB);
118 MouseUp += new MouseEventHandler (OnMouseUpTB);
119 MouseMove += new MouseEventHandler (OnMouseMoveTB);
120 holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
122 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
123 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
126 #region Private & Internal Properties
127 internal Rectangle ThumbPos {
137 internal Rectangle ThumbArea {
146 #endregion // Private & Internal Properties
148 #region Public Properties
150 [DefaultValue (true)]
151 public bool AutoSize {
152 get { return autosize; }
153 set { autosize = value;}
156 [EditorBrowsable (EditorBrowsableState.Never)]
158 public override Image BackgroundImage {
159 get { return base.BackgroundImage; }
161 if (base.BackgroundImage == value)
164 if (BackgroundImageChanged != null)
165 BackgroundImageChanged (this, EventArgs.Empty);
167 base.BackgroundImage = value;
171 protected override CreateParams CreateParams {
173 CreateParams createParams = base.CreateParams;
174 createParams.ClassName = XplatUI.DefaultClassName;
176 createParams.Style = (int) (
177 WindowStyles.WS_CHILD |
178 WindowStyles.WS_VISIBLE);
184 protected override ImeMode DefaultImeMode {
185 get {return ImeMode.Disable; }
188 protected override Size DefaultSize {
189 get { return ThemeEngine.Current.TrackBarDefaultSize; }
193 [EditorBrowsable (EditorBrowsableState.Never)]
194 public override Font Font {
195 get { return base.Font; }
196 set { base.Font = value; }
199 [EditorBrowsable (EditorBrowsableState.Never)]
201 public override Color ForeColor {
202 get { return base.ForeColor; }
204 if (value == base.ForeColor)
207 if (ForeColorChanged != null)
208 ForeColorChanged (this, EventArgs.Empty);
214 [EditorBrowsable (EditorBrowsableState.Never)]
216 public new ImeMode ImeMode {
217 get { return base.ImeMode; }
219 if (value == base.ImeMode)
222 base.ImeMode = value;
223 if (ImeModeChanged != null)
224 ImeModeChanged (this, EventArgs.Empty);
229 public int LargeChange
\r
231 get { return largeChange; }
234 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
241 [RefreshProperties (RefreshProperties.All)]
243 get { return maximum; }
245 if (maximum != value) {
248 if (maximum < minimum)
257 [RefreshProperties (RefreshProperties.All)]
259 get { return minimum; }
262 if (Minimum != value) {
265 if (minimum > maximum)
273 [DefaultValue (Orientation.Horizontal)]
275 public Orientation Orientation {
276 get { return orientation; }
278 if (!Enum.IsDefined (typeof (Orientation), value))
279 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Orientation", value));
281 /* Orientation can be changed once the control has been created */
282 if (orientation != value) {
285 int old_witdh = Width;
294 public int SmallChange {
295 get { return smallChange;}
298 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
300 if (smallChange != value) {
306 [EditorBrowsable (EditorBrowsableState.Never)]
309 public override string Text {
310 get { return base.Text; }
312 if (value == base.Text)
315 if (TextChanged != null)
316 TextChanged (this, EventArgs.Empty);
323 public int TickFrequency {
324 get { return tickFrequency; }
327 tickFrequency = value;
333 [DefaultValue (TickStyle.BottomRight)]
334 public TickStyle TickStyle {
335 get { return tickStyle; }
337 if (!Enum.IsDefined (typeof (TickStyle), value))
338 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for TickStyle", value));
340 if (tickStyle != value) {
350 get { return position; }
352 if (value < Minimum || value > Maximum)
353 throw new ArgumentException(
354 string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
356 if (position != value) {
359 if (ValueChanged != null)
360 ValueChanged (this, new EventArgs ());
362 Invalidate (thumb_area);
367 #endregion //Public Properties
369 #region Public Methods
371 public virtual void BeginInit ()
376 protected override void CreateHandle ()
378 base.CreateHandle ();
382 public virtual void EndInit ()
387 protected override bool IsInputKey (Keys keyData)
389 return base.IsInputKey (keyData);
392 protected override void OnBackColorChanged (EventArgs e)
394 base.OnBackColorChanged (e);
397 protected override void OnHandleCreated (EventArgs e)
399 base.OnHandleCreated (e);
402 if (Orientation == Orientation.Horizontal)
403 Size = new Size (Width, 40);
405 Size = new Size (50, Height);
407 UpdatePos (Value, true);
410 [EditorBrowsable (EditorBrowsableState.Advanced)]
411 protected override void OnMouseWheel (MouseEventArgs e)
413 if (!Enabled) return;
420 base.OnMouseWheel (e);
424 protected virtual void OnScroll (EventArgs e)
430 protected virtual void OnValueChanged (EventArgs e)
432 if (ValueChanged != null)
433 ValueChanged (this, e);
436 public void SetRange (int minValue, int maxValue)
442 public override string ToString()
444 return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
445 Minimum, Maximum, Value);
449 protected override void WndProc (ref Message m)
451 switch ((Msg) m.Msg) {
454 PaintEventArgs paint_event;
456 paint_event = XplatUI.PaintEventStart (Handle);
457 OnPaintTB (paint_event);
458 XplatUI.PaintEventEnd (Handle);
463 OnKeyDownTB (new KeyEventArgs ((Keys)m.WParam.ToInt32 ()));
466 case Msg.WM_ERASEBKGND:
467 m.Result = (IntPtr) 1; /* Disable background painting to avoid flickering */
474 base.WndProc (ref m);
477 #endregion Public Methods
479 #region Private Methods
481 private void UpdatePos (int newPos, bool update_trumbpos)
483 if (newPos < minimum){
487 if (newPos > maximum) {
496 private void LargeIncrement ()
498 UpdatePos (position + LargeChange, true);
499 Invalidate (thumb_area);
500 OnScroll (new EventArgs ());
503 private void LargeDecrement ()
505 UpdatePos (position - LargeChange, true);
506 Invalidate (thumb_area);
507 OnScroll (new EventArgs ());
510 private void SmallIncrement ()
512 UpdatePos (position + SmallChange, true);
513 Invalidate (thumb_area);
514 OnScroll (new EventArgs ());
517 private void SmallDecrement ()
519 UpdatePos (position - SmallChange, true);
520 Invalidate (thumb_area);
521 OnScroll (new EventArgs ());
524 private void Draw (Rectangle clip)
526 ThemeEngine.Current.DrawTrackBar (DeviceContext, clip, this);
529 private void OnMouseUpTB (object sender, MouseEventArgs e)
531 if (!Enabled) return;
533 if (thumb_pressed == true || mouse_clickmove == true) {
534 thumb_pressed = false;
535 holdclick_timer.Enabled = false;
536 this.Capture = false;
537 Invalidate (thumb_area);
541 private void OnMouseDownTB (object sender, MouseEventArgs e)
543 if (!Enabled) return;
545 bool fire_timer = false;
547 Point point = new Point (e.X, e.Y);
549 if (orientation == Orientation.Horizontal) {
551 if (thumb_pos.Contains (point)) {
553 thumb_pressed = true;
554 thumb_mouseclick = e.X;
555 Invalidate (thumb_area);
558 if (ClientRectangle.Contains (point)) {
559 if (e.X > thumb_pos.X + thumb_pos.Width)
564 Invalidate (thumb_area);
566 mouse_clickmove = true;
571 if (thumb_pos.Contains (point)) {
573 thumb_pressed = true;
574 thumb_mouseclick = e.Y;
575 Invalidate (thumb_area);
579 if (ClientRectangle.Contains (point)) {
580 if (e.Y > thumb_pos.Y + thumb_pos.Height)
585 Invalidate (thumb_area);
587 mouse_clickmove = true;
593 holdclick_timer.Interval = 300;
\r
594 holdclick_timer.Enabled = true;
598 private void OnMouseMoveTB (object sender, MouseEventArgs e)
600 if (!Enabled) return;
602 /* Moving the thumb */
605 if (orientation == Orientation.Horizontal){
606 if (ClientRectangle.Contains (e.X, thumb_pos.Y))
607 thumb_mouseclick = e.X;
610 if (ClientRectangle.Contains (thumb_pos.X, e.Y))
611 thumb_mouseclick = e.Y;
614 Invalidate (thumb_area);
615 OnScroll (new EventArgs ());
620 private void OnPaintTB (PaintEventArgs pevent)
623 Paint (this, pevent);
626 if (Width <= 0 || Height <= 0 || Visible == false)
629 /* Copies memory drawing buffer to screen */
630 Draw (pevent.ClipRectangle);
631 pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
634 private void OnKeyDownTB (KeyEventArgs e)
\r
636 switch (e.KeyCode) {
\r
669 private void OnFirstClickTimer (Object source, ElapsedEventArgs e)
\r
672 pnt = PointToClient (MousePosition);
\r
674 if (thumb_area.Contains (pnt)) {
\r
675 if (orientation == Orientation.Horizontal) {
\r
676 if (pnt.X > thumb_pos.X + thumb_pos.Width)
679 if (pnt.X < thumb_pos.X)
680 LargeDecrement ();
\r
683 if (pnt.Y > thumb_pos.Y + thumb_pos.Height)
686 if (pnt.Y < thumb_pos.Y)
690 Invalidate (thumb_area);
695 protected override void SetBoundsCore (int x, int y,int width, int height, BoundsSpecified specified)
697 base.SetBoundsCore (x, y,width, height, specified);
701 #endregion // Private Methods