1 // Copyright (c) 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 "ui/app_list/views/folder_header_view.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "ui/app_list/app_list_constants.h"
11 #include "ui/app_list/app_list_folder_item.h"
12 #include "ui/app_list/app_list_switches.h"
13 #include "ui/app_list/views/app_list_folder_view.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/resources/grit/ui_resources.h"
17 #include "ui/strings/grit/ui_strings.h"
18 #include "ui/views/border.h"
19 #include "ui/views/controls/button/image_button.h"
20 #include "ui/views/controls/textfield/textfield.h"
21 #include "ui/views/painter.h"
27 const int kPreferredWidth
= 360;
28 const int kPreferredHeight
= 48;
29 const int kIconDimension
= 24;
30 const int kBackButtonPadding
= 14;
31 const int kBottomSeparatorPadding
= 9; // Non-experimental app list only.
32 const int kBottomSeparatorHeight
= 1;
33 const int kMaxFolderNameWidth
= 300;
37 class FolderHeaderView::FolderNameView
: public views::Textfield
{
40 SetBorder(views::Border::CreateEmptyBorder(1, 1, 1, 1));
41 const SkColor kFocusBorderColor
= SkColorSetRGB(64, 128, 250);
42 SetFocusPainter(views::Painter::CreateSolidFocusPainter(
44 gfx::Insets(0, 0, 1, 1)));
46 SetTextColor(kFolderTitleColor
);
49 ~FolderNameView() override
{}
52 DISALLOW_COPY_AND_ASSIGN(FolderNameView
);
55 FolderHeaderView::FolderHeaderView(FolderHeaderViewDelegate
* delegate
)
56 : folder_item_(nullptr),
57 back_button_(nullptr),
58 folder_name_view_(new FolderNameView
),
59 folder_name_placeholder_text_(
60 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
61 IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER
)),
63 folder_name_visible_(true) {
64 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
65 if (!app_list::switches::IsExperimentalAppListEnabled()) {
66 back_button_
= new views::ImageButton(this);
67 back_button_
->SetImage(
68 views::ImageButton::STATE_NORMAL
,
69 rb
.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL
));
70 back_button_
->SetImageAlignment(views::ImageButton::ALIGN_CENTER
,
71 views::ImageButton::ALIGN_MIDDLE
);
72 AddChildView(back_button_
);
73 back_button_
->SetFocusable(true);
74 back_button_
->SetAccessibleName(
75 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
76 IDS_APP_LIST_FOLDER_CLOSE_FOLDER_ACCESSIBILE_NAME
));
79 folder_name_view_
->SetFontList(
80 rb
.GetFontList(ui::ResourceBundle::MediumFont
));
81 folder_name_view_
->set_placeholder_text_color(kFolderTitleHintTextColor
);
82 folder_name_view_
->set_placeholder_text(folder_name_placeholder_text_
);
83 folder_name_view_
->SetBorder(views::Border::NullBorder());
84 folder_name_view_
->SetBackgroundColor(kContentsBackgroundColor
);
85 folder_name_view_
->set_controller(this);
86 AddChildView(folder_name_view_
);
89 FolderHeaderView::~FolderHeaderView() {
91 folder_item_
->RemoveObserver(this);
94 void FolderHeaderView::SetFolderItem(AppListFolderItem
* folder_item
) {
96 folder_item_
->RemoveObserver(this);
98 folder_item_
= folder_item
;
101 folder_item_
->AddObserver(this);
103 folder_name_view_
->SetEnabled(folder_item_
->folder_type() !=
104 AppListFolderItem::FOLDER_TYPE_OEM
);
109 void FolderHeaderView::UpdateFolderNameVisibility(bool visible
) {
110 folder_name_visible_
= visible
;
115 void FolderHeaderView::OnFolderItemRemoved() {
119 void FolderHeaderView::Update() {
123 folder_name_view_
->SetVisible(folder_name_visible_
);
124 if (folder_name_visible_
) {
125 folder_name_view_
->SetText(base::UTF8ToUTF16(folder_item_
->name()));
126 UpdateFolderNameAccessibleName();
132 void FolderHeaderView::UpdateFolderNameAccessibleName() {
133 // Sets |folder_name_view_|'s accessible name to the placeholder text if
134 // |folder_name_view_| is blank; otherwise, clear the accessible name, the
135 // accessible state's value is set to be folder_name_view_->text() by
137 base::string16 accessible_name
= folder_name_view_
->text().empty()
138 ? folder_name_placeholder_text_
140 folder_name_view_
->SetAccessibleName(accessible_name
);
143 const base::string16
& FolderHeaderView::GetFolderNameForTest() {
144 return folder_name_view_
->text();
147 void FolderHeaderView::SetFolderNameForTest(const base::string16
& name
) {
148 folder_name_view_
->SetText(name
);
151 bool FolderHeaderView::IsFolderNameEnabledForTest() const {
152 return folder_name_view_
->enabled();
155 gfx::Size
FolderHeaderView::GetPreferredSize() const {
156 return gfx::Size(kPreferredWidth
, kPreferredHeight
);
159 void FolderHeaderView::Layout() {
160 gfx::Rect
rect(GetContentsBounds());
164 if (!switches::IsExperimentalAppListEnabled()) {
165 gfx::Rect back_bounds
;
166 DCHECK(back_button_
);
168 back_bounds
.set_width(kIconDimension
+ 2 * kBackButtonPadding
);
169 back_button_
->SetBoundsRect(back_bounds
);
172 gfx::Rect
text_bounds(rect
);
173 base::string16 text
= folder_item_
&& !folder_item_
->name().empty()
174 ? base::UTF8ToUTF16(folder_item_
->name())
175 : folder_name_placeholder_text_
;
177 gfx::Canvas::GetStringWidth(text
, folder_name_view_
->GetFontList()) +
178 folder_name_view_
->GetCaretBounds().width() +
179 folder_name_view_
->GetInsets().width();
180 text_width
= std::min(text_width
, kMaxFolderNameWidth
);
181 text_bounds
.set_x(rect
.x() + (rect
.width() - text_width
) / 2);
182 text_bounds
.set_width(text_width
);
183 text_bounds
.ClampToCenteredSize(gfx::Size(text_bounds
.width(),
184 folder_name_view_
->GetPreferredSize().height()));
185 folder_name_view_
->SetBoundsRect(text_bounds
);
188 bool FolderHeaderView::OnKeyPressed(const ui::KeyEvent
& event
) {
189 if (event
.key_code() == ui::VKEY_RETURN
)
190 delegate_
->GiveBackFocusToSearchBox();
195 void FolderHeaderView::OnPaint(gfx::Canvas
* canvas
) {
196 views::View::OnPaint(canvas
);
198 gfx::Rect
rect(GetContentsBounds());
199 if (rect
.IsEmpty() || !folder_name_visible_
)
202 // Draw bottom separator line.
203 int horizontal_padding
= app_list::switches::IsExperimentalAppListEnabled()
204 ? kExperimentalWindowPadding
205 : kBottomSeparatorPadding
;
206 rect
.Inset(horizontal_padding
, 0);
207 rect
.set_y(rect
.bottom() - kBottomSeparatorHeight
);
208 rect
.set_height(kBottomSeparatorHeight
);
209 canvas
->FillRect(rect
, kTopSeparatorColor
);
212 void FolderHeaderView::ContentsChanged(views::Textfield
* sender
,
213 const base::string16
& new_contents
) {
214 // Temporarily remove from observer to ignore data change caused by us.
218 folder_item_
->RemoveObserver(this);
219 // Enforce the maximum folder name length in UI.
220 std::string name
= base::UTF16ToUTF8(
221 folder_name_view_
->text().substr(0, kMaxFolderNameChars
));
222 if (name
!= folder_item_
->name())
223 delegate_
->SetItemName(folder_item_
, name
);
224 folder_item_
->AddObserver(this);
226 UpdateFolderNameAccessibleName();
231 void FolderHeaderView::ButtonPressed(views::Button
* sender
,
232 const ui::Event
& event
) {
233 delegate_
->NavigateBack(folder_item_
, event
);
236 void FolderHeaderView::ItemNameChanged() {
240 } // namespace app_list