2007-01-07 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Control.cs
index 582a4131a7aefb05db8a3c272b76782123672792..b32e216b53dda6b9816a5436080b0f2d4f09b358 100644 (file)
@@ -30,8 +30,6 @@
 //     John Sohn               jsohn@columbus.rr.com
 //
 
-// COMPLETE 
-
 #undef DebugRecreate
 #undef DebugFocus
 
@@ -387,15 +385,19 @@ namespace System.Windows.Forms
                                Dispose ();
                        }
                }
+
+               [ListBindable (false)]
 #if NET_2_0
                [ComVisible (false)]
+               public class ControlCollection : Layout.ArrangedElementCollection, IList, ICollection, ICloneable, IEnumerable {
 #else
                [DesignerSerializer("System.Windows.Forms.Design.ControlCollectionCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
-#endif
-               [ListBindable(false)]
                public class ControlCollection : IList, ICollection, ICloneable, IEnumerable {
+#endif
                        #region ControlCollection Local Variables
+#if !NET_2_0
                        ArrayList list;
+#endif
                        ArrayList impl_list;
                        Control[] all_controls;
                        Control owner;
@@ -404,7 +406,9 @@ namespace System.Windows.Forms
                        #region ControlCollection Public Constructor
                        public ControlCollection(Control owner) {
                                this.owner=owner;
+#if !NET_2_0
                                this.list=new ArrayList();
+#endif
                        }
                        #endregion
 
@@ -414,9 +418,11 @@ namespace System.Windows.Forms
                        }
 
 
+#if !NET_2_0
                        public int Count {
                                get { return list.Count; }
                        }
+#endif
 
 #if NET_2_0
                        bool IList.IsReadOnly
@@ -429,6 +435,22 @@ namespace System.Windows.Forms
                                }
                        }
 
+#if NET_2_0
+                       public Control Owner { get { return this.owner; } }
+                       
+                       public virtual Control this[string key] {
+                               get { 
+                                       int index = IndexOfKey (key);
+                                       
+                                       if (index >= 0)
+                                               return this[index];
+                                               
+                                       return null;
+                               }
+                       }
+                       
+                       new
+#endif
                        public virtual Control this[int index] {
                                get {
                                        if (index < 0 || index >= list.Count) {
@@ -436,10 +458,12 @@ namespace System.Windows.Forms
                                        }
                                        return (Control)list[index];
                                }
+                               
+                               
                        }
                        #endregion // ControlCollection Public Instance Properties
                        
-                       #region ControlCollection Private Instance Methods
+                       #region ControlCollection Instance Methods
                        public virtual void Add (Control value)
                        {
                                if (value == null)
@@ -538,6 +562,9 @@ namespace System.Windows.Forms
                                }
                        }
 
+#if NET_2_0
+                       new
+#endif
                        public virtual void Clear ()
                        {
                                all_controls = null;
@@ -590,17 +617,24 @@ namespace System.Windows.Forms
                                return Contains (value) || ImplicitContains (value);
                        }
 
+#if NET_2_0
+                       public virtual bool ContainsKey (string key)
+                       {
+                               return IndexOfKey (key) >= 0;
+                       }
+#endif
+
                        void ICollection.CopyTo (Array array, int index)
                        {
                                CopyTo (array, index);
                        }
 
-                       internal void CopyTo (Array array, int index)
+#if !NET_2_0
+                       public void CopyTo (Array array, int index)
                        {
                                list.CopyTo(array, index);
                        }
 
-#if !NET_2_0
                        public override bool Equals (object other)
                        {
                                if (other is ControlCollection && (((ControlCollection)other).owner==this.owner)) {
@@ -611,6 +645,27 @@ namespace System.Windows.Forms
                        }
 #endif
 
+#if NET_2_0
+                       // LAMESPEC: MSDN says AE, MS implementation throws ANE
+                       public Control[] Find (string key, bool searchAllChildren)
+                       {
+                               if (string.IsNullOrEmpty (key))
+                                       throw new ArgumentNullException ("key");
+                                       
+                               ArrayList al = new ArrayList ();
+                               
+                               foreach (Control c in list) {
+                                       if (c.Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
+                                               al.Add (c);
+                                               
+                                       if (searchAllChildren)
+                                               al.AddRange (c.Controls.Find (key, true));
+                               }
+                               
+                               return (Control[])al.ToArray (typeof (Control));
+                       }
+#endif
+
                        public int GetChildIndex(Control child) {
                                return GetChildIndex(child, false);
                        }
@@ -632,7 +687,7 @@ namespace System.Windows.Forms
                        }
 
 #if NET_2_0
-                       public virtual IEnumerator
+                       public override IEnumerator
 #else
                        public IEnumerator
 #endif
@@ -676,6 +731,20 @@ namespace System.Windows.Forms
                                return list.IndexOf(control);
                        }
 
+#if NET_2_0
+                       public virtual int IndexOfKey (string key)
+                       {
+                               if (string.IsNullOrEmpty (key))
+                                       return -1;
+                                       
+                               for (int i = 0; i < list.Count; i++)
+                                       if (((Control)list[i]).Name.Equals (key, StringComparison.CurrentCultureIgnoreCase))
+                                               return i;
+                                               
+                               return -1;
+                       }
+#endif
+
                        public virtual void Remove(Control value)
                        {
                                if (value == null)
@@ -704,6 +773,9 @@ namespace System.Windows.Forms
                                owner.UpdateChildrenZOrder ();
                        }
 
+#if NET_2_0
+                       new
+#endif
                        public void RemoveAt(int index)
                        {
                                if (index < 0 || index >= list.Count) {
@@ -713,6 +785,14 @@ namespace System.Windows.Forms
                        }
 
 #if NET_2_0
+                       public virtual void RemoveByKey (string key)
+                       {
+                               int index = IndexOfKey (key);
+                               
+                               if (index >= 0)
+                                       RemoveAt (index);
+                       }       
+               
                        public virtual void
 #else
                        public void
@@ -874,9 +954,6 @@ namespace System.Windows.Forms
                        tab_stop = true;
                        ime_mode = ImeMode.Inherit;
 
-                       layout_engine = this.LayoutEngine;
-                       if (layout_engine == null)
-                               layout_engine = new Layout.DefaultLayout ();
 #if NET_2_0
                        backgroundimage_layout = ImageLayout.Tile;
                        use_compatible_text_rendering = Application.use_compatible_text_rendering;
@@ -903,7 +980,8 @@ namespace System.Windows.Forms
                        child_controls = CreateControlsInstance();
                        client_size = new Size(DefaultSize.Width, DefaultSize.Height);
                        client_rect = new Rectangle(0, 0, DefaultSize.Width, DefaultSize.Height);
-                       XplatUI.CalculateWindowRect(ref client_rect, CreateParams.Style, CreateParams.ExStyle, null, out bounds);
+                       bounds.Size = SizeFromClientSize (client_size);
+                       
                        if ((CreateParams.Style & (int)WindowStyles.WS_CHILD) == 0) {
                                bounds.X=-1;
                                bounds.Y=-1;
@@ -1001,8 +1079,9 @@ namespace System.Windows.Forms
                                        border_style = value;
 
                                        if (IsHandleCreated) {
-                                               XplatUI.SetBorderStyle(window.Handle, (FormBorderStyle)border_style);
-                                               Refresh();
+                                               XplatUI.SetBorderStyle (window.Handle, (FormBorderStyle)border_style);
+                                               RecreateHandle ();
+                                               Refresh ();
                                        }
                                }
                        }
@@ -1138,7 +1217,7 @@ namespace System.Windows.Forms
                        }
 
                        container = GetContainerControl();
-                       if (container != null) {
+                       if (container != null && (Control)container != control) {
                                container.ActiveControl = control;
                        }
                        if (control.IsHandleCreated) {
@@ -1801,9 +1880,10 @@ namespace System.Windows.Forms
 
                                anchor_style=value;
 
-                               if (parent != null) {
+                               UpdateDistances ();
+
+                               if (parent != null)
                                        parent.PerformLayout(this, "Anchor");
-                               }
                        }
                }
 
@@ -1819,12 +1899,12 @@ namespace System.Windows.Forms
                [DefaultValue (false)]
                [MonoTODO("This method currently does nothing")]
                public virtual bool AutoSize {
-                       get {
-                               //Console.Error.WriteLine("Unimplemented: Control::get_AutoSize()");
-                               return auto_size;
-                       }
+                       get { return auto_size; }
                        set {
-                               auto_size = value;
+                               if (this.auto_size != value) {
+                                       auto_size = value;
+                                       OnAutoSizeChanged (EventArgs.Empty);
+                               }
                        }
                }
                
@@ -1847,7 +1927,10 @@ namespace System.Windows.Forms
                                return minimum_size;
                        }
                        set {
-                               minimum_size = value;
+                               if (minimum_size != value) {
+                                       minimum_size = value;
+                                       PerformLayout ();
+                               }
                        }
                }
 #endif // NET_2_0
@@ -1912,6 +1995,7 @@ namespace System.Windows.Forms
                                if (value != backgroundimage_layout) {
                                        backgroundimage_layout = value;
                                        Invalidate ();
+                                       OnBackgroundImageLayoutChanged (EventArgs.Empty);
                                }
                                
                        }
@@ -2067,6 +2151,9 @@ namespace System.Windows.Forms
 
                        set {
                                this.SetClientSizeCore(value.Width, value.Height);
+#if NET_2_0
+                               this.OnClientSizeChanged (EventArgs.Empty);
+#endif
                        }
                }
 
@@ -2080,10 +2167,10 @@ namespace System.Windows.Forms
                        }
                }
 
-        internal bool ContainerSelected {
-            get { return container_selected; }
-            set { container_selected = value; }
-        }
+               internal bool ContainerSelected {
+                       get { return container_selected; }
+                       set { container_selected = value; }
+               }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                [Browsable(false)]
@@ -2309,14 +2396,15 @@ namespace System.Windows.Forms
                        }
 
                        set {
+                               if (this.is_enabled != value) {
+                                       bool old_value = is_enabled;
 
-                               bool old_value = is_enabled;
+                                       is_enabled = value;
+                                       if (old_value != value && !value && this.has_focus)
+                                               SelectNextControl(this, true, true, true, true);
 
-                               is_enabled = value;
-                               if (old_value != value && !value && this.has_focus)
-                                       SelectNextControl(this, true, true, true, true);
-
-                               OnEnabledChanged (EventArgs.Empty);
+                                       OnEnabledChanged (EventArgs.Empty);
+                               }
                        }
                }
 
@@ -2355,6 +2443,7 @@ namespace System.Windows.Forms
                                font = value;
                                Invalidate();
                                OnFontChanged (EventArgs.Empty);
+                               PerformLayout ();
                        }
                }
 
@@ -2502,8 +2591,12 @@ namespace System.Windows.Forms
                public virtual
 #endif
                Layout.LayoutEngine LayoutEngine {
-                       get { return new Layout.DefaultLayout (); }
-               } 
+                       get {
+                               if (layout_engine == null)
+                                       layout_engine = new Layout.DefaultLayout ();
+                               return layout_engine;
+                       }
+               }
 
                [EditorBrowsable(EditorBrowsableState.Always)]
                [Browsable(false)]
@@ -2534,7 +2627,12 @@ namespace System.Windows.Forms
                [Localizable (true)]
                public Padding Margin {
                        get { return this.margin; }
-                       set { this.margin = value; }
+                       set { 
+                               if (this.margin != value) {
+                                       this.margin = value; 
+                                       OnMarginChanged (EventArgs.Empty);
+                               }
+                       }
                }
 #endif
 
@@ -2557,8 +2655,11 @@ namespace System.Windows.Forms
                        }
 
                        set {
-                               padding = value;
-                               OnPaddingChanged (EventArgs.Empty);
+                               if (padding != value) {
+                                       padding = value;
+                                       OnPaddingChanged (EventArgs.Empty);
+                                       PerformLayout ();
+                               }
                        }
                }
 #endif
@@ -2636,10 +2737,15 @@ namespace System.Windows.Forms
                        }
 
                        set {
-                               if (value != null && IsHandleCreated) {
-                                       XplatUI.SetClipRegion(Handle, value);
+                               if (clip_region != value) {
+                                       if (value != null && IsHandleCreated)
+                                               XplatUI.SetClipRegion(Handle, value);
+
+                                       clip_region = value;
+#if NET_2_0
+                                       OnRegionChanged (EventArgs.Empty);
+#endif
                                }
-                               clip_region = value;
                        }
                }
 
@@ -2670,6 +2776,7 @@ namespace System.Windows.Forms
                                if (value != right_to_left) {
                                        right_to_left = value;
                                        OnRightToLeftChanged(EventArgs.Empty);
+                                       PerformLayout ();
                                }
                        }
                }
@@ -2936,6 +3043,10 @@ namespace System.Windows.Forms
                        }
                }
 
+#if NET_2_0
+               protected virtual Cursor DefaultCursor { get { return Cursors.Default; } }
+#endif
+
                protected virtual ImeMode DefaultImeMode {
                        get {
                                return ImeMode.Inherit;
@@ -2946,6 +3057,10 @@ namespace System.Windows.Forms
                protected virtual Padding DefaultMargin {
                        get { return new Padding (3); }
                }
+               
+               protected virtual Size DefaultMaximumSize { get { return new Size (); } }
+               protected virtual Size DefaultMinimumSize { get { return new Size (); } }
+               protected virtual Padding DefaultPadding { get { return new Padding (); } }
 #endif
 
                protected virtual Size DefaultSize {
@@ -3226,14 +3341,17 @@ namespace System.Windows.Forms
                        if (!IsHandleCreated)
                                return;
 
-                       NotifyInvalidate(rc);
+                       if  (rc.Width > 0 && rc.Height > 0) {
 
-                       XplatUI.Invalidate(Handle, rc, false);
+                               NotifyInvalidate(rc);
 
-                       if (invalidateChildren) {
-                               Control [] controls = child_controls.GetAllControls ();
-                               for (int i=0; i<controls.Length; i++)
-                                       controls [i].Invalidate ();
+                               XplatUI.Invalidate(Handle, rc, false);
+
+                               if (invalidateChildren) {
+                                       Control [] controls = child_controls.GetAllControls ();
+                                       for (int i=0; i<controls.Length; i++)
+                                               controls [i].Invalidate ();
+                               }
                        }
                        OnInvalidated(new InvalidateEventArgs(rc));
                }
@@ -3306,9 +3424,6 @@ namespace System.Windows.Forms
 
                        // Perform all Dock and Anchor calculations
                        try {
-                               layout_engine.Layout(this, levent);
-
-                               // Let everyone know
                                OnLayout(levent);
                        }
 
@@ -3980,8 +4095,9 @@ namespace System.Windows.Forms
                        IContainerControl       container;
                        
                        container = GetContainerControl();
-                       if (container != null)
-                               container.ActiveControl = this;
+                       if (container != null && (Control)container != this)
+                if (!this.Parent.ContainerSelected)
+                                   container.ActiveControl = this;
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -4007,19 +4123,10 @@ namespace System.Windows.Forms
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void SetClientSizeCore(int x, int y) {
-                       // Calculate the actual window size from the client size (it usually stays the same or grows)
-                       Rectangle       ClientRect;
-                       Rectangle       WindowRect;
-                       CreateParams    cp;
-
-                       ClientRect = new Rectangle(0, 0, x, y);
-                       cp = this.CreateParams;
-
-                       if (XplatUI.CalculateWindowRect(ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect)==false) {
-                               return;
-                       }
-
-                       SetBounds(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
+                       Size NewSize = SizeFromClientSize (new Size (x, y));
+                       
+                       if (NewSize != Size.Empty)
+                               SetBounds (bounds.X, bounds.Y, NewSize.Width, NewSize.Height, BoundsSpecified.Size);
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -4033,7 +4140,7 @@ namespace System.Windows.Forms
 
                protected void SetTopLevel(bool value) {
                        if ((GetTopLevel() != value) && (parent != null)) {
-                               throw new Exception();
+                               throw new ArgumentException ("Cannot change toplevel style of a parented control.");
                        }
 
                        if (this is Form) {
@@ -4043,7 +4150,7 @@ namespace System.Windows.Forms
                                        }
                                } else {
                                        if (Visible) {
-                                               Visible = false;
+                                               Visible = false;
                                        }
                                }
                        }
@@ -4082,11 +4189,32 @@ namespace System.Windows.Forms
                                if (parent != null) {
                                        parent.PerformLayout(this, "visible");
                                } else {
-                                       PerformLayout(this, "visible");
+                                       if (is_visible)
+                                               PerformLayout(this, "visible");
                                }
                        }
                }
-       
+
+#if NET_2_0
+               protected 
+#else
+               internal
+#endif
+               virtual Size SizeFromClientSize (Size clientSize)
+               {
+                       Rectangle ClientRect;
+                       Rectangle WindowRect;
+                       CreateParams cp;
+
+                       ClientRect = new Rectangle (0, 0, clientSize.Width, clientSize.Height);
+                       cp = this.CreateParams;
+
+                       if (XplatUI.CalculateWindowRect (ref ClientRect, cp.Style, cp.ExStyle, null, out WindowRect))
+                               return new Size (WindowRect.Width, WindowRect.Height);
+                               
+                       return Size.Empty;
+               }
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected void UpdateBounds() {
                        int     x;
@@ -4150,6 +4278,9 @@ namespace System.Windows.Forms
 
                        if (resized) {
                                OnSizeChanged(EventArgs.Empty);
+#if NET_2_0
+                               OnClientSizeChanged (EventArgs.Empty);
+#endif
                        }
                }
 
@@ -4555,11 +4686,11 @@ namespace System.Windows.Forms
                        }
 
                        case Msg.WM_SETFOCUS: {
-                               if (!has_focus) {
-                                       this.has_focus = true;
+                               if (!has_focus) {                
                     if (this.Parent != null && this.Parent.ContainerSelected)
                         return;
-                                   OnGotFocusInternal (EventArgs.Empty);
+                    this.has_focus = true;
+                    OnGotFocusInternal (EventArgs.Empty);
                                }
                                return;
                        }
@@ -4590,7 +4721,16 @@ namespace System.Windows.Forms
                #endregion      // Public Instance Methods
 
                #region OnXXX methods
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
+#if NET_2_0
+               protected virtual void OnAutoSizeChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[AutoSizeChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+#endif
+
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected virtual void OnBackColorChanged(EventArgs e) {
                        EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]);
                        if (eh != null)
@@ -4606,6 +4746,16 @@ namespace System.Windows.Forms
                        for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentBackgroundImageChanged(e);
                }
 
+#if NET_2_0
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected virtual void OnBackgroundImageLayoutChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[BackgroundImageLayoutChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+#endif
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void OnBindingContextChanged(EventArgs e) {
                        CheckDataBindings ();
@@ -4636,6 +4786,16 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
+#if NET_2_0
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected virtual void OnClientSizeChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[ClientSizeChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+#endif
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void OnContextMenuChanged(EventArgs e) {
                        EventHandler eh = (EventHandler)(Events [ContextMenuChangedEvent]);
@@ -4861,6 +5021,8 @@ namespace System.Windows.Forms
                        LayoutEventHandler eh = (LayoutEventHandler)(Events [LayoutEvent]);
                        if (eh != null)
                                eh (this, levent);
+
+                       LayoutEngine.Layout (this, levent);
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -4886,6 +5048,13 @@ namespace System.Windows.Forms
                }
 
 #if NET_2_0
+               protected virtual void OnMarginChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[MarginChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected virtual void OnMouseCaptureChanged (EventArgs e)
                {
@@ -5086,13 +5255,23 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
+#if NET_2_0
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected virtual void OnRegionChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[RegionChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+#endif
+
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void OnResize(EventArgs e) {
+                       PerformLayout(this, "Bounds");
+
                        EventHandler eh = (EventHandler)(Events [ResizeEvent]);
                        if (eh != null)
                                eh (this, e);
-
-                       PerformLayout(this, "Bounds");
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]