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

Side by Side Diff: views/controls/textfield/native_textfield_views.cc

Issue 5988010: focus reverse traversal was not working for TextfieldViews. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 9 years, 11 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "views/controls/textfield/native_textfield_views.h" 5 #include "views/controls/textfield/native_textfield_views.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 "views/NativeTextfieldViews"; 50 "views/NativeTextfieldViews";
51 51
52 NativeTextfieldViews::NativeTextfieldViews(Textfield* parent) 52 NativeTextfieldViews::NativeTextfieldViews(Textfield* parent)
53 : textfield_(parent), 53 : textfield_(parent),
54 model_(new TextfieldViewsModel()), 54 model_(new TextfieldViewsModel()),
55 text_border_(new TextfieldBorder()), 55 text_border_(new TextfieldBorder()),
56 text_offset_(0), 56 text_offset_(0),
57 insert_(true), 57 insert_(true),
58 is_cursor_visible_(false), 58 is_cursor_visible_(false),
59 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) { 59 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) {
60 SetFocusable(true);
61 set_border(text_border_); 60 set_border(text_border_);
62 61
63 // Multiline is not supported. 62 // Multiline is not supported.
64 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE); 63 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE);
65 // Lowercase is not supported. 64 // Lowercase is not supported.
66 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE); 65 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE);
67 } 66 }
68 67
69 NativeTextfieldViews::~NativeTextfieldViews() { 68 NativeTextfieldViews::~NativeTextfieldViews() {
70 } 69 }
71 70
72 //////////////////////////////////////////////////////////////////////////////// 71 ////////////////////////////////////////////////////////////////////////////////
73 // NativeTextfieldViews, View overrides: 72 // NativeTextfieldViews, View overrides:
74 73
75 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { 74 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) {
76 RequestFocus(); 75 textfield_->RequestFocus();
77 size_t pos = FindCursorPosition(e.location()); 76 size_t pos = FindCursorPosition(e.location());
78 if (model_->MoveCursorTo(pos, false)) { 77 if (model_->MoveCursorTo(pos, false)) {
79 UpdateCursorBoundsAndTextOffset(); 78 UpdateCursorBoundsAndTextOffset();
80 SchedulePaint(); 79 SchedulePaint();
81 } 80 }
82 return true; 81 return true;
83 } 82 }
84 83
85 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { 84 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) {
86 size_t pos = FindCursorPosition(e.location()); 85 size_t pos = FindCursorPosition(e.location());
87 if (model_->MoveCursorTo(pos, true)) { 86 if (model_->MoveCursorTo(pos, true)) {
88 UpdateCursorBoundsAndTextOffset(); 87 UpdateCursorBoundsAndTextOffset();
89 SchedulePaint(); 88 SchedulePaint();
90 } 89 }
91 return true; 90 return true;
92 } 91 }
93 92
94 void NativeTextfieldViews::OnMouseReleased(const views::MouseEvent& e, 93 void NativeTextfieldViews::OnMouseReleased(const views::MouseEvent& e,
95 bool canceled) { 94 bool canceled) {
96 } 95 }
97 96
98 bool NativeTextfieldViews::OnKeyPressed(const views::KeyEvent& e) { 97 bool NativeTextfieldViews::OnKeyPressed(const views::KeyEvent& e) {
99 Textfield::Controller* controller = textfield_->GetController(); 98 // OnKeyPressed/OnKeyReleased/WillGainFocus/DidGainFocus/WillLoseFocus
100 bool handled = false; 99 // will never be invoked on NativeTextfieldViews as it will never
101 if (controller) 100 // gain focus.
102 handled = controller->HandleKeyEvent(textfield_, e); 101 NOTREACHED();
103 return handled || HandleKeyEvent(e); 102 return false;
104 } 103 }
105 104
106 bool NativeTextfieldViews::OnKeyReleased(const views::KeyEvent& e) { 105 bool NativeTextfieldViews::OnKeyReleased(const views::KeyEvent& e) {
107 return true; 106 NOTREACHED();
107 return false;
108 } 108 }
109 109
110 void NativeTextfieldViews::Paint(gfx::Canvas* canvas) { 110 void NativeTextfieldViews::Paint(gfx::Canvas* canvas) {
111 text_border_->set_has_focus(HasFocus()); 111 text_border_->set_has_focus(textfield_->HasFocus());
112 PaintBackground(canvas); 112 PaintBackground(canvas);
113 PaintTextAndCursor(canvas); 113 PaintTextAndCursor(canvas);
114 if (textfield_->draw_border()) 114 if (textfield_->draw_border())
115 PaintBorder(canvas); 115 PaintBorder(canvas);
116 } 116 }
117 117
118 void NativeTextfieldViews::DidChangeBounds(const gfx::Rect& previous,
119 const gfx::Rect& current) {
120 UpdateCursorBoundsAndTextOffset();
121 }
122
118 void NativeTextfieldViews::WillGainFocus() { 123 void NativeTextfieldViews::WillGainFocus() {
124 NOTREACHED();
119 } 125 }
120 126
121 void NativeTextfieldViews::DidGainFocus() { 127 void NativeTextfieldViews::DidGainFocus() {
122 is_cursor_visible_ = true; 128 NOTREACHED();
123 SchedulePaint();
124 // Start blinking cursor.
125 MessageLoop::current()->PostDelayedTask(
126 FROM_HERE,
127 cursor_timer_.NewRunnableMethod(&NativeTextfieldViews::UpdateCursor),
128 kCursorVisibleTimeMs);
129 } 129 }
130 130
131 void NativeTextfieldViews::WillLoseFocus() { 131 void NativeTextfieldViews::WillLoseFocus() {
132 // Stop blinking cursor. 132 NOTREACHED();
133 cursor_timer_.RevokeAll();
134 if (is_cursor_visible_) {
135 is_cursor_visible_ = false;
136 RepaintCursor();
137 }
138 }
139
140 void NativeTextfieldViews::DidChangeBounds(const gfx::Rect& previous,
141 const gfx::Rect& current) {
142 UpdateCursorBoundsAndTextOffset();
143 } 133 }
144 134
145 ///////////////////////////////////////////////////////////////// 135 /////////////////////////////////////////////////////////////////
146 // NativeTextfieldViews, NativeTextifieldWrapper overrides: 136 // NativeTextfieldViews, NativeTextifieldWrapper overrides:
147 137
148 string16 NativeTextfieldViews::GetText() const { 138 string16 NativeTextfieldViews::GetText() const {
149 return model_->text(); 139 return model_->text();
150 } 140 }
151 141
152 void NativeTextfieldViews::UpdateText() { 142 void NativeTextfieldViews::UpdateText() {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 UpdateCursorBoundsAndTextOffset(); 206 UpdateCursorBoundsAndTextOffset();
217 } 207 }
218 208
219 void NativeTextfieldViews::UpdateIsPassword() { 209 void NativeTextfieldViews::UpdateIsPassword() {
220 model_->set_is_password(textfield_->IsPassword()); 210 model_->set_is_password(textfield_->IsPassword());
221 UpdateCursorBoundsAndTextOffset(); 211 UpdateCursorBoundsAndTextOffset();
222 SchedulePaint(); 212 SchedulePaint();
223 } 213 }
224 214
225 void NativeTextfieldViews::UpdateEnabled() { 215 void NativeTextfieldViews::UpdateEnabled() {
216 SetEnabled(textfield_->IsEnabled());
226 SchedulePaint(); 217 SchedulePaint();
227 } 218 }
228 219
229 bool NativeTextfieldViews::IsPassword() {
230 // looks unnecessary. should we remove?
231 NOTREACHED();
232 return false;
233 }
234
235 gfx::Insets NativeTextfieldViews::CalculateInsets() { 220 gfx::Insets NativeTextfieldViews::CalculateInsets() {
236 return GetInsets(); 221 return GetInsets();
237 } 222 }
238 223
239 void NativeTextfieldViews::UpdateHorizontalMargins() { 224 void NativeTextfieldViews::UpdateHorizontalMargins() {
240 int left, right; 225 int left, right;
241 if (!textfield_->GetHorizontalMargins(&left, &right)) 226 if (!textfield_->GetHorizontalMargins(&left, &right))
242 return; 227 return;
243 gfx::Insets inset = GetInsets(); 228 gfx::Insets inset = GetInsets();
244 229
245 text_border_->SetInsets(inset.top(), left, inset.bottom(), right); 230 text_border_->SetInsets(inset.top(), left, inset.bottom(), right);
246 UpdateCursorBoundsAndTextOffset(); 231 UpdateCursorBoundsAndTextOffset();
247 } 232 }
248 233
249 void NativeTextfieldViews::UpdateVerticalMargins() { 234 void NativeTextfieldViews::UpdateVerticalMargins() {
250 int top, bottom; 235 int top, bottom;
251 if (!textfield_->GetVerticalMargins(&top, &bottom)) 236 if (!textfield_->GetVerticalMargins(&top, &bottom))
252 return; 237 return;
253 gfx::Insets inset = GetInsets(); 238 gfx::Insets inset = GetInsets();
254 239
255 text_border_->SetInsets(top, inset.left(), bottom, inset.right()); 240 text_border_->SetInsets(top, inset.left(), bottom, inset.right());
256 UpdateCursorBoundsAndTextOffset(); 241 UpdateCursorBoundsAndTextOffset();
257 } 242 }
258 243
259 void NativeTextfieldViews::SetFocus() { 244 bool NativeTextfieldViews::SetFocus() {
260 RequestFocus(); 245 return false;
261 } 246 }
262 247
263 View* NativeTextfieldViews::GetView() { 248 View* NativeTextfieldViews::GetView() {
264 return this; 249 return this;
265 } 250 }
266 251
267 gfx::NativeView NativeTextfieldViews::GetTestingHandle() const { 252 gfx::NativeView NativeTextfieldViews::GetTestingHandle() const {
268 NOTREACHED(); 253 NOTREACHED();
269 return NULL; 254 return NULL;
270 } 255 }
271 256
272 bool NativeTextfieldViews::IsIMEComposing() const { 257 bool NativeTextfieldViews::IsIMEComposing() const {
273 return false; 258 return false;
274 } 259 }
275 260
261 bool NativeTextfieldViews::HandleKeyPressed(const views::KeyEvent& e) {
262 Textfield::Controller* controller = textfield_->GetController();
263 bool handled = false;
264 if (controller) {
265 handled = controller->HandleKeyEvent(textfield_, e);
266 }
267 return handled || HandleKeyEvent(e);
268 }
269
270 bool NativeTextfieldViews::HandleKeyReleased(const views::KeyEvent& e) {
271 return true;
272 }
273
274 void NativeTextfieldViews::HandleWillGainFocus() {
275 }
276
277 void NativeTextfieldViews::HandleDidGainFocus() {
278 is_cursor_visible_ = true;
279 SchedulePaint();
280 // Start blinking cursor.
281 MessageLoop::current()->PostDelayedTask(
282 FROM_HERE,
283 cursor_timer_.NewRunnableMethod(&NativeTextfieldViews::UpdateCursor),
284 kCursorVisibleTimeMs);
285 }
286
287 void NativeTextfieldViews::HandleWillLoseFocus() {
288 // Stop blinking cursor.
289 cursor_timer_.RevokeAll();
290 if (is_cursor_visible_) {
291 is_cursor_visible_ = false;
292 RepaintCursor();
293 }
294 }
295
276 // static 296 // static
277 bool NativeTextfieldViews::IsTextfieldViewsEnabled() { 297 bool NativeTextfieldViews::IsTextfieldViewsEnabled() {
278 #if defined(TOUCH_UI) 298 #if defined(TOUCH_UI)
279 return true; 299 return true;
280 #else 300 #else
281 return textfield_view_enabled || 301 return textfield_view_enabled ||
282 CommandLine::ForCurrentProcess()->HasSwitch( 302 CommandLine::ForCurrentProcess()->HasSwitch(
283 kEnableViewsBasedTextfieldSwitch); 303 kEnableViewsBasedTextfieldSwitch);
284 #endif 304 #endif
285 } 305 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 width() - insets.width(), height() - insets.height()); 381 width() - insets.width(), height() - insets.height());
362 382
363 // TODO(oshima): bidi support 383 // TODO(oshima): bidi support
364 // TODO(varunjain): re-implement this so only that dirty text is painted. 384 // TODO(varunjain): re-implement this so only that dirty text is painted.
365 TextfieldViewsModel::TextFragments fragments; 385 TextfieldViewsModel::TextFragments fragments;
366 model_->GetFragments(&fragments); 386 model_->GetFragments(&fragments);
367 int x_offset = text_offset_ + insets.left(); 387 int x_offset = text_offset_ + insets.left();
368 int y = insets.top(); 388 int y = insets.top();
369 int text_height = height() - insets.height(); 389 int text_height = height() - insets.height();
370 SkColor selection_color = 390 SkColor selection_color =
371 HasFocus() ? kFocusedSelectionColor : kUnfocusedSelectionColor; 391 textfield_->HasFocus() ?
392 kFocusedSelectionColor : kUnfocusedSelectionColor;
372 SkColor text_color = 393 SkColor text_color =
373 textfield_->read_only() ? kReadonlyTextColor : GetTextColor(); 394 textfield_->read_only() ? kReadonlyTextColor : GetTextColor();
374 395
375 for (TextfieldViewsModel::TextFragments::const_iterator iter = 396 for (TextfieldViewsModel::TextFragments::const_iterator iter =
376 fragments.begin(); 397 fragments.begin();
377 iter != fragments.end(); 398 iter != fragments.end();
378 iter++) { 399 iter++) {
379 string16 text = model_->GetVisibleText((*iter).begin, (*iter).end); 400 string16 text = model_->GetVisibleText((*iter).begin, (*iter).end);
380 // TODO(oshima): This does not give the accurate position due to 401 // TODO(oshima): This does not give the accurate position due to
381 // kerning. Figure out how webkit does this with skia. 402 // kerning. Figure out how webkit does this with skia.
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 } 714 }
694 715
695 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, 716 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top,
696 int left, 717 int left,
697 int bottom, 718 int bottom,
698 int right) { 719 int right) {
699 insets_.Set(top, left, bottom, right); 720 insets_.Set(top, left, bottom, right);
700 } 721 }
701 722
702 } // namespace views 723 } // namespace views
OLDNEW
« no previous file with comments | « views/controls/textfield/native_textfield_views.h ('k') | views/controls/textfield/native_textfield_views_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698