| 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 |