1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_GTK_PANELS_PANEL_DRAG_GTK_H_ 6 #define CHROME_BROWSER_UI_GTK_PANELS_PANEL_DRAG_GTK_H_ 7 8 #include <gtk/gtk.h> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "ui/base/gtk/gtk_signal.h" 13 14 class Panel; 15 class PanelDragDelegate; 16 17 // Class for GTK handling of move-drag and resize-drag on a panel. 18 // Only one type of drag may be active at any time. 19 // Dragging only begins if the mouse is moved beyond the drag threshold. 20 // If mouse is released without exceeding the drag threshold, the mouse 21 // press and release is treated as a mouse click. 22 class PanelDragGtk { 23 public: 24 explicit PanelDragGtk(Panel* panel); 25 ~PanelDragGtk(); 26 widget()27 GtkWidget* widget() const { return drag_widget_; } 28 29 // Sets up mouse and keyboard events processing while the mouse 30 // is pressed on a window edge. 31 // |event| is the mouse press event. 32 // |cursor| is the cursor to display during the drag. 33 // |edge| is the window edge from which to resize the panel. 34 void InitialWindowEdgeMousePress(GdkEventButton* event, GdkCursor* cursor, 35 GdkWindowEdge& edge); 36 37 // Sets up mouse and keyboard events processing while the mouse is 38 // pressed on the titlebar. 39 // |event| is the mouse press event. 40 // |titlebar_widget| should handle the mouse release event if the mouse 41 // is released without exceeding the drag threshold (a mouse click). 42 void InitialTitlebarMousePress(GdkEventButton* event, 43 GtkWidget* titlebar_widget); 44 45 private: 46 friend class GtkNativePanelTesting; 47 48 enum DragState { 49 NOT_DRAGGING, 50 DRAG_CAN_START, // mouse pressed 51 DRAG_IN_PROGRESS, // mouse moved beyond drag threshold 52 DRAG_ENDED_WAITING_FOR_MOUSE_RELEASE 53 }; 54 55 // Callbacks for GTK mouse and key events. 56 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnMouseMoveEvent, 57 GdkEventMotion*); 58 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnButtonPressEvent, 59 GdkEventButton*); 60 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnButtonReleaseEvent, 61 GdkEventButton*); 62 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnKeyPressEvent, 63 GdkEventKey*); 64 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnKeyReleaseEvent, 65 GdkEventKey*); 66 CHROMEGTK_CALLBACK_1(PanelDragGtk, gboolean, OnGrabBrokenEvent, 67 GdkEventGrabBroken*); 68 69 // Utility to dcheck a bunch of state to ensure a clean slate. 70 // Returns only if all the dchecks pass. 71 void AssertCleanState(); 72 73 void GrabPointerAndKeyboard(GdkEventButton* event, 74 GdkCursor* cursor); 75 void ReleasePointerAndKeyboardGrab(); 76 77 // Ends any drag that is currently in progress (if any). 78 // Resets all drag state except for pointer and keyboard grabs. 79 // The grabs are released when the mouse is released to prevent a 80 // mouse release *after* the drag has ended (e.g. via ESC key) from 81 // being treated as a mouse click. 82 void EndDrag(bool canceled); 83 84 // Weak pointer to the panel being dragged. 85 Panel* panel_; 86 87 // Invisible event box to receive mouse and key events. 88 GtkWidget* drag_widget_; 89 90 DragState drag_state_; 91 92 // A copy of the initial button press event. 93 GdkEvent* initial_mouse_down_; 94 95 // Widget that should process the mouse click if mouse is released 96 // without exceeding the drag threshold. May be NULL if no click 97 // handling is necessary. 98 GtkWidget* click_handler_; 99 100 // Delegate for processing drag depends on actual type of drag. 101 PanelDragDelegate* drag_delegate_; 102 103 DISALLOW_COPY_AND_ASSIGN(PanelDragGtk); 104 }; 105 106 #endif // CHROME_BROWSER_UI_GTK_PANELS_PANEL_DRAG_GTK_H_ 107