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 "base/strings/utf_string_conversions.h"
8 #include "grit/ui_resources.h"
9 #include "grit/ui_strings.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/views/app_list_folder_view.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/views/border.h"
16 #include "ui/views/controls/button/image_button.h"
17 #include "ui/views/controls/textfield/textfield.h"
18 #include "ui/views/painter.h"
24 const int kPreferredWidth = 360;
25 const int kPreferredHeight = 48;
26 const int kIconDimension = 24;
27 const int kPadding = 14;
28 const int kBottomSeparatorWidth = 380;
29 const int kBottomSeparatorHeight = 1;
30 const int kMaxFolderNameWidth = 300;
31 const int kFolderNameLeftRightPaddingChars = 4;
33 const SkColor kHintTextColor = SkColorSetRGB(0xA0, 0xA0, 0xA0);
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)));
47 virtual ~FolderNameView() {
51 SetBackgroundColor(text().size() <= kMaxFolderNameChars
52 ? kContentsBackgroundColor
57 DISALLOW_COPY_AND_ASSIGN(FolderNameView);
60 FolderHeaderView::FolderHeaderView(FolderHeaderViewDelegate* delegate)
62 back_button_(new views::ImageButton(this)),
63 folder_name_view_(new FolderNameView),
64 folder_name_placeholder_text_(
65 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
66 IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)),
68 folder_name_visible_(true) {
69 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
70 back_button_->SetImage(views::ImageButton::STATE_NORMAL,
71 rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL));
72 back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
73 views::ImageButton::ALIGN_MIDDLE);
74 AddChildView(back_button_);
76 folder_name_view_->SetFontList(
77 rb.GetFontList(ui::ResourceBundle::MediumFont));
78 folder_name_view_->set_placeholder_text_color(kHintTextColor);
79 folder_name_view_->set_placeholder_text(folder_name_placeholder_text_);
80 folder_name_view_->SetBorder(views::Border::NullBorder());
81 folder_name_view_->SetBackgroundColor(kContentsBackgroundColor);
82 folder_name_view_->set_controller(this);
83 AddChildView(folder_name_view_);
86 FolderHeaderView::~FolderHeaderView() {
88 folder_item_->RemoveObserver(this);
91 void FolderHeaderView::SetFolderItem(AppListFolderItem* folder_item) {
93 folder_item_->RemoveObserver(this);
95 folder_item_ = folder_item;
98 folder_item_->AddObserver(this);
100 folder_name_view_->SetEnabled(folder_item_->folder_type() !=
101 AppListFolderItem::FOLDER_TYPE_OEM);
106 void FolderHeaderView::UpdateFolderNameVisibility(bool visible) {
107 folder_name_visible_ = visible;
112 void FolderHeaderView::OnFolderItemRemoved() {
116 void FolderHeaderView::Update() {
120 folder_name_view_->SetVisible(folder_name_visible_);
121 if (folder_name_visible_) {
122 folder_name_view_->SetText(base::UTF8ToUTF16(folder_item_->name()));
123 folder_name_view_->Update();
129 gfx::Size FolderHeaderView::GetPreferredSize() {
130 return gfx::Size(kPreferredWidth, kPreferredHeight);
133 void FolderHeaderView::Layout() {
134 gfx::Rect rect(GetContentsBounds());
138 gfx::Rect back_bounds(rect);
139 back_bounds.set_width(kIconDimension + 2 * kPadding);
140 back_button_->SetBoundsRect(back_bounds);
142 gfx::Rect text_bounds(rect);
143 int text_char_num = folder_item_->name().size()
144 ? folder_item_->name().size()
145 : folder_name_placeholder_text_.size();
146 int text_width = folder_name_view_->GetFontList().GetExpectedTextWidth(
147 text_char_num + kFolderNameLeftRightPaddingChars);
148 text_width = std::min(text_width, kMaxFolderNameWidth);
149 text_bounds.set_x(back_bounds.x() + (rect.width() - text_width) / 2);
150 text_bounds.set_width(text_width);
151 text_bounds.ClampToCenteredSize(gfx::Size(text_bounds.width(),
152 folder_name_view_->GetPreferredSize().height()));
153 folder_name_view_->SetBoundsRect(text_bounds);
156 bool FolderHeaderView::OnKeyPressed(const ui::KeyEvent& event) {
157 if (event.key_code() == ui::VKEY_RETURN)
158 delegate_->GiveBackFocusToSearchBox();
163 void FolderHeaderView::OnPaint(gfx::Canvas* canvas) {
164 views::View::OnPaint(canvas);
166 gfx::Rect rect(GetContentsBounds());
167 if (rect.IsEmpty() || !folder_name_visible_)
170 // Draw bottom separator line.
171 rect.set_x((rect.width() - kBottomSeparatorWidth) / 2 + rect.x());
172 rect.set_y(rect.y() + rect.height() - kBottomSeparatorHeight);
173 rect.set_width(kBottomSeparatorWidth);
174 rect.set_height(kBottomSeparatorHeight);
175 canvas->FillRect(rect, kTopSeparatorColor);
178 void FolderHeaderView::ContentsChanged(views::Textfield* sender,
179 const base::string16& new_contents) {
180 // Temporarily remove from observer to ignore data change caused by us.
184 folder_name_view_->Update();
185 folder_item_->RemoveObserver(this);
186 // Enforce the maximum folder name length in UI.
187 std::string name = base::UTF16ToUTF8(
188 folder_name_view_->text().substr(0, kMaxFolderNameChars));
189 if (name != folder_item_->name())
190 delegate_->SetItemName(folder_item_, name);
191 folder_item_->AddObserver(this);
196 void FolderHeaderView::ButtonPressed(views::Button* sender,
197 const ui::Event& event) {
198 delegate_->GiveBackFocusToSearchBox();
199 delegate_->NavigateBack(folder_item_, event);
202 void FolderHeaderView::ItemIconChanged() {
205 void FolderHeaderView::ItemNameChanged() {
209 void FolderHeaderView::ItemHighlightedChanged() {
212 void FolderHeaderView::ItemIsInstallingChanged() {
215 void FolderHeaderView::ItemPercentDownloadedChanged() {
218 } // namespace app_list