Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ash / shell / app_list.cc
bloba964fcd850b1109c06522417b74ff0a37014faad
1 // Copyright (c) 2012 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 <string>
6 #include <vector>
8 #include "ash/session/session_state_delegate.h"
9 #include "ash/shell.h"
10 #include "ash/shell/example_factory.h"
11 #include "ash/shell/toplevel_window.h"
12 #include "ash/shell_delegate.h"
13 #include "base/basictypes.h"
14 #include "base/callback.h"
15 #include "base/files/file_path.h"
16 #include "base/i18n/case_conversion.h"
17 #include "base/i18n/string_search.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "ui/app_list/app_list_item.h"
22 #include "ui/app_list/app_list_item_list.h"
23 #include "ui/app_list/app_list_model.h"
24 #include "ui/app_list/app_list_view_delegate.h"
25 #include "ui/app_list/search_box_model.h"
26 #include "ui/app_list/search_result.h"
27 #include "ui/app_list/speech_ui_model.h"
28 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/font_list.h"
30 #include "ui/gfx/geometry/rect.h"
31 #include "ui/gfx/image/image_skia.h"
32 #include "ui/views/examples/examples_window_with_content.h"
34 namespace ash {
35 namespace shell {
37 namespace {
39 // WindowTypeShelfItem is an app item of app list. It carries a window
40 // launch type and launches corresponding example window when activated.
41 class WindowTypeShelfItem : public app_list::AppListItem {
42 public:
43 enum Type {
44 TOPLEVEL_WINDOW = 0,
45 NON_RESIZABLE_WINDOW,
46 LOCK_SCREEN,
47 WIDGETS_WINDOW,
48 EXAMPLES_WINDOW,
49 LAST_TYPE,
52 WindowTypeShelfItem(const std::string& id, Type type);
53 ~WindowTypeShelfItem() override;
55 static gfx::ImageSkia GetIcon(Type type) {
56 static const SkColor kColors[] = {
57 SK_ColorRED,
58 SK_ColorGREEN,
59 SK_ColorBLUE,
60 SK_ColorYELLOW,
61 SK_ColorCYAN,
64 const int kIconSize = 128;
65 SkBitmap icon;
66 icon.allocN32Pixels(kIconSize, kIconSize);
67 icon.eraseColor(kColors[static_cast<int>(type) % arraysize(kColors)]);
68 return gfx::ImageSkia::CreateFrom1xBitmap(icon);
71 // The text below is not localized as this is an example code.
72 static std::string GetTitle(Type type) {
73 switch (type) {
74 case TOPLEVEL_WINDOW:
75 return "Create Window";
76 case NON_RESIZABLE_WINDOW:
77 return "Create Non-Resizable Window";
78 case LOCK_SCREEN:
79 return "Lock Screen";
80 case WIDGETS_WINDOW:
81 return "Show Example Widgets";
82 case EXAMPLES_WINDOW:
83 return "Open Views Examples Window";
84 default:
85 return "Unknown window type.";
89 // The text below is not localized as this is an example code.
90 static std::string GetDetails(Type type) {
91 // Assigns details only to some types so that we see both one-line
92 // and two-line results.
93 switch (type) {
94 case WIDGETS_WINDOW:
95 return "Creates a window to show example widgets";
96 case EXAMPLES_WINDOW:
97 return "Creates a window to show views example.";
98 default:
99 return std::string();
103 static void ActivateItem(Type type, int event_flags) {
104 switch (type) {
105 case TOPLEVEL_WINDOW: {
106 ToplevelWindow::CreateParams params;
107 params.can_resize = true;
108 ToplevelWindow::CreateToplevelWindow(params);
109 break;
111 case NON_RESIZABLE_WINDOW: {
112 ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
113 break;
115 case LOCK_SCREEN: {
116 Shell::GetInstance()->session_state_delegate()->LockScreen();
117 break;
119 case WIDGETS_WINDOW: {
120 CreateWidgetsWindow();
121 break;
123 case EXAMPLES_WINDOW: {
124 views::examples::ShowExamplesWindowWithContent(
125 views::examples::DO_NOTHING_ON_CLOSE,
126 Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
127 NULL);
128 break;
130 default:
131 break;
135 // AppListItem
136 void Activate(int event_flags) override { ActivateItem(type_, event_flags); }
138 private:
139 Type type_;
141 DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem);
144 WindowTypeShelfItem::WindowTypeShelfItem(const std::string& id, Type type)
145 : app_list::AppListItem(id), type_(type) {
146 std::string title(GetTitle(type));
147 SetIcon(GetIcon(type));
148 SetName(title);
151 WindowTypeShelfItem::~WindowTypeShelfItem() {
154 // ExampleSearchResult is an app list search result. It provides what icon to
155 // show, what should title and details text look like. It also carries the
156 // matching window launch type so that AppListViewDelegate knows how to open
157 // it.
158 class ExampleSearchResult : public app_list::SearchResult {
159 public:
160 ExampleSearchResult(WindowTypeShelfItem::Type type,
161 const base::string16& query)
162 : type_(type) {
163 SetIcon(WindowTypeShelfItem::GetIcon(type_));
165 base::string16 title =
166 base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_));
167 set_title(title);
169 Tags title_tags;
170 const size_t match_len = query.length();
172 // Highlight matching parts in title with bold.
173 // Note the following is not a proper way to handle i18n string.
174 title = base::i18n::ToLower(title);
175 size_t match_start = title.find(query);
176 while (match_start != base::string16::npos) {
177 title_tags.push_back(Tag(Tag::MATCH,
178 match_start,
179 match_start + match_len));
180 match_start = title.find(query, match_start + match_len);
182 set_title_tags(title_tags);
184 base::string16 details =
185 base::UTF8ToUTF16(WindowTypeShelfItem::GetDetails(type_));
186 set_details(details);
187 Tags details_tags;
188 details_tags.push_back(Tag(Tag::DIM, 0, details.length()));
189 set_details_tags(details_tags);
192 WindowTypeShelfItem::Type type() const { return type_; }
194 // app_list::SearchResult:
195 scoped_ptr<SearchResult> Duplicate() const override {
196 return scoped_ptr<SearchResult>();
199 private:
200 WindowTypeShelfItem::Type type_;
202 DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult);
205 class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
206 public:
207 ExampleAppListViewDelegate()
208 : model_(new app_list::AppListModel) {
209 PopulateApps();
210 DecorateSearchBox(model_->search_box());
213 private:
214 void PopulateApps() {
215 for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
216 WindowTypeShelfItem::Type type =
217 static_cast<WindowTypeShelfItem::Type>(i);
218 std::string id = base::IntToString(i);
219 scoped_ptr<WindowTypeShelfItem> shelf_item(
220 new WindowTypeShelfItem(id, type));
221 model_->AddItem(shelf_item.Pass());
225 gfx::ImageSkia CreateSearchBoxIcon() {
226 const base::string16 icon_text = base::ASCIIToUTF16("ash");
227 const gfx::Size icon_size(32, 32);
229 gfx::Canvas canvas(icon_size, 1.0f, false /* is_opaque */);
230 canvas.DrawStringRectWithFlags(
231 icon_text,
232 gfx::FontList(),
233 SK_ColorBLACK,
234 gfx::Rect(icon_size),
235 gfx::Canvas::TEXT_ALIGN_CENTER | gfx::Canvas::NO_SUBPIXEL_RENDERING);
237 return gfx::ImageSkia(canvas.ExtractImageRep());
240 void DecorateSearchBox(app_list::SearchBoxModel* search_box_model) {
241 search_box_model->SetIcon(CreateSearchBoxIcon());
242 search_box_model->SetHintText(base::ASCIIToUTF16("Type to search..."));
245 // Overridden from app_list::AppListViewDelegate:
246 bool ForceNativeDesktop() const override { return false; }
248 void SetProfileByPath(const base::FilePath& profile_path) override {
249 // Nothing needs to be done.
252 const Users& GetUsers() const override { return users_; }
254 bool ShouldCenterWindow() const override { return false; }
256 app_list::AppListModel* GetModel() override { return model_.get(); }
258 app_list::SpeechUIModel* GetSpeechUI() override { return &speech_ui_; }
260 void GetShortcutPathForApp(
261 const std::string& app_id,
262 const base::Callback<void(const base::FilePath&)>& callback) override {
263 callback.Run(base::FilePath());
266 void OpenSearchResult(app_list::SearchResult* result,
267 bool auto_launch,
268 int event_flags) override {
269 const ExampleSearchResult* example_result =
270 static_cast<const ExampleSearchResult*>(result);
271 WindowTypeShelfItem::ActivateItem(example_result->type(), event_flags);
274 void InvokeSearchResultAction(app_list::SearchResult* result,
275 int action_index,
276 int event_flags) override {
277 NOTIMPLEMENTED();
280 base::TimeDelta GetAutoLaunchTimeout() override { return base::TimeDelta(); }
282 void AutoLaunchCanceled() override {}
284 void StartSearch() override {
285 base::string16 query;
286 base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query);
287 query = base::i18n::ToLower(query);
289 model_->results()->DeleteAll();
290 if (query.empty())
291 return;
293 for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
294 WindowTypeShelfItem::Type type =
295 static_cast<WindowTypeShelfItem::Type>(i);
297 base::string16 title =
298 base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type));
299 if (base::i18n::StringSearchIgnoringCaseAndAccents(
300 query, title, NULL, NULL)) {
301 model_->results()->Add(new ExampleSearchResult(type, query));
306 void StopSearch() override {
307 // Nothing needs to be done.
310 void ViewInitialized() override {
311 // Nothing needs to be done.
314 void Dismiss() override {
315 DCHECK(ash::Shell::HasInstance());
316 Shell::GetInstance()->DismissAppList();
319 void ViewClosing() override {
320 // Nothing needs to be done.
323 gfx::ImageSkia GetWindowIcon() override { return gfx::ImageSkia(); }
325 void OpenSettings() override {
326 // Nothing needs to be done.
329 void OpenHelp() override {
330 // Nothing needs to be done.
333 void OpenFeedback() override {
334 // Nothing needs to be done.
337 void ToggleSpeechRecognition() override { NOTIMPLEMENTED(); }
339 void ShowForProfileByPath(const base::FilePath& profile_path) override {
340 // Nothing needs to be done.
343 views::View* CreateStartPageWebView(const gfx::Size& size) override {
344 return NULL;
347 std::vector<views::View*> CreateCustomPageWebViews(
348 const gfx::Size& size) override {
349 return std::vector<views::View*>();
352 void CustomLauncherPageAnimationChanged(double progress) override {}
354 void CustomLauncherPagePopSubpage() override {}
356 bool IsSpeechRecognitionEnabled() override { return false; }
358 scoped_ptr<app_list::AppListModel> model_;
359 app_list::SpeechUIModel speech_ui_;
360 Users users_;
362 DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
365 } // namespace
367 app_list::AppListViewDelegate* CreateAppListViewDelegate() {
368 return new ExampleAppListViewDelegate;
371 } // namespace shell
372 } // namespace ash