OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/ui/views/autofill/decorated_textfield.h" | 5 #include "chrome/browser/ui/views/autofill/decorated_textfield.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "chrome/browser/ui/views/autofill/tooltip_icon.h" | 9 #include "chrome/browser/ui/views/autofill/tooltip_icon.h" |
10 #include "ui/gfx/canvas.h" | 10 #include "ui/gfx/canvas.h" |
11 #include "ui/gfx/color_palette.h" | 11 #include "ui/gfx/color_palette.h" |
12 #include "ui/views/background.h" | 12 #include "ui/views/background.h" |
13 #include "ui/views/controls/button/label_button.h" | 13 #include "ui/views/controls/button/label_button.h" |
14 #include "ui/views/controls/focusable_border.h" | 14 #include "ui/views/controls/focusable_border.h" |
15 #include "ui/views/controls/textfield/textfield_controller.h" | 15 #include "ui/views/controls/textfield/textfield_controller.h" |
16 #include "ui/views/view_targeter.h" | 16 #include "ui/views/view_targeter.h" |
17 | 17 |
18 namespace { | |
19 | |
20 // Padding around icons inside DecoratedTextfields. | |
21 const int kTextfieldIconPadding = 3; | |
22 | |
23 } // namespace | |
24 | |
25 namespace autofill { | 18 namespace autofill { |
26 | 19 |
27 // static | 20 // static |
28 const char DecoratedTextfield::kViewClassName[] = "autofill/DecoratedTextfield"; | 21 const char DecoratedTextfield::kViewClassName[] = "autofill/DecoratedTextfield"; |
29 | 22 |
30 DecoratedTextfield::DecoratedTextfield( | 23 DecoratedTextfield::DecoratedTextfield( |
31 const base::string16& default_value, | 24 const base::string16& default_value, |
32 const base::string16& placeholder, | 25 const base::string16& placeholder, |
33 views::TextfieldController* controller) | 26 views::TextfieldController* controller) |
34 : invalid_(false), | 27 : invalid_(false) { |
35 editable_(true) { | |
36 UpdateBackground(); | |
37 UpdateBorder(); | 28 UpdateBorder(); |
38 | 29 |
39 set_placeholder_text(placeholder); | 30 set_placeholder_text(placeholder); |
40 SetText(default_value); | 31 SetText(default_value); |
41 set_controller(controller); | 32 set_controller(controller); |
42 | |
43 SetEventTargeter( | |
44 std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); | |
45 } | 33 } |
46 | 34 |
47 DecoratedTextfield::~DecoratedTextfield() {} | 35 DecoratedTextfield::~DecoratedTextfield() {} |
48 | 36 |
49 void DecoratedTextfield::SetInvalid(bool invalid) { | 37 void DecoratedTextfield::SetInvalid(bool invalid) { |
50 if (invalid_ == invalid) | 38 if (invalid_ == invalid) |
51 return; | 39 return; |
52 | 40 |
53 invalid_ = invalid; | 41 invalid_ = invalid; |
54 UpdateBorder(); | 42 UpdateBorder(); |
55 SchedulePaint(); | 43 SchedulePaint(); |
56 } | 44 } |
57 | 45 |
58 void DecoratedTextfield::SetEditable(bool editable) { | |
59 if (editable_ == editable) | |
60 return; | |
61 | |
62 editable_ = editable; | |
63 UpdateBackground(); | |
64 SetEnabled(editable); | |
65 IconChanged(); | |
66 } | |
67 | |
68 void DecoratedTextfield::SetIcon(const gfx::Image& icon) { | |
69 if (!icon_view_ && icon.IsEmpty()) | |
70 return; | |
71 | |
72 if (icon_view_) | |
73 RemoveChildView(icon_view_.get()); | |
74 | |
75 if (!icon.IsEmpty()) { | |
76 icon_view_.reset(new views::ImageView()); | |
77 icon_view_->set_owned_by_client(); | |
78 icon_view_->SetImage(icon.ToImageSkia()); | |
79 AddChildView(icon_view_.get()); | |
80 } | |
81 | |
82 IconChanged(); | |
83 } | |
84 | |
85 void DecoratedTextfield::SetTooltipIcon(const base::string16& text) { | |
86 if (!icon_view_ && text.empty()) | |
87 return; | |
88 | |
89 if (icon_view_) | |
90 RemoveChildView(icon_view_.get()); | |
91 | |
92 if (!text.empty()) { | |
93 icon_view_.reset(new TooltipIcon(text)); | |
94 AddChildView(icon_view_.get()); | |
95 } | |
96 | |
97 IconChanged(); | |
98 } | |
99 | |
100 base::string16 DecoratedTextfield::GetPlaceholderText() const { | |
101 return editable_ ? views::Textfield::GetPlaceholderText() : base::string16(); | |
102 } | |
103 | |
104 const char* DecoratedTextfield::GetClassName() const { | 46 const char* DecoratedTextfield::GetClassName() const { |
105 return kViewClassName; | 47 return kViewClassName; |
106 } | 48 } |
107 | 49 |
108 gfx::Size DecoratedTextfield::GetPreferredSize() const { | |
109 static const int height = | |
110 views::LabelButton(NULL, base::string16()).GetPreferredSize().height(); | |
111 const gfx::Size size = views::Textfield::GetPreferredSize(); | |
112 return gfx::Size(size.width(), std::max(size.height(), height)); | |
113 } | |
114 | |
115 void DecoratedTextfield::Layout() { | |
116 views::Textfield::Layout(); | |
117 | |
118 if (icon_view_ && icon_view_->visible()) { | |
119 gfx::Rect bounds = GetContentsBounds(); | |
120 gfx::Size icon_size = icon_view_->GetPreferredSize(); | |
121 int x = base::i18n::IsRTL() ? | |
122 bounds.x() - icon_size.width() - kTextfieldIconPadding : | |
123 bounds.right() + kTextfieldIconPadding; | |
124 // Vertically centered. | |
125 int y = bounds.y() + (bounds.height() - icon_size.height()) / 2; | |
126 gfx::Rect icon_bounds(x, y, icon_size.width(), icon_size.height()); | |
127 icon_bounds.set_x(GetMirroredXForRect(icon_bounds)); | |
128 icon_view_->SetBoundsRect(icon_bounds); | |
129 } | |
130 } | |
131 | |
132 views::View* DecoratedTextfield::TargetForRect(views::View* root, | |
133 const gfx::Rect& rect) { | |
134 CHECK_EQ(root, this); | |
135 | |
136 views::View* handler = views::ViewTargeterDelegate::TargetForRect(root, rect); | |
137 if (handler->GetClassName() == TooltipIcon::kViewClassName) | |
138 return handler; | |
139 return this; | |
140 } | |
141 | |
142 void DecoratedTextfield::UpdateBackground() { | |
143 if (editable_) | |
144 UseDefaultBackgroundColor(); | |
145 else | |
146 SetBackgroundColor(SK_ColorTRANSPARENT); | |
147 set_background( | |
148 views::Background::CreateSolidBackground(GetBackgroundColor())); | |
149 } | |
150 | |
151 void DecoratedTextfield::UpdateBorder() { | 50 void DecoratedTextfield::UpdateBorder() { |
152 std::unique_ptr<views::FocusableBorder> border(new views::FocusableBorder()); | 51 std::unique_ptr<views::FocusableBorder> border(new views::FocusableBorder()); |
153 if (invalid_) | 52 if (invalid_) |
154 border->SetColor(gfx::kGoogleRed700); | 53 border->SetColor(gfx::kGoogleRed700); |
155 else if (!editable_) | |
156 border->SetColor(SK_ColorTRANSPARENT); | |
157 | |
158 // Adjust the border insets to include the icon and its padding. | |
159 if (icon_view_ && icon_view_->visible()) { | |
160 int w = icon_view_->GetPreferredSize().width() + 2 * kTextfieldIconPadding; | |
161 gfx::Insets insets = border->GetInsets(); | |
162 int left = insets.left() + (base::i18n::IsRTL() ? w : 0); | |
163 int right = insets.right() + (base::i18n::IsRTL() ? 0 : w); | |
164 border->SetInsets(insets.top(), left, insets.bottom(), right); | |
165 } | |
166 | 54 |
167 SetBorder(std::move(border)); | 55 SetBorder(std::move(border)); |
168 } | 56 } |
169 | 57 |
170 void DecoratedTextfield::IconChanged() { | |
171 // Don't show the icon if nothing else is showing. | |
172 icon_view_->SetVisible(editable_ || !text().empty()); | |
173 UpdateBorder(); | |
174 Layout(); | |
175 } | |
176 | |
177 } // namespace autofill | 58 } // namespace autofill |
OLD | NEW |