Probably broke Win7 Tests (dbg)(6). http://build.chromium.org/p/chromium.win/builders...
[chromium-blink-merge.git] / ash / shell / app_list.cc
blobf8351532d384a5956fc608cf62d1eb18c02fc8d1
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>
7 #include "ash/session/session_state_delegate.h"
8 #include "ash/shell.h"
9 #include "ash/shell/example_factory.h"
10 #include "ash/shell/toplevel_window.h"
11 #include "ash/shell_delegate.h"
12 #include "base/basictypes.h"
13 #include "base/callback.h"
14 #include "base/files/file_path.h"
15 #include "base/i18n/case_conversion.h"
16 #include "base/i18n/string_search.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "ui/app_list/app_list_item.h"
21 #include "ui/app_list/app_list_item_list.h"
22 #include "ui/app_list/app_list_model.h"
23 #include "ui/app_list/app_list_view_delegate.h"
24 #include "ui/app_list/search_box_model.h"
25 #include "ui/app_list/search_result.h"
26 #include "ui/app_list/speech_ui_model.h"
27 #include "ui/gfx/canvas.h"
28 #include "ui/gfx/font_list.h"
29 #include "ui/gfx/geometry/rect.h"
30 #include "ui/gfx/image/image_skia.h"
31 #include "ui/views/examples/examples_window_with_content.h"
33 namespace ash {
34 namespace shell {
36 namespace {
38 // WindowTypeShelfItem is an app item of app list. It carries a window
39 // launch type and launches corresponding example window when activated.
40 class WindowTypeShelfItem : public app_list::AppListItem {
41 public:
42 enum Type {
43 TOPLEVEL_WINDOW = 0,
44 NON_RESIZABLE_WINDOW,
45 LOCK_SCREEN,
46 WIDGETS_WINDOW,
47 EXAMPLES_WINDOW,
48 LAST_TYPE,
51 explicit WindowTypeShelfItem(const std::string& id, Type type)
52 : app_list::AppListItem(id),
53 type_(type) {
54 std::string title(GetTitle(type));
55 SetIcon(GetIcon(type), false);
56 SetName(title);
59 static gfx::ImageSkia GetIcon(Type type) {
60 static const SkColor kColors[] = {
61 SK_ColorRED,
62 SK_ColorGREEN,
63 SK_ColorBLUE,
64 SK_ColorYELLOW,
65 SK_ColorCYAN,
68 const int kIconSize = 128;
69 SkBitmap icon;
70 icon.allocN32Pixels(kIconSize, kIconSize);
71 icon.eraseColor(kColors[static_cast<int>(type) % arraysize(kColors)]);
72 return gfx::ImageSkia::CreateFrom1xBitmap(icon);
75 // The text below is not localized as this is an example code.
76 static std::string GetTitle(Type type) {
77 switch (type) {
78 case TOPLEVEL_WINDOW:
79 return "Create Window";
80 case NON_RESIZABLE_WINDOW:
81 return "Create Non-Resizable Window";
82 case LOCK_SCREEN:
83 return "Lock Screen";
84 case WIDGETS_WINDOW:
85 return "Show Example Widgets";
86 case EXAMPLES_WINDOW:
87 return "Open Views Examples Window";
88 default:
89 return "Unknown window type.";
93 // The text below is not localized as this is an example code.
94 static std::string GetDetails(Type type) {
95 // Assigns details only to some types so that we see both one-line
96 // and two-line results.
97 switch (type) {
98 case WIDGETS_WINDOW:
99 return "Creates a window to show example widgets";
100 case EXAMPLES_WINDOW:
101 return "Creates a window to show views example.";
102 default:
103 return std::string();
107 static void ActivateItem(Type type, int event_flags) {
108 switch (type) {
109 case TOPLEVEL_WINDOW: {
110 ToplevelWindow::CreateParams params;
111 params.can_resize = true;
112 ToplevelWindow::CreateToplevelWindow(params);
113 break;
115 case NON_RESIZABLE_WINDOW: {
116 ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
117 break;
119 case LOCK_SCREEN: {
120 Shell::GetInstance()->session_state_delegate()->LockScreen();
121 break;
123 case WIDGETS_WINDOW: {
124 CreateWidgetsWindow();
125 break;
127 case EXAMPLES_WINDOW: {
128 views::examples::ShowExamplesWindowWithContent(
129 views::examples::DO_NOTHING_ON_CLOSE,
130 Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
131 NULL);
132 break;
134 default:
135 break;
139 // AppListItem
140 virtual void Activate(int event_flags) OVERRIDE {
141 ActivateItem(type_, event_flags);
144 private:
145 Type type_;
147 DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem);
150 // ExampleSearchResult is an app list search result. It provides what icon to
151 // show, what should title and details text look like. It also carries the
152 // matching window launch type so that AppListViewDelegate knows how to open
153 // it.
154 class ExampleSearchResult : public app_list::SearchResult {
155 public:
156 ExampleSearchResult(WindowTypeShelfItem::Type type,
157 const base::string16& query)
158 : type_(type) {
159 SetIcon(WindowTypeShelfItem::GetIcon(type_));
161 base::string16 title =
162 base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_));
163 set_title(title);
165 Tags title_tags;
166 const size_t match_len = query.length();
168 // Highlight matching parts in title with bold.
169 // Note the following is not a proper way to handle i18n string.
170 title = base::i18n::ToLower(title);
171 size_t match_start = title.find(query);
172 while (match_start != base::string16::npos) {
173 title_tags.push_back(Tag(Tag::MATCH,
174 match_start,
175 match_start + match_len));
176 match_start = title.find(query, match_start + match_len);
178 set_title_tags(title_tags);
180 base::string16 details =
181 base::UTF8ToUTF16(WindowTypeShelfItem::GetDetails(type_));
182 set_details(details);
183 Tags details_tags;
184 details_tags.push_back(Tag(Tag::DIM, 0, details.length()));
185 set_details_tags(details_tags);
188 WindowTypeShelfItem::Type type() const { return type_; }
190 private:
191 WindowTypeShelfItem::Type type_;
193 DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult);
196 class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
197 public:
198 ExampleAppListViewDelegate()
199 : model_(new app_list::AppListModel),
200 speech_ui_(app_list::SPEECH_RECOGNITION_OFF) {
201 PopulateApps();
202 DecorateSearchBox(model_->search_box());
205 private:
206 void PopulateApps() {
207 for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
208 WindowTypeShelfItem::Type type =
209 static_cast<WindowTypeShelfItem::Type>(i);
210 std::string id = base::StringPrintf("%d", i);
211 scoped_ptr<WindowTypeShelfItem> shelf_item(
212 new WindowTypeShelfItem(id, type));
213 model_->AddItem(shelf_item.PassAs<app_list::AppListItem>());
217 gfx::ImageSkia CreateSearchBoxIcon() {
218 const base::string16 icon_text = base::ASCIIToUTF16("ash");
219 const gfx::Size icon_size(32, 32);
221 gfx::Canvas canvas(icon_size, 1.0f, false /* is_opaque */);
222 canvas.DrawStringRectWithFlags(
223 icon_text,
224 gfx::FontList(),
225 SK_ColorBLACK,
226 gfx::Rect(icon_size),
227 gfx::Canvas::TEXT_ALIGN_CENTER | gfx::Canvas::NO_SUBPIXEL_RENDERING);
229 return gfx::ImageSkia(canvas.ExtractImageRep());
232 void DecorateSearchBox(app_list::SearchBoxModel* search_box_model) {
233 search_box_model->SetIcon(CreateSearchBoxIcon());
234 search_box_model->SetHintText(base::ASCIIToUTF16("Type to search..."));
237 // Overridden from app_list::AppListViewDelegate:
238 virtual bool ForceNativeDesktop() const OVERRIDE {
239 return false;
242 virtual void SetProfileByPath(const base::FilePath& profile_path) OVERRIDE {
243 // Nothing needs to be done.
246 virtual const Users& GetUsers() const OVERRIDE {
247 return users_;
250 virtual bool ShouldCenterWindow() const OVERRIDE {
251 return false;
254 virtual app_list::AppListModel* GetModel() OVERRIDE { return model_.get(); }
256 virtual app_list::SpeechUIModel* GetSpeechUI() OVERRIDE {
257 return &speech_ui_;
260 virtual void GetShortcutPathForApp(
261 const std::string& app_id,
262 const base::Callback<void(const base::FilePath&)>& callback) OVERRIDE {
263 callback.Run(base::FilePath());
266 virtual 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 virtual void InvokeSearchResultAction(app_list::SearchResult* result,
275 int action_index,
276 int event_flags) OVERRIDE {
277 NOTIMPLEMENTED();
280 virtual base::TimeDelta GetAutoLaunchTimeout() OVERRIDE {
281 return base::TimeDelta();
284 virtual void AutoLaunchCanceled() OVERRIDE {
287 virtual void StartSearch() OVERRIDE {
288 base::string16 query;
289 base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query);
290 query = base::i18n::ToLower(query);
292 model_->results()->DeleteAll();
293 if (query.empty())
294 return;
296 for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
297 WindowTypeShelfItem::Type type =
298 static_cast<WindowTypeShelfItem::Type>(i);
300 base::string16 title =
301 base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type));
302 if (base::i18n::StringSearchIgnoringCaseAndAccents(
303 query, title, NULL, NULL)) {
304 model_->results()->Add(new ExampleSearchResult(type, query));
309 virtual void StopSearch() OVERRIDE {
310 // Nothing needs to be done.
313 virtual void ViewInitialized() OVERRIDE {
314 // Nothing needs to be done.
317 virtual void Dismiss() OVERRIDE {
318 DCHECK(ash::Shell::HasInstance());
319 if (Shell::GetInstance()->GetAppListTargetVisibility())
320 Shell::GetInstance()->ToggleAppList(NULL);
323 virtual void ViewClosing() OVERRIDE {
324 // Nothing needs to be done.
327 virtual gfx::ImageSkia GetWindowIcon() OVERRIDE {
328 return gfx::ImageSkia();
331 virtual void OpenSettings() OVERRIDE {
332 // Nothing needs to be done.
335 virtual void OpenHelp() OVERRIDE {
336 // Nothing needs to be done.
339 virtual void OpenFeedback() OVERRIDE {
340 // Nothing needs to be done.
343 virtual void ToggleSpeechRecognition() OVERRIDE {
344 NOTIMPLEMENTED();
347 virtual void ShowForProfileByPath(
348 const base::FilePath& profile_path) OVERRIDE {
349 // Nothing needs to be done.
352 virtual views::View* CreateStartPageWebView(const gfx::Size& size) OVERRIDE {
353 return NULL;
356 virtual views::View* CreateCustomPageWebView(const gfx::Size& size) OVERRIDE {
357 return NULL;
360 virtual bool IsSpeechRecognitionEnabled() OVERRIDE {
361 return false;
364 scoped_ptr<app_list::AppListModel> model_;
365 app_list::SpeechUIModel speech_ui_;
366 Users users_;
368 DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
371 } // namespace
373 app_list::AppListViewDelegate* CreateAppListViewDelegate() {
374 return new ExampleAppListViewDelegate;
377 } // namespace shell
378 } // namespace ash