| 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 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |