blob: 139c5d846fb1ca265189cd1849171387adb34b93 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/autofill/decorated_textfield.h"
#include "chrome/browser/ui/autofill/autofill_dialog_types.h"
#include "ui/gfx/canvas.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/focusable_border.h"
#include "ui/views/controls/textfield/textfield_controller.h"
namespace {
// Padding around icons inside DecoratedTextfields.
const int kTextfieldIconPadding = 3;
// Size of the triangular mark that indicates an invalid textfield (in pixels).
const int kDogEarSize = 10;
} // namespace
namespace autofill {
// static
const char DecoratedTextfield::kViewClassName[] = "autofill/DecoratedTextfield";
const int DecoratedTextfield::kMagicInsetNumber = 6;
DecoratedTextfield::DecoratedTextfield(
const base::string16& default_value,
const base::string16& placeholder,
views::TextfieldController* controller)
: border_(new views::FocusableBorder()),
invalid_(false) {
set_background(
views::Background::CreateSolidBackground(GetBackgroundColor()));
set_border(border_);
// Removes the border from |native_wrapper_|.
RemoveBorder();
set_placeholder_text(placeholder);
SetText(default_value);
SetController(controller);
SetHorizontalMargins(0, 0);
}
DecoratedTextfield::~DecoratedTextfield() {}
void DecoratedTextfield::SetInvalid(bool invalid) {
invalid_ = invalid;
if (invalid)
border_->SetColor(kWarningColor);
else
border_->UseDefaultColor();
SchedulePaint();
}
void DecoratedTextfield::SetIcon(const gfx::Image& icon) {
int icon_space = icon.IsEmpty() ? 0 :
icon.Width() + 2 * kTextfieldIconPadding;
// Extra indent inside of textfield before text starts, in px.
const int kTextIndent = 6;
int left = base::i18n::IsRTL() ? icon_space : kTextIndent;
int right = base::i18n::IsRTL() ? kTextIndent : icon_space;
SetHorizontalMargins(left, right);
icon_ = icon;
PreferredSizeChanged();
SchedulePaint();
}
const char* DecoratedTextfield::GetClassName() const {
return kViewClassName;
}
void DecoratedTextfield::PaintChildren(gfx::Canvas* canvas) {}
void DecoratedTextfield::OnPaint(gfx::Canvas* canvas) {
// Draw the border and background.
border_->set_has_focus(HasFocus());
views::View::OnPaint(canvas);
// Then the textfield.
views::View::PaintChildren(canvas);
// Then the icon.
if (!icon_.IsEmpty()) {
gfx::Rect bounds = GetContentsBounds();
int x = base::i18n::IsRTL() ?
kTextfieldIconPadding :
bounds.right() - icon_.Width() - kTextfieldIconPadding;
canvas->DrawImageInt(icon_.AsImageSkia(), x,
bounds.y() + (bounds.height() - icon_.Height()) / 2);
}
// Then the invalid indicator.
if (invalid_) {
if (base::i18n::IsRTL()) {
canvas->Translate(gfx::Vector2d(width(), 0));
canvas->Scale(-1, 1);
}
SkPath dog_ear;
dog_ear.moveTo(width() - kDogEarSize, 0);
dog_ear.lineTo(width(), 0);
dog_ear.lineTo(width(), kDogEarSize);
dog_ear.close();
canvas->ClipPath(dog_ear);
canvas->DrawColor(kWarningColor);
}
}
gfx::Size DecoratedTextfield::GetPreferredSize() {
int w = views::Textfield::GetPreferredSize().width();
views::LabelButton button(NULL, string16());
button.SetStyle(views::Button::STYLE_BUTTON);
int h = button.GetPreferredSize().height();
return gfx::Size(w, h - kMagicInsetNumber);
}
} // namespace autofill