OLD | NEW |
---|---|
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 Loading... | |
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 a focus. |
Jay Civelli
2011/01/06 00:55:54
Nit: gain a focus -> gain focus.
oshima
2011/01/06 01:31:22
Done. fixed other places as well.
| |
102 Textfield::Keystroke ks(&e); | 101 NOTREACHED(); |
103 handled = controller->HandleKeystroke(textfield_, ks); | 102 return false; |
104 } | |
105 return handled || HandleKeyEvent(e); | |
106 } | 103 } |
107 | 104 |
108 bool NativeTextfieldViews::OnKeyReleased(const views::KeyEvent& e) { | 105 bool NativeTextfieldViews::OnKeyReleased(const views::KeyEvent& e) { |
109 return true; | 106 NOTREACHED(); |
107 return false; | |
110 } | 108 } |
111 | 109 |
112 void NativeTextfieldViews::Paint(gfx::Canvas* canvas) { | 110 void NativeTextfieldViews::Paint(gfx::Canvas* canvas) { |
113 text_border_->set_has_focus(HasFocus()); | 111 text_border_->set_has_focus(textfield_->HasFocus()); |
114 PaintBackground(canvas); | 112 PaintBackground(canvas); |
115 PaintTextAndCursor(canvas); | 113 PaintTextAndCursor(canvas); |
116 if (textfield_->draw_border()) | 114 if (textfield_->draw_border()) |
117 PaintBorder(canvas); | 115 PaintBorder(canvas); |
118 } | 116 } |
119 | 117 |
118 void NativeTextfieldViews::DidChangeBounds(const gfx::Rect& previous, | |
119 const gfx::Rect& current) { | |
120 UpdateCursorBoundsAndTextOffset(); | |
121 } | |
122 | |
120 void NativeTextfieldViews::WillGainFocus() { | 123 void NativeTextfieldViews::WillGainFocus() { |
124 NOTREACHED(); | |
121 } | 125 } |
122 | 126 |
123 void NativeTextfieldViews::DidGainFocus() { | 127 void NativeTextfieldViews::DidGainFocus() { |
124 is_cursor_visible_ = true; | 128 NOTREACHED(); |
125 SchedulePaint(); | |
126 // Start blinking cursor. | |
127 MessageLoop::current()->PostDelayedTask( | |
128 FROM_HERE, | |
129 cursor_timer_.NewRunnableMethod(&NativeTextfieldViews::UpdateCursor), | |
130 kCursorVisibleTimeMs); | |
131 } | 129 } |
132 | 130 |
133 void NativeTextfieldViews::WillLoseFocus() { | 131 void NativeTextfieldViews::WillLoseFocus() { |
134 // Stop blinking cursor. | 132 NOTREACHED(); |
135 cursor_timer_.RevokeAll(); | |
136 if (is_cursor_visible_) { | |
137 is_cursor_visible_ = false; | |
138 RepaintCursor(); | |
139 } | |
140 } | |
141 | |
142 void NativeTextfieldViews::DidChangeBounds(const gfx::Rect& previous, | |
143 const gfx::Rect& current) { | |
144 UpdateCursorBoundsAndTextOffset(); | |
145 } | 133 } |
146 | 134 |
147 ///////////////////////////////////////////////////////////////// | 135 ///////////////////////////////////////////////////////////////// |
148 // NativeTextfieldViews, NativeTextifieldWrapper overrides: | 136 // NativeTextfieldViews, NativeTextifieldWrapper overrides: |
149 | 137 |
150 string16 NativeTextfieldViews::GetText() const { | 138 string16 NativeTextfieldViews::GetText() const { |
151 return model_->text(); | 139 return model_->text(); |
152 } | 140 } |
153 | 141 |
154 void NativeTextfieldViews::UpdateText() { | 142 void NativeTextfieldViews::UpdateText() { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 UpdateCursorBoundsAndTextOffset(); | 206 UpdateCursorBoundsAndTextOffset(); |
219 } | 207 } |
220 | 208 |
221 void NativeTextfieldViews::UpdateIsPassword() { | 209 void NativeTextfieldViews::UpdateIsPassword() { |
222 model_->set_is_password(textfield_->IsPassword()); | 210 model_->set_is_password(textfield_->IsPassword()); |
223 UpdateCursorBoundsAndTextOffset(); | 211 UpdateCursorBoundsAndTextOffset(); |
224 SchedulePaint(); | 212 SchedulePaint(); |
225 } | 213 } |
226 | 214 |
227 void NativeTextfieldViews::UpdateEnabled() { | 215 void NativeTextfieldViews::UpdateEnabled() { |
216 SetEnabled(textfield_->IsEnabled()); | |
228 SchedulePaint(); | 217 SchedulePaint(); |
229 } | 218 } |
230 | 219 |
231 bool NativeTextfieldViews::IsPassword() { | |
232 // looks unnecessary. should we remove? | |
233 NOTREACHED(); | |
234 return false; | |
235 } | |
236 | |
237 gfx::Insets NativeTextfieldViews::CalculateInsets() { | 220 gfx::Insets NativeTextfieldViews::CalculateInsets() { |
238 return GetInsets(); | 221 return GetInsets(); |
239 } | 222 } |
240 | 223 |
241 void NativeTextfieldViews::UpdateHorizontalMargins() { | 224 void NativeTextfieldViews::UpdateHorizontalMargins() { |
242 int left, right; | 225 int left, right; |
243 if (!textfield_->GetHorizontalMargins(&left, &right)) | 226 if (!textfield_->GetHorizontalMargins(&left, &right)) |
244 return; | 227 return; |
245 gfx::Insets inset = GetInsets(); | 228 gfx::Insets inset = GetInsets(); |
246 | 229 |
247 text_border_->SetInsets(inset.top(), left, inset.bottom(), right); | 230 text_border_->SetInsets(inset.top(), left, inset.bottom(), right); |
248 UpdateCursorBoundsAndTextOffset(); | 231 UpdateCursorBoundsAndTextOffset(); |
249 } | 232 } |
250 | 233 |
251 void NativeTextfieldViews::UpdateVerticalMargins() { | 234 void NativeTextfieldViews::UpdateVerticalMargins() { |
252 int top, bottom; | 235 int top, bottom; |
253 if (!textfield_->GetVerticalMargins(&top, &bottom)) | 236 if (!textfield_->GetVerticalMargins(&top, &bottom)) |
254 return; | 237 return; |
255 gfx::Insets inset = GetInsets(); | 238 gfx::Insets inset = GetInsets(); |
256 | 239 |
257 text_border_->SetInsets(top, inset.left(), bottom, inset.right()); | 240 text_border_->SetInsets(top, inset.left(), bottom, inset.right()); |
258 UpdateCursorBoundsAndTextOffset(); | 241 UpdateCursorBoundsAndTextOffset(); |
259 } | 242 } |
260 | 243 |
261 void NativeTextfieldViews::SetFocus() { | 244 bool NativeTextfieldViews::SetFocus() { |
262 RequestFocus(); | 245 return false; |
263 } | 246 } |
264 | 247 |
265 View* NativeTextfieldViews::GetView() { | 248 View* NativeTextfieldViews::GetView() { |
266 return this; | 249 return this; |
267 } | 250 } |
268 | 251 |
269 gfx::NativeView NativeTextfieldViews::GetTestingHandle() const { | 252 gfx::NativeView NativeTextfieldViews::GetTestingHandle() const { |
270 NOTREACHED(); | 253 NOTREACHED(); |
271 return NULL; | 254 return NULL; |
272 } | 255 } |
273 | 256 |
274 bool NativeTextfieldViews::IsIMEComposing() const { | 257 bool NativeTextfieldViews::IsIMEComposing() const { |
275 return false; | 258 return false; |
276 } | 259 } |
277 | 260 |
261 bool NativeTextfieldViews::HandleKeyPressed(const views::KeyEvent& e) { | |
262 Textfield::Controller* controller = textfield_->GetController(); | |
263 bool handled = false; | |
264 if (controller) { | |
265 Textfield::Keystroke ks(&e); | |
266 handled = controller->HandleKeystroke(textfield_, ks); | |
267 } | |
268 return handled || HandleKeyEvent(e); | |
269 } | |
270 | |
271 bool NativeTextfieldViews::HandleKeyReleased(const views::KeyEvent& e) { | |
272 return true; | |
273 } | |
274 | |
275 void NativeTextfieldViews::HandleWillGainFocus() { | |
276 } | |
277 | |
278 void NativeTextfieldViews::HandleDidGainFocus() { | |
279 is_cursor_visible_ = true; | |
280 SchedulePaint(); | |
281 // Start blinking cursor. | |
282 MessageLoop::current()->PostDelayedTask( | |
283 FROM_HERE, | |
284 cursor_timer_.NewRunnableMethod(&NativeTextfieldViews::UpdateCursor), | |
285 kCursorVisibleTimeMs); | |
286 } | |
287 | |
288 void NativeTextfieldViews::HandleWillLoseFocus() { | |
289 // Stop blinking cursor. | |
290 cursor_timer_.RevokeAll(); | |
291 if (is_cursor_visible_) { | |
292 is_cursor_visible_ = false; | |
293 RepaintCursor(); | |
294 } | |
295 } | |
296 | |
278 // static | 297 // static |
279 bool NativeTextfieldViews::IsTextfieldViewsEnabled() { | 298 bool NativeTextfieldViews::IsTextfieldViewsEnabled() { |
280 #if defined(TOUCH_UI) | 299 #if defined(TOUCH_UI) |
281 return true; | 300 return true; |
282 #else | 301 #else |
283 return textfield_view_enabled || | 302 return textfield_view_enabled || |
284 CommandLine::ForCurrentProcess()->HasSwitch( | 303 CommandLine::ForCurrentProcess()->HasSwitch( |
285 kEnableViewsBasedTextfieldSwitch); | 304 kEnableViewsBasedTextfieldSwitch); |
286 #endif | 305 #endif |
287 } | 306 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 width() - insets.width(), height() - insets.height()); | 382 width() - insets.width(), height() - insets.height()); |
364 | 383 |
365 // TODO(oshima): bidi support | 384 // TODO(oshima): bidi support |
366 // TODO(varunjain): re-implement this so only that dirty text is painted. | 385 // TODO(varunjain): re-implement this so only that dirty text is painted. |
367 TextfieldViewsModel::TextFragments fragments; | 386 TextfieldViewsModel::TextFragments fragments; |
368 model_->GetFragments(&fragments); | 387 model_->GetFragments(&fragments); |
369 int x_offset = text_offset_ + insets.left(); | 388 int x_offset = text_offset_ + insets.left(); |
370 int y = insets.top(); | 389 int y = insets.top(); |
371 int text_height = height() - insets.height(); | 390 int text_height = height() - insets.height(); |
372 SkColor selection_color = | 391 SkColor selection_color = |
373 HasFocus() ? kFocusedSelectionColor : kUnfocusedSelectionColor; | 392 textfield_->HasFocus() ? |
393 kFocusedSelectionColor : kUnfocusedSelectionColor; | |
374 SkColor text_color = | 394 SkColor text_color = |
375 textfield_->read_only() ? kReadonlyTextColor : GetTextColor(); | 395 textfield_->read_only() ? kReadonlyTextColor : GetTextColor(); |
376 | 396 |
377 for (TextfieldViewsModel::TextFragments::const_iterator iter = | 397 for (TextfieldViewsModel::TextFragments::const_iterator iter = |
378 fragments.begin(); | 398 fragments.begin(); |
379 iter != fragments.end(); | 399 iter != fragments.end(); |
380 iter++) { | 400 iter++) { |
381 string16 text = model_->GetVisibleText((*iter).begin, (*iter).end); | 401 string16 text = model_->GetVisibleText((*iter).begin, (*iter).end); |
382 // TODO(oshima): This does not give the accurate position due to | 402 // TODO(oshima): This does not give the accurate position due to |
383 // kerning. Figure out how webkit does this with skia. | 403 // kerning. Figure out how webkit does this with skia. |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 } | 715 } |
696 | 716 |
697 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, | 717 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, |
698 int left, | 718 int left, |
699 int bottom, | 719 int bottom, |
700 int right) { | 720 int right) { |
701 insets_.Set(top, left, bottom, right); | 721 insets_.Set(top, left, bottom, right); |
702 } | 722 } |
703 | 723 |
704 } // namespace views | 724 } // namespace views |
OLD | NEW |