// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// Autors:
-// Jordi Mas i Hernandez, jordi@ximian.com
+//
+// Copyright (c) 2004-2005 Novell, Inc.
+//
+// Authors:
+// 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
-//
-// Copyright (C) Novell Inc., 2004
-//
-//
-// $Revision: 1.7 $
-// $Modtime: $
-// $Log: TrackBar.cs,v $
-// 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
-//
-// Revision 1.2 2004/07/26 17:42:03 jordi
-// Theme support
-//
-// Revision 1.1 2004/07/15 09:38:02 jordi
-// Horizontal and Vertical TrackBar control implementation
-//
//
+
// NOT COMPLETE
using System.ComponentModel;
+using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
+using System.Timers;
namespace System.Windows.Forms
{
+ [Designer("System.Windows.Forms.Design.TrackBarDesigner, " + Consts.AssemblySystem_Design)]
+ [DefaultEvent ("Scroll")]
+ [DefaultProperty("Value")]
public class TrackBar : Control, ISupportInitialize
{
private int minimum;
private int maximum;
- private int tickFrequency;
+ internal int tickFrequency;
private bool autosize;
private int position;
private int smallChange;
private int largeChange;
private Orientation orientation;
- private TickStyle tickStyle;
- private Rectangle paint_area = new Rectangle ();
+ private TickStyle tickStyle;
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;
-
- #region Events
+ internal bool thumb_pressed = false;
+ private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
+ internal int thumb_mouseclick;
+ private bool mouse_clickmove;
+
+ #region events
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler BackgroundImageChanged;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler Click;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler DoubleClick;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler FontChanged;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler ForeColorChanged;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler ImeModeChanged;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event PaintEventHandler Paint;
+
public event EventHandler Scroll;
- public event EventHandler ValueChanged;
+
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler TextChanged;
+ public event EventHandler ValueChanged;
+
#endregion // Events
public TrackBar ()
position = 0;
tickStyle = TickStyle.BottomRight;
smallChange = 1;
- largeChange = 5;
- Scroll = null;
- ValueChanged = null;
+ largeChange = 5;
+ mouse_clickmove = false;
+ MouseDown += new MouseEventHandler (OnMouseDownTB);
+ MouseUp += new MouseEventHandler (OnMouseUpTB);
+ MouseMove += new MouseEventHandler (OnMouseMoveTB);
+ holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
}
+ #region Private & Internal Properties
+ internal Rectangle ThumbPos {
+ get {
+ return thumb_pos;
+ }
+
+ set {
+ thumb_pos = value;
+ }
+ }
+
+ internal Rectangle ThumbArea {
+ get {
+ return thumb_area;
+ }
+
+ set {
+ thumb_area = value;
+ }
+ }
+ #endregion // Private & Internal Properties
+
#region Public Properties
+ [DefaultValue (true)]
public bool AutoSize {
get { return autosize; }
set { autosize = value;}
}
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ [Browsable (false)]
public override Image BackgroundImage {
get { return base.BackgroundImage; }
- set { base.BackgroundImage = value; }
+ set {
+ if (base.BackgroundImage == value)
+ return;
+
+ if (BackgroundImageChanged != null)
+ BackgroundImageChanged (this, EventArgs.Empty);
+
+ base.BackgroundImage = value;
+ }
}
protected override CreateParams CreateParams {
}
protected override Size DefaultSize {
- get { return new System.Drawing.Size (104, 42); }
+ get { return ThemeEngine.Current.TrackBarDefaultSize; }
}
-
+
+ [Browsable(false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
public override Font Font {
get { return base.Font; }
set { base.Font = value; }
}
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ [Browsable (false)]
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 ();
+ }
+ }
+
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ [Browsable (false)]
+ 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 {
+ [DefaultValue (5)]
+ 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;
- Refresh ();
+ largeChange = value;
}
}
+ [DefaultValue (10)]
+ [RefreshProperties (RefreshProperties.All)]
public int Maximum {
get { return maximum; }
set {
}
}
+ [DefaultValue (0)]
+ [RefreshProperties (RefreshProperties.All)]
public int Minimum {
get { return minimum; }
set {
}
}
+ [DefaultValue (Orientation.Horizontal)]
+ [Localizable (true)]
public Orientation Orientation {
get { return orientation; }
set {
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*/
+ /* Orientation can be changed once the control has been created */
if (orientation != value) {
orientation = value;
}
}
+ [DefaultValue (1)]
public int SmallChange {
get { return smallChange;}
set {
throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
if (smallChange != value) {
- smallChange = value;
- Refresh ();
+ smallChange = value;
}
}
}
-
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ [Bindable (false)]
+ [Browsable (false)]
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 ();
+ }
+ }
+ [DefaultValue (1)]
public int TickFrequency {
get { return tickFrequency; }
set {
}
}
+ [DefaultValue (TickStyle.BottomRight)]
public TickStyle TickStyle {
get { return tickStyle; }
set {
}
}
}
-
-
+
+ [DefaultValue (0)]
+ [Bindable (true)]
public int Value {
get { return position; }
set {
if (ValueChanged != null)
ValueChanged (this, new EventArgs ());
- Refresh ();
+ Invalidate (thumb_area);
}
}
}
protected override bool IsInputKey (Keys keyData)
{
- return false;
+ return base.IsInputKey (keyData);
}
protected override void OnBackColorChanged (EventArgs e)
{
-
+ base.OnBackColorChanged (e);
}
protected override void OnHandleCreated (EventArgs e)
- {
+ {
+ base.OnHandleCreated (e);
+
if (AutoSize)
if (Orientation == Orientation.Horizontal)
- Size = new Size (Width, 45);
+ Size = new Size (Width, 40);
else
Size = new Size (50, Height);
-
- UpdateArea ();
- CreateBuffers (Width, Height);
-
- UpdatePos (Value, true);
- UpdatePixelPerPos ();
-
- Draw ();
- UpdatePos (Value, true);
-
+ UpdatePos (Value, true);
}
-
+
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
protected override void OnMouseWheel (MouseEventArgs e)
{
+ base.OnMouseWheel (e);
+
if (!Enabled) return;
if (e.Delta > 0)
SmallDecrement ();
else
- SmallIncrement ();
-
+ SmallIncrement ();
}
protected virtual void OnScroll (EventArgs e)
public void SetRange (int minValue, int maxValue)
{
Minimum = minValue;
- Maximum = maxValue;
-
- Refresh ();
+ Maximum = maxValue;
}
public override string ToString()
return string.Format("System.Windows.Forms.Trackbar, Minimum: {0}, Maximum: {1}, Value: {2}",
Minimum, Maximum, Value);
}
-
-
+
protected override void WndProc (ref Message m)
{
- int clicks = 1;
-
switch ((Msg) m.Msg) {
-
- case Msg.WM_LBUTTONDOWN:
- OnMouseDownTB (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()),
- clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),
- 0));
-
- break;
-
- 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_SIZE:
- OnResize_TB ();
- break;
-
- case Msg.WM_PAINT: {
- Rectangle rect;
+
+ case Msg.WM_PAINT: {
PaintEventArgs paint_event;
paint_event = XplatUI.PaintEventStart (Handle);
- OnPaint_TB (paint_event);
+ 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 */
+ m.Result = (IntPtr) 1; /* Disable background painting to avoid flickering */
return;
default:
#endregion Public Methods
#region Private Methods
-
- private void UpdateArea ()
+
+ private void UpdatePos (int newPos, bool update_trumbpos)
{
- paint_area.X = paint_area.Y = 0;
- paint_area.Width = Width;
- paint_area.Height = Height;
-
- UpdatePixelPerPos ();
- //Console.WriteLine ("UpdateArea: {0} {1} {2}", thumb_area.Width, thumb_pos.Width, pixel_per_pos);
-
- }
-
- private void UpdateThumbPos (int pixel, bool update_value)
- {
- 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;
-
- 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;
-
- new_pos = (float) (thumb_pos.Y - thumb_area.Y);
- new_pos = new_pos / pixel_per_pos;
-
+ if (newPos < minimum){
+ Value = minimum;
}
-
-
- //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);
-
- if (update_value)
- UpdatePos ((int) new_pos, false);
- }
-
+ else {
+ if (newPos > maximum) {
+ Value = maximum;
+ }
+ else {
+ Value = newPos;
+ }
+ }
+ }
+
private void LargeIncrement ()
{
UpdatePos (position + LargeChange, true);
- Refresh ();
+ Invalidate (thumb_area);
OnScroll (new EventArgs ());
}
private void LargeDecrement ()
{
UpdatePos (position - LargeChange, true);
- Refresh ();
+ Invalidate (thumb_area);
OnScroll (new EventArgs ());
}
private void SmallIncrement ()
{
UpdatePos (position + SmallChange, true);
- Refresh ();
+ Invalidate (thumb_area);
OnScroll (new EventArgs ());
}
private void SmallDecrement ()
{
UpdatePos (position - SmallChange, true);
- Refresh ();
+ Invalidate (thumb_area);
OnScroll (new EventArgs ());
}
-
- private void UpdatePixelPerPos ()
- {
- pixel_per_pos = ((float)(thumb_area.Width)
- / (float) (1 + Maximum - Minimum));
- }
-
- private void Draw ()
- {
- int ticks = (Maximum - Minimum) / tickFrequency;
-
- ThemeEngine.Current.DrawTrackBar (DeviceContext, paint_area, ref thumb_pos, ref thumb_area,
- tickStyle, ticks, Orientation, Focused);
+
+ 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;
+ Invalidate (thumb_area);
+ }
}
- private void UpdatePos (int newPos, bool update_trumbpos)
+ private void OnMouseDownTB (object sender, MouseEventArgs e)
{
- int old = position;
-
- if (newPos < minimum)
- Value = minimum;
- else
- if (newPos > maximum)
- Value = maximum;
- else
- Value = newPos;
-
- 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);
- }
- }
+ if (!Enabled) return;
- private void OnMouseDownTB (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)) {
- //XplatUI.GrabWindow (Handle);
+ this.Capture = true;
thumb_pressed = true;
- Refresh ();
- thumb_pixel_click_move = e.X;
+ thumb_mouseclick = e.X;
+ Invalidate (thumb_area);
}
else {
- if (paint_area.Contains (point)) {
+ if (ClientRectangle.Contains (point)) {
if (e.X > thumb_pos.X + thumb_pos.Width)
LargeIncrement ();
else
LargeDecrement ();
- Refresh ();
+ Invalidate (thumb_area);
+ fire_timer = true;
+ mouse_clickmove = true;
}
}
}
else {
if (thumb_pos.Contains (point)) {
- //XplatUI.GrabWindow (Handle);
+ this.Capture = true;
thumb_pressed = true;
- Refresh ();
- thumb_pixel_click_move = e.Y;
+ thumb_mouseclick = e.Y;
+ Invalidate (thumb_area);
+
}
else {
- if (paint_area.Contains (point)) {
+ if (ClientRectangle.Contains (point)) {
if (e.Y > thumb_pos.Y + thumb_pos.Height)
LargeIncrement ();
else
LargeDecrement ();
- Refresh ();
+ Invalidate (thumb_area);
+ fire_timer = true;
+ mouse_clickmove = true;
}
}
-
}
+
+ if (fire_timer) { \r
+ holdclick_timer.Interval = 300;\r
+ holdclick_timer.Enabled = true;
+ }
}
- private void OnMouseMoveTB (MouseEventArgs e)
+ private void OnMouseMoveTB (object sender, MouseEventArgs e)
{
if (!Enabled) return;
- Point pnt = new Point (e.X, e.Y);
-
/* Moving the thumb */
- if (thumb_pos.Contains (pnt) && thumb_pressed) {
-
- //System.Console.WriteLine ("OnMouseMove " + thumb_pressed);
- //XplatUI.GrabWindow (Handle);
- int pixel_pos;
-
- 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);
-
- UpdateThumbPos (pixel_pos, true);
-
- if (orientation == Orientation.Horizontal)
- thumb_pixel_click_move = e.X;
- else
- thumb_pixel_click_move = e.Y;
+ if (thumb_pressed) {
+
+ if (orientation == Orientation.Horizontal){
+ if (ClientRectangle.Contains (e.X, thumb_pos.Y))
+ thumb_mouseclick = e.X;
+ }
+ else {
+ if (ClientRectangle.Contains (thumb_pos.X, e.Y))
+ thumb_mouseclick = e.Y;
+ }
+ Invalidate (thumb_area);
OnScroll (new EventArgs ());
-
- //System.Console.WriteLine ("OnMouseMove thumb "+ e.Y
- // + " clickpos " + thumb_pixel_click_move + " pos:" + thumb_pos.Y);
-
- Refresh ();
- }
-
- if (!thumb_pos.Contains (pnt) && thumb_pressed) {
- //XplatUI.ReleaseWindow (Handle);
- thumb_pressed = false;
- Invalidate ();
}
-
}
- private void OnResize_TB ()
- {
- //Console.WriteLine ("OnResize");
+ private void OnPaintTB (PaintEventArgs pevent)
+ {
+ if (Paint != null) {
+ Paint (this, pevent);
+ }
+ ThemeEngine.Current.DrawTrackBar (pevent.Graphics, pevent.ClipRectangle, this);
+ }
- if (Width <= 0 || Height <= 0)
- return;
+ private void OnKeyDownTB (KeyEventArgs e) \r
+ {
+ switch (e.KeyCode) {
+
+ case Keys.Down:
+ case Keys.Right:
+ SmallIncrement ();
+ break;
+
+ case Keys.Up:
+ case Keys.Left:
+ SmallDecrement ();
+ break;
+
+ case Keys.PageUp:
+ LargeDecrement ();
+ break;
+
+ case Keys.PageDown:
+ LargeIncrement ();
+ break;
+
+ case Keys.Home:
+ Value = Minimum;
+ break;
+
+ case Keys.End:
+ Value = Maximum;
+ break;
+
+ default:
+ break;
+ }
+ }
- UpdateArea ();
- CreateBuffers (Width, Height);
- }
+ 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 ();
+ }
- private void OnPaint_TB (PaintEventArgs pevent)
- {
- if (Width <= 0 || Height <= 0 || Visible == false)
- return;
+ Invalidate (thumb_area);
+\r
+ } \r
+ }
- /* Copies memory drawing buffer to screen*/
- UpdateArea ();
- Draw ();
- pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
- }
+ protected override void SetBoundsCore (int x, int y,int width, int height, BoundsSpecified specified)
+ {
+ base.SetBoundsCore (x, y,width, height, specified);
+ }
+
#endregion // Private Methods
}
}