Infobar material design refresh: layout
[chromium-blink-merge.git] / chrome / browser / ui / views / autofill / expanding_textfield.cc
blobc7957d58fea68fff5752bf651e401d49870c6363
1 // Copyright 2014 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/expanding_textfield.h"
7 #include "base/bind.h"
8 #include "base/strings/string_split.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/ui/views/autofill/decorated_textfield.h"
12 #include "ui/views/layout/box_layout.h"
14 namespace autofill {
16 namespace {
18 // The vertical padding between textfields.
19 const int kManualInputRowPadding = 10;
21 } // namespace
23 // static
24 const char ExpandingTextfield::kViewClassName[] = "autofill/ExpandingTextfield";
26 ExpandingTextfield::ExpandingTextfield(
27 const base::string16& default_value,
28 const base::string16& placeholder,
29 bool multiline,
30 views::TextfieldController* controller)
31 : controller_(controller) {
32 textfields_.push_back(
33 new DecoratedTextfield(base::string16(), placeholder, this));
34 if (multiline) {
35 textfields_.push_back(
36 new DecoratedTextfield(base::string16(), placeholder, this));
38 SetText(default_value);
40 for (std::list<DecoratedTextfield*>::iterator iter = textfields_.begin();
41 iter != textfields_.end(); ++iter) {
42 AddChildView(*iter);
45 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
46 kManualInputRowPadding));
49 ExpandingTextfield::~ExpandingTextfield() {}
51 void ExpandingTextfield::SetText(const base::string16& text) {
52 textfields_.front()->SetText(text);
53 std::vector<base::string16> strings = base::SplitString(
54 text, base::string16(1, '\n'),
55 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
57 size_t i = 0;
58 for (std::list<DecoratedTextfield*>::iterator iter = textfields_.begin();
59 iter != textfields_.end(); ++iter) {
60 (*iter)->SetText(i < strings.size() ? strings[i++] : base::string16());
63 for (; i < strings.size(); ++i) {
64 textfields_.push_back(new DecoratedTextfield(
65 strings[i],
66 textfields_.front()->GetPlaceholderText(),
67 this));
68 AddChildView(textfields_.back());
69 PreferredSizeChanged();
73 base::string16 ExpandingTextfield::GetText() {
74 base::string16 text = textfields_.front()->text();
75 std::list<DecoratedTextfield*>::const_iterator iter = ++textfields_.begin();
76 while (iter != textfields_.end()) {
77 text += base::ASCIIToUTF16("\n") + (*iter++)->text();
79 base::TrimWhitespace(text, base::TRIM_ALL, &text);
80 return text;
83 void ExpandingTextfield::SetInvalid(bool invalid) {
84 textfields_.front()->SetInvalid(invalid);
87 void ExpandingTextfield::SetDefaultWidthInCharacters(int chars) {
88 ForEachTextfield(&DecoratedTextfield::set_default_width_in_chars, chars);
91 void ExpandingTextfield::SetPlaceholderText(const base::string16& placeholder) {
92 ForEachTextfield<views::Textfield, const base::string16&>(
93 &DecoratedTextfield::set_placeholder_text, placeholder);
96 void ExpandingTextfield::SetIcon(const gfx::Image& icon) {
97 textfields_.front()->SetIcon(icon);
100 void ExpandingTextfield::SetTooltipIcon(const base::string16& text) {
101 textfields_.front()->SetTooltipIcon(text);
104 void ExpandingTextfield::SetEditable(bool editable) {
105 ForEachTextfield(&DecoratedTextfield::SetEditable, editable);
108 const char* ExpandingTextfield::GetClassName() const {
109 return kViewClassName;
112 void ExpandingTextfield::ContentsChanged(views::Textfield* sender,
113 const base::string16& new_contents) {
114 if (textfields_.size() > 1 && sender == textfields_.back() &&
115 !new_contents.empty()) {
116 textfields_.push_back(
117 new DecoratedTextfield(base::string16(),
118 sender->GetPlaceholderText(),
119 this));
120 AddChildView(textfields_.back());
121 PreferredSizeChanged();
124 controller_->ContentsChanged(sender, new_contents);
127 bool ExpandingTextfield::HandleKeyEvent(views::Textfield* sender,
128 const ui::KeyEvent& key_event) {
129 return controller_->HandleKeyEvent(sender, key_event);
132 bool ExpandingTextfield::HandleMouseEvent(views::Textfield* sender,
133 const ui::MouseEvent& mouse_event) {
134 return controller_->HandleMouseEvent(sender, mouse_event);
137 template <typename BaseType, typename Param>
138 void ExpandingTextfield::ForEachTextfield(
139 void (BaseType::* f)(Param), Param p) const {
140 for (std::list<DecoratedTextfield*>::const_iterator iter =
141 textfields_.begin();
142 iter != textfields_.end(); ++iter) {
143 base::Bind(f, base::Unretained(*iter), p).Run();
147 } // namespace autofill