// Jordi Mas i Hernandez, jordi@ximian.com
//
// TODO:
-// - Draging the thumb does not behave exactly like in Win32
// - The AutoSize functionality seems quite broken for vertical controls in .Net 1.1. Not
// sure if we are implementing it the right way.
-// - Vertical orientation still needs some work
-// - OnMouseWheel event
//
// Copyright (C) Novell Inc., 2004
//
//
-// $Revision: 1.3 $
+// $Revision: 1.12 $
// $Modtime: $
// $Log: TrackBar.cs,v $
+// Revision 1.12 2004/08/21 20:21:48 pbartok
+// - Replaced direct XplatUI calls with their Control counterpart
+//
+// Revision 1.11 2004/08/20 19:45:50 jordi
+// fixes timer, new properties and methods
+//
+// Revision 1.10 2004/08/13 20:55:20 jordi
+// change from wndproc to events
+//
+// Revision 1.9 2004/08/13 18:46:26 jordi
+// adds timer and grap window
+//
+// Revision 1.8 2004/08/12 20:29:01 jordi
+// Trackbar enhancement, fix mouse problems, highli thumb, etc
+//
+// Revision 1.7 2004/08/10 23:27:12 jordi
+// add missing methods, properties, and restructure to hide extra ones
+//
+// Revision 1.6 2004/08/10 15:47:11 jackson
+// Allow control to handle buffering
+//
+// Revision 1.5 2004/08/07 23:32:26 jordi
+// throw exceptions of invalid enums values
+//
+// Revision 1.4 2004/08/06 23:18:06 pbartok
+// - Fixed some rounding issues with float/int
+//
// Revision 1.3 2004/07/27 15:53:02 jordi
// fixes trackbar events, def classname, methods signature
//
//
//
+// NOT COMPLETE
+
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
+using System.Timers;
namespace System.Windows.Forms
{
private int largeChange;
private Orientation orientation;
private TickStyle tickStyle;
- private Bitmap bmp_mem = null;
- private Graphics dc_mem = null;
private Rectangle paint_area = new Rectangle ();
private Rectangle thumb_pos = new Rectangle (); /* Current position and size of the thumb */
private Rectangle thumb_area = new Rectangle (); /* Area where the thumb can scroll */
- private bool thumb_pressed = false;
- private int thumb_pixel_click_move;
- private float pixel_per_pos = 0;
+ private bool thumb_pressed = false;
+ private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
+ private int thumb_mouseclick;
+ private bool mouse_clickmove;
#region Events
public event EventHandler Scroll;
public event EventHandler ValueChanged;
-
+ public new event EventHandler ImeModeChanged;
+ public new event EventHandler ForeColorChanged;
+ public new event EventHandler TextChanged;
#endregion // Events
public TrackBar ()
largeChange = 5;
Scroll = null;
ValueChanged = null;
+ mouse_clickmove = false;
+ SizeChanged += new System.EventHandler (OnResizeTB);
+ MouseDown += new MouseEventHandler (OnMouseDownTB);
+ MouseUp += new MouseEventHandler (OnMouseUpTB);
+ holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
set { autosize = value;}
}
+ [EditorBrowsable (EditorBrowsableState.Never)]
public override Image BackgroundImage {
get { return base.BackgroundImage; }
set { base.BackgroundImage = value; }
}
+ protected override CreateParams CreateParams {
+ get {
+ CreateParams createParams = base.CreateParams;
+ createParams.ClassName = XplatUI.DefaultClassName;
+
+ createParams.Style = (int) (
+ WindowStyles.WS_CHILD |
+ WindowStyles.WS_VISIBLE);
+
+ return createParams;
+ }
+ }
+
+ protected override ImeMode DefaultImeMode {
+ get {return ImeMode.Disable; }
+ }
+
+ protected override Size DefaultSize {
+ get { return new System.Drawing.Size (104, 42); }
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Never)]
public override Font Font {
get { return base.Font; }
set { base.Font = value; }
}
+ [EditorBrowsable (EditorBrowsableState.Never)]
public override Color ForeColor {
get { return base.ForeColor; }
- set { base.ForeColor = value; }
- }
+ set {
+ if (value == base.ForeColor)
+ return;
+
+ if (ForeColorChanged != null)
+ ForeColorChanged (this, EventArgs.Empty);
+ Refresh ();
+ }
+ }
- public int LargeChange {
+ public new ImeMode ImeMode {
+ get { return base.ImeMode; }
+ set {
+ if (value == base.ImeMode)
+ return;
+
+ base.ImeMode = value;
+ if (ImeModeChanged != null)
+ ImeModeChanged (this, EventArgs.Empty);
+ }
+ }
+
+ public int LargeChange \r
+ {
get { return largeChange; }
set {
if (value < 0)
throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
largeChange = value;
- Invalidate ();
+ Refresh ();
}
}
public int Maximum {
get { return maximum; }
set {
- maximum = value;
+ if (maximum != value) {
+ maximum = value;
- if (maximum < minimum)
- minimum = maximum;
+ if (maximum < minimum)
+ minimum = maximum;
- Invalidate ();
+ Refresh ();
+ }
}
}
public int Minimum {
get { return minimum; }
set {
- minimum = value;
- if (minimum > maximum)
- maximum = minimum;
+ if (Minimum != value) {
+ minimum = value;
+
+ if (minimum > maximum)
+ maximum = minimum;
- Invalidate ();
+ Refresh ();
+ }
}
}
public Orientation Orientation {
get { return orientation; }
set {
- /* Orientation can be changed once the control has been created*/
- orientation = value;
+ if (!Enum.IsDefined (typeof (Orientation), value))
+ throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Orientation", value));
+
+ /* Orientation can be changed once the control has been created */
+ if (orientation != value) {
+ orientation = value;
- int old_witdh = Width;
- Width = Height;
- Height = old_witdh;
- Invalidate();
+ int old_witdh = Width;
+ Width = Height;
+ Height = old_witdh;
+ Refresh ();
+ }
}
}
if ( value < 0 )
throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
- smallChange = value;
- Invalidate ();
+ if (smallChange != value) {
+ smallChange = value;
+ Refresh ();
+ }
}
}
-
+ [EditorBrowsable (EditorBrowsableState.Never)]
public override string Text {
- get { return base.Text; }
- set { base.Text = value; }
+ get { return base.Text; }
+ set {
+ if (value == base.Text)
+ return;
+
+ if (TextChanged != null)
+ TextChanged (this, EventArgs.Empty);
+
+ Refresh ();
+ }
}
set {
if ( value > 0 ) {
tickFrequency = value;
- Invalidate ();
+ Refresh ();
}
}
}
public TickStyle TickStyle {
get { return tickStyle; }
- set { tickStyle = value ;}
+ set {
+ if (!Enum.IsDefined (typeof (TickStyle), value))
+ throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for TickStyle", value));
+
+ if (tickStyle != value) {
+ tickStyle = value;
+ Refresh ();
+ }
+ }
}
-
public int Value {
get { return position; }
set {
if (ValueChanged != null)
ValueChanged (this, new EventArgs ());
- Invalidate ();
+ Refresh ();
}
}
}
#region Public Methods
- public void SetRange (int minValue, int maxValue)
+ public virtual void BeginInit ()
{
- Minimum = minValue;
- Maximum = maxValue;
- Invalidate ();
}
- public override string ToString()
+ protected override void CreateHandle ()
{
- return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
- Minimum, Maximum, Value);
+ base.CreateHandle ();
}
- protected override CreateParams CreateParams {
- get {
- CreateParams createParams = base.CreateParams;
- createParams.ClassName = XplatUI.DefaultClassName;
- createParams.Style = (int) (
- WindowStyles.WS_CHILD |
- WindowStyles.WS_VISIBLE);
+ public virtual void EndInit ()
+ {
- return createParams;
- }
}
- protected override ImeMode DefaultImeMode {
- get {return ImeMode.Disable; }
+ protected override bool IsInputKey (Keys keyData)
+ {
+ return false;
}
- protected override Size DefaultSize {
- get { return new System.Drawing.Size (104, 42); }
- }
-
- public virtual void BeginInit()
+ protected override void OnBackColorChanged (EventArgs e)
{
}
- public virtual void EndInit()
- {
+ protected override void OnHandleCreated (EventArgs e)
+ {
+ if (AutoSize)
+ if (Orientation == Orientation.Horizontal)
+ Size = new Size (Width, 40);
+ else
+ Size = new Size (50, Height);
+ UpdateArea ();
+ CreateBuffers (Width, Height);
+ UpdatePos (Value, true);
}
- #endregion Public Methods
-
- #region Private Methods
+ protected override void OnMouseWheel (MouseEventArgs e)
+ {
+ if (!Enabled) return;
+
+ if (e.Delta > 0)
+ SmallDecrement ();
+ else
+ SmallIncrement ();
+
+ }
- private void fire_scroll_event ()
+ protected virtual void OnScroll (EventArgs e)
{
- if (Scroll == null)
- return;
+ if (Scroll != null)
+ Scroll (this, e);
+ }
- Scroll (this, new EventArgs ());
+ protected virtual void OnValueChanged (EventArgs e)
+ {
+ if (ValueChanged != null)
+ ValueChanged (this, e);
}
- private void UpdateArea ()
+ public void SetRange (int minValue, int maxValue)
{
- paint_area.X = paint_area.Y = 0;
- paint_area.Width = Width;
- paint_area.Height = Height;
+ Minimum = minValue;
+ Maximum = maxValue;
- UpdatePixelPerPos ();
- //Console.WriteLine ("UpdateArea: {0} {1} {2}", thumb_area.Width, thumb_pos.Width, pixel_per_pos);
+ Refresh ();
+ }
+ public override string ToString()
+ {
+ return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
+ Minimum, Maximum, Value);
}
+
+
- private void UpdateThumbPos (int pixel, bool update_value)
+ protected override void WndProc (ref Message m)
{
- float new_pos = 0;
- //Console.WriteLine ("UpdateThumbPos: " + pixel + " per " + pixel_per_pos);
-
- if (orientation == Orientation.Horizontal) {
-
- if (pixel < thumb_area.X)
- thumb_pos.X = thumb_area.X;
- else
- if (pixel > thumb_area.X + thumb_area.Width - thumb_pos.Width)
- thumb_pos.X = thumb_area.X + thumb_area.Width - thumb_pos.Width;
- else
- thumb_pos.X = pixel;
+ int clicks = 1;
- new_pos = (float) (thumb_pos.X - thumb_area.X);
- new_pos = new_pos / pixel_per_pos;
-
- } else {
-
- if (pixel < thumb_area.Y)
- thumb_pos.Y = thumb_area.Y;
- else
- if (pixel > thumb_area.Y + thumb_area.Height - thumb_pos.Height)
- thumb_pos.Y = thumb_area.Y + thumb_area.Height - thumb_pos.Height;
- else
- thumb_pos.Y = pixel;
+ switch ((Msg) m.Msg) {
+
+
+ case Msg.WM_MOUSEMOVE:
+ OnMouseMoveTB (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ clicks,
+ LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
+ 0));
+ break;
+
+ case Msg.WM_PAINT: {
+ PaintEventArgs paint_event;
- new_pos = (float) (thumb_pos.Y - thumb_area.Y);
- new_pos = new_pos / pixel_per_pos;
+ paint_event = XplatUI.PaintEventStart (Handle);
+ OnPaintTB (paint_event);
+ XplatUI.PaintEventEnd (Handle);
+ return;
+ }
+ case Msg.WM_KEYDOWN:
+ OnKeyDownTB (new KeyEventArgs ((Keys)m.WParam.ToInt32 ()));
+ return;
+
+ case Msg.WM_ERASEBKGND:
+ m.Result = (IntPtr) 1; /* Disable background painting to avoid flickering */
+ return;
+
+ default:
+ break;
}
+ base.WndProc (ref m);
+ }
+
+ #endregion Public Methods
- //Console.WriteLine ("UpdateThumbPos: thumb_pos.Y {0} thumb_area.Y {1} pixel_per_pos {2}, new pos {3}, pixel {4}",
- // thumb_pos.Y, thumb_area.Y, pixel_per_pos, new_pos, pixel);
+ #region Private Methods
- if (update_value)
- UpdatePos ((int) new_pos, false);
- }
+ private void UpdateArea ()
+ {
+ paint_area.X = paint_area.Y = 0;
+ paint_area.Width = Width;
+ paint_area.Height = Height;
+ }
- private void LargeIncrement()
- {
- //Console.WriteLine ("large inc: {0} {1}", position, LargeChange);
+ private void UpdatePos (int newPos, bool update_trumbpos)
+ {
+ int old = position;
+
+ if (newPos < minimum)
+ Value = minimum;
+ else
+ if (newPos > maximum)
+ Value = maximum;
+ else
+ Value = newPos;
+ }
+
+ private void LargeIncrement ()
+ {
UpdatePos (position + LargeChange, true);
-
- fire_scroll_event ();
+ Refresh ();
+ OnScroll (new EventArgs ());
}
- private void LargeDecrement()
+ private void LargeDecrement ()
{
- //Console.WriteLine ("large dec: {0} {1}", position, LargeChange);
UpdatePos (position - LargeChange, true);
-
- fire_scroll_event ();
- }
-
- private void UpdatePixelPerPos ()
- {
- pixel_per_pos = ((float)(thumb_area.Width)
- / (float) (1 + Maximum - Minimum));
+ Refresh ();
+ OnScroll (new EventArgs ());
}
- private void UpdatePos (int newPos, bool update_trumbpos)
- {
- int old = position;
-
- if (newPos < minimum)
- Value = minimum;
- else
- if (newPos > maximum)
- Value = maximum;
- else
- Value = newPos;
-
- //Console.WriteLine ("UpdatePos: " + newPos + " ; " + Value);
-
- //Console.WriteLine ("event : {0} {1} {2}", Scroll != null, position, old);
-
- if (orientation == Orientation.Horizontal) {
- if (update_trumbpos)
- UpdateThumbPos (thumb_area.X + (int)(((float)(Value - Minimum)) * pixel_per_pos), false);
- }
- else {
- if (update_trumbpos)
- UpdateThumbPos (thumb_area.Y + (int)(((float)(Value - Minimum)) * pixel_per_pos), false);
- }
+ private void SmallIncrement ()
+ {
+ UpdatePos (position + SmallChange, true);
+ Refresh ();
+ OnScroll (new EventArgs ());
}
- #endregion // Private Methods
-
- #region Override Event Methods
-
- protected override void OnResize (EventArgs e)
+ private void SmallDecrement ()
{
- //Console.WriteLine ("OnResize");
- base.OnResize (e);
-
- if (Width <= 0 || Height <= 0)
- return;
-
- UpdateArea ();
-
- /* Area for double buffering */
- bmp_mem = new Bitmap (Width, Height, PixelFormat.Format32bppArgb);
- dc_mem = Graphics.FromImage (bmp_mem);
+ UpdatePos (position - SmallChange, true);
+ Refresh ();
+ OnScroll (new EventArgs ());
}
-
-
- protected override void OnHandleCreated (EventArgs e)
- {
- base.OnHandleCreated(e);
- //Console.WriteLine ("OnHandleCreated");
- UpdateArea ();
-
- bmp_mem = new Bitmap (Width, Height, PixelFormat.Format32bppArgb);
- dc_mem = Graphics.FromImage (bmp_mem);
-
- UpdatePos (Value, true);
- UpdatePixelPerPos ();
-
- draw();
- UpdatePos (Value, true);
-
- if (AutoSize)
- if (Orientation == Orientation.Horizontal)
- Size = new Size (Width, 45);
- else
- Size = new Size (50, Height);
+
+ private void Draw ()
+ {
+ float ticks = (Maximum - Minimum) / tickFrequency; /* N of ticks draw*/
+
+ if (thumb_pressed)
+ ThemeEngine.Current.DrawTrackBar (DeviceContext, paint_area, this,
+ ref thumb_pos, ref thumb_area, thumb_pressed, ticks, thumb_mouseclick, true);
+ else
+ ThemeEngine.Current.DrawTrackBar (DeviceContext, paint_area, this,
+ ref thumb_pos, ref thumb_area, thumb_pressed, ticks, Value - Minimum, false);
+
+ }
+
+ private void OnMouseUpTB (object sender, MouseEventArgs e)
+ {
+ if (!Enabled) return;
+
+ if (thumb_pressed == true || mouse_clickmove == true) {
+ thumb_pressed = false;
+ holdclick_timer.Enabled = false;
+ this.Capture = false;
+ Refresh ();
+ }
}
-
- /* Disable background painting to avoid flickering, since we do our painting*/
- protected override void OnPaintBackground (PaintEventArgs pevent)
+ private void OnMouseDownTB (object sender, MouseEventArgs e)
{
- // None
- }
-
- private void draw ()
- {
- int ticks = (Maximum - Minimum) / tickFrequency;
-
- ThemeEngine.Current.DrawTrackBar (dc_mem, paint_area, ref thumb_pos, ref thumb_area,
- tickStyle, ticks, Orientation, Focused);
- }
+ if (!Enabled) return;
- protected override void OnPaint (PaintEventArgs pevent)
- {
- Console.WriteLine ("OnDraw");
-
- if (Width <= 0 || Height <= 0 || Visible == false)
- return;
-
- /* Copies memory drawing buffer to screen*/
- UpdateArea ();
- draw();
- pevent.Graphics.DrawImage (bmp_mem, 0, 0);
- }
-
- protected override void OnMouseDown (MouseEventArgs e)
- {
- if (!Enabled) return;
-
- //System.Console.WriteLine ("OnMouseDown" + thumb_pos);
+ bool fire_timer = false;
Point point = new Point (e.X, e.Y);
if (orientation == Orientation.Horizontal) {
-
+
if (thumb_pos.Contains (point)) {
+ this.Capture = true;
thumb_pressed = true;
- Invalidate ();
- thumb_pixel_click_move = e.X;
+ thumb_mouseclick = e.X;
+ Refresh ();
}
else {
if (paint_area.Contains (point)) {
else
LargeDecrement ();
- Invalidate ();
+ Refresh ();
+ fire_timer = true;
+ mouse_clickmove = true;
}
}
}
else {
if (thumb_pos.Contains (point)) {
+ this.Capture = true;
thumb_pressed = true;
- Invalidate ();
- thumb_pixel_click_move = e.Y;
+ thumb_mouseclick = e.Y;
+ Refresh ();
+
}
else {
if (paint_area.Contains (point)) {
else
LargeDecrement ();
- Invalidate ();
+ Refresh ();
+ fire_timer = true;
+ mouse_clickmove = true;
}
}
-
}
+
+ if (fire_timer) { \r
+ holdclick_timer.Interval = 300;\r
+ holdclick_timer.Enabled = true;
+ }
}
- protected override void OnMouseMove (MouseEventArgs e)
+ private void OnMouseMoveTB (MouseEventArgs e)
{
if (!Enabled) return;
-
- //System.Console.WriteLine ("OnMouseMove " + thumb_pressed);
+
Point pnt = new Point (e.X, e.Y);
/* Moving the thumb */
- if (thumb_pos.Contains (pnt) && thumb_pressed) {
-
- System.Console.WriteLine ("OnMouseMove " + thumb_pressed);
-
- int pixel_pos;
+ if (thumb_pressed) {
+
+ if (orientation == Orientation.Horizontal){
+ if (paint_area.Contains (e.X, thumb_pos.Y))
+ thumb_mouseclick = e.X;
+ }
+ else {
+ if (paint_area.Contains (thumb_pos.X, e.Y))
+ thumb_mouseclick = e.Y;
+ }
- if (orientation == Orientation.Horizontal)
- pixel_pos = e.X - (thumb_pixel_click_move - thumb_pos.X);
- else
- pixel_pos = e.Y - (thumb_pixel_click_move - thumb_pos.Y);
+ Refresh ();
+ OnScroll (new EventArgs ());
+ }
+ }
- UpdateThumbPos (pixel_pos, true);
+ private void OnResizeTB (object sender, System.EventArgs e)
+ {
+ if (Width <= 0 || Height <= 0)
+ return;
- if (orientation == Orientation.Horizontal)
- thumb_pixel_click_move = e.X;
- else
- thumb_pixel_click_move = e.Y;
+ UpdateArea ();
+ CreateBuffers (Width, Height);
+ }
+ private void OnPaintTB (PaintEventArgs pevent)
+ {
+ if (Width <= 0 || Height <= 0 || Visible == false)
+ return;
- fire_scroll_event ();
+ /* Copies memory drawing buffer to screen*/
+ UpdateArea ();
+ Draw ();
+ pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
+ }
+
+ private void OnKeyDownTB (KeyEventArgs e) \r
+ {
+ switch (e.KeyCode) { \r
+ case Keys.Up:
+ case Keys.Right:
+ SmallIncrement ();
+ break;
+
+ case Keys.Down:
+ case Keys.Left:
+ SmallDecrement ();
+ break;
+
+ default:
+ break;
+ }
+ }
- //System.Console.WriteLine ("OnMouseMove thumb "+ e.Y
- // + " clickpos " + thumb_pixel_click_move + " pos:" + thumb_pos.Y);
+ private void OnFirstClickTimer (Object source, ElapsedEventArgs e)\r
+ { \r
+ Point pnt;\r
+ pnt = PointToClient (MousePosition); \r
+\r
+ if (thumb_area.Contains (pnt)) {\r
+ if (orientation == Orientation.Horizontal) {\r
+ if (pnt.X > thumb_pos.X + thumb_pos.Width)
+ LargeIncrement ();
+
+ if (pnt.X < thumb_pos.X)
+ LargeDecrement (); \r
+ }\r
+ else {\r
+ if (pnt.Y > thumb_pos.Y + thumb_pos.Height)
+ LargeIncrement ();
+
+ if (pnt.Y < thumb_pos.Y)
+ LargeDecrement ();
+ }
- Invalidate ();
- }
+ Refresh ();
+\r
+ } \r
+ }
- if (!thumb_pos.Contains (pnt) && thumb_pressed) {
- thumb_pressed = false;
- Invalidate ();
- }
+ protected override void SetBoundsCore (int x, int y,int width, int height, BoundsSpecified specified)
+ {
+ base.SetBoundsCore (x, y,width, height, specified);
+ }
- }
-
- protected override void OnMouseWheel (MouseEventArgs e)
- {
- if (!Enabled) return;
-
- //System.Console.WriteLine ("OnMouseWheel delta: " + e.Delta + " clicks:" + e.Clicks);
-
- }
-
- #endregion //Override Event Methods
+
+ #endregion // Private Methods
}
}