Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1323)

Side by Side Diff: ui/views/touchui/touch_selection_controller_impl_unittest.cc

Issue 700563002: Implementing directional text selection handles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new_assets_text
Patch Set: Removing the SelectionBound test from Android, since touch_editing_controller not included in Andro… Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "ui/aura/client/screen_position_client.h" 7 #include "ui/aura/client/screen_position_client.h"
8 #include "ui/aura/test/test_cursor_client.h"
8 #include "ui/aura/window.h" 9 #include "ui/aura/window.h"
9 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/base/touch/touch_editing_controller.h" 11 #include "ui/base/touch/touch_editing_controller.h"
11 #include "ui/base/ui_base_switches.h" 12 #include "ui/base/ui_base_switches.h"
12 #include "ui/events/test/event_generator.h" 13 #include "ui/events/test/event_generator.h"
13 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/point.h" 15 #include "ui/gfx/point.h"
15 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
16 #include "ui/gfx/render_text.h" 17 #include "ui/gfx/render_text.h"
17 #include "ui/resources/grit/ui_resources.h" 18 #include "ui/resources/grit/ui_resources.h"
18 #include "ui/views/controls/textfield/textfield.h" 19 #include "ui/views/controls/textfield/textfield.h"
19 #include "ui/views/controls/textfield/textfield_test_api.h" 20 #include "ui/views/controls/textfield/textfield_test_api.h"
20 #include "ui/views/test/views_test_base.h" 21 #include "ui/views/test/views_test_base.h"
21 #include "ui/views/touchui/touch_selection_controller_impl.h" 22 #include "ui/views/touchui/touch_selection_controller_impl.h"
22 #include "ui/views/views_touch_selection_controller_factory.h" 23 #include "ui/views/views_touch_selection_controller_factory.h"
23 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
25 #include "ui/wm/core/default_screen_position_client.h"
24 26
25 using base::ASCIIToUTF16; 27 using base::ASCIIToUTF16;
26 using base::UTF16ToUTF8; 28 using base::UTF16ToUTF8;
27 using base::WideToUTF16; 29 using base::WideToUTF16;
28 30
29 namespace { 31 namespace {
30 // Should match kSelectionHandlePadding in touch_selection_controller.
31 const int kPadding = 10;
32
33 // Should match kSelectionHandleBarMinHeight in touch_selection_controller. 32 // Should match kSelectionHandleBarMinHeight in touch_selection_controller.
34 const int kBarMinHeight = 5; 33 const int kBarMinHeight = 5;
35 34
36 // Should match kSelectionHandleBarBottomAllowance in 35 // Should match kSelectionHandleBarBottomAllowance in
37 // touch_selection_controller. 36 // touch_selection_controller.
38 const int kBarBottomAllowance = 3; 37 const int kBarBottomAllowance = 3;
39 38
40 // Should match kMenuButtonWidth in touch_editing_menu. 39 // Should match kMenuButtonWidth in touch_editing_menu.
41 const int kMenuButtonWidth = 63; 40 const int kMenuButtonWidth = 63;
42 41
43 // Should match size of kMenuCommands array in touch_editing_menu. 42 // Should match size of kMenuCommands array in touch_editing_menu.
44 const int kMenuCommandCount = 3; 43 const int kMenuCommandCount = 3;
45 44
46 gfx::Image* GetHandleImage() { 45 // For selection bounds |b1| and |b2| in a paragraph of text, returns -1 if |b1|
47 static gfx::Image* handle_image = NULL; 46 // is physically before |b2|, +1 if |b2| is before |b1|, and 0 if they are at
48 if (!handle_image) { 47 // the same location.
49 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( 48 int CompareTextSelectionBounds(const ui::SelectionBound& b1,
50 IDR_TEXT_SELECTION_HANDLE); 49 const ui::SelectionBound& b2) {
51 } 50 if ((b1.edge_top.y() < b2.edge_top.y()) || b1.edge_top.x() < b2.edge_top.x())
52 return handle_image; 51 return -1;
52 else if (b1 == b2)
53 return 0;
54 else
55 return 1;
53 } 56 }
54 57
55 gfx::Size GetHandleImageSize() {
56 return GetHandleImage()->Size();
57 }
58 } // namespace 58 } // namespace
59 59
60 namespace views { 60 namespace views {
61 61
62 class TouchSelectionControllerImplTest : public ViewsTestBase { 62 class TouchSelectionControllerImplTest : public ViewsTestBase {
63 public: 63 public:
64 TouchSelectionControllerImplTest() 64 TouchSelectionControllerImplTest()
65 : textfield_widget_(NULL), 65 : textfield_widget_(nullptr),
66 widget_(NULL), 66 widget_(nullptr),
67 textfield_(NULL), 67 textfield_(nullptr),
68 views_tsc_factory_(new ViewsTouchSelectionControllerFactory) { 68 views_tsc_factory_(new ViewsTouchSelectionControllerFactory) {
69 CommandLine::ForCurrentProcess()->AppendSwitch( 69 CommandLine::ForCurrentProcess()->AppendSwitch(
70 switches::kEnableTouchEditing); 70 switches::kEnableTouchEditing);
71 ui::TouchSelectionControllerFactory::SetInstance(views_tsc_factory_.get()); 71 ui::TouchSelectionControllerFactory::SetInstance(views_tsc_factory_.get());
72 } 72 }
73 73
74 ~TouchSelectionControllerImplTest() override { 74 ~TouchSelectionControllerImplTest() override {
75 ui::TouchSelectionControllerFactory::SetInstance(NULL); 75 ui::TouchSelectionControllerFactory::SetInstance(nullptr);
76 }
77
78 void SetUp() override {
79 ViewsTestBase::SetUp();
80 SetUpRootWindowClients(GetContext());
76 } 81 }
77 82
78 void TearDown() override { 83 void TearDown() override {
84 test_cursor_client_.reset();
79 if (textfield_widget_ && !textfield_widget_->IsClosed()) 85 if (textfield_widget_ && !textfield_widget_->IsClosed())
80 textfield_widget_->Close(); 86 textfield_widget_->Close();
81 if (widget_ && !widget_->IsClosed()) 87 if (widget_ && !widget_->IsClosed())
82 widget_->Close(); 88 widget_->Close();
83 ViewsTestBase::TearDown(); 89 ViewsTestBase::TearDown();
84 } 90 }
85 91
86 void CreateTextfield() { 92 void CreateTextfield() {
87 textfield_ = new Textfield(); 93 textfield_ = new Textfield();
88 textfield_widget_ = new Widget; 94 textfield_widget_ = new Widget;
89 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 95 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
90 params.bounds = gfx::Rect(0, 0, 200, 200); 96 params.bounds = gfx::Rect(0, 0, 200, 200);
91 textfield_widget_->Init(params); 97 textfield_widget_->Init(params);
92 View* container = new View(); 98 View* container = new View();
93 textfield_widget_->SetContentsView(container); 99 textfield_widget_->SetContentsView(container);
94 container->AddChildView(textfield_); 100 container->AddChildView(textfield_);
95 101
96 textfield_->SetBoundsRect(gfx::Rect(0, 0, 200, 20)); 102 textfield_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
97 textfield_->set_id(1); 103 textfield_->set_id(1);
98 textfield_widget_->Show(); 104 textfield_widget_->Show();
99 105
100 textfield_->RequestFocus(); 106 textfield_->RequestFocus();
101
102 textfield_test_api_.reset(new TextfieldTestApi(textfield_)); 107 textfield_test_api_.reset(new TextfieldTestApi(textfield_));
103 } 108 }
104 109
105 void CreateWidget() { 110 void CreateWidget() {
106 widget_ = new Widget; 111 widget_ = new Widget;
107 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 112 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
108 params.bounds = gfx::Rect(0, 0, 200, 200); 113 params.bounds = gfx::Rect(0, 0, 200, 200);
109 widget_->Init(params); 114 widget_->Init(params);
110 widget_->Show(); 115 widget_->Show();
111 } 116 }
112 117
113 protected: 118 protected:
114 static bool IsCursorHandleVisibleFor( 119 static bool IsCursorHandleVisibleFor(
115 ui::TouchSelectionController* controller) { 120 ui::TouchSelectionController* controller) {
116 TouchSelectionControllerImpl* impl = 121 TouchSelectionControllerImpl* impl =
117 static_cast<TouchSelectionControllerImpl*>(controller); 122 static_cast<TouchSelectionControllerImpl*>(controller);
118 return impl->IsCursorHandleVisible(); 123 return impl->IsCursorHandleVisible();
119 } 124 }
120 125
121 gfx::Rect GetCursorRect(const gfx::SelectionModel& sel) { 126 gfx::Rect GetCursorRect(const gfx::SelectionModel& sel) {
(...skipping 11 matching lines...) Expand all
133 } 138 }
134 139
135 void StartTouchEditing() { 140 void StartTouchEditing() {
136 textfield_test_api_->CreateTouchSelectionControllerAndNotifyIt(); 141 textfield_test_api_->CreateTouchSelectionControllerAndNotifyIt();
137 } 142 }
138 143
139 void EndTouchEditing() { 144 void EndTouchEditing() {
140 textfield_test_api_->ResetTouchSelectionController(); 145 textfield_test_api_->ResetTouchSelectionController();
141 } 146 }
142 147
143 void SimulateSelectionHandleDrag(gfx::Point p, int selection_handle) { 148 void SimulateSelectionHandleDrag(gfx::Vector2d v, int selection_handle) {
144 TouchSelectionControllerImpl* controller = GetSelectionController(); 149 TouchSelectionControllerImpl* controller = GetSelectionController();
145 // Do the work of OnMousePressed(). 150 views::WidgetDelegateView* handle = nullptr;
146 if (selection_handle == 1) 151 if (selection_handle == 1)
147 controller->SetDraggingHandle(controller->selection_handle_1_.get()); 152 handle = controller->GetHandle1View();
148 else 153 else
149 controller->SetDraggingHandle(controller->selection_handle_2_.get()); 154 handle = controller->GetHandle2View();
150 155
151 // Offset the drag position by the selection handle radius since it is 156 gfx::Point grip_location = gfx::Point(handle->size().width() / 2,
152 // supposed to be in the coordinate system of the handle. 157 handle->size().height() / 2);
153 p.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); 158 base::TimeDelta time_stamp = base::TimeDelta();
154 controller->SelectionHandleDragged(p); 159 {
155 160 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_BEGIN);
156 // Do the work of OnMouseReleased(). 161 ui::GestureEvent scroll_begin(
157 controller->dragging_handle_ = NULL; 162 grip_location.x(), grip_location.y(), 0, time_stamp, details);
163 handle->OnGestureEvent(&scroll_begin);
164 }
165 test_cursor_client_->DisableMouseEvents();
166 {
167 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_UPDATE);
168 gfx::Point update_location = grip_location + v;
169 ui::GestureEvent scroll_update(
170 update_location.x(), update_location.y(), 0, time_stamp, details);
171 handle->OnGestureEvent(&scroll_update);
172 }
173 {
174 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_END);
175 ui::GestureEvent scroll_end(
176 grip_location.x(), grip_location.y(), 0, time_stamp, details);
177 handle->OnGestureEvent(&scroll_end);
178 }
179 test_cursor_client_->EnableMouseEvents();
158 } 180 }
159 181
160 gfx::NativeView GetCursorHandleNativeView() { 182 gfx::NativeView GetCursorHandleNativeView() {
161 return GetSelectionController()->GetCursorHandleNativeView(); 183 return GetSelectionController()->GetCursorHandleNativeView();
162 } 184 }
163 185
164 gfx::Point GetSelectionHandle1Position() { 186 gfx::Rect GetSelectionHandle1Bounds() {
165 return GetSelectionController()->GetSelectionHandle1Position(); 187 return GetSelectionController()->GetSelectionHandle1Bounds();
166 } 188 }
167 189
168 gfx::Point GetSelectionHandle2Position() { 190 gfx::Rect GetSelectionHandle2Bounds() {
169 return GetSelectionController()->GetSelectionHandle2Position(); 191 return GetSelectionController()->GetSelectionHandle2Bounds();
170 } 192 }
171 193
172 gfx::Point GetCursorHandlePosition() { 194 gfx::Rect GetCursorHandleBounds() {
173 return GetSelectionController()->GetCursorHandlePosition(); 195 return GetSelectionController()->GetCursorHandleBounds();
196 }
197
198 gfx::Rect GetExpectedHandleBounds(const ui::SelectionBound& bound) {
199 return GetSelectionController()->GetExpectedHandleBounds(bound);
174 } 200 }
175 201
176 bool IsSelectionHandle1Visible() { 202 bool IsSelectionHandle1Visible() {
177 return GetSelectionController()->IsSelectionHandle1Visible(); 203 return GetSelectionController()->IsSelectionHandle1Visible();
178 } 204 }
179 205
180 bool IsSelectionHandle2Visible() { 206 bool IsSelectionHandle2Visible() {
181 return GetSelectionController()->IsSelectionHandle2Visible(); 207 return GetSelectionController()->IsSelectionHandle2Visible();
182 } 208 }
183 209
184 bool IsCursorHandleVisible() { 210 bool IsCursorHandleVisible() {
185 return GetSelectionController()->IsCursorHandleVisible(); 211 return GetSelectionController()->IsCursorHandleVisible();
186 } 212 }
187 213
188 gfx::RenderText* GetRenderText() { 214 gfx::RenderText* GetRenderText() {
189 return textfield_test_api_->GetRenderText(); 215 return textfield_test_api_->GetRenderText();
190 } 216 }
191 217
192 gfx::Point GetCursorHandleDragPoint() { 218 gfx::Point GetCursorHandleDragPoint() {
193 gfx::Point point = GetCursorHandlePosition(); 219 gfx::Rect rect = GetCursorHandleBounds();
194 const gfx::SelectionModel& sel = textfield_->GetSelectionModel(); 220 const gfx::SelectionModel& sel = textfield_->GetSelectionModel();
195 int cursor_height = GetCursorRect(sel).height(); 221 int cursor_height = GetCursorRect(sel).height();
196 point.Offset(GetHandleImageSize().width() / 2 + kPadding, 222 gfx::Point point = rect.CenterPoint();
197 GetHandleImageSize().height() / 2 + cursor_height); 223 point.Offset(0, cursor_height);
198 return point; 224 return point;
199 } 225 }
200 226
227 // If textfield has selection, this verifies that the selection handles
228 // are visible, at the correct positions (at the end points of selection), and
229 // (if |check_direction| is set to true), that they have the correct
230 // directionality.
231 // |cursor_at_selection_handle_1| is used to decide whether selection
232 // handle 1's position is matched against the start of selection or the end.
233 void VerifyHandlePositions(bool cursor_at_selection_handle_1,
234 bool check_direction,
235 const tracked_objects::Location& from_here) {
236 ui::SelectionBound anchor, focus;
237 textfield_->GetSelectionEndPoints(&anchor, &focus);
238 std::string from_str = from_here.ToString();
239 if (textfield_->HasSelection()) {
240 EXPECT_TRUE(IsSelectionHandle1Visible()) << from_str;
241 EXPECT_TRUE(IsSelectionHandle2Visible()) << from_str;
242 EXPECT_FALSE(IsCursorHandleVisible());
243 gfx::Rect sh1_bounds = GetSelectionHandle1Bounds();
244 gfx::Rect sh2_bounds = GetSelectionHandle2Bounds();
245 if (cursor_at_selection_handle_1) {
246 EXPECT_EQ(sh1_bounds, GetExpectedHandleBounds(focus)) << from_str;
247 EXPECT_EQ(sh2_bounds, GetExpectedHandleBounds(anchor)) << from_str;
248 } else {
249 EXPECT_EQ(sh1_bounds, GetExpectedHandleBounds(anchor)) << from_str;
250 EXPECT_EQ(sh2_bounds, GetExpectedHandleBounds(focus)) << from_str;
251 }
252 } else {
253 EXPECT_FALSE(IsSelectionHandle1Visible()) << from_str;
254 EXPECT_FALSE(IsSelectionHandle2Visible()) << from_str;
255 EXPECT_TRUE(IsCursorHandleVisible());
256 gfx::Rect cursor_bounds = GetCursorHandleBounds();
257 DCHECK(anchor == focus);
258 EXPECT_EQ(cursor_bounds, GetExpectedHandleBounds(anchor)) << from_str;
259 }
260 if (check_direction) {
261 if (CompareTextSelectionBounds(anchor, focus) < 0) {
262 EXPECT_EQ(ui::SelectionBound::LEFT, anchor.type) << from_str;
263 EXPECT_EQ(ui::SelectionBound::RIGHT, focus.type) << from_str;
264 } else if (CompareTextSelectionBounds(anchor, focus) > 0) {
265 EXPECT_EQ(ui::SelectionBound::LEFT, focus.type) << from_str;
266 EXPECT_EQ(ui::SelectionBound::RIGHT, anchor.type) << from_str;
267 } else {
268 EXPECT_EQ(ui::SelectionBound::CENTER, focus.type) << from_str;
269 EXPECT_EQ(ui::SelectionBound::CENTER, anchor.type) << from_str;
270 }
271 }
272 }
273
201 Widget* textfield_widget_; 274 Widget* textfield_widget_;
202 Widget* widget_; 275 Widget* widget_;
203 276
204 Textfield* textfield_; 277 Textfield* textfield_;
205 scoped_ptr<TextfieldTestApi> textfield_test_api_; 278 scoped_ptr<TextfieldTestApi> textfield_test_api_;
206 scoped_ptr<ViewsTouchSelectionControllerFactory> views_tsc_factory_; 279 scoped_ptr<ViewsTouchSelectionControllerFactory> views_tsc_factory_;
280 scoped_ptr<wm::DefaultScreenPositionClient> screen_position_client_;
281 scoped_ptr<aura::test::TestCursorClient> test_cursor_client_;
207 282
208 private: 283 private:
284 void SetUpRootWindowClients(aura::Window* root_window) {
285 if (!screen_position_client_) {
286 screen_position_client_.reset(new wm::DefaultScreenPositionClient());
287 aura::client::SetScreenPositionClient(root_window,
288 screen_position_client_.get());
289 test_cursor_client_.reset(new aura::test::TestCursorClient(root_window));
290 }
291 }
292
209 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest); 293 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest);
210 }; 294 };
211 295
212 // If textfield has selection, this macro verifies that the selection handles
213 // are visible and at the correct positions (at the end points of selection).
214 // |cursor_at_selection_handle_1| is used to decide whether selection
215 // handle 1's position is matched against the start of selection or the end.
216 #define VERIFY_HANDLE_POSITIONS(cursor_at_selection_handle_1) \
217 { \
218 gfx::SelectionModel sel = textfield_->GetSelectionModel(); \
219 if (textfield_->HasSelection()) { \
220 EXPECT_TRUE(IsSelectionHandle1Visible()); \
221 EXPECT_TRUE(IsSelectionHandle2Visible()); \
222 EXPECT_FALSE(IsCursorHandleVisible()); \
223 gfx::SelectionModel sel_start = GetRenderText()-> \
224 GetSelectionModelForSelectionStart(); \
225 gfx::Point selection_start = GetCursorPosition(sel_start); \
226 gfx::Point selection_end = GetCursorPosition(sel); \
227 gfx::Point sh1 = GetSelectionHandle1Position(); \
228 gfx::Point sh2 = GetSelectionHandle2Position(); \
229 sh1.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \
230 sh2.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \
231 if (cursor_at_selection_handle_1) { \
232 EXPECT_EQ(sh1, selection_end); \
233 EXPECT_EQ(sh2, selection_start); \
234 } else { \
235 EXPECT_EQ(sh1, selection_start); \
236 EXPECT_EQ(sh2, selection_end); \
237 } \
238 } else { \
239 EXPECT_FALSE(IsSelectionHandle1Visible()); \
240 EXPECT_FALSE(IsSelectionHandle2Visible()); \
241 EXPECT_TRUE(IsCursorHandleVisible()); \
242 gfx::Point cursor_pos = GetCursorPosition(sel); \
243 gfx::Point ch_pos = GetCursorHandlePosition(); \
244 ch_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \
245 EXPECT_EQ(ch_pos, cursor_pos); \
246 } \
247 }
248
249 // Tests that the selection handles are placed appropriately when selection in 296 // Tests that the selection handles are placed appropriately when selection in
250 // a Textfield changes. 297 // a Textfield changes.
251 TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) { 298 TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) {
252 CreateTextfield(); 299 CreateTextfield();
253 textfield_->SetText(ASCIIToUTF16("some text")); 300 textfield_->SetText(ASCIIToUTF16("some text"));
254 // Tap the textfield to invoke touch selection. 301 // Tap the textfield to invoke touch selection.
255 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 302 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
256 details.set_tap_count(1); 303 details.set_tap_count(1);
257 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 304 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
258 textfield_->OnGestureEvent(&tap); 305 textfield_->OnGestureEvent(&tap);
259 306
260 // Test selecting a range. 307 // Test selecting a range.
261 textfield_->SelectRange(gfx::Range(3, 7)); 308 textfield_->SelectRange(gfx::Range(3, 7));
262 VERIFY_HANDLE_POSITIONS(false); 309 VerifyHandlePositions(false, true, FROM_HERE);
263 310
264 // Test selecting everything. 311 // Test selecting everything.
265 textfield_->SelectAll(false); 312 textfield_->SelectAll(false);
266 VERIFY_HANDLE_POSITIONS(false); 313 VerifyHandlePositions(false, true, FROM_HERE);
267 314
268 // Test with no selection. 315 // Test with no selection.
269 textfield_->ClearSelection(); 316 textfield_->ClearSelection();
270 VERIFY_HANDLE_POSITIONS(false); 317 VerifyHandlePositions(false, true, FROM_HERE);
271 318
272 // Test with lost focus. 319 // Test with lost focus.
273 textfield_widget_->GetFocusManager()->ClearFocus(); 320 textfield_widget_->GetFocusManager()->ClearFocus();
274 EXPECT_FALSE(GetSelectionController()); 321 EXPECT_FALSE(GetSelectionController());
275 322
276 // Test with focus re-gained. 323 // Test with focus re-gained.
277 textfield_widget_->GetFocusManager()->SetFocusedView(textfield_); 324 textfield_widget_->GetFocusManager()->SetFocusedView(textfield_);
278 EXPECT_FALSE(GetSelectionController()); 325 EXPECT_FALSE(GetSelectionController());
279 textfield_->OnGestureEvent(&tap); 326 textfield_->OnGestureEvent(&tap);
280 VERIFY_HANDLE_POSITIONS(false); 327 VerifyHandlePositions(false, true, FROM_HERE);
281 } 328 }
282 329
283 // Tests that the selection handles are placed appropriately in bidi text. 330 // Tests that the selection handles are placed appropriately in bidi text.
284 TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) { 331 TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) {
285 CreateTextfield(); 332 CreateTextfield();
286 textfield_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 333 textfield_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
287 // Tap the textfield to invoke touch selection. 334 // Tap the textfield to invoke touch selection.
288 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 335 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
289 details.set_tap_count(1); 336 details.set_tap_count(1);
290 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 337 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
291 textfield_->OnGestureEvent(&tap); 338 textfield_->OnGestureEvent(&tap);
292 339
293 // Test cursor at run boundary and with empty selection. 340 // Test cursor at run boundary and with empty selection.
294 textfield_->SelectSelectionModel( 341 textfield_->SelectSelectionModel(
295 gfx::SelectionModel(3, gfx::CURSOR_BACKWARD)); 342 gfx::SelectionModel(3, gfx::CURSOR_BACKWARD));
296 VERIFY_HANDLE_POSITIONS(false); 343 VerifyHandlePositions(false, true, FROM_HERE);
297 344
298 // Test selection range inside one run and starts or ends at run boundary. 345 // Test selection range inside one run and starts or ends at run boundary.
299 textfield_->SelectRange(gfx::Range(2, 3)); 346 textfield_->SelectRange(gfx::Range(2, 3));
300 VERIFY_HANDLE_POSITIONS(false); 347 VerifyHandlePositions(false, true, FROM_HERE);
301 348
302 textfield_->SelectRange(gfx::Range(3, 2)); 349 textfield_->SelectRange(gfx::Range(3, 2));
303 VERIFY_HANDLE_POSITIONS(false); 350 VerifyHandlePositions(false, true, FROM_HERE);
304 351
352 // TODO(mfomitchev): crbug.com/429705
353 // The correct behavior for handles in mixed ltr/rtl text line is not known,
354 // so passing false for |check_direction| in some of these tests.
305 textfield_->SelectRange(gfx::Range(3, 4)); 355 textfield_->SelectRange(gfx::Range(3, 4));
306 VERIFY_HANDLE_POSITIONS(false); 356 VerifyHandlePositions(false, false, FROM_HERE);
307 357
308 textfield_->SelectRange(gfx::Range(4, 3)); 358 textfield_->SelectRange(gfx::Range(4, 3));
309 VERIFY_HANDLE_POSITIONS(false); 359 VerifyHandlePositions(false, false, FROM_HERE);
310 360
311 textfield_->SelectRange(gfx::Range(3, 6)); 361 textfield_->SelectRange(gfx::Range(3, 6));
312 VERIFY_HANDLE_POSITIONS(false); 362 VerifyHandlePositions(false, false, FROM_HERE);
313 363
314 textfield_->SelectRange(gfx::Range(6, 3)); 364 textfield_->SelectRange(gfx::Range(6, 3));
315 VERIFY_HANDLE_POSITIONS(false); 365 VerifyHandlePositions(false, false, FROM_HERE);
316 366
317 // Test selection range accross runs. 367 // Test selection range accross runs.
318 textfield_->SelectRange(gfx::Range(0, 6)); 368 textfield_->SelectRange(gfx::Range(0, 6));
319 VERIFY_HANDLE_POSITIONS(false); 369 VerifyHandlePositions(false, true, FROM_HERE);
320 370
321 textfield_->SelectRange(gfx::Range(6, 0)); 371 textfield_->SelectRange(gfx::Range(6, 0));
322 VERIFY_HANDLE_POSITIONS(false); 372 VerifyHandlePositions(false, true, FROM_HERE);
323 373
324 textfield_->SelectRange(gfx::Range(1, 4)); 374 textfield_->SelectRange(gfx::Range(1, 4));
325 VERIFY_HANDLE_POSITIONS(false); 375 VerifyHandlePositions(false, true, FROM_HERE);
326 376
327 textfield_->SelectRange(gfx::Range(4, 1)); 377 textfield_->SelectRange(gfx::Range(4, 1));
328 VERIFY_HANDLE_POSITIONS(false); 378 VerifyHandlePositions(false, true, FROM_HERE);
329 } 379 }
330 380
331 // Tests if the SelectRect callback is called appropriately when selection 381 // Tests if the SelectRect callback is called appropriately when selection
332 // handles are moved. 382 // handles are moved.
333 TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) { 383 TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) {
334 CreateTextfield(); 384 CreateTextfield();
335 textfield_->SetText(ASCIIToUTF16("textfield with selected text")); 385 textfield_->SetText(ASCIIToUTF16("textfield with selected text"));
336 // Tap the textfield to invoke touch selection. 386 // Tap the textfield to invoke touch selection.
337 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 387 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
338 details.set_tap_count(1); 388 details.set_tap_count(1);
339 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 389 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
340 textfield_->OnGestureEvent(&tap); 390 textfield_->OnGestureEvent(&tap);
341 textfield_->SelectRange(gfx::Range(3, 7)); 391 textfield_->SelectRange(gfx::Range(3, 7));
342 392
343 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfie"); 393 gfx::Point textfield_origin;
344 VERIFY_HANDLE_POSITIONS(false); 394 textfield_->ConvertPointToScreen(&textfield_origin);
395
396 EXPECT_EQ("tfie", UTF16ToUTF8(textfield_->GetSelectedText()));
397 VerifyHandlePositions(false, true, FROM_HERE);
345 398
346 // Drag selection handle 2 to right by 3 chars. 399 // Drag selection handle 2 to right by 3 chars.
347 const gfx::FontList& font_list = textfield_->GetFontList(); 400 const gfx::FontList& font_list = textfield_->GetFontList();
348 int x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("ld "), font_list); 401 int x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("ld "), font_list);
349 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 402 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
350 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfield "); 403 EXPECT_EQ("tfield ", UTF16ToUTF8(textfield_->GetSelectedText()));
351 VERIFY_HANDLE_POSITIONS(false); 404 VerifyHandlePositions(false, true, FROM_HERE);
352 405
353 // Drag selection handle 1 to the left by a large amount (selection should 406 // Drag selection handle 1 to the left by a large amount (selection should
354 // just stick to the beginning of the textfield). 407 // just stick to the beginning of the textfield).
355 SimulateSelectionHandleDrag(gfx::Point(-50, 0), 1); 408 SimulateSelectionHandleDrag(gfx::Vector2d(-50, 0), 1);
356 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "textfield "); 409 EXPECT_EQ("textfield ", UTF16ToUTF8(textfield_->GetSelectedText()));
357 VERIFY_HANDLE_POSITIONS(true); 410 VerifyHandlePositions(true, true, FROM_HERE);
358 411
359 // Drag selection handle 1 across selection handle 2. 412 // Drag selection handle 1 across selection handle 2.
360 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("textfield with "), font_list); 413 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("textfield with "), font_list);
361 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 414 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
362 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "with "); 415 EXPECT_EQ("with ", UTF16ToUTF8(textfield_->GetSelectedText()));
363 VERIFY_HANDLE_POSITIONS(true); 416 VerifyHandlePositions(true, true, FROM_HERE);
364 417
365 // Drag selection handle 2 across selection handle 1. 418 // Drag selection handle 2 across selection handle 1.
366 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("with selected "), font_list); 419 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("with selected "), font_list);
367 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 420 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
368 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "selected "); 421 EXPECT_EQ("selected ", UTF16ToUTF8(textfield_->GetSelectedText()));
369 VERIFY_HANDLE_POSITIONS(false); 422 VerifyHandlePositions(false, true, FROM_HERE);
370 } 423 }
371 424
372 TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) { 425 TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) {
373 CreateTextfield(); 426 CreateTextfield();
374 textfield_->SetText(WideToUTF16(L"abc\x05e1\x05e2\x05e3" L"def")); 427 textfield_->SetText(WideToUTF16(L"abc\x05e1\x05e2\x05e3" L"def"));
375 // Tap the textfield to invoke touch selection. 428 // Tap the textfield to invoke touch selection.
376 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 429 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
377 details.set_tap_count(1); 430 details.set_tap_count(1);
378 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 431 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
379 textfield_->OnGestureEvent(&tap); 432 textfield_->OnGestureEvent(&tap);
380 433
381 // Select [c] from left to right. 434 // Select [c] from left to right.
382 textfield_->SelectRange(gfx::Range(2, 3)); 435 textfield_->SelectRange(gfx::Range(2, 3));
383 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText()); 436 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
384 VERIFY_HANDLE_POSITIONS(false); 437 VerifyHandlePositions(false, true, FROM_HERE);
385 438
386 // Drag selection handle 2 to right by 1 char. 439 // Drag selection handle 2 to right by 1 char.
387 const gfx::FontList& font_list = textfield_->GetFontList(); 440 const gfx::FontList& font_list = textfield_->GetFontList();
388 int x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list); 441 int x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list);
389 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 442 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
390 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 443 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
391 VERIFY_HANDLE_POSITIONS(false); 444 VerifyHandlePositions(false, true, FROM_HERE);
392 445
393 // Drag selection handle 1 to left by 1 char. 446 // Drag selection handle 1 to left by 1 char.
394 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list); 447 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list);
395 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 448 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
396 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText()); 449 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
397 VERIFY_HANDLE_POSITIONS(true); 450 VerifyHandlePositions(true, true, FROM_HERE);
398 451
399 // Select [c] from right to left. 452 // Select [c] from right to left.
400 textfield_->SelectRange(gfx::Range(3, 2)); 453 textfield_->SelectRange(gfx::Range(3, 2));
401 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText()); 454 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
402 VERIFY_HANDLE_POSITIONS(false); 455 VerifyHandlePositions(false, true, FROM_HERE);
403 456
404 // Drag selection handle 1 to right by 1 char. 457 // Drag selection handle 1 to right by 1 char.
405 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list); 458 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list);
406 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 459 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
407 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 460 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
408 VERIFY_HANDLE_POSITIONS(true); 461 VerifyHandlePositions(true, true, FROM_HERE);
409 462
410 // Drag selection handle 2 to left by 1 char. 463 // Drag selection handle 2 to left by 1 char.
411 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list); 464 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list);
412 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 465 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
413 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText()); 466 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
414 VERIFY_HANDLE_POSITIONS(false); 467 VerifyHandlePositions(false, true, FROM_HERE);
415 468
416 // Select [\x5e1] from right to left. 469 // Select [\x5e1] from right to left.
417 textfield_->SelectRange(gfx::Range(3, 4)); 470 textfield_->SelectRange(gfx::Range(3, 4));
418 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText()); 471 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
419 VERIFY_HANDLE_POSITIONS(false); 472 // TODO(mfomitchev): crbug.com/429705
473 // The correct behavior for handles in mixed ltr/rtl text line is not known,
474 // so passing false for |check_direction| in some of these tests.
475 VerifyHandlePositions(false, false, FROM_HERE);
420 476
421 /* TODO(xji): for bidi text "abcDEF" whose display is "abcFEDhij", when click 477 /* TODO(xji): for bidi text "abcDEF" whose display is "abcFEDhij", when click
422 right of 'D' and select [D] then move the left selection handle to left 478 right of 'D' and select [D] then move the left selection handle to left
423 by one character, it should select [ED], instead it selects [F]. 479 by one character, it should select [ED], instead it selects [F].
424 Reason: click right of 'D' and left of 'h' return the same x-axis position, 480 Reason: click right of 'D' and left of 'h' return the same x-axis position,
425 pass this position to FindCursorPosition() returns index of 'h'. which 481 pass this position to FindCursorPosition() returns index of 'h'. which
426 means the selection start changed from 3 to 6. 482 means the selection start changed from 3 to 6.
427 Need further investigation on whether this is a bug in Pango and how to 483 Need further investigation on whether this is a bug in Pango and how to
428 work around it. 484 work around it.
429 // Drag selection handle 2 to left by 1 char. 485 // Drag selection handle 2 to left by 1 char.
430 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 486 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
431 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 487 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
432 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText()); 488 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
433 VERIFY_HANDLE_POSITIONS(false); 489 VERIFY_HANDLE_POSITIONS(false);
434 */ 490 */
435 491
436 // Drag selection handle 1 to right by 1 char. 492 // Drag selection handle 1 to right by 1 char.
437 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list); 493 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list);
438 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 494 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
439 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText()); 495 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
440 VERIFY_HANDLE_POSITIONS(true); 496 VerifyHandlePositions(true, true, FROM_HERE);
441 497
442 // Select [\x5e1] from left to right. 498 // Select [\x5e1] from left to right.
443 textfield_->SelectRange(gfx::Range(4, 3)); 499 textfield_->SelectRange(gfx::Range(4, 3));
444 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText()); 500 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
445 VERIFY_HANDLE_POSITIONS(false); 501 VerifyHandlePositions(false, false, FROM_HERE);
446 502
447 /* TODO(xji): see detail of above commented out test case. 503 /* TODO(xji): see detail of above commented out test case.
448 // Drag selection handle 1 to left by 1 char. 504 // Drag selection handle 1 to left by 1 char.
449 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 505 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
450 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 506 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
451 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText()); 507 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
452 VERIFY_HANDLE_POSITIONS(true); 508 VERIFY_HANDLE_POSITIONS(true);
453 */ 509 */
454 510
455 // Drag selection handle 2 to right by 1 char. 511 // Drag selection handle 2 to right by 1 char.
456 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list); 512 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list);
457 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 513 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
458 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText()); 514 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
459 VERIFY_HANDLE_POSITIONS(false); 515 VerifyHandlePositions(false, true, FROM_HERE);
460 516
461 // Select [\x05r3] from right to left. 517 // Select [\x05r3] from right to left.
462 textfield_->SelectRange(gfx::Range(5, 6)); 518 textfield_->SelectRange(gfx::Range(5, 6));
463 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText()); 519 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
464 VERIFY_HANDLE_POSITIONS(false); 520 VerifyHandlePositions(false, false, FROM_HERE);
465 521
466 // Drag selection handle 2 to left by 1 char. 522 // Drag selection handle 2 to left by 1 char.
467 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list); 523 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list);
468 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 524 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
469 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 525 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
470 VERIFY_HANDLE_POSITIONS(false); 526 VerifyHandlePositions(false, true, FROM_HERE);
471 527
472 // Drag selection handle 1 to right by 1 char. 528 // Drag selection handle 1 to right by 1 char.
473 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 529 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
474 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 530 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
475 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText()); 531 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
476 VERIFY_HANDLE_POSITIONS(true); 532 VerifyHandlePositions(true, true, FROM_HERE);
477 533
478 // Select [\x05r3] from left to right. 534 // Select [\x05r3] from left to right.
479 textfield_->SelectRange(gfx::Range(6, 5)); 535 textfield_->SelectRange(gfx::Range(6, 5));
480 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText()); 536 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
481 VERIFY_HANDLE_POSITIONS(false); 537 VerifyHandlePositions(false, false, FROM_HERE);
482 538
483 // Drag selection handle 1 to left by 1 char. 539 // Drag selection handle 1 to left by 1 char.
484 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list); 540 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list);
485 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 541 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
486 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 542 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
487 VERIFY_HANDLE_POSITIONS(true); 543 VerifyHandlePositions(true, true, FROM_HERE);
488 544
489 // Drag selection handle 2 to right by 1 char. 545 // Drag selection handle 2 to right by 1 char.
490 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 546 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
491 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 547 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
492 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText()); 548 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
493 VERIFY_HANDLE_POSITIONS(false); 549 VerifyHandlePositions(false, false, FROM_HERE);
494 } 550 }
495 551
496 TEST_F(TouchSelectionControllerImplTest, 552 TEST_F(TouchSelectionControllerImplTest,
497 HiddenSelectionHandleRetainsCursorPosition) { 553 HiddenSelectionHandleRetainsCursorPosition) {
498 // Create a textfield with lots of text in it. 554 // Create a textfield with lots of text in it.
499 CreateTextfield(); 555 CreateTextfield();
500 std::string textfield_text("some text"); 556 std::string textfield_text("some text");
501 for (int i = 0; i < 10; ++i) 557 for (int i = 0; i < 10; ++i)
502 textfield_text += textfield_text; 558 textfield_text += textfield_text;
503 textfield_->SetText(ASCIIToUTF16(textfield_text)); 559 textfield_->SetText(ASCIIToUTF16(textfield_text));
(...skipping 10 matching lines...) Expand all
514 // Check that one selection handle is hidden. 570 // Check that one selection handle is hidden.
515 EXPECT_FALSE(IsSelectionHandle1Visible()); 571 EXPECT_FALSE(IsSelectionHandle1Visible());
516 EXPECT_TRUE(IsSelectionHandle2Visible()); 572 EXPECT_TRUE(IsSelectionHandle2Visible());
517 EXPECT_EQ(gfx::Range(10, textfield_text.length()), 573 EXPECT_EQ(gfx::Range(10, textfield_text.length()),
518 textfield_->GetSelectedRange()); 574 textfield_->GetSelectedRange());
519 575
520 // Drag the visible handle around and make sure the selection end point of the 576 // Drag the visible handle around and make sure the selection end point of the
521 // invisible handle does not change. 577 // invisible handle does not change.
522 size_t visible_handle_position = textfield_->GetSelectedRange().end(); 578 size_t visible_handle_position = textfield_->GetSelectedRange().end();
523 for (int i = 0; i < 10; ++i) { 579 for (int i = 0; i < 10; ++i) {
524 SimulateSelectionHandleDrag(gfx::Point(-10, 0), 2); 580 static const int drag_diff = -10;
581 SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2);
525 // Make sure that the visible handle is being dragged. 582 // Make sure that the visible handle is being dragged.
526 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end()); 583 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end());
527 visible_handle_position = textfield_->GetSelectedRange().end(); 584 visible_handle_position = textfield_->GetSelectedRange().end();
528 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start()); 585 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start());
529 } 586 }
530 } 587 }
531 588
532 TEST_F(TouchSelectionControllerImplTest, 589 TEST_F(TouchSelectionControllerImplTest,
533 DoubleTapInTextfieldWithCursorHandleShouldSelectText) { 590 DoubleTapInTextfieldWithCursorHandleShouldSelectText) {
534 CreateTextfield(); 591 CreateTextfield();
535 textfield_->SetText(ASCIIToUTF16("some text")); 592 textfield_->SetText(ASCIIToUTF16("some text"));
536 ui::test::EventGenerator generator( 593 ui::test::EventGenerator generator(
537 textfield_->GetWidget()->GetNativeView()->GetRootWindow()); 594 textfield_->GetWidget()->GetNativeView()->GetRootWindow());
538 595
539 // Tap the textfield to invoke touch selection. 596 // Tap the textfield to invoke touch selection.
540 generator.GestureTapAt(gfx::Point(10, 10)); 597 generator.GestureTapAt(gfx::Point(10, 10));
541 598
542 // Cursor handle should be visible. 599 // Cursor handle should be visible.
543 EXPECT_FALSE(textfield_->HasSelection()); 600 EXPECT_FALSE(textfield_->HasSelection());
544 VERIFY_HANDLE_POSITIONS(false); 601 VerifyHandlePositions(false, true, FROM_HERE);
545 602
546 // Double tap on the cursor handle position. We want to check that the cursor 603 // Double tap on the cursor handle position. We want to check that the cursor
547 // handle is not eating the event and that the event is falling through to the 604 // handle is not eating the event and that the event is falling through to the
548 // textfield. 605 // textfield.
549 gfx::Point cursor_pos = GetCursorHandlePosition(); 606 gfx::Point cursor_pos = GetCursorHandleBounds().origin();
550 cursor_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); 607 cursor_pos.Offset(GetCursorHandleBounds().width() / 2, 0);
551 generator.GestureTapAt(cursor_pos); 608 generator.GestureTapAt(cursor_pos);
552 generator.GestureTapAt(cursor_pos); 609 generator.GestureTapAt(cursor_pos);
553 EXPECT_TRUE(textfield_->HasSelection()); 610 EXPECT_TRUE(textfield_->HasSelection());
554 } 611 }
555 612
556 // A simple implementation of TouchEditable that allows faking cursor position 613 // A simple implementation of TouchEditable that allows faking cursor position
557 // inside its boundaries. 614 // inside its boundaries.
558 class TestTouchEditable : public ui::TouchEditable { 615 class TestTouchEditable : public ui::TouchEditable {
559 public: 616 public:
560 explicit TestTouchEditable(aura::Window* window) 617 explicit TestTouchEditable(aura::Window* window)
561 : window_(window) { 618 : window_(window) {
562 DCHECK(window); 619 DCHECK(window);
563 } 620 }
564 621
565 void set_bounds(const gfx::Rect& bounds) { 622 void set_bounds(const gfx::Rect& bounds) {
566 bounds_ = bounds; 623 bounds_ = bounds;
567 } 624 }
568 625
569 void set_cursor_rect(const gfx::Rect& cursor_rect) { 626 void set_cursor_rect(const gfx::Rect& cursor_rect) {
570 cursor_rect_ = cursor_rect; 627 cursor_bound_.edge_top = cursor_rect.origin();
628 cursor_bound_.edge_bottom = cursor_rect.bottom_left();
629 cursor_bound_.type = ui::SelectionBound::Type::CENTER;
571 } 630 }
572 631
573 ~TestTouchEditable() override {} 632 ~TestTouchEditable() override {}
574 633
575 private: 634 private:
576 // Overridden from ui::TouchEditable. 635 // Overridden from ui::TouchEditable.
577 void SelectRect(const gfx::Point& start, const gfx::Point& end) override { 636 void SelectRect(const gfx::Point& start, const gfx::Point& end) override {
578 NOTREACHED(); 637 NOTREACHED();
579 } 638 }
580 void MoveCaretTo(const gfx::Point& point) override { NOTREACHED(); } 639 void MoveCaretTo(const gfx::Point& point) override { NOTREACHED(); }
581 void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) override { 640 void GetSelectionEndPoints(ui::SelectionBound* anchor,
582 *p1 = *p2 = cursor_rect_; 641 ui::SelectionBound* focus) override {
642 *anchor = *focus = cursor_bound_;
583 } 643 }
584 gfx::Rect GetBounds() override { return gfx::Rect(bounds_.size()); } 644 gfx::Rect GetBounds() override { return gfx::Rect(bounds_.size()); }
585 gfx::NativeView GetNativeView() const override { return window_; } 645 gfx::NativeView GetNativeView() const override { return window_; }
586 void ConvertPointToScreen(gfx::Point* point) override { 646 void ConvertPointToScreen(gfx::Point* point) override {
587 aura::client::ScreenPositionClient* screen_position_client = 647 aura::client::ScreenPositionClient* screen_position_client =
588 aura::client::GetScreenPositionClient(window_->GetRootWindow()); 648 aura::client::GetScreenPositionClient(window_->GetRootWindow());
589 if (screen_position_client) 649 if (screen_position_client)
590 screen_position_client->ConvertPointToScreen(window_, point); 650 screen_position_client->ConvertPointToScreen(window_, point);
591 } 651 }
592 void ConvertPointFromScreen(gfx::Point* point) override { 652 void ConvertPointFromScreen(gfx::Point* point) override {
(...skipping 23 matching lines...) Expand all
616 void ExecuteCommand(int command_id, int event_flags) override { 676 void ExecuteCommand(int command_id, int event_flags) override {
617 NOTREACHED(); 677 NOTREACHED();
618 } 678 }
619 679
620 aura::Window* window_; 680 aura::Window* window_;
621 681
622 // Boundaries of the client view. 682 // Boundaries of the client view.
623 gfx::Rect bounds_; 683 gfx::Rect bounds_;
624 684
625 // Cursor position inside the client view. 685 // Cursor position inside the client view.
626 gfx::Rect cursor_rect_; 686 //gfx::Rect cursor_rect_;
687 ui::SelectionBound cursor_bound_;
627 688
628 DISALLOW_COPY_AND_ASSIGN(TestTouchEditable); 689 DISALLOW_COPY_AND_ASSIGN(TestTouchEditable);
629 }; 690 };
630 691
631 // Tests if the touch editing handle is shown or hidden properly according to 692 // Tests if the touch editing handle is shown or hidden properly according to
632 // the cursor position relative to the client boundaries. 693 // the cursor position relative to the client boundaries.
633 TEST_F(TouchSelectionControllerImplTest, 694 TEST_F(TouchSelectionControllerImplTest,
634 VisibilityOfHandleRegardingClientBounds) { 695 VisibilityOfHandleRegardingClientBounds) {
635 CreateWidget(); 696 CreateWidget();
636 697
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 // image width and check that anchor rect's height is not adjusted. 825 // image width and check that anchor rect's height is not adjusted.
765 anchor_rect = 826 anchor_rect =
766 gfx::Rect(0, 0, quick_menu_width + handle_image_size.width() + 10, 20); 827 gfx::Rect(0, 0, quick_menu_width + handle_image_size.width() + 10, 20);
767 quick_menu = TouchEditingMenuView::Create( 828 quick_menu = TouchEditingMenuView::Create(
768 quick_menu_controller.get(), anchor_rect, handle_image_size, window); 829 quick_menu_controller.get(), anchor_rect, handle_image_size, window);
769 EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString()); 830 EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString());
770 831
771 // Close the widget, hence quick menus, before quick menu controller goes out 832 // Close the widget, hence quick menus, before quick menu controller goes out
772 // of scope. 833 // of scope.
773 widget_->CloseNow(); 834 widget_->CloseNow();
774 widget_ = NULL; 835 widget_ = nullptr;
775 } 836 }
776 837
777 TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) { 838 TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) {
778 CreateTextfield(); 839 CreateTextfield();
779 EXPECT_FALSE(GetSelectionController()); 840 EXPECT_FALSE(GetSelectionController());
780 841
781 ui::test::EventGenerator generator( 842 ui::test::EventGenerator generator(
782 textfield_widget_->GetNativeView()->GetRootWindow()); 843 textfield_widget_->GetNativeView()->GetRootWindow());
783 844
784 generator.set_current_location(gfx::Point(5, 5)); 845 generator.set_current_location(gfx::Point(5, 5));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 // Start touch editing; then press a key and ensure it deactivates touch 888 // Start touch editing; then press a key and ensure it deactivates touch
828 // selection. 889 // selection.
829 StartTouchEditing(); 890 StartTouchEditing();
830 EXPECT_TRUE(GetSelectionController()); 891 EXPECT_TRUE(GetSelectionController());
831 generator.PressKey(ui::VKEY_A, 0); 892 generator.PressKey(ui::VKEY_A, 0);
832 RunPendingMessages(); 893 RunPendingMessages();
833 EXPECT_FALSE(GetSelectionController()); 894 EXPECT_FALSE(GetSelectionController());
834 } 895 }
835 896
836 } // namespace views 897 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/touchui/touch_selection_controller_impl.cc ('k') | ui/views/widget/widget_interactive_uitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698