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