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

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