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