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