Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / views / folder_header_view.cc
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.
4
5 #include "ui/app_list/views/folder_header_view.h"
6
7 #include <algorithm>
8
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"
22
23 namespace app_list {
24
25 namespace {
26
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;
34
35 }  // namespace
36
37 class FolderHeaderView::FolderNameView : public views::Textfield {
38  public:
39   FolderNameView() {
40     SetBorder(views::Border::CreateEmptyBorder(1, 1, 1, 1));
41     const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
42     SetFocusPainter(views::Painter::CreateSolidFocusPainter(
43           kFocusBorderColor,
44           gfx::Insets(0, 0, 1, 1)));
45
46     SetTextColor(kFolderTitleColor);
47   }
48
49   ~FolderNameView() override {}
50
51  private:
52   DISALLOW_COPY_AND_ASSIGN(FolderNameView);
53 };
54
55 FolderHeaderView::FolderHeaderView(FolderHeaderViewDelegate* delegate)
56     : folder_item_(NULL),
57       back_button_(new views::ImageButton(this)),
58       folder_name_view_(new FolderNameView),
59       folder_name_placeholder_text_(
60           ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
61               IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)),
62       delegate_(delegate),
63       folder_name_visible_(true) {
64   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
65   back_button_->SetImage(views::ImageButton::STATE_NORMAL,
66       rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL));
67   back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
68       views::ImageButton::ALIGN_MIDDLE);
69   AddChildView(back_button_);
70   back_button_->SetFocusable(true);
71   back_button_->SetAccessibleName(
72       ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
73           IDS_APP_LIST_FOLDER_CLOSE_FOLDER_ACCESSIBILE_NAME));
74
75   folder_name_view_->SetFontList(
76       rb.GetFontList(ui::ResourceBundle::MediumFont));
77   folder_name_view_->set_placeholder_text_color(kFolderTitleHintTextColor);
78   folder_name_view_->set_placeholder_text(folder_name_placeholder_text_);
79   folder_name_view_->SetBorder(views::Border::NullBorder());
80   folder_name_view_->SetBackgroundColor(kContentsBackgroundColor);
81   folder_name_view_->set_controller(this);
82   AddChildView(folder_name_view_);
83 }
84
85 FolderHeaderView::~FolderHeaderView() {
86   if (folder_item_)
87     folder_item_->RemoveObserver(this);
88 }
89
90 void FolderHeaderView::SetFolderItem(AppListFolderItem* folder_item) {
91   if (folder_item_)
92     folder_item_->RemoveObserver(this);
93
94   folder_item_ = folder_item;
95   if (!folder_item_)
96     return;
97   folder_item_->AddObserver(this);
98
99   folder_name_view_->SetEnabled(folder_item_->folder_type() !=
100                                 AppListFolderItem::FOLDER_TYPE_OEM);
101
102   Update();
103 }
104
105 void FolderHeaderView::UpdateFolderNameVisibility(bool visible) {
106   folder_name_visible_ = visible;
107   Update();
108   SchedulePaint();
109 }
110
111 void FolderHeaderView::OnFolderItemRemoved() {
112   folder_item_ = NULL;
113 }
114
115 void FolderHeaderView::Update() {
116   if (!folder_item_)
117     return;
118
119   folder_name_view_->SetVisible(folder_name_visible_);
120   if (folder_name_visible_) {
121     folder_name_view_->SetText(base::UTF8ToUTF16(folder_item_->name()));
122     UpdateFolderNameAccessibleName();
123   }
124
125   Layout();
126 }
127
128 void FolderHeaderView::UpdateFolderNameAccessibleName() {
129   // Sets |folder_name_view_|'s accessible name to the placeholder text if
130   // |folder_name_view_| is blank; otherwise, clear the accessible name, the
131   // accessible state's value is set to be folder_name_view_->text() by
132   // TextField.
133   base::string16 accessible_name = folder_name_view_->text().empty()
134                                        ? folder_name_placeholder_text_
135                                        : base::string16();
136   folder_name_view_->SetAccessibleName(accessible_name);
137 }
138
139 const base::string16& FolderHeaderView::GetFolderNameForTest() {
140   return folder_name_view_->text();
141 }
142
143 void FolderHeaderView::SetFolderNameForTest(const base::string16& name) {
144   folder_name_view_->SetText(name);
145 }
146
147 bool FolderHeaderView::IsFolderNameEnabledForTest() const {
148   return folder_name_view_->enabled();
149 }
150
151 gfx::Size FolderHeaderView::GetPreferredSize() const {
152   return gfx::Size(kPreferredWidth, kPreferredHeight);
153 }
154
155 void FolderHeaderView::Layout() {
156   gfx::Rect rect(GetContentsBounds());
157   if (rect.IsEmpty())
158     return;
159
160   gfx::Rect back_bounds(rect);
161   back_bounds.set_width(kIconDimension + 2 * kBackButtonPadding);
162   if (app_list::switches::IsExperimentalAppListEnabled()) {
163     // Align the left edge of the button image with the left margin of the
164     // launcher window. Note that this means the physical button dimensions
165     // extends slightly into the margin.
166     back_bounds.set_x(kExperimentalWindowPadding - kBackButtonPadding);
167   }
168   back_button_->SetBoundsRect(back_bounds);
169
170   gfx::Rect text_bounds(rect);
171   base::string16 text = folder_item_ && !folder_item_->name().empty()
172                             ? base::UTF8ToUTF16(folder_item_->name())
173                             : folder_name_placeholder_text_;
174   int text_width =
175       gfx::Canvas::GetStringWidth(text, folder_name_view_->GetFontList()) +
176       folder_name_view_->GetCaretBounds().width() +
177       folder_name_view_->GetInsets().width();
178   text_width = std::min(text_width, kMaxFolderNameWidth);
179   text_bounds.set_x(back_bounds.x() + (rect.width() - text_width) / 2);
180   text_bounds.set_width(text_width);
181   text_bounds.ClampToCenteredSize(gfx::Size(text_bounds.width(),
182       folder_name_view_->GetPreferredSize().height()));
183   folder_name_view_->SetBoundsRect(text_bounds);
184 }
185
186 bool FolderHeaderView::OnKeyPressed(const ui::KeyEvent& event) {
187   if (event.key_code() == ui::VKEY_RETURN)
188     delegate_->GiveBackFocusToSearchBox();
189
190   return false;
191 }
192
193 void FolderHeaderView::OnPaint(gfx::Canvas* canvas) {
194   views::View::OnPaint(canvas);
195
196   gfx::Rect rect(GetContentsBounds());
197   if (rect.IsEmpty() || !folder_name_visible_)
198     return;
199
200   // Draw bottom separator line.
201   int horizontal_padding = app_list::switches::IsExperimentalAppListEnabled()
202                                ? kExperimentalWindowPadding
203                                : kBottomSeparatorPadding;
204   rect.Inset(horizontal_padding, 0);
205   rect.set_y(rect.bottom() - kBottomSeparatorHeight);
206   rect.set_height(kBottomSeparatorHeight);
207   canvas->FillRect(rect, kTopSeparatorColor);
208 }
209
210 void FolderHeaderView::ContentsChanged(views::Textfield* sender,
211                                        const base::string16& new_contents) {
212   // Temporarily remove from observer to ignore data change caused by us.
213   if (!folder_item_)
214     return;
215
216   folder_item_->RemoveObserver(this);
217   // Enforce the maximum folder name length in UI.
218   std::string name = base::UTF16ToUTF8(
219       folder_name_view_->text().substr(0, kMaxFolderNameChars));
220   if (name != folder_item_->name())
221     delegate_->SetItemName(folder_item_, name);
222   folder_item_->AddObserver(this);
223
224   UpdateFolderNameAccessibleName();
225
226   Layout();
227 }
228
229 void FolderHeaderView::ButtonPressed(views::Button* sender,
230                                      const ui::Event& event) {
231   delegate_->NavigateBack(folder_item_, event);
232 }
233
234 void FolderHeaderView::ItemNameChanged() {
235   Update();
236 }
237
238 }  // namespace app_list