2007-04-02 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Splitter.cs
index 53963adb2db442cbe7c26916162ba8fbf72800a1..677279fd28ff7c048487027899aca19088e67e27 100644 (file)
@@ -38,7 +38,11 @@ namespace System.Windows.Forms {
        [DefaultEvent("SplitterMoved")]
        [Designer("System.Windows.Forms.Design.SplitterDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        [DefaultProperty("Dock")]
-       public class Splitter : Control, IMessageFilter {
+       public class Splitter : Control
+#if !NET_2_0
+       , IMessageFilter
+#endif
+       {
                #region Enums
                private enum DrawType {
                        Initial,
@@ -50,7 +54,8 @@ namespace System.Windows.Forms {
                #region Local Variables
                static private Cursor           splitter_ns;
                static private Cursor           splitter_we;
-               private BorderStyle             border_style;
+               // XXX this "new" shouldn't be here.  Control shouldn't define border_style as internal.
+               new private BorderStyle         border_style;
                private int                     min_extra;
                private int                     min_size;
                private int                     split_position;         // Current splitter position
@@ -143,25 +148,21 @@ namespace System.Windows.Forms {
                                border_style = value;
 
                                switch(value) {
-                                       case BorderStyle.FixedSingle: {
-                                               splitter_size = 4;      // We don't get motion events for 1px wide windows on X11. sigh.
-                                               break;
-                                       }
+                               case BorderStyle.FixedSingle:
+                                       splitter_size = 4;      // We don't get motion events for 1px wide windows on X11. sigh.
+                                       break;
 
-                                       case BorderStyle.Fixed3D: {
-                                               value = BorderStyle.None;
-                                               splitter_size = 3;
-                                               break;
-                                       }
+                               case BorderStyle.Fixed3D:
+                                       value = BorderStyle.None;
+                                       splitter_size = 3;
+                                       break;
 
-                                       case BorderStyle.None: {
-                                               splitter_size = 3;
-                                               break;
-                                       }
+                               case BorderStyle.None:
+                                       splitter_size = 3;
+                                       break;
 
-                                       default: {
-                                               throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
-                                       }
+                               default:
+                                       throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
                                }
 
                                base.InternalBorderStyle = value;
@@ -284,29 +285,21 @@ namespace System.Windows.Forms {
                                if (affected == null) {
                                        split_requested = value;
                                }
-
-                               if (Capture || (affected == null)) {
-                                       return;
-                               }
-
-                               if (horizontal) {
-                                       affected.Height = value;
-                               } else {
-                                       affected.Width = value;
+                               else {
+                                       if (horizontal) {
+                                               affected.Height = value;
+                                       } else {
+                                               affected.Width = value;
+                                       }
                                }
                        }
                }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public bool TabStop {
-                       get {
-                               return base.TabStop;
-                       }
-
-                       set {
-                               base.TabStop = value;
-                       }
+               public new bool TabStop {
+                       get { return base.TabStop; }
+                       set { base.TabStop = value; }
                }
 
                [Bindable(false)]
@@ -346,9 +339,11 @@ namespace System.Windows.Forms {
                #endregion      // Protected Instance Properties
 
                #region Public Instance Methods
+#if !NET_2_0
                public bool PreFilterMessage(ref Message m) {
                        return false;
                }
+#endif
 
                public override string ToString() {
                        return base.ToString () + String.Format(", MinExtra: {0}, MinSize: {1}", min_extra, min_size);
@@ -385,7 +380,7 @@ namespace System.Windows.Forms {
                        // Calculate limits
                        if (filler != null) {
                                if (horizontal) {
-                                       if (dock_style == DockStyle.Top) {
+                                       if (Dock == DockStyle.Top) {
                                                limit_min = affected.Bounds.Top + min_size;
                                                limit_max = filler.Bounds.Bottom - min_extra + this.bounds.Top - filler.Bounds.Top;
                                        } else {
@@ -393,7 +388,7 @@ namespace System.Windows.Forms {
                                                limit_max = affected.Bounds.Bottom - min_size - this.Height;
                                        }
                                } else {
-                                       if (dock_style == DockStyle.Left) {
+                                       if (Dock == DockStyle.Left) {
                                                limit_min = affected.Bounds.Left + min_size;
                                                limit_max = filler.Bounds.Right - min_extra + this.bounds.Left - filler.Bounds.Left;
                                        } else {
@@ -414,18 +409,18 @@ namespace System.Windows.Forms {
                                Console.WriteLine("Sizing limits: Min:{0}, Max:{1}", limit_min, limit_max);
                        #endif
 
-                       pt = PointToScreen(parent.PointToClient(new Point(e.X, e.Y)));
+                       pt = PointToScreen(Parent.PointToClient(new Point(e.X, e.Y)));
 
                        if (horizontal) {
                                split_position = pt.Y;
-                               if (dock_style == DockStyle.Top) {
+                               if (Dock == DockStyle.Top) {
                                        click_offset = e.Y;
                                } else {
                                        click_offset = -e.Y;
                                }
                        } else {
                                split_position = pt.X;
-                               if (dock_style == DockStyle.Left) {
+                               if (Dock == DockStyle.Left) {
                                        click_offset = e.X;
                                } else {
                                        click_offset = -e.X;
@@ -453,15 +448,29 @@ namespace System.Windows.Forms {
                        }
 
                        // We need our mouse coordinates relative to our parent
-                       pt = PointToScreen(parent.PointToClient(new Point(e.X, e.Y)));
+                       pt = PointToScreen(Parent.PointToClient(new Point(e.X, e.Y)));
 
                        // Grab our new coordinates
                        prev_split_position = split_position;
-                       if (horizontal) {
-                               split_position = pt.Y;
-                       } else {
-                               split_position = pt.X;
-                       }
+
+                       int candidate = horizontal ? pt.Y : pt.X;
+
+                       // Enforce limit on what we send to the event
+                       if (candidate < limit_min)
+                               candidate = limit_min;
+                       else if (candidate > limit_max)
+                               candidate = limit_max;
+
+                       sevent.x = pt.X;
+                       sevent.y = pt.Y;
+                       sevent.split_x = horizontal ? 0 : candidate;
+                       sevent.split_y = horizontal ? candidate : 0;
+
+                       // Fire the event
+                       OnSplitterMoving(sevent);
+
+                       split_position = horizontal ? sevent.split_y : sevent.split_x;
+
                        // Enforce limits
                        if (split_position < limit_min) {
                                #if Debug
@@ -475,26 +484,8 @@ namespace System.Windows.Forms {
                                split_position = limit_max;
                        }
 
-                       // Don't waste cycles
-                       if (prev_split_position != split_position) {
-                               // Update our handle location
-                               DrawDragHandle(DrawType.Redraw);
-                       }
-
-                       // Prepare the event
-                       if (horizontal) {
-                               sevent.split_x = 0;
-                               sevent.split_y = split_position;
-                       } else {
-                               sevent.split_x = split_position;
-                               sevent.split_y = 0;
-                       }
-
-                       sevent.x = pt.X;
-                       sevent.y = pt.Y;
-
-                       // Fire the event
-                       OnSplitterMoving(sevent);
+                       // Update our handle location
+                       DrawDragHandle(DrawType.Redraw);
                }
 
                protected override void OnMouseUp(MouseEventArgs e) {
@@ -543,15 +534,15 @@ namespace System.Windows.Forms {
                }
 
                protected virtual void OnSplitterMoved(SplitterEventArgs sevent) {
-                       if (SplitterMoved != null) {
-                               SplitterMoved(this, sevent);
-                       }
+                       SplitterEventHandler eh = (SplitterEventHandler)(Events [SplitterMovedEvent]);
+                       if (eh != null)
+                               eh (this, sevent);
                }
 
                protected virtual void OnSplitterMoving(SplitterEventArgs sevent) {
-                       if (SplitterMoving != null) {
-                               SplitterMoving(this, sevent);
-                       }
+                       SplitterEventHandler eh = (SplitterEventHandler)(Events [SplitterMovingEvent]);
+                       if (eh != null)
+                               eh (this, sevent);
                }
 
                protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
@@ -575,40 +566,28 @@ namespace System.Windows.Forms {
                #region Private Properties and Methods
                private Control AffectedControl {
                        get {
-                               if (parent == null) {
+                               if (Parent == null)
                                        return null;
-                               }
 
                                // Doc says the first control preceeding us in the zorder 
-                               for (int i = parent.Controls.GetChildIndex(this) + 1; i < parent.Controls.Count; i++) {
-                                       switch(this.Dock) {
-                                               case DockStyle.Top: {
-                                                       if (Top == parent.Controls[i].Bottom) {
-                                                               return parent.Controls[i];
-                                                       }
-                                                       break;
-                                               }
-
-                                               case DockStyle.Bottom: {
-                                                       if (Bottom == parent.Controls[i].Top) {
-                                                               return parent.Controls[i];
-                                                       }
-                                                       break;
-                                               }
-
-                                               case DockStyle.Left: {
-                                                       if (Left == parent.Controls[i].Right) {
-                                                               return parent.Controls[i];
-                                                       }
-                                                       break;
-                                               }
-
-                                               case DockStyle.Right: {
-                                                       if (Right == parent.Controls[i].Left) {
-                                                               return parent.Controls[i];
-                                                       }
-                                                       break;
-                                               }
+                               for (int i = Parent.Controls.GetChildIndex(this) + 1; i < Parent.Controls.Count; i++) {
+                                       switch (Dock) {
+                                       case DockStyle.Top:
+                                               if (Top == Parent.Controls[i].Bottom)
+                                                       return Parent.Controls[i];
+                                               break;
+                                       case DockStyle.Bottom:
+                                               if (Bottom == Parent.Controls[i].Top)
+                                                       return Parent.Controls[i];
+                                               break;
+                                       case DockStyle.Left:
+                                               if (Left == Parent.Controls[i].Right)
+                                                       return Parent.Controls[i];
+                                               break;
+                                       case DockStyle.Right:
+                                               if (Right == Parent.Controls[i].Left)
+                                                       return Parent.Controls[i];
+                                               break;
                                        }
                                }
                                return null;
@@ -617,14 +596,13 @@ namespace System.Windows.Forms {
 
                private Control FillerControl {
                        get {
-                               if (parent == null) {
+                               if (Parent == null)
                                        return null;
-                               }
 
                                // Doc says the first control preceeding us in the zorder 
-                               for (int i = parent.Controls.GetChildIndex(this) - 1; i >= 0; i--) {
-                                       if (parent.Controls[i].Dock == DockStyle.Fill) {
-                                               return parent.Controls[i];
+                               for (int i = Parent.Controls.GetChildIndex(this) - 1; i >= 0; i--) {
+                                       if (Parent.Controls[i].Dock == DockStyle.Fill) {
+                                               return Parent.Controls[i];
                                        }
                                }
                                return null;
@@ -633,17 +611,15 @@ namespace System.Windows.Forms {
 
                private int CalculateSplitPosition() {
                        if (horizontal) {
-                               if (dock_style == DockStyle.Top) {
+                               if (Dock == DockStyle.Top)
                                        return split_position - affected.Top;
-                               } else {
+                               else
                                        return affected.Bottom - split_position - splitter_size;
-                               }
                        } else {
-                               if (dock_style == DockStyle.Left) {
+                               if (Dock == DockStyle.Left)
                                        return split_position - affected.Left;
-                               } else {
+                               else
                                        return affected.Right - split_position - splitter_size;
-                               }
                        }
                }
 
@@ -678,25 +654,21 @@ namespace System.Windows.Forms {
                        }
 
                        switch(type) {
-                               case DrawType.Initial: {
-                                       XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
-                                       return;
-                               }
-
-                               case DrawType.Redraw: {
-                                       if (prev.X == current.X && prev.Y == current.Y) {
-                                               return;
-                                       }
+                       case DrawType.Initial:
+                               XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
+                               return;
 
-                                       XplatUI.DrawReversibleRectangle(Parent.window.Handle, prev, 3);
-                                       XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
+                       case DrawType.Redraw:
+                               if (prev.X == current.X && prev.Y == current.Y)
                                        return;
-                               }
 
-                               case DrawType.Finish: {
-                                       XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
-                                       return;
-                               }
+                               XplatUI.DrawReversibleRectangle(Parent.window.Handle, prev, 3);
+                               XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
+                               return;
+
+                       case DrawType.Finish:
+                               XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
+                               return;
                        }
                }
                #endregion      // Private Properties and Methods
@@ -779,8 +751,18 @@ namespace System.Windows.Forms {
                        remove { base.TextChanged -= value; }
                }
 
-               public event SplitterEventHandler SplitterMoved;
-               public event SplitterEventHandler SplitterMoving;
+               static object SplitterMovedEvent = new object ();
+               static object SplitterMovingEvent = new object ();
+
+               public event SplitterEventHandler SplitterMoved {
+                       add { Events.AddHandler (SplitterMovedEvent, value); }
+                       remove { Events.RemoveHandler (SplitterMovedEvent, value); }
+               }
+
+               public event SplitterEventHandler SplitterMoving {
+                       add { Events.AddHandler (SplitterMovingEvent, value); }
+                       remove { Events.RemoveHandler (SplitterMovingEvent, value); }
+               }
                #endregion      // Events
        }
 }