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.
5 #include "chrome/browser/ui/views/autofill/decorated_textfield.h"
7 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
8 #include "ui/gfx/canvas.h"
9 #include "ui/views/background.h"
10 #include "ui/views/controls/button/label_button.h"
11 #include "ui/views/controls/focusable_border.h"
12 #include "ui/views/controls/textfield/textfield_controller.h"
16 // Padding around icons inside DecoratedTextfields.
17 const int kTextfieldIconPadding
= 3;
19 // Size of the triangular mark that indicates an invalid textfield (in pixels).
20 const int kDogEarSize
= 10;
27 const char DecoratedTextfield::kViewClassName
[] = "autofill/DecoratedTextfield";
29 const int DecoratedTextfield::kMagicInsetNumber
= 6;
31 DecoratedTextfield::DecoratedTextfield(
32 const base::string16
& default_value
,
33 const base::string16
& placeholder
,
34 views::TextfieldController
* controller
)
35 : border_(new views::FocusableBorder()),
38 views::Background::CreateSolidBackground(GetBackgroundColor()));
41 // Removes the border from |native_wrapper_|.
44 set_placeholder_text(placeholder
);
45 SetText(default_value
);
46 SetController(controller
);
47 SetHorizontalMargins(0, 0);
50 DecoratedTextfield::~DecoratedTextfield() {}
52 void DecoratedTextfield::SetInvalid(bool invalid
) {
55 border_
->SetColor(kWarningColor
);
57 border_
->UseDefaultColor();
61 void DecoratedTextfield::SetIcon(const gfx::Image
& icon
) {
62 int icon_space
= icon
.IsEmpty() ? 0 :
63 icon
.Width() + 2 * kTextfieldIconPadding
;
64 // Extra indent inside of textfield before text starts, in px.
65 const int kTextIndent
= 6;
66 int left
= base::i18n::IsRTL() ? icon_space
: kTextIndent
;
67 int right
= base::i18n::IsRTL() ? kTextIndent
: icon_space
;
68 SetHorizontalMargins(left
, right
);
71 PreferredSizeChanged();
75 const char* DecoratedTextfield::GetClassName() const {
76 return kViewClassName
;
79 void DecoratedTextfield::PaintChildren(gfx::Canvas
* canvas
) {}
81 void DecoratedTextfield::OnPaint(gfx::Canvas
* canvas
) {
82 // Draw the border and background.
83 border_
->set_has_focus(HasFocus());
84 views::View::OnPaint(canvas
);
86 // Then the textfield.
87 views::View::PaintChildren(canvas
);
90 if (!icon_
.IsEmpty()) {
91 gfx::Rect bounds
= GetContentsBounds();
92 int x
= base::i18n::IsRTL() ?
93 kTextfieldIconPadding
:
94 bounds
.right() - icon_
.Width() - kTextfieldIconPadding
;
95 canvas
->DrawImageInt(icon_
.AsImageSkia(), x
,
96 bounds
.y() + (bounds
.height() - icon_
.Height()) / 2);
99 // Then the invalid indicator.
101 if (base::i18n::IsRTL()) {
102 canvas
->Translate(gfx::Vector2d(width(), 0));
103 canvas
->Scale(-1, 1);
107 dog_ear
.moveTo(width() - kDogEarSize
, 0);
108 dog_ear
.lineTo(width(), 0);
109 dog_ear
.lineTo(width(), kDogEarSize
);
111 canvas
->ClipPath(dog_ear
);
112 canvas
->DrawColor(kWarningColor
);
116 gfx::Size
DecoratedTextfield::GetPreferredSize() {
117 int w
= views::Textfield::GetPreferredSize().width();
118 views::LabelButton
button(NULL
, string16());
119 button
.SetStyle(views::Button::STYLE_BUTTON
);
120 int h
= button
.GetPreferredSize().height();
121 return gfx::Size(w
, h
- kMagicInsetNumber
);
124 } // namespace autofill