1 // Copyright 2013 Samsung Electronics. 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 selection_controller_h
6 #define selection_controller_h
10 #include "base/strings/string16.h"
11 #include "content/browser/selection/selection_box_efl.h"
12 #include "content/browser/selection/selection_handle_efl.h"
13 #include "content/browser/selection/selection_magnifier_efl.h"
14 #include "content/common/content_export.h"
15 #include "third_party/WebKit/public/platform/WebGestureEvent.h"
16 #include "third_party/WebKit/public/platform/WebInputEvent.h"
17 #include "ui/events/event_constants.h"
18 #include "ui/gfx/range/range.h"
19 #include "ui/gfx/selection_bound.h"
20 #include "ui/gfx/geometry/rect.h"
23 #include "vconf/vconf.h"
30 class WebContentsImpl;
31 class RenderWidgetHostViewEfl;
33 // Controls the selection after long tap.
34 // This handles long tap down, long tap move, long tap up.
35 // On long tap down touch point is sent to engine by SendGestureEvent and
36 // magnifier is shown. On long tap move touch events are sent to engine by
37 // SelectClosestWord and magnifier is shown.
38 // On long tap up selection handlers are shown and context menu event is sent.
39 // Handlers are shown to extent selection, On handler move touch points are sent
40 // to engine by SelectRange to extend the selection.
41 class CONTENT_EXPORT SelectionControllerEfl {
44 explicit SelectionControllerEfl(RenderWidgetHostViewEfl* rwhv);
45 ~SelectionControllerEfl();
47 // Functions that handle long press, long press move and release
48 bool HandleLongPressEvent(const gfx::Point& touch_point,
49 const content::ContextMenuParams& params);
50 void HandleLongPressMoveEvent(const gfx::Point& touch_point);
51 void HandleLongPressEndEvent();
52 bool HandleBeingDragged() const { return handle_being_dragged_; }
54 void PostHandleTapGesture(bool is_content_editable);
56 // Set if selection is valid
57 void SetSelectionStatus(bool enable);
58 bool GetSelectionStatus() const;
60 // Set if selection is in edit field
61 void SetSelectionEditable(bool enable);
62 bool GetSelectionEditable() const;
64 void SetSelectionEmpty(bool value) {
65 selection_on_empty_form_control_ = value;
68 bool GetCaretSelectionStatus() const;
70 // Set if the selection base (or anchor) comes logically
71 // first than its respective extent.
72 void SetIsAnchorFirst(bool value);
74 // To update the selection string
75 void UpdateSelectionData(const base::string16& text);
77 void GetSelectionBounds(gfx::Rect* left, gfx::Rect* right);
79 // Handles the touch press, move and relase events on selection handles
80 void HandleDragBeginNotification(SelectionHandleEfl*);
81 void HandleDragUpdateNotification(SelectionHandleEfl*);
82 void HandleDragEndNotification();
84 // Clears the selection and hides context menu and handles
85 void ClearSelection();
86 bool ClearSelectionViaEWebView();
88 void HideHandleAndContextMenu();
89 bool IsAnyHandleVisible() const;
91 void SetControlsTemporarilyHidden(bool hidden,
92 bool from_custom_scroll_callback = false);
94 gfx::Rect GetLeftRect() const;
95 gfx::Rect GetRightRect() const;
97 void OnSelectionChanged(const gfx::SelectionBound&, const gfx::SelectionBound&);
98 void OnTextInputStateChanged();
100 bool GetLongPressed() { return long_mouse_press_; }
102 bool TextSelectionDown(int x, int y);
103 bool TextSelectionUp(int x, int y);
105 // 'Reason' enum class enumerates all reasons that can cause
106 // text selection changes that require changes on the status
107 // of selection controls (handles and context menu).
109 ScrollOrZoomGestureEnded = 0,
116 RequestedByContextMenu,
120 void SetWaitsForRendererSelectionChanges(
121 Reason reason) { selection_change_reason_ = reason; }
124 void HandlePostponedGesture(int x, int y, ui::EventType type);
125 void HandleGesture(blink::WebGestureEvent& event);
127 gfx::Rect GetVisibleViewportRect() const;
129 bool IsCaretModeForced() const { return is_caret_mode_forced_; }
130 void TriggerOnSelectionChange();
131 void ToggleCaretAfterSelection();
132 bool ExistsSelectedText();
133 void ShowHandleAndContextMenuIfRequired(
134 Reason explicit_reason = Reason::Irrelevant);
136 RenderWidgetHostViewEfl* rwhv() const { return rwhv_; }
137 content::WebContents* web_contents() const;
139 bool IsCaretMode() const;
141 void ContextMenuStatusHidden();
142 void ContextMenuStatusVisible();
144 // The area where selection menu shouldn't be shown if possible
145 // (selection area, handles, menu padding).
146 gfx::Rect GetForbiddenRegionRect(const gfx::Rect& selection_rect) const;
149 enum SelectionMode { None = 0, Caret, Range };
151 enum ContextMenuStatusTag { NONE = 0, HIDDEN, INPROGRESS, VISIBLE };
153 void DetermineSelectionMode(const gfx::Rect& left_rect,
154 const gfx::Rect& right_rect);
155 void SetSelectionMode(enum SelectionMode);
157 // sets selection_change_reason_ based on visiblity
158 void SetVisiblityStatus(bool visiblity);
160 // To update the selection bounds
161 // returns false if rects are invalid, otherwise true
162 bool UpdateSelectionDataAndShow(const gfx::Rect& left_rect,
163 const gfx::Rect& right_rect,
166 void HandleLongPressEventPrivate(const gfx::Point& touch_point);
170 bool IsSelectionValid(const gfx::Rect& left_rect,
171 const gfx::Rect& right_rect);
173 void QuerySelectionStyle();
175 void ShowContextMenu();
176 void CancelContextMenu(int request_id);
178 float device_scale_factor() const;
180 static void EvasParentViewMoveCallback(void* data,
184 reinterpret_cast<SelectionControllerEfl*>(data)->OnParentParentViewMove();
187 static Eina_Bool ScrollIfNeeded(void* data);
189 #if defined(OS_TIZEN)
190 static void PlatformLanguageChanged(keynode_t* keynode, void* data);
193 void OnParentParentViewMove();
195 static Eina_Bool EcoreEventFilterCallback(void* user_data,
200 // Is required to send back selction points and range extenstion co-ordinates
201 RenderWidgetHostViewEfl* rwhv_;
203 // Saves state so that selection controls are temporarily hidden due
204 // to scrolling or zooming.
205 bool controls_temporarily_hidden_;
207 // Cache the reason of why browser has requested a text selection
208 // change to the renderer. At the next composited selection update
209 // the cache is handled and reset.
210 Reason selection_change_reason_;
212 // Saves state so that handlers and context menu is not shown when seletion
213 // change event occurs.
214 bool long_mouse_press_;
216 // Saves the data that are required to draw handle and context menu
217 std::unique_ptr<SelectionBoxEfl> selection_data_;
219 // Points to start of the selection for extending selection
220 std::unique_ptr<SelectionHandleEfl> start_handle_;
222 // Points to the end of the selection for extending selection
223 std::unique_ptr<SelectionHandleEfl> end_handle_;
225 // Points to the caret in edit box where cursor is present
226 std::unique_ptr<SelectionHandleEfl> input_handle_;
228 // Points to show the contents magnified
229 std::unique_ptr<SelectionMagnifierEfl> magnifier_;
231 // Helper pointer to the handle being dragged.
232 SelectionHandleEfl* dragging_handle_;
234 // Helper pointer to the stationary handle (during dragging).
235 SelectionHandleEfl* stationary_handle_;
237 bool handle_being_dragged_;
239 bool selection_on_empty_form_control_;
241 bool is_caret_mode_forced_;
242 Ecore_Event_Filter* ecore_events_filter_;
244 SelectionHandleEfl* dragged_handle_;
246 gfx::Point finger_position_;
247 Ecore_Timer* edge_scrolling_timer_;
249 enum ContextMenuStatusTag context_menu_status_;
250 bool triggered_selection_change_;
252 enum SelectionMode selection_mode_;
253 gfx::SelectionBound start_selection_;
254 gfx::SelectionBound end_selection_;
257 } // namespace content