Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / app_list / views / folder_header_view.cc
bloba1238157825b3d0dad4478850142400cc9af5fe6
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"
7 #include <algorithm>
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/focus/focus_manager.h"
22 #include "ui/views/painter.h"
24 namespace app_list {
26 namespace {
28 const int kPreferredWidth = 360;
29 const int kPreferredHeight = 48;
30 const int kIconDimension = 24;
31 const int kBackButtonPadding = 14;
32 const int kBottomSeparatorPadding = 9; // Non-experimental app list only.
33 const int kBottomSeparatorHeight = 1;
34 const int kMaxFolderNameWidth = 300;
36 } // namespace
38 class FolderHeaderView::FolderNameView : public views::Textfield {
39 public:
40 FolderNameView() {
41 SetBorder(views::Border::CreateEmptyBorder(1, 1, 1, 1));
42 const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
43 SetFocusPainter(views::Painter::CreateSolidFocusPainter(
44 kFocusBorderColor,
45 gfx::Insets(0, 0, 1, 1)));
47 SetTextColor(kFolderTitleColor);
50 ~FolderNameView() override {}
52 private:
53 DISALLOW_COPY_AND_ASSIGN(FolderNameView);
56 FolderHeaderView::FolderHeaderView(FolderHeaderViewDelegate* delegate)
57 : folder_item_(nullptr),
58 back_button_(nullptr),
59 folder_name_view_(new FolderNameView),
60 folder_name_placeholder_text_(
61 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
62 IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)),
63 delegate_(delegate),
64 folder_name_visible_(true) {
65 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
66 if (!app_list::switches::IsExperimentalAppListEnabled()) {
67 back_button_ = new views::ImageButton(this);
68 back_button_->SetImage(
69 views::ImageButton::STATE_NORMAL,
70 rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL));
71 back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
72 views::ImageButton::ALIGN_MIDDLE);
73 AddChildView(back_button_);
74 back_button_->SetFocusable(true);
75 back_button_->SetAccessibleName(
76 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
77 IDS_APP_LIST_FOLDER_CLOSE_FOLDER_ACCESSIBILE_NAME));
80 folder_name_view_->SetFontList(
81 rb.GetFontList(ui::ResourceBundle::MediumFont));
82 folder_name_view_->set_placeholder_text_color(kFolderTitleHintTextColor);
83 folder_name_view_->set_placeholder_text(folder_name_placeholder_text_);
84 folder_name_view_->SetBorder(views::Border::NullBorder());
85 folder_name_view_->SetBackgroundColor(kContentsBackgroundColor);
86 folder_name_view_->set_controller(this);
87 AddChildView(folder_name_view_);
90 FolderHeaderView::~FolderHeaderView() {
91 if (folder_item_)
92 folder_item_->RemoveObserver(this);
95 void FolderHeaderView::SetFolderItem(AppListFolderItem* folder_item) {
96 if (folder_item_)
97 folder_item_->RemoveObserver(this);
99 folder_item_ = folder_item;
100 if (!folder_item_)
101 return;
102 folder_item_->AddObserver(this);
104 folder_name_view_->SetEnabled(folder_item_->folder_type() !=
105 AppListFolderItem::FOLDER_TYPE_OEM);
107 Update();
110 void FolderHeaderView::UpdateFolderNameVisibility(bool visible) {
111 folder_name_visible_ = visible;
112 Update();
113 SchedulePaint();
116 void FolderHeaderView::OnFolderItemRemoved() {
117 folder_item_ = NULL;
120 void FolderHeaderView::SetTextFocus() {
121 if (!folder_name_view_->HasFocus()) {
122 views::FocusManager* focus_manager = GetFocusManager();
123 if (focus_manager)
124 focus_manager->SetFocusedView(folder_name_view_);
128 bool FolderHeaderView::HasTextFocus() const {
129 return folder_name_view_->HasFocus();
132 void FolderHeaderView::Update() {
133 if (!folder_item_)
134 return;
136 folder_name_view_->SetVisible(folder_name_visible_);
137 if (folder_name_visible_) {
138 folder_name_view_->SetText(base::UTF8ToUTF16(folder_item_->name()));
139 UpdateFolderNameAccessibleName();
142 Layout();
145 void FolderHeaderView::UpdateFolderNameAccessibleName() {
146 // Sets |folder_name_view_|'s accessible name to the placeholder text if
147 // |folder_name_view_| is blank; otherwise, clear the accessible name, the
148 // accessible state's value is set to be folder_name_view_->text() by
149 // TextField.
150 base::string16 accessible_name = folder_name_view_->text().empty()
151 ? folder_name_placeholder_text_
152 : base::string16();
153 folder_name_view_->SetAccessibleName(accessible_name);
156 const base::string16& FolderHeaderView::GetFolderNameForTest() {
157 return folder_name_view_->text();
160 void FolderHeaderView::SetFolderNameForTest(const base::string16& name) {
161 folder_name_view_->SetText(name);
164 bool FolderHeaderView::IsFolderNameEnabledForTest() const {
165 return folder_name_view_->enabled();
168 gfx::Size FolderHeaderView::GetPreferredSize() const {
169 return gfx::Size(kPreferredWidth, kPreferredHeight);
172 void FolderHeaderView::Layout() {
173 gfx::Rect rect(GetContentsBounds());
174 if (rect.IsEmpty())
175 return;
177 if (!switches::IsExperimentalAppListEnabled()) {
178 gfx::Rect back_bounds;
179 DCHECK(back_button_);
180 back_bounds = rect;
181 back_bounds.set_width(kIconDimension + 2 * kBackButtonPadding);
182 back_button_->SetBoundsRect(back_bounds);
185 gfx::Rect text_bounds(rect);
186 base::string16 text = folder_item_ && !folder_item_->name().empty()
187 ? base::UTF8ToUTF16(folder_item_->name())
188 : folder_name_placeholder_text_;
189 int text_width =
190 gfx::Canvas::GetStringWidth(text, folder_name_view_->GetFontList()) +
191 folder_name_view_->GetCaretBounds().width() +
192 folder_name_view_->GetInsets().width();
193 text_width = std::min(text_width, kMaxFolderNameWidth);
194 text_bounds.set_x(rect.x() + (rect.width() - text_width) / 2);
195 text_bounds.set_width(text_width);
196 text_bounds.ClampToCenteredSize(gfx::Size(text_bounds.width(),
197 folder_name_view_->GetPreferredSize().height()));
198 folder_name_view_->SetBoundsRect(text_bounds);
201 bool FolderHeaderView::OnKeyPressed(const ui::KeyEvent& event) {
202 if (event.key_code() == ui::VKEY_RETURN)
203 delegate_->GiveBackFocusToSearchBox();
205 return false;
208 void FolderHeaderView::OnPaint(gfx::Canvas* canvas) {
209 views::View::OnPaint(canvas);
211 gfx::Rect rect(GetContentsBounds());
212 if (rect.IsEmpty() || !folder_name_visible_)
213 return;
215 // Draw bottom separator line.
216 int horizontal_padding = app_list::switches::IsExperimentalAppListEnabled()
217 ? kExperimentalAppsGridPadding
218 : kBottomSeparatorPadding;
219 rect.Inset(horizontal_padding, 0);
220 rect.set_y(rect.bottom() - kBottomSeparatorHeight);
221 rect.set_height(kBottomSeparatorHeight);
222 canvas->FillRect(rect, kTopSeparatorColor);
225 void FolderHeaderView::ContentsChanged(views::Textfield* sender,
226 const base::string16& new_contents) {
227 // Temporarily remove from observer to ignore data change caused by us.
228 if (!folder_item_)
229 return;
231 folder_item_->RemoveObserver(this);
232 // Enforce the maximum folder name length in UI.
233 std::string name = base::UTF16ToUTF8(
234 folder_name_view_->text().substr(0, kMaxFolderNameChars));
235 if (name != folder_item_->name())
236 delegate_->SetItemName(folder_item_, name);
237 folder_item_->AddObserver(this);
239 UpdateFolderNameAccessibleName();
241 Layout();
244 void FolderHeaderView::ButtonPressed(views::Button* sender,
245 const ui::Event& event) {
246 delegate_->NavigateBack(folder_item_, event);
249 void FolderHeaderView::ItemNameChanged() {
250 Update();
253 } // namespace app_list