Author: toshok
Date: 2007-01-10 14:28:52 -0500 (Wed, 10 Jan 2007)
New Revision: 70804

Modified:
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
   
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
Log:
2007-01-10  Chris Toshok  <[EMAIL PROTECTED]>

        * ContainerControl.cs (set_ActiveControl): rework this a bit (and
        add some nice ascii art pictures and explanation of the process).
        (GetMostDeeplyNestedActiveControl): new utility function we need
        because our ActiveControl can refer to a child container with its
        own ActiveControl.

        * Form.cs (OnActivated): remove the call to SelectActiveControl
        from here, since you can override this method and not chain up,
        and winforms still sets the active control.
        (OnCreateControl): also remove the unnecessary SelectActiveControl
        call from here.
        (WndProc): it's actually called from the WM_ACTIVATE block, just
        before calling OnActivated.

        * Control.cs (Select (Control)): move the call to XplatUI.SetFocus
        inside the else.  the ActiveControl setter will end up setting
        focus on @control.  This keeps us from setting it again (and
        generating an extra LostFocus/GotFocus pair).
        (Select (bool, bool)): reindent.



Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1,3 +1,25 @@
+2007-01-10  Chris Toshok  <[EMAIL PROTECTED]>
+
+       * ContainerControl.cs (set_ActiveControl): rework this a bit (and
+       add some nice ascii art pictures and explanation of the process).
+       (GetMostDeeplyNestedActiveControl): new utility function we need
+       because our ActiveControl can refer to a child container with its
+       own ActiveControl.
+
+       * Form.cs (OnActivated): remove the call to SelectActiveControl
+       from here, since you can override this method and not chain up,
+       and winforms still sets the active control.
+       (OnCreateControl): also remove the unnecessary SelectActiveControl
+       call from here.
+       (WndProc): it's actually called from the WM_ACTIVATE block, just
+       before calling OnActivated.
+
+       * Control.cs (Select (Control)): move the call to XplatUI.SetFocus
+       inside the else.  the ActiveControl setter will end up setting
+       focus on @control.  This keeps us from setting it again (and
+       generating an extra LostFocus/GotFocus pair).
+       (Select (bool, bool)): reindent.
+
 2007-01-10  Jonathan Pobst  <[EMAIL PROTECTED]>
 
        * FlowLayoutPanel.cs, MenuStrip.cs, SplitContainer.cs, SplitterPanel.cs,

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
===================================================================
--- 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs  
    2007-01-10 19:27:11 UTC (rev 70803)
+++ 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs  
    2007-01-10 19:28:52 UTC (rev 70804)
@@ -69,7 +69,7 @@
                        }
 
                        set {
-                               if (value==null || (active_control == value && 
active_control.has_focus)) {
+                               if (value==null || (active_control == value)) {
                                        return;
                                }
 
@@ -80,34 +80,83 @@
                                // Fire the enter and leave events if possible
                                Form form = FindForm ();
                                if (form != null) {
-                                       Control active = form.ActiveControl;
-                                       Control common_container = 
GetCommonContainer (form.ActiveControl, value);
+                                       Control active = 
GetMostDeeplyNestedActiveControl (form);
+                                       Control common_container = 
GetCommonContainer (active, value);
                                        ArrayList chain = new ArrayList ();
+                                       ArrayList validation_chain = new 
ArrayList ();
                                        Control walk = active;
 
-                                       // Generate the leave messages  
+                                       // we split this up into three steps:
+                                       //    1. walk up the tree (if we need 
to) to our root, firing leave events.
+                                       //    2. validate.
+                                       //    3. walk down the tree (if we need 
to), firing enter events.
+
+                                       // "our root" is either the common 
container of the current active
+                                       // control and the new active control, 
or the current active control,
+                                       // or the new active control.  That is, 
it's either one of these three
+                                       // configurations:
+
+                                       //  (1)     root            (2)  new    
      (3)  current
+                                       //          /  \                /   \   
            /   \
+                                       //        ...   ...           ...   ... 
          ...   ...
+                                       //        /      \            /         
                  \
+                                       //     current   new       current      
                  new
+
+
+                                       // note (3) doesn't require any upward 
walking, and no leave events are generated.
+                                       //      (2) doesn't require any 
downward walking, and no enter events are generated.
+
+                                       // as we walk up the tree, we generate 
a list of all controls which cause
+                                       // validation.  After firing the leave 
events, we invoke (in order starting from
+                                       // the most deeply nested) their 
Validating event.  If one sets CancelEventArgs.Cancel
+                                       // to true, we ignore the control the 
user wanted to set ActiveControl to, and use
+                                       // the Validating control instead.
+
+                                       bool fire_enter = true;
+                                       Control root = common_container;
+
+                                       // Generate the leave messages
                                        while (walk != common_container) {
+                                               if (walk == value) {
+                                                       root = value;
+                                                       fire_enter = false;
+                                                       break;
+                                               }
                                                walk.FireLeave ();
-                                               if (walk.CausesValidation && 
!ValidateControl (walk))
-                                                       return;
+                                               /* clear our idea of the active 
control as we go back up */
+                                               if (walk is ContainerControl)
+                                                       
((ContainerControl)walk).active_control = null;
+
+                                               if (walk.CausesValidation)
+                                                       validation_chain.Add 
(walk);
+
                                                walk = walk.Parent;
                                        }
 
-                                       walk = value;
-                                       while (walk != common_container) {
-                                               chain.Add (walk);
-                                               walk = walk.Parent;
+                                       for (int i = 0; i < 
validation_chain.Count; i ++) {
+                                               if (!ValidateControl 
((Control)validation_chain[i])) {
+                                                       value = 
(Control)validation_chain[i];
+                                                       fire_enter = true;
+                                               }
                                        }
 
-                                       for (int i = chain.Count - 1; i >= 0; 
i--) {
-                                               walk = (Control) chain [i];
-                                               walk.FireEnter ();
+                                       if (fire_enter) {
+                                               walk = value;
+                                               while (walk != root) {
+                                                       chain.Add (walk);
+                                                       walk = walk.Parent;
+                                               }
+
+                                               for (int i = chain.Count - 1; i 
>= 0; i--) {
+                                                       walk = (Control) chain 
[i];
+                                                       walk.FireEnter ();
+                                               }
                                        }
 
-                                       walk = this.Parent;
+                                       walk = this;
                                        while (walk != null) {
-                                               if (walk is ContainerControl)
-                                                       
((ContainerControl)walk).active_control = this;
+                                               if (walk.Parent is 
ContainerControl)
+                                                       
((ContainerControl)walk.Parent).active_control = walk;
                                                walk = walk.Parent;
                                        }
                                }
@@ -127,10 +176,6 @@
 
                private bool ValidateControl (Control c)
                {
-                       if (c is ContainerControl && 
((ContainerControl)c).ActiveControl != null && !c.ContainerSelected)
-                               if 
(!((ContainerControl)c).ValidateControl(((ContainerControl)c).ActiveControl))
-                                       return false;
-
                        CancelEventArgs e = new CancelEventArgs ();
 
                        c.FireValidating (e);
@@ -142,6 +187,17 @@
                        return true;
                }
 
+               private Control GetMostDeeplyNestedActiveControl 
(ContainerControl container)
+               {
+                       Control active = container.ActiveControl;
+                       while (active is ContainerControl) {
+                               if (((ContainerControl)active).ActiveControl == 
null)
+                                       break;
+                               active = 
((ContainerControl)active).ActiveControl;
+                       }
+                       return active;
+               }
+
                // Just in a separate method to make debugging a little easier,
                // should eventually be rolled into ActiveControl setter
                private Control GetCommonContainer (Control active_control, 
Control value)
@@ -190,7 +246,7 @@
                                if (auto_scale_dimensions.IsEmpty) {
                                        return new SizeF(1f, 1f);
                                }
-                               return new 
SizeF(CurrentAutoScaleDimensions.Width / auto_scale_dimensions.Width, 
+                               return new 
SizeF(CurrentAutoScaleDimensions.Width / auto_scale_dimensions.Width,
                                        CurrentAutoScaleDimensions.Height / 
auto_scale_dimensions.Height);
                        }
                }
@@ -315,7 +371,7 @@
                        base.Dispose(disposing);
                }
 
-               // LAMESPEC This used to be documented, but it's not in code 
+               // LAMESPEC This used to be documented, but it's not in code
                // and no longer listed in MSDN2
                // [EditorBrowsable (EditorBrowsableState.Advanced)]
                // protected override void OnControlRemoved(ControlEventArgs e) 
{
@@ -380,7 +436,7 @@
                                                return true;
                                        }
                                        break;
-                               } 
+                               }
 
 
                        }
@@ -409,7 +465,7 @@
                                        wrapped = true;
                                }
                        } while (c != active_control);
-                       
+
                        return false;
                }
 
@@ -441,18 +497,22 @@
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected override void WndProc(ref Message m) {
                        switch ((Msg) m.Msg) {
-                       
+
                                case Msg.WM_LBUTTONDOWN:
-                                       OnMouseDown (new MouseEventArgs 
(FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
+                                       OnMouseDown (new MouseEventArgs 
(FromParamToMouseButtons ((int) m.WParam.ToInt32()),
                                                mouse_clicks, LowOrder ((int) 
m.LParam.ToInt32 ()),
                                                HighOrder ((int) 
m.LParam.ToInt32 ()), 0));
                                break;
-                       
+
                                case Msg.WM_SETFOCUS:
                                        if (active_control != null)
                                                Select (active_control);
                                        else
+                                               base.WndProc (ref m);
+#if false
+                                       else
                                                SelectNextControl (null, true, 
true, true, false);
+#endif
                                break;
 
                                default:
@@ -468,7 +528,7 @@
                        // do nothing here, only called if it is a Form
                }
                #endregion      // Internal Methods
-               
+
 #if NET_2_0
                protected override void OnParentChanged (EventArgs e)
                {

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs       
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs       
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1218,7 +1218,7 @@
                        if (container != null && (Control)container != control) 
{
                                container.ActiveControl = control;
                        }
-                       if (control.IsHandleCreated) {
+                       else if (control.IsHandleCreated) {
                                XplatUI.SetFocus(control.window.Handle);
                        }
                        return true;
@@ -4117,8 +4117,8 @@
                        
                        container = GetContainerControl();
                        if (container != null && (Control)container != this)
-                if (!this.Parent.ContainerSelected)
-                                   container.ActiveControl = this;
+                               if (!this.Parent.ContainerSelected)
+                                       container.ActiveControl = this;
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs  
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs  
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1520,9 +1520,6 @@
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected virtual void OnActivated(EventArgs e)
                {
-                       if (is_loaded)
-                               SelectActiveControl ();
-
                        EventHandler eh = (EventHandler)(Events 
[ActivatedEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -1553,8 +1550,6 @@
 
                        OnLoad(EventArgs.Empty);
                        
-                       SelectActiveControl ();
-
                        // Send initial location
                        OnLocationChanged(EventArgs.Empty);
 
@@ -1934,6 +1929,9 @@
        
                                case Msg.WM_ACTIVATE: {
                                        if (m.WParam != 
(IntPtr)WindowActiveFlags.WA_INACTIVE) {
+                                               if (is_loaded)
+                                                       SelectActiveControl ();
+
                                                OnActivated(EventArgs.Empty);
                                        } else {
                                                OnDeactivate(EventArgs.Empty);

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to