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" |
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()) { |
oshima
2011/01/12 18:46:25
q: should this be "Only"?
varunjain
2011/01/12 19:59:05
the behaviour of the current textfield in chrome's
| |
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 } | |
sadrul
2011/01/12 19:09:16
Are there plans for middle-click-to-paste? Or is t
oshima
2011/01/12 19:25:31
It's X selection and different from cut&paste. I'v
| |
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 if (!context_menu_menu_.get()) | |
149 CreateContextMenu(); | |
150 context_menu_menu_->RunContextMenuAt(p); | |
151 } | |
152 | |
153 ///////////////////////////////////////////////////////////////// | |
136 // NativeTextfieldViews, NativeTextifieldWrapper overrides: | 154 // NativeTextfieldViews, NativeTextifieldWrapper overrides: |
137 | 155 |
138 string16 NativeTextfieldViews::GetText() const { | 156 string16 NativeTextfieldViews::GetText() const { |
139 return model_->text(); | 157 return model_->text(); |
140 } | 158 } |
141 | 159 |
142 void NativeTextfieldViews::UpdateText() { | 160 void NativeTextfieldViews::UpdateText() { |
143 bool changed = model_->SetText(textfield_->text()); | 161 bool changed = model_->SetText(textfield_->text()); |
144 UpdateCursorBoundsAndTextOffset(); | 162 UpdateCursorBoundsAndTextOffset(); |
145 SchedulePaint(); | 163 SchedulePaint(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 | 304 |
287 void NativeTextfieldViews::HandleWillLoseFocus() { | 305 void NativeTextfieldViews::HandleWillLoseFocus() { |
288 // Stop blinking cursor. | 306 // Stop blinking cursor. |
289 cursor_timer_.RevokeAll(); | 307 cursor_timer_.RevokeAll(); |
290 if (is_cursor_visible_) { | 308 if (is_cursor_visible_) { |
291 is_cursor_visible_ = false; | 309 is_cursor_visible_ = false; |
292 RepaintCursor(); | 310 RepaintCursor(); |
293 } | 311 } |
294 } | 312 } |
295 | 313 |
314 ///////////////////////////////////////////////////////////////// | |
315 // NativeTextfieldViews, menus::SimpleMenuModel::Delegate overrides: | |
316 | |
317 bool NativeTextfieldViews::IsCommandIdChecked(int command_id) const { | |
318 return true; | |
319 } | |
320 | |
321 bool NativeTextfieldViews::IsCommandIdEnabled(int command_id) const { | |
322 string16 result; | |
323 switch (command_id) { | |
324 case IDS_APP_CUT: | |
325 return model_->HasSelection(); | |
326 case IDS_APP_COPY: | |
327 return model_->HasSelection(); | |
328 case IDS_APP_PASTE: | |
329 views::ViewsDelegate::views_delegate->GetClipboard() | |
330 ->ReadText(ui::Clipboard::BUFFER_STANDARD, &result); | |
331 return !result.empty(); | |
332 case IDS_APP_DELETE: | |
333 return model_->HasSelection(); | |
334 case IDS_APP_SELECT_ALL: | |
335 return true; | |
336 default: | |
337 return false; | |
338 } | |
339 return false; | |
340 } | |
341 | |
342 bool NativeTextfieldViews::GetAcceleratorForCommandId(int command_id, | |
343 menus::Accelerator* accelerator) { | |
344 return false; | |
345 } | |
346 | |
347 void NativeTextfieldViews::ExecuteCommand(int command_id) { | |
348 bool text_changed = false; | |
349 switch (command_id) { | |
350 case IDS_APP_CUT: | |
351 text_changed = model_->Cut(); | |
352 break; | |
353 case IDS_APP_COPY: | |
354 model_->Copy(); | |
355 break; | |
356 case IDS_APP_PASTE: | |
357 text_changed = model_->Paste(); | |
358 break; | |
359 case IDS_APP_DELETE: | |
360 text_changed = model_->Delete(); | |
361 break; | |
362 case IDS_APP_SELECT_ALL: | |
363 SelectAll(); | |
364 break; | |
365 default: | |
oshima
2011/01/12 18:46:25
NOTREACHED() << "unkonwn command:" << command_id;
varunjain
2011/01/12 19:59:05
Done.
| |
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::CreateContextMenu() { | |
776 context_menu_contents_.reset(new menus::SimpleMenuModel(this)); | |
777 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); | |
sadrul
2011/01/12 19:09:16
IDC_xxx should be used for command-id, and IDS_xxx
varunjain
2011/01/12 19:59:05
I was confused by this... IDCs are defined in chro
sadrul
2011/01/12 20:24:59
I fixed up some cases of IDS_/IDC_ mixups in chrom
| |
778 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); | |
779 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); | |
780 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); | |
781 context_menu_contents_->AddSeparator(); | |
782 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, | |
783 IDS_APP_SELECT_ALL); | |
784 context_menu_menu_.reset(new Menu2(context_menu_contents_.get())); | |
785 } | |
786 | |
696 /////////////////////////////////////////////////////////////////////////////// | 787 /////////////////////////////////////////////////////////////////////////////// |
697 // NativeTextfieldWrapper: | 788 // NativeTextfieldWrapper: |
698 | 789 |
699 // static | 790 // static |
700 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( | 791 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( |
701 Textfield* field) { | 792 Textfield* field) { |
702 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { | 793 if (NativeTextfieldViews::IsTextfieldViewsEnabled()) { |
703 return new NativeTextfieldViews(field); | 794 return new NativeTextfieldViews(field); |
704 } else { | 795 } else { |
705 return new NativeTextfieldGtk(field); | 796 return new NativeTextfieldGtk(field); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 } | 845 } |
755 | 846 |
756 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, | 847 void NativeTextfieldViews::TextfieldBorder::SetInsets(int top, |
757 int left, | 848 int left, |
758 int bottom, | 849 int bottom, |
759 int right) { | 850 int right) { |
760 insets_.Set(top, left, bottom, right); | 851 insets_.Set(top, left, bottom, right); |
761 } | 852 } |
762 | 853 |
763 } // namespace views | 854 } // namespace views |
OLD | NEW |