Home | History | Annotate | Download | only in touchui
      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/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"
     15 
     16 namespace views {
     17 
     18 namespace test {
     19 class WidgetTestInteractive;
     20 }
     21 
     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 {
     30  public:
     31   class EditingHandleView;
     32 
     33   // Use TextSelectionController::create().
     34   explicit TouchSelectionControllerImpl(
     35       ui::TouchEditable* client_view);
     36 
     37   virtual ~TouchSelectionControllerImpl();
     38 
     39   // TextSelectionController.
     40   virtual void SelectionChanged() OVERRIDE;
     41   virtual bool IsHandleDragInProgress() OVERRIDE;
     42   virtual void HideHandles(bool quick) OVERRIDE;
     43 
     44  private:
     45   friend class TouchSelectionControllerImplTest;
     46   friend class test::WidgetTestInteractive;
     47 
     48   void SetDraggingHandle(EditingHandleView* handle);
     49 
     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);
     53 
     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);
     57 
     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);
     62 
     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;
     66 
     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;
     72 
     73   // Overriden from aura::WindowObserver.
     74   virtual void OnAncestorWindowTransformed(aura::Window* source,
     75                                            aura::Window* window) OVERRIDE;
     76 
     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;
     83 
     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;
     88 
     89   // Time to show context menu.
     90   void ContextMenuTimerFired();
     91 
     92   void StartContextMenuTimer();
     93 
     94   // Convenience method to update the position/visibility of the context menu.
     95   void UpdateContextMenu();
     96 
     97   // Convenience method for hiding context menu.
     98   void HideContextMenu();
     99 
    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();
    108 
    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_;
    115 
    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_;
    120 
    121   // Pointer to the SelectionHandleView being dragged during a drag session.
    122   EditingHandleView* dragging_handle_;
    123 
    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_;
    134 
    135   DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImpl);
    136 };
    137 
    138 }  // namespace views
    139 
    140 #endif  // UI_UI_VIEWS_TOUCHUI_TOUCH_SELECTION_CONTROLLER_IMPL_H_
    141