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

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

Issue 9358049: Implement STYLE_LOWERCASE style for Aura NativeTextfield. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for comments. Created 8 years, 8 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/views/controls/textfield/native_textfield_views.h" 5 #include "ui/views/controls/textfield/native_textfield_views.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/i18n/case_conversion.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/message_loop.h" 14 #include "base/message_loop.h"
14 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
15 #include "grit/app_locale_settings.h" 16 #include "grit/app_locale_settings.h"
16 #include "grit/ui_strings.h" 17 #include "grit/ui_strings.h"
17 #include "third_party/skia/include/core/SkColor.h" 18 #include "third_party/skia/include/core/SkColor.h"
18 #include "ui/base/clipboard/clipboard.h" 19 #include "ui/base/clipboard/clipboard.h"
19 #include "ui/base/dragdrop/drag_drop_types.h" 20 #include "ui/base/dragdrop/drag_drop_types.h"
20 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/range/range.h" 22 #include "ui/base/range/range.h"
22 #include "ui/gfx/canvas.h" 23 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/compositor/layer.h" 24 #include "ui/gfx/compositor/layer.h"
24 #include "ui/gfx/insets.h" 25 #include "ui/gfx/insets.h"
25 #include "ui/gfx/render_text.h" 26 #include "ui/gfx/render_text.h"
26 #include "ui/views/background.h" 27 #include "ui/views/background.h"
27 #include "ui/views/border.h" 28 #include "ui/views/border.h"
28 #include "ui/views/controls/focusable_border.h" 29 #include "ui/views/controls/focusable_border.h"
29 #include "ui/views/controls/menu/menu_item_view.h" 30 #include "ui/views/controls/menu/menu_item_view.h"
30 #include "ui/views/controls/menu/menu_model_adapter.h" 31 #include "ui/views/controls/menu/menu_model_adapter.h"
31 #include "ui/views/controls/menu/menu_runner.h" 32 #include "ui/views/controls/menu/menu_runner.h"
32 #include "ui/views/controls/textfield/textfield.h" 33 #include "ui/views/controls/textfield/textfield.h"
33 #include "ui/views/controls/textfield/textfield_controller.h" 34 #include "ui/views/controls/textfield/textfield_controller.h"
34 #include "ui/views/controls/textfield/textfield_views_model.h" 35 #include "ui/views/controls/textfield/textfield_views_model.h"
35 #include "ui/views/events/event.h" 36 #include "ui/views/events/event.h"
36 #include "ui/views/ime/input_method.h" 37 #include "ui/views/ime/input_method.h"
37 #include "ui/views/metrics.h" 38 #include "ui/views/metrics.h"
38 #include "ui/views/views_delegate.h" 39 #include "ui/views/views_delegate.h"
39 #include "ui/views/widget/widget.h" 40 #include "ui/views/widget/widget.h"
41 #include "unicode/uchar.h"
40 42
41 #if defined(USE_AURA) 43 #if defined(USE_AURA)
42 #include "ui/base/cursor/cursor.h" 44 #include "ui/base/cursor/cursor.h"
43 #endif 45 #endif
44 46
45 namespace { 47 namespace {
46 48
47 // Text color for read only. 49 // Text color for read only.
48 const SkColor kReadonlyTextColor = SK_ColorDKGRAY; 50 const SkColor kReadonlyTextColor = SK_ColorDKGRAY;
49 51
(...skipping 20 matching lines...) Expand all
70 skip_input_method_cancel_composition_(false), 72 skip_input_method_cancel_composition_(false),
71 initiating_drag_(false), 73 initiating_drag_(false),
72 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)), 74 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)),
73 aggregated_clicks_(0), 75 aggregated_clicks_(0),
74 last_click_time_(), 76 last_click_time_(),
75 last_click_location_(), 77 last_click_location_(),
76 ALLOW_THIS_IN_INITIALIZER_LIST(touch_selection_controller_( 78 ALLOW_THIS_IN_INITIALIZER_LIST(touch_selection_controller_(
77 TouchSelectionController::create(this))) { 79 TouchSelectionController::create(this))) {
78 set_border(text_border_); 80 set_border(text_border_);
79 81
80 // Lowercase is not supported.
81 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE);
82
83 #if defined(OS_CHROMEOS) 82 #if defined(OS_CHROMEOS)
84 GetRenderText()->SetFontList(gfx::FontList(l10n_util::GetStringUTF8( 83 GetRenderText()->SetFontList(gfx::FontList(l10n_util::GetStringUTF8(
85 IDS_UI_FONT_FAMILY_CROS))); 84 IDS_UI_FONT_FAMILY_CROS)));
86 #else 85 #else
87 GetRenderText()->SetFontList(gfx::FontList(textfield_->font())); 86 GetRenderText()->SetFontList(gfx::FontList(textfield_->font()));
88 #endif 87 #endif
89 // Set the default text style. 88 // Set the default text style.
90 gfx::StyleRange default_style; 89 gfx::StyleRange default_style;
91 default_style.foreground = textfield_->text_color(); 90 default_style.foreground = textfield_->text_color();
92 GetRenderText()->set_default_style(default_style); 91 GetRenderText()->set_default_style(default_style);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 DCHECK(CanDrop(event.data())); 190 DCHECK(CanDrop(event.data()));
192 DCHECK(!initiating_drag_ || 191 DCHECK(!initiating_drag_ ||
193 !GetRenderText()->IsPointInSelection(event.location())); 192 !GetRenderText()->IsPointInSelection(event.location()));
194 OnBeforeUserAction(); 193 OnBeforeUserAction();
195 skip_input_method_cancel_composition_ = true; 194 skip_input_method_cancel_composition_ = true;
196 195
197 gfx::SelectionModel drop_destination_model = 196 gfx::SelectionModel drop_destination_model =
198 GetRenderText()->FindCursorPosition(event.location()); 197 GetRenderText()->FindCursorPosition(event.location());
199 string16 text; 198 string16 text;
200 event.data().GetString(&text); 199 event.data().GetString(&text);
200 text = GetTextForDisplay(text);
201 201
202 // We'll delete the current selection for a drag and drop within this view. 202 // We'll delete the current selection for a drag and drop within this view.
203 bool move = initiating_drag_ && !event.IsControlDown() && 203 bool move = initiating_drag_ && !event.IsControlDown() &&
204 event.source_operations() & ui::DragDropTypes::DRAG_MOVE; 204 event.source_operations() & ui::DragDropTypes::DRAG_MOVE;
205 if (move) { 205 if (move) {
206 gfx::SelectionModel selected; 206 gfx::SelectionModel selected;
207 model_->GetSelectionModel(&selected); 207 model_->GetSelectionModel(&selected);
208 // Adjust the drop destination if it is on or after the current selection. 208 // Adjust the drop destination if it is on or after the current selection.
209 size_t drop_destination = drop_destination_model.caret_pos(); 209 size_t drop_destination = drop_destination_model.caret_pos();
210 drop_destination -= 210 drop_destination -=
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 } 314 }
315 315
316 ///////////////////////////////////////////////////////////////// 316 /////////////////////////////////////////////////////////////////
317 // NativeTextfieldViews, NativeTextifieldWrapper overrides: 317 // NativeTextfieldViews, NativeTextifieldWrapper overrides:
318 318
319 string16 NativeTextfieldViews::GetText() const { 319 string16 NativeTextfieldViews::GetText() const {
320 return model_->GetText(); 320 return model_->GetText();
321 } 321 }
322 322
323 void NativeTextfieldViews::UpdateText() { 323 void NativeTextfieldViews::UpdateText() {
324 model_->SetText(textfield_->text()); 324 model_->SetText(GetTextForDisplay(textfield_->text()));
325 OnCaretBoundsChanged(); 325 OnCaretBoundsChanged();
326 SchedulePaint(); 326 SchedulePaint();
327 textfield_->GetWidget()->NotifyAccessibilityEvent( 327 textfield_->GetWidget()->NotifyAccessibilityEvent(
328 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); 328 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
329 } 329 }
330 330
331 void NativeTextfieldViews::AppendText(const string16& text) { 331 void NativeTextfieldViews::AppendText(const string16& text) {
332 if (text.empty()) 332 if (text.empty())
333 return; 333 return;
334 model_->Append(text); 334 model_->Append(GetTextForDisplay(text));
335 OnCaretBoundsChanged(); 335 OnCaretBoundsChanged();
336 SchedulePaint(); 336 SchedulePaint();
337 } 337 }
338 338
339 string16 NativeTextfieldViews::GetSelectedText() const { 339 string16 NativeTextfieldViews::GetSelectedText() const {
340 return model_->GetSelectedText(); 340 return model_->GetSelectedText();
341 } 341 }
342 342
343 void NativeTextfieldViews::SelectAll() { 343 void NativeTextfieldViews::SelectAll() {
344 OnBeforeUserAction(); 344 OnBeforeUserAction();
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 662 }
663 663
664 void NativeTextfieldViews::InsertText(const string16& text) { 664 void NativeTextfieldViews::InsertText(const string16& text) {
665 // TODO(suzhe): Filter invalid characters. 665 // TODO(suzhe): Filter invalid characters.
666 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || text.empty()) 666 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || text.empty())
667 return; 667 return;
668 668
669 OnBeforeUserAction(); 669 OnBeforeUserAction();
670 skip_input_method_cancel_composition_ = true; 670 skip_input_method_cancel_composition_ = true;
671 if (GetRenderText()->insert_mode()) 671 if (GetRenderText()->insert_mode())
672 model_->InsertText(text); 672 model_->InsertText(GetTextForDisplay(text));
673 else 673 else
674 model_->ReplaceText(text); 674 model_->ReplaceText(GetTextForDisplay(text));
675 skip_input_method_cancel_composition_ = false; 675 skip_input_method_cancel_composition_ = false;
676 UpdateAfterChange(true, true); 676 UpdateAfterChange(true, true);
677 OnAfterUserAction(); 677 OnAfterUserAction();
678 } 678 }
679 679
680 void NativeTextfieldViews::InsertChar(char16 ch, int flags) { 680 void NativeTextfieldViews::InsertChar(char16 ch, int flags) {
681 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || 681 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE ||
682 !ShouldInsertChar(ch, flags)) { 682 !ShouldInsertChar(ch, flags)) {
683 return; 683 return;
684 } 684 }
685 685
686 OnBeforeUserAction(); 686 OnBeforeUserAction();
687 skip_input_method_cancel_composition_ = true; 687 skip_input_method_cancel_composition_ = true;
688 if (GetRenderText()->insert_mode()) 688 if (GetRenderText()->insert_mode())
689 model_->InsertChar(ch); 689 model_->InsertChar(ch);
690 else 690 else
691 model_->ReplaceChar(ch); 691 model_->ReplaceChar(ch);
692 skip_input_method_cancel_composition_ = false; 692 skip_input_method_cancel_composition_ = false;
693
694 model_->SetText(GetTextForDisplay(GetText()));
695
693 UpdateAfterChange(true, true); 696 UpdateAfterChange(true, true);
694 OnAfterUserAction(); 697 OnAfterUserAction();
695 } 698 }
696 699
697 ui::TextInputType NativeTextfieldViews::GetTextInputType() const { 700 ui::TextInputType NativeTextfieldViews::GetTextInputType() const {
698 return textfield_->GetTextInputType(); 701 return textfield_->GetTextInputType();
699 } 702 }
700 703
701 bool NativeTextfieldViews::CanComposeInline() const { 704 bool NativeTextfieldViews::CanComposeInline() const {
702 return true; 705 return true;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 if (skip_input_method_cancel_composition_) 788 if (skip_input_method_cancel_composition_)
786 return; 789 return;
787 DCHECK(textfield_->GetInputMethod()); 790 DCHECK(textfield_->GetInputMethod());
788 textfield_->GetInputMethod()->CancelComposition(textfield_); 791 textfield_->GetInputMethod()->CancelComposition(textfield_);
789 } 792 }
790 793
791 gfx::RenderText* NativeTextfieldViews::GetRenderText() const { 794 gfx::RenderText* NativeTextfieldViews::GetRenderText() const {
792 return model_->render_text(); 795 return model_->render_text();
793 } 796 }
794 797
798 string16 NativeTextfieldViews::GetTextForDisplay(const string16& text) {
799 return textfield_->style() & Textfield::STYLE_LOWERCASE ?
800 base::i18n::ToLower(text) : text;
801 }
802
795 void NativeTextfieldViews::UpdateCursor() { 803 void NativeTextfieldViews::UpdateCursor() {
796 is_cursor_visible_ = !is_cursor_visible_; 804 is_cursor_visible_ = !is_cursor_visible_;
797 RepaintCursor(); 805 RepaintCursor();
798 MessageLoop::current()->PostDelayedTask( 806 MessageLoop::current()->PostDelayedTask(
799 FROM_HERE, 807 FROM_HERE,
800 base::Bind(&NativeTextfieldViews::UpdateCursor, 808 base::Bind(&NativeTextfieldViews::UpdateCursor,
801 cursor_timer_.GetWeakPtr()), 809 cursor_timer_.GetWeakPtr()),
802 is_cursor_visible_ ? kCursorVisibleTimeMs : kCursorInvisibleTimeMs); 810 is_cursor_visible_ ? kCursorVisibleTimeMs : kCursorInvisibleTimeMs);
803 } 811 }
804 812
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 if (model_->Copy()) { 1048 if (model_->Copy()) {
1041 TextfieldController* controller = textfield_->GetController(); 1049 TextfieldController* controller = textfield_->GetController();
1042 if (controller) 1050 if (controller)
1043 controller->OnAfterCutOrCopy(); 1051 controller->OnAfterCutOrCopy();
1044 return true; 1052 return true;
1045 } 1053 }
1046 return false; 1054 return false;
1047 } 1055 }
1048 1056
1049 bool NativeTextfieldViews::Paste() { 1057 bool NativeTextfieldViews::Paste() {
1058 const string16 original_text = GetText();
1050 const bool success = model_->Paste(); 1059 const bool success = model_->Paste();
1051 1060
1052 // Calls TextfieldController::ContentsChanged() explicitly if the paste action 1061 if (success) {
1053 // did not change the content at all. See http://crbug.com/79002 1062 // As Paste is handled in model_->Paste(), the RenderText may contain
1054 if (success && GetText() == textfield_->text()) { 1063 // upper case characters. This is not consistent with other places
1055 TextfieldController* controller = textfield_->GetController(); 1064 // which keeps RenderText only containing lower case characters.
1056 if (controller) 1065 string16 new_text = GetTextForDisplay(GetText());
1057 controller->ContentsChanged(textfield_, textfield_->text()); 1066 model_->SetText(new_text);
1067
1068 // Calls TextfieldController::ContentsChanged() explicitly if the paste
1069 // action did not change the content at all. See http://crbug.com/79002
1070 if (new_text == original_text) {
1071 TextfieldController* controller = textfield_->GetController();
1072 if (controller)
1073 controller->ContentsChanged(textfield_, textfield_->text());
1074 }
1058 } 1075 }
1059 return success; 1076 return success;
1060 } 1077 }
1061 1078
1062 void NativeTextfieldViews::TrackMouseClicks(const MouseEvent& event) { 1079 void NativeTextfieldViews::TrackMouseClicks(const MouseEvent& event) {
1063 if (event.IsOnlyLeftMouseButton()) { 1080 if (event.IsOnlyLeftMouseButton()) {
1064 base::TimeDelta time_delta = event.time_stamp() - last_click_time_; 1081 base::TimeDelta time_delta = event.time_stamp() - last_click_time_;
1065 if (time_delta.InMilliseconds() <= GetDoubleClickInterval() && 1082 if (time_delta.InMilliseconds() <= GetDoubleClickInterval() &&
1066 !ExceededDragThresholdFromLastClickLocation(event)) { 1083 !ExceededDragThresholdFromLastClickLocation(event)) {
1067 aggregated_clicks_ = (aggregated_clicks_ + 1) % 3; 1084 aggregated_clicks_ = (aggregated_clicks_ + 1) % 3;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 1139
1123 #if defined(USE_AURA) 1140 #if defined(USE_AURA)
1124 // static 1141 // static
1125 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( 1142 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper(
1126 Textfield* field) { 1143 Textfield* field) {
1127 return new NativeTextfieldViews(field); 1144 return new NativeTextfieldViews(field);
1128 } 1145 }
1129 #endif 1146 #endif
1130 1147
1131 } // namespace views 1148 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/native_textfield_views.h ('k') | ui/views/controls/textfield/native_textfield_views_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698