* X11Dnd.cs: Add support for handling the QueryContinue and
authorJackson Harper <jackson@novell.com>
Wed, 31 Jan 2007 19:31:01 +0000 (19:31 -0000)
committerJackson Harper <jackson@novell.com>
Wed, 31 Jan 2007 19:31:01 +0000 (19:31 -0000)
        GiveFeedback events.
        - Cancel drag and drop actions when the escape key is clicked.
        * XplatUIX11.cs: Let the dnd subsystem get key events, so that
        * it
        can handle the ESCAPE key.
        - Allow dnd to swallow BUTTONUP messages if it needs to.  This
          is
        done when dnd events are continued after the button is released.
        - Add a new helper method so that dnd can translate key events.

svn path=/trunk/mcs/; revision=72049

mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

index b128c9065738dd954ee96ec7dadd7884089010c2..2d20ed9045ae3f694cfc00cf87f6b626b165a21e 100644 (file)
@@ -1,3 +1,14 @@
+2007-01-31  Jackson Harper  <jackson@ximian.com>
+
+       * X11Dnd.cs: Add support for handling the QueryContinue and
+       GiveFeedback events.
+       - Cancel drag and drop actions when the escape key is clicked.
+       * XplatUIX11.cs: Let the dnd subsystem get key events, so that it
+       can handle the ESCAPE key.
+       - Allow dnd to swallow BUTTONUP messages if it needs to.  This is
+       done when dnd events are continued after the button is released.
+       - Add a new helper method so that dnd can translate key events.
+
 2007-01-31  Alexander Olk  <alex.olk@googlemail.com>
 
        * FileDialog.cs: Rewrite of Jacksons OnClickCancelButton patch to
index 1331c328a6a82b59593bdab7764edd54db336be0..ac2e6d2ddb79c46aa8f6687af62f418e1b91fd3b 100644 (file)
@@ -381,24 +381,26 @@ namespace System.Windows.Forms {
                        return DragDropEffects.Copy;
                }
 
-               public void HandleButtonRelease (ref XEvent xevent)
+               public bool HandleButtonRelease (ref XEvent xevent)
                {
                        if (drag_data == null)
-                               return;
+                               return false;
 
                        if (!((drag_data.MouseState == MouseButtons.Left &&
                                              xevent.ButtonEvent.button == 1) ||
                                            (drag_data.MouseState == MouseButtons.Right &&
                                                            xevent.ButtonEvent.button == 3)))
-                               return;
+                               return false;
 
                        if (drag_data.State == DragState.Beginning) {
                                //state = State.Accepting;
                        } else if (drag_data.State != DragState.None) {
 
                                if (drag_data.WillAccept) {
-                                       SendDrop (drag_data.LastTopLevel, xevent.AnyEvent.window,
-                                                       xevent.ButtonEvent.time);
+
+                                       if (QueryContinue (xevent, false, DragAction.Drop))
+                                               return true;
+                                       
                                }
 
                                drag_data.State = DragState.None;
@@ -406,6 +408,8 @@ namespace System.Windows.Forms {
                                // most likely going to be used by the SelectionRequest
                                // handlers
                        }
+
+                       return false;
                }
 
                public bool HandleMotionNotify (ref XEvent xevent)
@@ -490,6 +494,16 @@ namespace System.Windows.Forms {
                        return false;
                }
 
+               public bool HandleKeyPress (ref XEvent xevent)
+               {
+                       if (VirtualKeys.VK_ESCAPE == XplatUIX11.EventToKeyCode (xevent)) {
+                               if (!QueryContinue (xevent, true, DragAction.Cancel))
+                                       return true;
+                       }
+
+                       return false;
+               }
+
                // return true if the event is handled here
                public bool HandleClientMessage (ref XEvent xevent)
                {
@@ -546,6 +560,62 @@ namespace System.Windows.Forms {
                        return true;
                }
 
+               private bool QueryContinue (XEvent xevent, bool escape, DragAction action)
+               {
+                       QueryContinueDragEventArgs qce = new QueryContinueDragEventArgs ((int) XplatUI.State.ModifierKeys,
+                                       escape, action);
+                       Control c = MwfWindow (source);
+                       c.DndContinueDrag (qce);
+
+                       switch (qce.Action) {
+                       case DragAction.Continue:
+                               return true;
+                       case DragAction.Drop:
+                               Console.WriteLine ("sending drop");
+                               SendDrop (drag_data.LastTopLevel, source, xevent.ButtonEvent.time);
+                               break;
+                       case DragAction.Cancel:
+                               drag_data.Reset ();
+                               c.InternalCapture = false;
+                               break;
+                       }
+
+                       return false;
+               }
+
+               private void GiveFeedback (IntPtr action)
+               {
+                       if (drag_event == null)
+                               return;
+                       GiveFeedbackEventArgs gfe = new GiveFeedbackEventArgs (drag_event.Effect, true);
+                       Control c = MwfWindow (source);
+
+                       c.DndFeedback (gfe);
+                       
+                       if (gfe.UseDefaultCursors) {
+                               Cursor cursor = CursorNo;
+                               if (drag_data.WillAccept) {
+                                       // Same order as on MS
+                                       if (action == XdndActionCopy)
+                                               cursor = CursorCopy;
+                                       else if (action == XdndActionLink)
+                                               cursor = CursorLink;
+                                       else if (action == XdndActionMove)
+                                               cursor = CursorMove;
+                               }
+                               // TODO: Try not to set the cursor so much
+                               //if (cursor.Handle != CurrentCursorHandle) {
+                               XplatUIX11.XChangeActivePointerGrab (display,
+                                               EventMask.ButtonMotionMask |
+                                               EventMask.PointerMotionMask |
+                                               EventMask.ButtonPressMask |
+                                               EventMask.ButtonReleaseMask,
+                                               cursor.Handle, IntPtr.Zero);
+                               //CurrentCursorHandle = cursor.Handle;
+                               //}
+                       }
+               }
+
                private void SetProperty (ref XEvent xevent, IntPtr data, int length)
                {
                        XEvent sel = new XEvent();
@@ -709,30 +779,13 @@ namespace System.Windows.Forms {
                private bool HandleStatusEvent (ref XEvent xevent)
                {
                        if (drag_data != null && drag_data.State == DragState.Entered) {
-                               drag_data.WillAccept = ((int) xevent.ClientMessageEvent.ptr2 & 0x1) != 0;
-                               Cursor cursor = CursorNo;
-                               if (drag_data.WillAccept) {
-                                       // Same order as on MS
-                                       IntPtr action = xevent.ClientMessageEvent.ptr5;
-                                       if (action == XdndActionCopy)
-                                               cursor = CursorCopy;
-                                       else if (action == XdndActionLink)
-                                               cursor = CursorLink;
-                                       else if (action == XdndActionMove)
-                                               cursor = CursorMove;
 
-                               }
+                               if (!QueryContinue (xevent, false, DragAction.Continue))
+                                       return true;
 
-                                       // TODO: Try not to set the cursor so much
-                               //if (cursor.Handle != CurrentCursorHandle) {
-                                       XplatUIX11.XChangeActivePointerGrab (display,
-                                                       EventMask.ButtonMotionMask |
-                                                       EventMask.PointerMotionMask |
-                                                       EventMask.ButtonPressMask |
-                                                       EventMask.ButtonReleaseMask,
-                                                       cursor.Handle, IntPtr.Zero);
-                                       //CurrentCursorHandle = cursor.Handle;
-                                       //}     
+                               drag_data.WillAccept = ((int) xevent.ClientMessageEvent.ptr2 & 0x1) != 0;
+
+                               GiveFeedback (xevent.ClientMessageEvent.ptr5);
                        }
                        return true;
                }
index 7cecb34f401e78187dd2e51507a90e84d283aa5b..e91793517ad6143afc6b35936514ed38764d253c 100644 (file)
@@ -3288,6 +3288,8 @@ namespace System.Windows.Forms {
                        //
                        switch(xevent.type) {
                                case XEventName.KeyPress: {
+                                       if (Dnd.InDrag ())
+                                               Dnd.HandleKeyPress (ref xevent);
                                        Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
                                        break;
                                }
@@ -3404,8 +3406,10 @@ namespace System.Windows.Forms {
 
                                case XEventName.ButtonRelease: {
                                        if (Dnd.InDrag()) {
-                                               Dnd.HandleButtonRelease (ref xevent);
-                                               // Don't break here, so that the BUTTONUP message can get through
+                                               if (Dnd.HandleButtonRelease (ref xevent)) {
+                                                       break;
+                                               }
+                                               // Allow the LBUTTONUP message to get through
                                        }
 
                                        switch(xevent.ButtonEvent.button) {
@@ -4451,6 +4455,10 @@ namespace System.Windows.Forms {
                        return count;
                }
 
+               internal static VirtualKeys EventToKeyCode (XEvent key_event)
+               {
+                       return (VirtualKeys) Keyboard.EventToVkey (key_event);
+               }
 
                internal override void SetAllowDrop (IntPtr handle, bool value)
                {