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.
5 #ifndef UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_
6 #define UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_
8 #include "base/timer/timer.h"
9 #include "ui/aura/window_observer.h"
10 #include "ui/base/touch/touch_editing_controller.h"
11 #include "ui/gfx/point.h"
12 #include "ui/views/touchui/touch_editing_menu.h"
13 #include "ui/views/view.h"
14 #include "ui/views/views_export.h"
19 class WidgetTestInteractive
;
22 // Touch specific implementation of TouchSelectionController. Responsible for
23 // displaying selection handles and menu elements relevant in a touch interface.
24 class VIEWS_EXPORT TouchSelectionControllerImpl
25 : public ui::TouchSelectionController
,
26 public TouchEditingMenuController
,
27 public aura::WindowObserver
,
28 public WidgetObserver
,
29 public ui::EventHandler
{
31 class EditingHandleView
;
33 // Use TextSelectionController::create().
34 explicit TouchSelectionControllerImpl(
35 ui::TouchEditable
* client_view
);
37 virtual ~TouchSelectionControllerImpl();
39 // TextSelectionController.
40 virtual void SelectionChanged() override
;
41 virtual bool IsHandleDragInProgress() override
;
42 virtual void HideHandles(bool quick
) override
;
45 friend class TouchSelectionControllerImplTest
;
46 friend class test::WidgetTestInteractive
;
48 void SetDraggingHandle(EditingHandleView
* handle
);
50 // Callback to inform the client view that the selection handle has been
51 // dragged, hence selection may need to be updated.
52 void SelectionHandleDragged(const gfx::Point
& drag_pos
);
54 // Convenience method to convert a point from a selection handle's coordinate
55 // system to that of the client view.
56 void ConvertPointToClientView(EditingHandleView
* source
, gfx::Point
* point
);
58 // Convenience method to set a handle's selection rect and hide it if it is
59 // located out of client view.
60 void SetHandleSelectionRect(EditingHandleView
* handle
, const gfx::Rect
& rect
,
61 const gfx::Rect
& rect_in_screen
);
63 // Checks if handle should be shown for a selection end-point at |rect|.
64 // |rect| should be the clipped version of the selection end-point.
65 bool ShouldShowHandleFor(const gfx::Rect
& rect
) const;
67 // Overridden from TouchEditingMenuController.
68 virtual bool IsCommandIdEnabled(int command_id
) const override
;
69 virtual void ExecuteCommand(int command_id
, int event_flags
) override
;
70 virtual void OpenContextMenu() override
;
71 virtual void OnMenuClosed(TouchEditingMenuView
* menu
) override
;
73 // Overriden from aura::WindowObserver.
74 virtual void OnAncestorWindowTransformed(aura::Window
* source
,
75 aura::Window
* window
) override
;
77 // Overridden from WidgetObserver. We will observe the widget backing the
78 // |client_view_| so that when its moved/resized, we can update the selection
79 // handles appropriately.
80 virtual void OnWidgetClosing(Widget
* widget
) override
;
81 virtual void OnWidgetBoundsChanged(Widget
* widget
,
82 const gfx::Rect
& new_bounds
) override
;
84 // Overriden from ui::EventHandler.
85 virtual void OnKeyEvent(ui::KeyEvent
* event
) override
;
86 virtual void OnMouseEvent(ui::MouseEvent
* event
) override
;
87 virtual void OnScrollEvent(ui::ScrollEvent
* event
) override
;
89 // Time to show context menu.
90 void ContextMenuTimerFired();
92 void StartContextMenuTimer();
94 // Convenience method to update the position/visibility of the context menu.
95 void UpdateContextMenu();
97 // Convenience method for hiding context menu.
98 void HideContextMenu();
100 // Convenience methods for testing.
101 gfx::NativeView
GetCursorHandleNativeView();
102 gfx::Point
GetSelectionHandle1Position();
103 gfx::Point
GetSelectionHandle2Position();
104 gfx::Point
GetCursorHandlePosition();
105 bool IsSelectionHandle1Visible();
106 bool IsSelectionHandle2Visible();
107 bool IsCursorHandleVisible();
109 ui::TouchEditable
* client_view_
;
110 Widget
* client_widget_
;
111 scoped_ptr
<EditingHandleView
> selection_handle_1_
;
112 scoped_ptr
<EditingHandleView
> selection_handle_2_
;
113 scoped_ptr
<EditingHandleView
> cursor_handle_
;
114 TouchEditingMenuView
* context_menu_
;
116 // Timer to trigger |context_menu| (|context_menu| is not shown if the
117 // selection handles are being updated. It appears only when the handles are
118 // stationary for a certain amount of time).
119 base::OneShotTimer
<TouchSelectionControllerImpl
> context_menu_timer_
;
121 // Pointer to the SelectionHandleView being dragged during a drag session.
122 EditingHandleView
* dragging_handle_
;
124 // Selection end points. In cursor mode, the two end points are the same and
125 // correspond to |cursor_handle_|; otherwise, they correspond to
126 // |selection_handle_1_| and |selection_handle_2_|, respectively. These
127 // values should be used when selection end points are needed rather than
128 // position of handles which might be invalid when handles are hidden.
129 gfx::Rect selection_end_point_1_
;
130 gfx::Rect selection_end_point_2_
;
131 // Selection end points, clipped to client view's boundaries.
132 gfx::Rect selection_end_point_1_clipped_
;
133 gfx::Rect selection_end_point_2_clipped_
;
135 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImpl
);
140 #endif // UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_