* ContextMenu.cs : SourceControl, Show method
[mono.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / Control.cs
index 0d5e5ce45ac7a841b0b976c087d242512b3baf40..eef0b0ee10805851740f5f8bfcc6ed2ea78ccc1d 100644 (file)
@@ -73,7 +73,7 @@
                Rectangle oldBounds;
 
                bool causesValidation;
-               //ContextMenu contextMenu;
+               ContextMenu contextMenu;
                DockStyle dock;
                bool enabled;
                Font font;
@@ -86,8 +86,9 @@
                RightToLeft rightToLeft;
                bool tabStop;
                protected string text;
-               bool visible;
+               protected bool visible;
                protected ControlStyles controlStyles_;
+               Cursor  cursor;
 
                int clientWidth;
                int clientHeight;
@@ -98,6 +99,7 @@
                private static readonly int DISPOSED         = BitVector32.CreateMask( LAYOUT_PENDING );
                private static readonly int RECREATING_HANDLE= BitVector32.CreateMask( DISPOSED );
                private static readonly int CREATED          = BitVector32.CreateMask( RECREATING_HANDLE );
+               private static readonly int DISPOSING        = BitVector32.CreateMask( CREATED );
 
                        object tag;
                        protected bool mouseIsInside_;
                        oldBounds = new Rectangle();
                        // bindingContext = null;
                        causesValidation = true;
-                       // contextMenu = null;
+                       contextMenu = null;
                        dock = DockStyle.None;
                        enabled = true;
                        // font = Control.DefaultFont;
                        text = "";
                        visible = true;
                        parent = null;
+                       cursor = null;
 
                        oldBounds.Width  = bounds.Width = DefaultSize.Width;
                        oldBounds.Height = bounds.Height= DefaultSize.Height;
                [MonoTODO]
                public bool CanSelect {
                        get {
-    //                                 if (ControlStyles.Selectable &&
-    //                                     isContainedInAnotherControl &&
-    //                                     parentIsVisiable && isVisialbe &&
-    //                                     parentIsEnabled && isEnabled) {
-    //                                         return true;
-    //                                 }
-    //                                 return false;
-    
-                               throw new NotImplementedException ();
+                               if ( !GetStyle ( ControlStyles.Selectable ) )
+                                       return false;
+
+                               if ( Parent == null )
+                                       return false;
+
+                               Control parent = Parent;
+                               while ( parent != null ) {
+                                       if ( !parent.Visible || !parent.Enabled )
+                                               return false;
+                                       parent = parent.Parent;
+                               }
+
+                               return true;
                        }
                }
                
                public bool ContainsFocus {
                        get {
                                if (IsHandleCreated) {
-                                       IntPtr focusedWindow = Win32.GetFocus();
-                                       if (focusedWindow == Handle)
-                                               return true;
+                                               if (Focused) return true;
+                                               foreach (Control ctr in Controls) {
+                                                       if (ctr.ContainsFocus) return true;
+                                               }
                                }
                                return false;
                        }
                [MonoTODO]
                public virtual ContextMenu ContextMenu {
                        get {
-                               //return contextMenu;
-                               throw new NotImplementedException ();
+                               return contextMenu;
                        }
                        set {
-                               //contextMenu=value;
-                               throw new NotImplementedException ();
+                               if ( contextMenu != value ) {
+                                       contextMenu = value;
+                                       OnContextMenuChanged ( EventArgs.Empty );
+                               }
                        }
                }
                
                                                createParams.Parent = ParkingWindowHandle;
          
                                        createParams.Style = (int) WindowStyles.WS_OVERLAPPED;
+                                       if( visible) {
+                                               createParams.Style |= (int) WindowStyles.WS_VISIBLE;
+                                       }
          
                                return createParams;
                        }
 
                [MonoTODO]
                public virtual Cursor Cursor {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-                       set {
-                               throw new NotImplementedException ();
-                       }
+                       get { 
+                               if ( cursor == null )
+                                       return Cursors.Default;
+                               return cursor; 
+                       }
+                       set { cursor = value;}
                }
                
                        //Compact Framework
                        }
                }
                
-               [MonoTODO]
                public bool Disposing {
-                       get {
-                               throw new NotImplementedException ();
-                       }
+                       get { return statuses [ DISPOSING ]; }
                }
                
                public virtual DockStyle Dock {
                        //Compact Framework
                public virtual bool Focused {
                        get {
-                               return ContainsFocus;
-                       }
+                                       if (IsHandleCreated) {
+                                               IntPtr focusedWindow = Win32.GetFocus();
+                                               if (focusedWindow == Handle)
+                                                       return true;
+                                       }
+                                       return false;
+                               }
                }
                
                        //Compact Framework
                        }
                }
                
-               private static IntPtr ParkingWindowHandle {
+               protected static IntPtr ParkingWindowHandle {
                        get {
                                if ( parkingWindow == null )
                                        parkingWindow = new NativeWindow ( );
                        }
                }
        
-               protected override void Dispose (bool disposing
+               protected override void Dispose ( bool disposing 
                {
-                       statuses [ DISPOSED ] = true;
-                               //FIXME: 
-                       base.Dispose(disposing);
+                       lock ( this ) {
+                               statuses [ DISPOSING ] = true;
+                               try {
+                                       if ( disposing ) {
+                                               DestroyHandle ( );
+                                       }
+                                       // close/free unmanaged resources
+                               }
+                               finally {
+                                       base.Dispose( disposing );
+                               }
+                               statuses [ DISPOSED ] = true;
+                       }
                }
        
                [MonoTODO]
                
                protected virtual void OnDockChanged (EventArgs e)
                {
-                       PerformLayout ( this, "Dock" );
+                       // changing this property does not affect the control directly
+                       // so have its parent to calculate new layout
+                       if ( Parent != null )
+                               Parent.PerformLayout ( this, "Dock" );
                        if (DockChanged != null)
                                DockChanged (this, e);
                }
                
                protected virtual void OnLocationChanged (EventArgs e) 
                {
-                       PerformLayout ( this, "Location" );
                        if (LocationChanged != null)
                                LocationChanged (this, e);
                }
                        if (Resize != null)
                                Resize (this, e);
 
-                       PerformLayout ( );
+                       PerformLayout ( this, "Bounds" );
                }
                
                protected virtual void OnRightToLeftChanged (EventArgs e) 
                protected virtual void OnSizeChanged (EventArgs e) 
                {
                        OnResize ( e );
-                       PerformLayout ( this, "Size" );
                        if (SizeChanged != null)
                                SizeChanged (this, e);
                }
 
                        visible = value;
 
+                       if ( visibleChanged )
+                               OnVisibleChanged ( EventArgs.Empty );
+
                        if ( IsHandleCreated ) {
                                SetWindowPosFlags flags = value ? SetWindowPosFlags.SWP_SHOWWINDOW : SetWindowPosFlags.SWP_HIDEWINDOW;
                                flags |= SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE;
 
                        foreach ( Control c in Controls )
                                c.Visible = value ;
-
-                       if ( visibleChanged )
-                               OnVisibleChanged ( EventArgs.Empty );
                }
                
                public void Show () 
                                        }
                                        break;
                        case Msg.WM_SIZE:
-                               OnResize (eventArgs);
-                               UpdateBounds ( );
                                if( GetStyle(ControlStyles.ResizeRedraw)) {
                                        Invalidate();           
                                }
                                        CallControlWndProc(ref m);
                                        }
                                        break;
+                               case Msg.WM_SETCURSOR:
+                                       if ( cursor != null && cursor.Handle != IntPtr.Zero ) {
+                                               Win32.SetCursor ( cursor.Handle );
+                                               m.Result = (IntPtr)1;
+                                       } else
+                                               CallControlWndProc( ref m );
+                               break;
+                               case Msg.WM_RBUTTONDOWN:
+                                       if ( contextMenu != null ) {
+                                               contextMenu.Show ( this, 
+                                                       new Point ( Win32.HIGH_ORDER ( m.LParam.ToInt32() ),
+                                                                   Win32.LOW_ORDER ( m.LParam.ToInt32() ) ) );
+                                       }
+                                       CallControlWndProc( ref m );
+                               break;
                                default:
                                        CallControlWndProc(ref m);
 /*
                        }
                }
 
+               private void DoAnchor(Control ctrl) {
+                       int deltaWidth = Bounds.Width - oldBounds.Width;
+                       int deltaHeight = Bounds.Height - oldBounds.Height;
+                       int halfDeltaWidth = deltaWidth / 2;
+                       int halfDeltaHeight = deltaHeight / 2;
+                       Rectangle controlBounds = ctrl.Bounds;
+                       if ((ctrl.Anchor & AnchorStyles.Left) == 0) {
+                               controlBounds.X += halfDeltaWidth;
+                       }
+                       if ((ctrl.Anchor & AnchorStyles.Top) == 0) {
+                               controlBounds.Y += halfDeltaHeight;
+                       }
+                       if ((ctrl.Anchor & AnchorStyles.Right) == AnchorStyles.Right) {
+                               if ((ctrl.Anchor & AnchorStyles.Left) == AnchorStyles.Left) {
+                                       controlBounds.Width += deltaWidth;
+                               }
+                               else {
+                                       controlBounds.X += halfDeltaWidth;
+                               }
+                       }
+                       if ((ctrl.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom) {
+                               if ((ctrl.Anchor & AnchorStyles.Top) == AnchorStyles.Top) {
+                                       controlBounds.Height += deltaHeight;
+                               }
+                               else {
+                                       controlBounds.Y += halfDeltaHeight;
+                               }
+                       }
+                       ctrl.Bounds = controlBounds;
+               }
+
                private void DoDockAndAnchorLayout ( LayoutEventArgs e ) {
                        Rectangle area = DisplayRectangle;
                        
                                        area.X += control.Width;
                                        area.Width -= control.Width;
                                break;
+                               case DockStyle.None:
+                                       DoAnchor(control);
+                               break;
                                }
                        }