OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "gfx/canvas.h" | 13 #include "gfx/canvas.h" |
14 #include "gfx/canvas_skia.h" | 14 #include "gfx/canvas_skia.h" |
15 #include "gfx/insets.h" | 15 #include "gfx/insets.h" |
16 #include "grit/app_strings.h" | |
17 #include "ui/base/clipboard/clipboard.h" | |
16 #include "views/background.h" | 18 #include "views/background.h" |
17 #include "views/border.h" | 19 #include "views/border.h" |
20 #include "views/controls/menu/menu_2.h" | |
18 #include "views/controls/textfield/native_textfield_gtk.h" | 21 #include "views/controls/textfield/native_textfield_gtk.h" |
19 #include "views/controls/textfield/textfield.h" | 22 #include "views/controls/textfield/textfield.h" |
20 #include "views/controls/textfield/textfield_views_model.h" | 23 #include "views/controls/textfield/textfield_views_model.h" |
21 #include "views/event.h" | 24 #include "views/event.h" |
25 #include "views/views_delegate.h" | |
22 | 26 |
23 namespace { | 27 namespace { |
24 | 28 |
25 // A global flag to switch the Textfield wrapper to TextfieldViews. | 29 // A global flag to switch the Textfield wrapper to TextfieldViews. |
26 bool textfield_view_enabled = false; | 30 bool textfield_view_enabled = false; |
27 | 31 |
28 // Color setttings for text, border, backgrounds and cursor. | 32 // Color setttings for text, border, backgrounds and cursor. |
29 // These are tentative, and should be derived from theme, system | 33 // These are tentative, and should be derived from theme, system |
30 // settings and current settings. | 34 // settings and current settings. |
31 const SkColor kSelectedTextColor = SK_ColorWHITE; | 35 const SkColor kSelectedTextColor = SK_ColorWHITE; |
(...skipping 24 matching lines...) Expand all Loading... | |
56 text_offset_(0), | 60 text_offset_(0), |
57 insert_(true), | 61 insert_(true), |
58 is_cursor_visible_(false), | 62 is_cursor_visible_(false), |
59 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) { | 63 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)) { |
60 set_border(text_border_); | 64 set_border(text_border_); |
61 | 65 |
62 // Multiline is not supported. | 66 // Multiline is not supported. |
63 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE); | 67 DCHECK_NE(parent->style(), Textfield::STYLE_MULTILINE); |
64 // Lowercase is not supported. | 68 // Lowercase is not supported. |
65 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE); | 69 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE); |
70 | |
71 SetContextMenuController(this); | |
66 } | 72 } |
67 | 73 |
68 NativeTextfieldViews::~NativeTextfieldViews() { | 74 NativeTextfieldViews::~NativeTextfieldViews() { |
69 } | 75 } |
70 | 76 |
71 //////////////////////////////////////////////////////////////////////////////// | 77 //////////////////////////////////////////////////////////////////////////////// |
72 // NativeTextfieldViews, View overrides: | 78 // NativeTextfieldViews, View overrides: |
73 | 79 |
74 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { | 80 bool NativeTextfieldViews::OnMousePressed(const views::MouseEvent& e) { |
75 textfield_->RequestFocus(); | 81 textfield_->RequestFocus(); |
76 size_t pos = FindCursorPosition(e.location()); | 82 if (e.IsLeftMouseButton()) { |
77 if (model_->MoveCursorTo(pos, false)) { | 83 size_t pos = FindCursorPosition(e.location()); |
78 UpdateCursorBoundsAndTextOffset(); | 84 if (model_->MoveCursorTo(pos, false)) { |
79 SchedulePaint(); | 85 UpdateCursorBoundsAndTextOffset(); |
86 SchedulePaint(); | |
87 } | |
80 } | 88 } |
81 return true; | 89 return true; |
82 } | 90 } |
83 | 91 |
84 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { | 92 bool NativeTextfieldViews::OnMouseDragged(const views::MouseEvent& e) { |
85 size_t pos = FindCursorPosition(e.location()); | 93 size_t pos = FindCursorPosition(e.location()); |
86 if (model_->MoveCursorTo(pos, true)) { | 94 if (model_->MoveCursorTo(pos, true)) { |
87 UpdateCursorBoundsAndTextOffset(); | 95 UpdateCursorBoundsAndTextOffset(); |
88 SchedulePaint(); | 96 SchedulePaint(); |
89 } | 97 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 | 134 |
127 void NativeTextfieldViews::DidGainFocus() { | 135 void NativeTextfieldViews::DidGainFocus() { |
128 NOTREACHED(); | 136 NOTREACHED(); |
129 } | 137 } |
130 | 138 |
131 void NativeTextfieldViews::WillLoseFocus() { | 139 void NativeTextfieldViews::WillLoseFocus() { |
132 NOTREACHED(); | 140 NOTREACHED(); |
133 } | 141 } |
134 | 142 |
135 ///////////////////////////////////////////////////////////////// | 143 ///////////////////////////////////////////////////////////////// |
144 // NativeTextfieldViews, views::ContextMenuController overrides: | |
145 void NativeTextfieldViews::ShowContextMenu(View* source, | |
146 const gfx::Point& p, | |
147 bool is_mouse_gesture) { | |
148 InitContextMenuIfRequired(); | |
149 context_menu_menu_->RunContextMenuAt(p); | |
150 } | |
151 | |
152 ///////////////////////////////////////////////////////////////// | |
136 // NativeTextfieldViews, NativeTextifieldWrapper overrides: | 153 // NativeTextfieldViews, NativeTextifieldWrapper overrides: |
137 | 154 |
138 string16 NativeTextfieldViews::GetText() const { | 155 string16 NativeTextfieldViews::GetText() const { |
139 return model_->text(); | 156 return model_->text(); |
140 } | 157 } |
141 | 158 |
142 void NativeTextfieldViews::UpdateText() { | 159 void NativeTextfieldViews::UpdateText() { |
143 bool changed = model_->SetText(textfield_->text()); | 160 bool changed = model_->SetText(textfield_->text()); |
144 UpdateCursorBoundsAndTextOffset(); | 161 UpdateCursorBoundsAndTextOffset(); |
145 SchedulePaint(); | 162 SchedulePaint(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 | 303 |
287 void NativeTextfieldViews::HandleWillLoseFocus() { | 304 void NativeTextfieldViews::HandleWillLoseFocus() { |
288 // Stop blinking cursor. | 305 // Stop blinking cursor. |
289 cursor_timer_.RevokeAll(); | 306 cursor_timer_.RevokeAll(); |
290 if (is_cursor_visible_) { | 307 if (is_cursor_visible_) { |
291 is_cursor_visible_ = false; | 308 is_cursor_visible_ = false; |
292 RepaintCursor(); | 309 RepaintCursor(); |
293 } | 310 } |
294 } | 311 } |
295 | 312 |
313 ///////////////////////////////////////////////////////////////// | |
314 // NativeTextfieldViews, menus::SimpleMenuModel::Delegate overrides: | |
315 | |
316 bool NativeTextfieldViews::IsCommandIdChecked(int command_id) const { | |
317 return true; | |
318 } | |
319 | |
320 bool NativeTextfieldViews::IsCommandIdEnabled(int command_id) const { | |
321 string16 result; | |
322 switch (command_id) { | |
323 case IDS_APP_CUT: | |
324 return model_->HasSelection(); | |
325 case IDS_APP_COPY: | |
326 return model_->HasSelection(); | |
327 case IDS_APP_PASTE: | |
328 views::ViewsDelegate::views_delegate->GetClipboard() | |
329 ->ReadText(ui::Clipboard::BUFFER_STANDARD, &result); | |
330 return !result.empty(); | |
331 case IDS_APP_DELETE: | |
332 return model_->HasSelection(); | |
333 case IDS_APP_SELECT_ALL: | |
334 return true; | |
335 default: | |
oshima
2011/01/12 21:01:47
NOTREACHED()
varunjain
2011/01/12 21:28:11
Done.
| |
336 return false; | |
337 } | |
338 return false; | |
oshima
2011/01/12 21:01:47
won't compiler complain this? I think this is unre
varunjain
2011/01/12 21:28:11
the compiler doesnot seem to care. I removed it an
| |
339 } | |
340 | |
341 bool NativeTextfieldViews::GetAcceleratorForCommandId(int command_id, | |
342 menus::Accelerator* accelerator) { | |
343 return false; | |
344 } | |
345 | |
346 void NativeTextfieldViews::ExecuteCommand(int command_id) { | |
347 bool text_changed = false; | |
348 switch (command_id) { | |
349 case IDS_APP_CUT: | |
350 text_changed = model_->Cut(); | |
351 break; | |
352 case IDS_APP_COPY: | |
353 model_->Copy(); | |
354 break; | |
355 case IDS_APP_PASTE: | |
356 text_changed = model_->Paste(); | |
357 break; | |
358 case IDS_APP_DELETE: | |
359 text_changed = model_->Delete(); | |
360 break; | |
361 case IDS_APP_SELECT_ALL: | |
362 SelectAll(); | |
363 break; | |
364 default: | |
365 NOTREACHED() << "unknown command: " << command_id; | |
366 break; | |
367 } | |
368 if (text_changed) | |
369 PropagateTextChange(); | |
370 } | |
371 | |
296 // static | 372 // static |
297 bool NativeTextfieldViews::IsTextfieldViewsEnabled() { | 373 bool NativeTextfieldViews::IsTextfieldViewsEnabled() { |
298 #if defined(TOUCH_UI) | 374 #if defined(TOUCH_UI) |
299 return true; | 375 return true; |
300 #else | 376 #else |
301 return textfield_view_enabled || | 377 return textfield_view_enabled || |
302 CommandLine::ForCurrentProcess()->HasSwitch( | 378 CommandLine::ForCurrentProcess()->HasSwitch( |
303 kEnableViewsBasedTextfieldSwitch); | 379 kEnableViewsBasedTextfieldSwitch); |
304 #endif | 380 #endif |
305 } | 381 } |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 break; | 594 break; |
519 } | 595 } |
520 char16 print_char = GetPrintableChar(key_event); | 596 char16 print_char = GetPrintableChar(key_event); |
521 if (!control && print_char) { | 597 if (!control && print_char) { |
522 if (insert_) | 598 if (insert_) |
523 model_->Insert(print_char); | 599 model_->Insert(print_char); |
524 else | 600 else |
525 model_->Replace(print_char); | 601 model_->Replace(print_char); |
526 text_changed = true; | 602 text_changed = true; |
527 } | 603 } |
528 if (text_changed) { | 604 if (text_changed) |
529 textfield_->SyncText(); | 605 PropagateTextChange(); |
530 Textfield::Controller* controller = textfield_->GetController(); | |
531 if (controller) | |
532 controller->ContentsChanged(textfield_, GetText()); | |
533 } | |
534 if (cursor_changed) { | 606 if (cursor_changed) { |
535 is_cursor_visible_ = true; | 607 is_cursor_visible_ = true; |
536 RepaintCursor(); | 608 RepaintCursor(); |
537 } | 609 } |
538 if (text_changed || cursor_changed) { | 610 if (text_changed || cursor_changed) { |
539 UpdateCursorBoundsAndTextOffset(); | 611 UpdateCursorBoundsAndTextOffset(); |
540 SchedulePaint(); | 612 SchedulePaint(); |
541 return true; | 613 return true; |
542 } | 614 } |
543 } | 615 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 } else if (pivot == x) { | 758 } else if (pivot == x) { |
687 return pivot_pos; | 759 return pivot_pos; |
688 } else { | 760 } else { |
689 right = pivot; | 761 right = pivot; |
690 right_pos = pivot_pos; | 762 right_pos = pivot_pos; |
691 } | 763 } |
692 } | 764 } |
693 return left_pos; | 765 return left_pos; |
694 } | 766 } |
695 | 767 |
768 void NativeTextfieldViews::PropagateTextChange() { | |
769 textfield_->SyncText(); | |
770 Textfield::Controller* controller = textfield_->GetController(); | |
771 if (controller) | |
772 controller->ContentsChanged(textfield_, GetText()); | |
773 } | |
774 | |
775 void NativeTextfieldViews::InitContextMenuIfRequired() { | |
776 if (context_menu_menu_.get()) | |
777 return; | |
778 context_menu_contents_.reset(new menus::SimpleMenuModel(this)); | |
779 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); | |
780 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); | |
781 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); | |
782 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); | |
783 context_menu_contents_->AddSeparator(); | |
784 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, | |
785 IDS_APP_SELECT_ALL); | |
786 context_menu_menu_.reset(new Menu2(context_menu_contents_.get())); | |
787 } | |
788 | |
696 /////////////////////////////////////////////////////////////////////////////// | 789 /////////////////////////////////////////////////////////////////////////////// |
697 // NativeTextfieldWrapper: | 790 // NativeTextfieldWrapper: |
698 | 791 |
699 // static | 792 // static |
700 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( | 793 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( |
701 Textfield* field) { | 794 Textfield* field) { |
702 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { | 795 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { |
703 return new NativeTextfieldViews(field); | 796 return new NativeTextfieldViews(field); |
704 } else { | 797 } else { |
705 return new NativeTextfieldGtk(field); | 798 return new NativeTextfieldGtk(field); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 } | 847 } |
755 | 848 |
756 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, | 849 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, |
757 int left, | 850 int left, |
758 int bottom, | 851 int bottom, |
759 int right) { | 852 int right) { |
760 insets_.Set(top, left, bottom, right); | 853 insets_.Set(top, left, bottom, right); |
761 } | 854 } |
762 | 855 |
763 } // namespace views | 856 } // namespace views |
OLD | NEW |