Home | History | Annotate | Download | only in autofill
      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 "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"
     13 
     14 namespace {
     15 
     16 // Padding around icons inside DecoratedTextfields.
     17 const int kTextfieldIconPadding = 3;
     18 
     19 // Size of the triangular mark that indicates an invalid textfield (in pixels).
     20 const int kDogEarSize = 10;
     21 
     22 }  // namespace
     23 
     24 namespace autofill {
     25 
     26 // static
     27 const char DecoratedTextfield::kViewClassName[] = "autofill/DecoratedTextfield";
     28 
     29 const int DecoratedTextfield::kMagicInsetNumber = 6;
     30 
     31 DecoratedTextfield::DecoratedTextfield(
     32     const base::string16& default_value,
     33     const base::string16& placeholder,
     34     views::TextfieldController* controller)
     35     : border_(new views::FocusableBorder()),
     36       invalid_(false) {
     37   set_background(
     38       views::Background::CreateSolidBackground(GetBackgroundColor()));
     39 
     40   set_border(border_);
     41   // Removes the border from |native_wrapper_|.
     42   RemoveBorder();
     43 
     44   set_placeholder_text(placeholder);
     45   SetText(default_value);
     46   SetController(controller);
     47   SetHorizontalMargins(0, 0);
     48 }
     49 
     50 DecoratedTextfield::~DecoratedTextfield() {}
     51 
     52 void DecoratedTextfield::SetInvalid(bool invalid) {
     53   invalid_ = invalid;
     54   if (invalid)
     55     border_->SetColor(kWarningColor);
     56   else
     57     border_->UseDefaultColor();
     58   SchedulePaint();
     59 }
     60 
     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);
     69   icon_ = icon;
     70 
     71   PreferredSizeChanged();
     72   SchedulePaint();
     73 }
     74 
     75 const char* DecoratedTextfield::GetClassName() const {
     76   return kViewClassName;
     77 }
     78 
     79 void DecoratedTextfield::PaintChildren(gfx::Canvas* canvas) {}
     80 
     81 void DecoratedTextfield::OnPaint(gfx::Canvas* canvas) {
     82   // Draw the border and background.
     83   border_->set_has_focus(HasFocus());
     84   views::View::OnPaint(canvas);
     85 
     86   // Then the textfield.
     87   views::View::PaintChildren(canvas);
     88 
     89   // Then the icon.
     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);
     97   }
     98 
     99   // Then the invalid indicator.
    100   if (invalid_) {
    101     if (base::i18n::IsRTL()) {
    102       canvas->Translate(gfx::Vector2d(width(), 0));
    103       canvas->Scale(-1, 1);
    104     }
    105 
    106     SkPath dog_ear;
    107     dog_ear.moveTo(width() - kDogEarSize, 0);
    108     dog_ear.lineTo(width(), 0);
    109     dog_ear.lineTo(width(), kDogEarSize);
    110     dog_ear.close();
    111     canvas->ClipPath(dog_ear);
    112     canvas->DrawColor(kWarningColor);
    113   }
    114 }
    115 
    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);
    122 }
    123 
    124 } // namespace autofill
    125