1 // Copyright (c) 2013 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 UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_ 6 #define UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_ 7 8 #include "base/timer/timer.h" 9 #include "ui/base/touch/touch_editing_controller.h" 10 #include "ui/gfx/point.h" 11 #include "ui/views/touchui/touch_editing_menu.h" 12 #include "ui/views/view.h" 13 #include "ui/views/views_export.h" 14 15 namespace views { 16 17 // Touch specific implementation of TouchSelectionController. Responsible for 18 // displaying selection handles and menu elements relevant in a touch interface. 19 class VIEWS_EXPORT TouchSelectionControllerImpl 20 : public ui::TouchSelectionController, 21 public TouchEditingMenuController, 22 public WidgetObserver { 23 public: 24 // Use TextSelectionController::create(). 25 explicit TouchSelectionControllerImpl( 26 ui::TouchEditable* client_view); 27 28 virtual ~TouchSelectionControllerImpl(); 29 30 // TextSelectionController. 31 virtual void SelectionChanged() OVERRIDE; 32 virtual bool IsHandleDragInProgress() OVERRIDE; 33 34 private: 35 friend class TouchSelectionControllerImplTest; 36 class EditingHandleView; 37 38 void SetDraggingHandle(EditingHandleView* handle); 39 40 // Callback to inform the client view that the selection handle has been 41 // dragged, hence selection may need to be updated. 42 void SelectionHandleDragged(const gfx::Point& drag_pos); 43 44 // Convenience method to convert a point from a selection handle's coordinate 45 // system to that of the client view. 46 void ConvertPointToClientView(EditingHandleView* source, gfx::Point* point); 47 48 // Convenience method to set a handle's selection rect and hide it if it is 49 // located out of client view. 50 void SetHandleSelectionRect(EditingHandleView* handle, const gfx::Rect& rect, 51 const gfx::Rect& rect_in_screen); 52 53 // Overridden from TouchEditingMenuController. 54 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 55 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 56 virtual void OpenContextMenu() OVERRIDE; 57 virtual void OnMenuClosed(TouchEditingMenuView* menu) OVERRIDE; 58 59 // Overridden from WidgetObserver. We will observe the widget backing the 60 // |client_view_| so that when its moved/resized, we can update the selection 61 // handles appropriately. 62 virtual void OnWidgetClosing(Widget* widget) OVERRIDE; 63 virtual void OnWidgetBoundsChanged(Widget* widget, 64 const gfx::Rect& new_bounds) OVERRIDE; 65 66 // Time to show context menu. 67 void ContextMenuTimerFired(); 68 69 void StartContextMenuTimer(); 70 71 // Convenience method to update the position/visibility of the context menu. 72 void UpdateContextMenu(const gfx::Point& p1, const gfx::Point& p2); 73 74 // Convenience method for hiding context menu. 75 void HideContextMenu(); 76 77 // Convenience methods for testing. 78 gfx::Point GetSelectionHandle1Position(); 79 gfx::Point GetSelectionHandle2Position(); 80 gfx::Point GetCursorHandlePosition(); 81 bool IsSelectionHandle1Visible(); 82 bool IsSelectionHandle2Visible(); 83 bool IsCursorHandleVisible(); 84 85 ui::TouchEditable* client_view_; 86 Widget* client_widget_; 87 scoped_ptr<EditingHandleView> selection_handle_1_; 88 scoped_ptr<EditingHandleView> selection_handle_2_; 89 scoped_ptr<EditingHandleView> cursor_handle_; 90 TouchEditingMenuView* context_menu_; 91 92 // Timer to trigger |context_menu| (|context_menu| is not shown if the 93 // selection handles are being updated. It appears only when the handles are 94 // stationary for a certain amount of time). 95 base::OneShotTimer<TouchSelectionControllerImpl> context_menu_timer_; 96 97 // Pointer to the SelectionHandleView being dragged during a drag session. 98 EditingHandleView* dragging_handle_; 99 100 // Selection end points. In cursor mode, the two end points are the same and 101 // correspond to |cursor_handle_|; otherwise, they correspond to 102 // |selection_handle_1_| and |selection_handle_2_|, respectively. These 103 // values should be used when selection end points are needed rather than 104 // position of handles which might be invalid when handles are hidden. 105 gfx::Rect selection_end_point_1_; 106 gfx::Rect selection_end_point_2_; 107 108 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImpl); 109 }; 110 111 class VIEWS_EXPORT ViewsTouchSelectionControllerFactory 112 : public ui::TouchSelectionControllerFactory { 113 public: 114 ViewsTouchSelectionControllerFactory(); 115 116 // Overridden from ui::TouchSelectionControllerFactory. 117 virtual ui::TouchSelectionController* create( 118 ui::TouchEditable* client_view) OVERRIDE; 119 }; 120 121 } // namespace views 122 123 #endif // UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_ 124