- add sources.
[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
15 namespace {
16
17 // Padding around icons inside DecoratedTextfields.
18 const int kTextfieldIconPadding = 3;
19
20 }  // namespace
21
22 namespace autofill {
23
24 // static
25 const char DecoratedTextfield::kViewClassName[] = "autofill/DecoratedTextfield";
26
27 const int DecoratedTextfield::kMagicInsetNumber = 6;
28
29 DecoratedTextfield::DecoratedTextfield(
30     const base::string16& default_value,
31     const base::string16& placeholder,
32     views::TextfieldController* controller)
33     : border_(new views::FocusableBorder()),
34       invalid_(false),
35       editable_(true) {
36   UpdateBackground();
37
38   set_border(border_);
39   // Removes the border from |native_wrapper_|.
40   RemoveBorder();
41
42   set_placeholder_text(placeholder);
43   SetText(default_value);
44   SetController(controller);
45   SetHorizontalMargins(0, 0);
46 }
47
48 DecoratedTextfield::~DecoratedTextfield() {}
49
50 void DecoratedTextfield::SetInvalid(bool invalid) {
51   invalid_ = invalid;
52   if (!editable_)
53     return;
54
55   if (invalid)
56     border_->SetColor(kWarningColor);
57   else
58     border_->UseDefaultColor();
59   SchedulePaint();
60 }
61
62 void DecoratedTextfield::SetEditable(bool editable) {
63   if (editable_ == editable)
64     return;
65
66   editable_ = editable;
67   if (editable) {
68     SetInvalid(invalid_);
69     UseDefaultBackgroundColor();
70   } else {
71     border_->SetColor(SK_ColorTRANSPARENT);
72     SetBackgroundColor(SK_ColorTRANSPARENT);
73   }
74
75   UpdateBackground();
76   SetEnabled(editable);
77   IconChanged();
78 }
79
80 void DecoratedTextfield::SetIcon(const gfx::Image& icon) {
81   if (!icon_view_ && icon.IsEmpty())
82     return;
83
84   if (icon_view_)
85     RemoveChildView(icon_view_.get());
86
87   if (!icon.IsEmpty()) {
88     icon_view_.reset(new views::ImageView());
89     icon_view_->set_owned_by_client();
90     icon_view_->SetImage(icon.ToImageSkia());
91     AddChildView(icon_view_.get());
92   }
93
94   IconChanged();
95 }
96
97 void DecoratedTextfield::SetTooltipIcon(const base::string16& text) {
98   if (!icon_view_ && text.empty())
99     return;
100
101   if (icon_view_)
102     RemoveChildView(icon_view_.get());
103
104   if (!text.empty()) {
105     icon_view_.reset(new TooltipIcon(text));
106     AddChildView(icon_view_.get());
107   }
108
109   IconChanged();
110 }
111
112 base::string16 DecoratedTextfield::GetPlaceholderText() const {
113   if (!editable_)
114     return base::string16();
115
116   return views::Textfield::GetPlaceholderText();
117 }
118
119 const char* DecoratedTextfield::GetClassName() const {
120   return kViewClassName;
121 }
122
123 views::View* DecoratedTextfield::GetEventHandlerForPoint(
124     const gfx::Point& point) {
125   return native_wrapper_->GetView();
126 }
127
128 void DecoratedTextfield::OnFocus() {
129   border_->set_has_focus(true);
130   views::Textfield::OnFocus();
131 }
132
133 void DecoratedTextfield::OnBlur() {
134   border_->set_has_focus(false);
135   views::Textfield::OnBlur();
136 }
137
138 gfx::Size DecoratedTextfield::GetPreferredSize() {
139   int w = views::Textfield::GetPreferredSize().width();
140   views::LabelButton button(NULL, string16());
141   button.SetStyle(views::Button::STYLE_BUTTON);
142   int h = button.GetPreferredSize().height();
143   return gfx::Size(w, h - kMagicInsetNumber);
144 }
145
146 void DecoratedTextfield::Layout() {
147   views::Textfield::Layout();
148
149   if (icon_view_ && icon_view_->visible()) {
150     gfx::Rect bounds = GetContentsBounds();
151     gfx::Size icon_size = icon_view_->GetPreferredSize();
152     int x = base::i18n::IsRTL() ?
153         kTextfieldIconPadding :
154         bounds.right() - icon_size.width() - kTextfieldIconPadding;
155     // Vertically centered.
156     int y = bounds.y() + (bounds.height() - icon_size.height()) / 2;
157     icon_view_->SetBounds(x,
158                           y,
159                           icon_size.width(),
160                           icon_size.height());
161   }
162 }
163
164 void DecoratedTextfield::UpdateBackground() {
165   set_background(
166       views::Background::CreateSolidBackground(GetBackgroundColor()));
167 }
168
169 void DecoratedTextfield::IconChanged() {
170   // Don't show the icon if nothing else is showing.
171   icon_view_->SetVisible(editable_ || !text().empty());
172
173   int icon_space = icon_view_ ?
174       icon_view_->GetPreferredSize().width() + 2 * kTextfieldIconPadding : 0;
175
176   bool is_rtl = base::i18n::IsRTL();
177   SetHorizontalMargins(is_rtl ? icon_space : 0, is_rtl ? 0 : icon_space);
178
179   Layout();
180   SchedulePaint();
181 }
182
183 } // namespace autofill