Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / shell / app_list.cc
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.
4
5 #include <string>
6
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"
32
33 namespace ash {
34 namespace shell {
35
36 namespace {
37
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,
49   };
50
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);
57   }
58
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,
66     };
67
68     const int kIconSize = 128;
69     SkBitmap icon;
70     icon.setConfig(SkBitmap::kARGB_8888_Config, kIconSize, kIconSize);
71     icon.allocPixels();
72     icon.eraseColor(kColors[static_cast<int>(type) % arraysize(kColors)]);
73     return gfx::ImageSkia::CreateFrom1xBitmap(icon);
74   }
75
76   // The text below is not localized as this is an example code.
77   static std::string GetTitle(Type type) {
78     switch (type) {
79       case TOPLEVEL_WINDOW:
80         return "Create Window";
81       case NON_RESIZABLE_WINDOW:
82         return "Create Non-Resizable Window";
83       case LOCK_SCREEN:
84         return "Lock Screen";
85       case WIDGETS_WINDOW:
86         return "Show Example Widgets";
87       case EXAMPLES_WINDOW:
88         return "Open Views Examples Window";
89       default:
90         return "Unknown window type.";
91     }
92   }
93
94   // The text below is not localized as this is an example code.
95   static std::string GetDetails(Type type) {
96     // Assigns details only to some types so that we see both one-line
97     // and two-line results.
98     switch (type) {
99       case WIDGETS_WINDOW:
100         return "Creates a window to show example widgets";
101       case EXAMPLES_WINDOW:
102         return "Creates a window to show views example.";
103       default:
104         return std::string();
105     }
106   }
107
108   static void ActivateItem(Type type, int event_flags) {
109      switch (type) {
110       case TOPLEVEL_WINDOW: {
111         ToplevelWindow::CreateParams params;
112         params.can_resize = true;
113         ToplevelWindow::CreateToplevelWindow(params);
114         break;
115       }
116       case NON_RESIZABLE_WINDOW: {
117         ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
118         break;
119       }
120       case LOCK_SCREEN: {
121         Shell::GetInstance()->session_state_delegate()->LockScreen();
122         break;
123       }
124       case WIDGETS_WINDOW: {
125         CreateWidgetsWindow();
126         break;
127       }
128       case EXAMPLES_WINDOW: {
129         views::examples::ShowExamplesWindowWithContent(
130             views::examples::DO_NOTHING_ON_CLOSE,
131             Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
132             NULL);
133         break;
134       }
135       default:
136         break;
137     }
138   }
139
140   // AppListItem
141   virtual void Activate(int event_flags) OVERRIDE {
142     ActivateItem(type_, event_flags);
143   }
144
145  private:
146   Type type_;
147
148   DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem);
149 };
150
151 // ExampleSearchResult is an app list search result. It provides what icon to
152 // show, what should title and details text look like. It also carries the
153 // matching window launch type so that AppListViewDelegate knows how to open
154 // it.
155 class ExampleSearchResult : public app_list::SearchResult {
156  public:
157   ExampleSearchResult(WindowTypeShelfItem::Type type,
158                       const base::string16& query)
159       : type_(type) {
160     SetIcon(WindowTypeShelfItem::GetIcon(type_));
161
162     base::string16 title =
163         base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_));
164     set_title(title);
165
166     Tags title_tags;
167     const size_t match_len = query.length();
168
169     // Highlight matching parts in title with bold.
170     // Note the following is not a proper way to handle i18n string.
171     title = base::i18n::ToLower(title);
172     size_t match_start = title.find(query);
173     while (match_start != base::string16::npos) {
174       title_tags.push_back(Tag(Tag::MATCH,
175                                match_start,
176                                match_start + match_len));
177       match_start = title.find(query, match_start + match_len);
178     }
179     set_title_tags(title_tags);
180
181     base::string16 details =
182         base::UTF8ToUTF16(WindowTypeShelfItem::GetDetails(type_));
183     set_details(details);
184     Tags details_tags;
185     details_tags.push_back(Tag(Tag::DIM, 0, details.length()));
186     set_details_tags(details_tags);
187   }
188
189   WindowTypeShelfItem::Type type() const { return type_; }
190
191  private:
192   WindowTypeShelfItem::Type type_;
193
194   DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult);
195 };
196
197 class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
198  public:
199   ExampleAppListViewDelegate()
200       : model_(new app_list::AppListModel),
201         speech_ui_(app_list::SPEECH_RECOGNITION_OFF) {
202     PopulateApps();
203     DecorateSearchBox(model_->search_box());
204   }
205
206  private:
207   void PopulateApps() {
208     for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
209       WindowTypeShelfItem::Type type =
210           static_cast<WindowTypeShelfItem::Type>(i);
211       std::string id = base::StringPrintf("%d", i);
212       scoped_ptr<WindowTypeShelfItem> shelf_item(
213           new WindowTypeShelfItem(id, type));
214       model_->AddItem(shelf_item.PassAs<app_list::AppListItem>());
215     }
216   }
217
218   gfx::ImageSkia CreateSearchBoxIcon() {
219     const base::string16 icon_text = base::ASCIIToUTF16("ash");
220     const gfx::Size icon_size(32, 32);
221
222     gfx::Canvas canvas(icon_size, 1.0f, false /* is_opaque */);
223     canvas.DrawStringRectWithFlags(
224         icon_text,
225         gfx::FontList(),
226         SK_ColorBLACK,
227         gfx::Rect(icon_size),
228         gfx::Canvas::TEXT_ALIGN_CENTER | gfx::Canvas::NO_SUBPIXEL_RENDERING);
229
230     return gfx::ImageSkia(canvas.ExtractImageRep());
231   }
232
233   void DecorateSearchBox(app_list::SearchBoxModel* search_box_model) {
234     search_box_model->SetIcon(CreateSearchBoxIcon());
235     search_box_model->SetHintText(base::ASCIIToUTF16("Type to search..."));
236   }
237
238   // Overridden from app_list::AppListViewDelegate:
239   virtual bool ForceNativeDesktop() const OVERRIDE {
240     return false;
241   }
242
243   virtual void SetProfileByPath(const base::FilePath& profile_path) OVERRIDE {
244     // Nothing needs to be done.
245   }
246
247   virtual const Users& GetUsers() const OVERRIDE {
248     return users_;
249   }
250
251   virtual bool ShouldCenterWindow() const OVERRIDE {
252     return false;
253   }
254
255   virtual app_list::AppListModel* GetModel() OVERRIDE { return model_.get(); }
256
257   virtual app_list::SigninDelegate* GetSigninDelegate() OVERRIDE {
258     return NULL;
259   }
260
261   virtual app_list::SpeechUIModel* GetSpeechUI() OVERRIDE {
262     return &speech_ui_;
263   }
264
265   virtual void GetShortcutPathForApp(
266       const std::string& app_id,
267       const base::Callback<void(const base::FilePath&)>& callback) OVERRIDE {
268     callback.Run(base::FilePath());
269   }
270
271   virtual void OpenSearchResult(app_list::SearchResult* result,
272                                 bool auto_launch,
273                                 int event_flags) OVERRIDE {
274     const ExampleSearchResult* example_result =
275         static_cast<const ExampleSearchResult*>(result);
276     WindowTypeShelfItem::ActivateItem(example_result->type(), event_flags);
277   }
278
279   virtual void InvokeSearchResultAction(app_list::SearchResult* result,
280                                         int action_index,
281                                         int event_flags) OVERRIDE {
282     NOTIMPLEMENTED();
283   }
284
285   virtual base::TimeDelta GetAutoLaunchTimeout() OVERRIDE {
286     return base::TimeDelta();
287   }
288
289   virtual void AutoLaunchCanceled() OVERRIDE {
290   }
291
292   virtual void StartSearch() OVERRIDE {
293     base::string16 query;
294     base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query);
295     query = base::i18n::ToLower(query);
296
297     model_->results()->DeleteAll();
298     if (query.empty())
299       return;
300
301     for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
302       WindowTypeShelfItem::Type type =
303           static_cast<WindowTypeShelfItem::Type>(i);
304
305       base::string16 title =
306           base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type));
307       if (base::i18n::StringSearchIgnoringCaseAndAccents(
308               query, title, NULL, NULL)) {
309         model_->results()->Add(new ExampleSearchResult(type, query));
310       }
311     }
312   }
313
314   virtual void StopSearch() OVERRIDE {
315     // Nothing needs to be done.
316   }
317
318   virtual void ViewInitialized() OVERRIDE {
319     // Nothing needs to be done.
320   }
321
322   virtual void Dismiss() OVERRIDE {
323     DCHECK(ash::Shell::HasInstance());
324     if (Shell::GetInstance()->GetAppListTargetVisibility())
325       Shell::GetInstance()->ToggleAppList(NULL);
326   }
327
328   virtual void ViewClosing() OVERRIDE {
329     // Nothing needs to be done.
330   }
331
332   virtual gfx::ImageSkia GetWindowIcon() OVERRIDE {
333     return gfx::ImageSkia();
334   }
335
336   virtual void OpenSettings() OVERRIDE {
337     // Nothing needs to be done.
338   }
339
340   virtual void OpenHelp() OVERRIDE {
341     // Nothing needs to be done.
342   }
343
344   virtual void OpenFeedback() OVERRIDE {
345     // Nothing needs to be done.
346   }
347
348   virtual void ToggleSpeechRecognition() OVERRIDE {
349     NOTIMPLEMENTED();
350   }
351
352   virtual void ShowForProfileByPath(
353       const base::FilePath& profile_path) OVERRIDE {
354     // Nothing needs to be done.
355   }
356
357   virtual content::WebContents* GetStartPageContents() OVERRIDE {
358     return NULL;
359   }
360
361   virtual content::WebContents* GetSpeechRecognitionContents() OVERRIDE {
362     return NULL;
363   }
364
365   scoped_ptr<app_list::AppListModel> model_;
366   app_list::SpeechUIModel speech_ui_;
367   Users users_;
368
369   DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
370 };
371
372 }  // namespace
373
374 app_list::AppListViewDelegate* CreateAppListViewDelegate() {
375   return new ExampleAppListViewDelegate;
376 }
377
378 }  // namespace shell
379 }  // namespace ash