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.
7 #include "ash/session_state_delegate.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.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/gfx/rect.h"
31 #include "ui/views/examples/examples_window_with_content.h"
38 // WindowTypeLauncherItem is an app item of app list. It carries a window
39 // launch type and launches corresponding example window when activated.
40 class WindowTypeLauncherItem
: public app_list::AppListItem
{
51 explicit WindowTypeLauncherItem(const std::string
& id
, Type type
)
52 : app_list::AppListItem(id
),
54 std::string
title(GetTitle(type
));
55 SetIcon(GetIcon(type
), false);
56 SetTitleAndFullName(title
, title
);
59 static gfx::ImageSkia
GetIcon(Type type
) {
60 static const SkColor kColors
[] = {
68 const int kIconSize
= 128;
70 icon
.setConfig(SkBitmap::kARGB_8888_Config
, kIconSize
, kIconSize
);
72 icon
.eraseColor(kColors
[static_cast<int>(type
) % arraysize(kColors
)]);
73 return gfx::ImageSkia::CreateFrom1xBitmap(icon
);
76 // The text below is not localized as this is an example code.
77 static std::string
GetTitle(Type type
) {
80 return "Create Window";
81 case NON_RESIZABLE_WINDOW
:
82 return "Create Non-Resizable Window";
86 return "Show Example Widgets";
88 return "Open Views Examples Window";
90 return "Unknown window type.";
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.
100 return "Creates a window to show example widgets";
101 case EXAMPLES_WINDOW
:
102 return "Creates a window to show views example.";
104 return std::string();
108 static void ActivateItem(Type type
, int event_flags
) {
110 case TOPLEVEL_WINDOW
: {
111 ToplevelWindow::CreateParams params
;
112 params
.can_resize
= true;
113 ToplevelWindow::CreateToplevelWindow(params
);
116 case NON_RESIZABLE_WINDOW
: {
117 ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
121 Shell::GetInstance()->session_state_delegate()->LockScreen();
124 case WIDGETS_WINDOW
: {
125 CreateWidgetsWindow();
128 case EXAMPLES_WINDOW
: {
129 views::examples::ShowExamplesWindowWithContent(
130 views::examples::DO_NOTHING_ON_CLOSE
,
131 Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
141 virtual void Activate(int event_flags
) OVERRIDE
{
142 ActivateItem(type_
, event_flags
);
148 DISALLOW_COPY_AND_ASSIGN(WindowTypeLauncherItem
);
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
155 class ExampleSearchResult
: public app_list::SearchResult
{
157 ExampleSearchResult(WindowTypeLauncherItem::Type type
,
158 const base::string16
& query
)
160 SetIcon(WindowTypeLauncherItem::GetIcon(type_
));
162 base::string16 title
=
163 base::UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type_
));
167 const size_t match_len
= query
.length();
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
,
176 match_start
+ match_len
));
177 match_start
= title
.find(query
, match_start
+ match_len
);
179 set_title_tags(title_tags
);
181 base::string16 details
=
182 base::UTF8ToUTF16(WindowTypeLauncherItem::GetDetails(type_
));
183 set_details(details
);
185 details_tags
.push_back(Tag(Tag::DIM
, 0, details
.length()));
186 set_details_tags(details_tags
);
189 WindowTypeLauncherItem::Type
type() const { return type_
; }
192 WindowTypeLauncherItem::Type type_
;
194 DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult
);
197 class ExampleAppListViewDelegate
: public app_list::AppListViewDelegate
{
199 ExampleAppListViewDelegate()
200 : model_(new app_list::AppListModel
) {
201 PopulateApps(model_
->item_list());
202 DecorateSearchBox(model_
->search_box());
206 void PopulateApps(app_list::AppListItemList
* item_list
) {
208 i
< static_cast<int>(WindowTypeLauncherItem::LAST_TYPE
);
210 WindowTypeLauncherItem::Type type
=
211 static_cast<WindowTypeLauncherItem::Type
>(i
);
212 std::string id
= base::StringPrintf("%d", i
);
213 item_list
->AddItem(new WindowTypeLauncherItem(id
, type
));
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
.DrawStringInt(icon_text
,
225 0, 0, icon_size
.width(), icon_size
.height(),
226 gfx::Canvas::TEXT_ALIGN_CENTER
|
227 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
{
242 virtual void SetProfileByPath(const base::FilePath
& profile_path
) OVERRIDE
{
243 // Nothing needs to be done.
246 virtual const Users
& GetUsers() const OVERRIDE
{
250 virtual app_list::AppListModel
* GetModel() OVERRIDE
{ return model_
.get(); }
252 virtual app_list::SigninDelegate
* GetSigninDelegate() OVERRIDE
{
256 virtual app_list::SpeechUIModel
* GetSpeechUI() OVERRIDE
{
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 int event_flags
) OVERRIDE
{
268 const ExampleSearchResult
* example_result
=
269 static_cast<const ExampleSearchResult
*>(result
);
270 WindowTypeLauncherItem::ActivateItem(example_result
->type(), event_flags
);
273 virtual void InvokeSearchResultAction(app_list::SearchResult
* result
,
275 int event_flags
) OVERRIDE
{
279 virtual base::TimeDelta
GetAutoLaunchTimeout() OVERRIDE
{
280 return base::TimeDelta();
283 virtual void AutoLaunchCanceled() OVERRIDE
{
286 virtual void StartSearch() OVERRIDE
{
287 base::string16 query
;
288 TrimWhitespace(model_
->search_box()->text(), TRIM_ALL
, &query
);
289 query
= base::i18n::ToLower(query
);
291 model_
->results()->DeleteAll();
296 i
< static_cast<int>(WindowTypeLauncherItem::LAST_TYPE
);
298 WindowTypeLauncherItem::Type type
=
299 static_cast<WindowTypeLauncherItem::Type
>(i
);
301 base::string16 title
=
302 base::UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type
));
303 if (base::i18n::StringSearchIgnoringCaseAndAccents(
304 query
, title
, NULL
, NULL
)) {
305 model_
->results()->Add(new ExampleSearchResult(type
, query
));
310 virtual void StopSearch() OVERRIDE
{
311 // Nothing needs to be done.
314 virtual void ViewInitialized() OVERRIDE
{
315 // Nothing needs to be done.
318 virtual void Dismiss() OVERRIDE
{
319 DCHECK(ash::Shell::HasInstance());
320 if (Shell::GetInstance()->GetAppListTargetVisibility())
321 Shell::GetInstance()->ToggleAppList(NULL
);
324 virtual void ViewClosing() OVERRIDE
{
325 // Nothing needs to be done.
328 virtual gfx::ImageSkia
GetWindowIcon() OVERRIDE
{
329 return gfx::ImageSkia();
332 virtual void OpenSettings() OVERRIDE
{
333 // Nothing needs to be done.
336 virtual void OpenHelp() OVERRIDE
{
337 // Nothing needs to be done.
340 virtual void OpenFeedback() OVERRIDE
{
341 // Nothing needs to be done.
344 virtual void ToggleSpeechRecognition() OVERRIDE
{
348 virtual void ShowForProfileByPath(
349 const base::FilePath
& profile_path
) OVERRIDE
{
350 // Nothing needs to be done.
353 virtual content::WebContents
* GetStartPageContents() OVERRIDE
{
357 virtual content::WebContents
* GetSpeechRecognitionContents() OVERRIDE
{
361 scoped_ptr
<app_list::AppListModel
> model_
;
362 app_list::SpeechUIModel speech_ui_
;
365 DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate
);
370 app_list::AppListViewDelegate
* CreateAppListViewDelegate() {
371 return new ExampleAppListViewDelegate
;