Update To 11.40.268.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 #include <vector>
7
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_util.h"
19 #include "base/strings/stringprintf.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"
33
34 namespace ash {
35 namespace shell {
36
37 namespace {
38
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,
50   };
51
52   WindowTypeShelfItem(const std::string& id, Type type);
53   ~WindowTypeShelfItem() override;
54
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,
62     };
63
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);
69   }
70
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.";
86     }
87   }
88
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();
100     }
101   }
102
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;
110       }
111       case NON_RESIZABLE_WINDOW: {
112         ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
113         break;
114       }
115       case LOCK_SCREEN: {
116         Shell::GetInstance()->session_state_delegate()->LockScreen();
117         break;
118       }
119       case WIDGETS_WINDOW: {
120         CreateWidgetsWindow();
121         break;
122       }
123       case EXAMPLES_WINDOW: {
124         views::examples::ShowExamplesWindowWithContent(
125             views::examples::DO_NOTHING_ON_CLOSE,
126             Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
127             NULL);
128         break;
129       }
130       default:
131         break;
132     }
133   }
134
135   // AppListItem
136   void Activate(int event_flags) override { ActivateItem(type_, event_flags); }
137
138  private:
139   Type type_;
140
141   DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem);
142 };
143
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), false);
148   SetName(title);
149 }
150
151 WindowTypeShelfItem::~WindowTypeShelfItem() {
152 }
153
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_));
164
165     base::string16 title =
166         base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_));
167     set_title(title);
168
169     Tags title_tags;
170     const size_t match_len = query.length();
171
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);
181     }
182     set_title_tags(title_tags);
183
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);
190   }
191
192   WindowTypeShelfItem::Type type() const { return type_; }
193
194   // app_list::SearchResult:
195   scoped_ptr<SearchResult> Duplicate() override {
196     return scoped_ptr<SearchResult>();
197   }
198
199  private:
200   WindowTypeShelfItem::Type type_;
201
202   DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult);
203 };
204
205 class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
206  public:
207   ExampleAppListViewDelegate()
208       : model_(new app_list::AppListModel) {
209     PopulateApps();
210     DecorateSearchBox(model_->search_box());
211   }
212
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::StringPrintf("%d", i);
219       scoped_ptr<WindowTypeShelfItem> shelf_item(
220           new WindowTypeShelfItem(id, type));
221       model_->AddItem(shelf_item.Pass());
222     }
223   }
224
225   gfx::ImageSkia CreateSearchBoxIcon() {
226     const base::string16 icon_text = base::ASCIIToUTF16("ash");
227     const gfx::Size icon_size(32, 32);
228
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);
236
237     return gfx::ImageSkia(canvas.ExtractImageRep());
238   }
239
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..."));
243   }
244
245   // Overridden from app_list::AppListViewDelegate:
246   bool ForceNativeDesktop() const override { return false; }
247
248   void SetProfileByPath(const base::FilePath& profile_path) override {
249     // Nothing needs to be done.
250   }
251
252   const Users& GetUsers() const override { return users_; }
253
254   bool ShouldCenterWindow() const override { return false; }
255
256   app_list::AppListModel* GetModel() override { return model_.get(); }
257
258   app_list::SpeechUIModel* GetSpeechUI() override { return &speech_ui_; }
259
260   void GetShortcutPathForApp(
261       const std::string& app_id,
262       const base::Callback<void(const base::FilePath&)>& callback) override {
263     callback.Run(base::FilePath());
264   }
265
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);
272   }
273
274   void InvokeSearchResultAction(app_list::SearchResult* result,
275                                 int action_index,
276                                 int event_flags) override {
277     NOTIMPLEMENTED();
278   }
279
280   base::TimeDelta GetAutoLaunchTimeout() override { return base::TimeDelta(); }
281
282   void AutoLaunchCanceled() override {}
283
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);
288
289     model_->results()->DeleteAll();
290     if (query.empty())
291       return;
292
293     for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) {
294       WindowTypeShelfItem::Type type =
295           static_cast<WindowTypeShelfItem::Type>(i);
296
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));
302       }
303     }
304   }
305
306   void StopSearch() override {
307     // Nothing needs to be done.
308   }
309
310   void ViewInitialized() override {
311     // Nothing needs to be done.
312   }
313
314   void Dismiss() override {
315     DCHECK(ash::Shell::HasInstance());
316     Shell::GetInstance()->DismissAppList();
317   }
318
319   void ViewClosing() override {
320     // Nothing needs to be done.
321   }
322
323   gfx::ImageSkia GetWindowIcon() override { return gfx::ImageSkia(); }
324
325   void OpenSettings() override {
326     // Nothing needs to be done.
327   }
328
329   void OpenHelp() override {
330     // Nothing needs to be done.
331   }
332
333   void OpenFeedback() override {
334     // Nothing needs to be done.
335   }
336
337   void ToggleSpeechRecognition() override { NOTIMPLEMENTED(); }
338
339   void ShowForProfileByPath(const base::FilePath& profile_path) override {
340     // Nothing needs to be done.
341   }
342
343   views::View* CreateStartPageWebView(const gfx::Size& size) override {
344     return NULL;
345   }
346
347   std::vector<views::View*> CreateCustomPageWebViews(
348       const gfx::Size& size) override {
349     return std::vector<views::View*>();
350   }
351
352   bool IsSpeechRecognitionEnabled() override { return false; }
353
354   scoped_ptr<app_list::AppListModel> model_;
355   app_list::SpeechUIModel speech_ui_;
356   Users users_;
357
358   DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
359 };
360
361 }  // namespace
362
363 app_list::AppListViewDelegate* CreateAppListViewDelegate() {
364   return new ExampleAppListViewDelegate;
365 }
366
367 }  // namespace shell
368 }  // namespace ash