| Index: ash/shell/app_list.cc
|
| diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
|
| index 383a45075544730f4f5e2ac1cad503fdfcd2fcc0..b9d117498f4fb36a5a68039d466182671b6fbb7c 100644
|
| --- a/ash/shell/app_list.cc
|
| +++ b/ash/shell/app_list.cc
|
| @@ -2,14 +2,25 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <string>
|
| +
|
| #include "ash/shell.h"
|
| #include "ash/shell_delegate.h"
|
| #include "ash/shell/example_factory.h"
|
| #include "ash/shell/toplevel_window.h"
|
| #include "base/basictypes.h"
|
| +#include "base/i18n/case_conversion.h"
|
| +#include "base/i18n/string_search.h"
|
| +#include "base/string_util.h"
|
| +#include "base/utf_string_conversions.h"
|
| #include "ui/app_list/app_list_item_model.h"
|
| #include "ui/app_list/app_list_model.h"
|
| #include "ui/app_list/app_list_view_delegate.h"
|
| +#include "ui/app_list/search_box_model.h"
|
| +#include "ui/app_list/search_result.h"
|
| +#include "ui/gfx/canvas.h"
|
| +#include "ui/gfx/font.h"
|
| +#include "ui/gfx/rect.h"
|
| #include "ui/views/examples/examples_window.h"
|
|
|
| namespace ash {
|
| @@ -17,6 +28,8 @@ namespace shell {
|
|
|
| namespace {
|
|
|
| +// WindowTypeLauncherItem is an app item of app list. It carries a window
|
| +// launch type and launches corresponding example window when activated.
|
| class WindowTypeLauncherItem : public app_list::AppListItemModel {
|
| public:
|
| enum Type {
|
| @@ -50,6 +63,7 @@ class WindowTypeLauncherItem : public app_list::AppListItemModel {
|
| return icon;
|
| }
|
|
|
| + // The text below is not localized as this is an example code.
|
| static std::string GetTitle(Type type) {
|
| switch (type) {
|
| case TOPLEVEL_WINDOW:
|
| @@ -67,8 +81,22 @@ class WindowTypeLauncherItem : public app_list::AppListItemModel {
|
| }
|
| }
|
|
|
| - void Activate(int event_flags) {
|
| - switch (type_) {
|
| + // The text below is not localized as this is an example code.
|
| + static std::string GetDetails(Type type) {
|
| + // Assigns details only to some types so that we see both one-line
|
| + // and two-line results.
|
| + switch (type) {
|
| + case WIDGETS_WINDOW:
|
| + return "Creates a window to show example widgets";
|
| + case EXAMPLES_WINDOW:
|
| + return "Creates a window to show views example.";
|
| + default:
|
| + return std::string();
|
| + }
|
| + }
|
| +
|
| + static void Activate(Type type, int event_flags) {
|
| + switch (type) {
|
| case TOPLEVEL_WINDOW: {
|
| ToplevelWindow::CreateParams params;
|
| params.can_resize = true;
|
| @@ -100,24 +128,125 @@ class WindowTypeLauncherItem : public app_list::AppListItemModel {
|
| }
|
| }
|
|
|
| + void Activate(int event_flags) {
|
| + Activate(type_, event_flags);
|
| + }
|
| +
|
| private:
|
| Type type_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(WindowTypeLauncherItem);
|
| };
|
|
|
| +// ExampleSearchResult is an app list search result. It provides what icon to
|
| +// show, what should title and details text look like. It also carries the
|
| +// matching window launch type so that AppListViewDelegate knows how to open
|
| +// it.
|
| +class ExampleSearchResult : public app_list::SearchResult {
|
| + public:
|
| + ExampleSearchResult(WindowTypeLauncherItem::Type type,
|
| + const string16& query)
|
| + : type_(type) {
|
| + set_icon(WindowTypeLauncherItem::GetIcon(type_));
|
| +
|
| + string16 title = UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type_));
|
| + set_title(title);
|
| +
|
| + Tags title_tags;
|
| + const size_t match_len = query.length();
|
| +
|
| + // Highlight matching parts in title with bold.
|
| + // Note the following is not a proper way to handle i18n string.
|
| + title = base::i18n::ToLower(title);
|
| + size_t match_start = title.find(query);
|
| + while (match_start != string16::npos) {
|
| + title_tags.push_back(Tag(Tag::MATCH,
|
| + match_start,
|
| + match_start + match_len));
|
| + match_start = title.find(query, match_start + match_len);
|
| + }
|
| + set_title_tags(title_tags);
|
| +
|
| + string16 details = UTF8ToUTF16(WindowTypeLauncherItem::GetDetails(type_));
|
| + set_details(details);
|
| + Tags details_tags;
|
| + details_tags.push_back(Tag(Tag::DIM, 0, details.length()));
|
| + set_details_tags(details_tags);
|
| + }
|
| +
|
| + WindowTypeLauncherItem::Type type() const { return type_; }
|
| +
|
| + private:
|
| + WindowTypeLauncherItem::Type type_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult);
|
| +};
|
| +
|
| class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
|
| public:
|
| ExampleAppListViewDelegate() : model_(NULL) {}
|
|
|
| private:
|
| + void PopulateApps(app_list::AppListModel::Apps* apps) {
|
| + for (int i = 0;
|
| + i < static_cast<int>(WindowTypeLauncherItem::LAST_TYPE);
|
| + ++i) {
|
| + WindowTypeLauncherItem::Type type =
|
| + static_cast<WindowTypeLauncherItem::Type>(i);
|
| +
|
| + std::string title = WindowTypeLauncherItem::GetTitle(type);
|
| + apps->Add(new WindowTypeLauncherItem(type));
|
| + }
|
| + }
|
| +
|
| + SkBitmap CreateSearchBoxIcon() {
|
| + const string16 icon_text = ASCIIToUTF16("ash");
|
| + const gfx::Size icon_size(32, 32);
|
| +
|
| + gfx::Canvas canvas(icon_size, false /* is_opaque */);
|
| + canvas.DrawStringInt(icon_text,
|
| + gfx::Font(),
|
| + SK_ColorBLACK,
|
| + 0, 0, icon_size.width(), icon_size.height(),
|
| + gfx::Canvas::TEXT_ALIGN_CENTER |
|
| + gfx::Canvas::TEXT_VALIGN_MIDDLE |
|
| + gfx::Canvas::NO_SUBPIXEL_RENDERING);
|
| +
|
| + return canvas.ExtractBitmap();
|
| + }
|
| +
|
| + void DecorateSearchBox(app_list::SearchBoxModel* search_box_model) {
|
| + search_box_model->SetIcon(CreateSearchBoxIcon());
|
| + search_box_model->SetHintText(ASCIIToUTF16("Type to search..."));
|
| + }
|
| +
|
| // Overridden from ash::AppListViewDelegate:
|
| virtual void SetModel(app_list::AppListModel* model) OVERRIDE {
|
| model_ = model;
|
| + PopulateApps(model_->apps());
|
| + DecorateSearchBox(model_->search_box());
|
| + }
|
| +
|
| + virtual void ActivateAppListItem(app_list::AppListItemModel* item,
|
| + int event_flags) OVERRIDE {
|
| + static_cast<WindowTypeLauncherItem*>(item)->Activate(event_flags);
|
| + }
|
| +
|
| + virtual void OpenSearchResult(const app_list::SearchResult& result,
|
| + int event_flags) OVERRIDE {
|
| + const ExampleSearchResult* example_result =
|
| + static_cast<const ExampleSearchResult*>(&result);
|
| + WindowTypeLauncherItem::Activate(example_result->type(), event_flags);
|
| }
|
|
|
| - virtual void UpdateModel(const std::string& query) OVERRIDE {
|
| - DCHECK(model_ && model_->item_count() == 0);
|
| + virtual void StartSearch() OVERRIDE {
|
| + string16 query;
|
| + TrimWhitespace(model_->search_box()->text(), TRIM_ALL, &query);
|
| + query = base::i18n::ToLower(query);
|
| +
|
| + model_->results()->DeleteAll();
|
| + if (query.empty())
|
| + return;
|
|
|
| for (int i = 0;
|
| i < static_cast<int>(WindowTypeLauncherItem::LAST_TYPE);
|
| @@ -125,15 +254,14 @@ class ExampleAppListViewDelegate : public app_list::AppListViewDelegate {
|
| WindowTypeLauncherItem::Type type =
|
| static_cast<WindowTypeLauncherItem::Type>(i);
|
|
|
| - std::string title = WindowTypeLauncherItem::GetTitle(type);
|
| - if (title.find(query) != std::string::npos)
|
| - model_->AddItem(new WindowTypeLauncherItem(type));
|
| + string16 title = UTF8ToUTF16(WindowTypeLauncherItem::GetTitle(type));
|
| + if (base::i18n::StringSearchIgnoringCaseAndAccents(query, title))
|
| + model_->results()->Add(new ExampleSearchResult(type, query));
|
| }
|
| }
|
|
|
| - virtual void OnAppListItemActivated(app_list::AppListItemModel* item,
|
| - int event_flags) OVERRIDE {
|
| - static_cast<WindowTypeLauncherItem*>(item)->Activate(event_flags);
|
| + virtual void StopSearch() OVERRIDE {
|
| + // Nothing needs to be done.
|
| }
|
|
|
| virtual void Close() OVERRIDE {
|
|
|