summaryrefslogtreecommitdiffstats
path: root/ash/shell/app_list.cc
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 00:16:17 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 00:16:17 +0000
commitef59e6c4064973e58c923fbcfb51e68911cff8d8 (patch)
tree74b264a7a69765dc3c9b716b4f4b969612ec63e8 /ash/shell/app_list.cc
parent38ddaff588d764ac6a92ec1e8b6766732ba92efd (diff)
downloadchromium_src-ef59e6c4064973e58c923fbcfb51e68911cff8d8.zip
chromium_src-ef59e6c4064973e58c923fbcfb51e68911cff8d8.tar.gz
chromium_src-ef59e6c4064973e58c923fbcfb51e68911cff8d8.tar.bz2
app_list: Add search box and search result view for v2.
- Add a SearchBoxModel that represents search box's icon, placeholder text, user typed text and selection model (current selection and cursor position); - Add a SearchBoxView that displays SearchBoxModel and observes SearchBoxModel changes via SearchBoxModelObserver; When user typed/changed text in search box, the view also fires query changed notification to its SearchBoxViewDelegate; - Add a SearchResult that carries an icon, two tagged texts; - Add a SearchResultView that displays a SearchResult; - Change AppListModel to be a master model that has three sub models: apps list, search box and search results; - Add a SearchResultListView that display search results sub model of AppListModel using a list of SeachResultView; The view supports up/down key navigation and when user selects a result via mouse click or enter key, it asks its SearchResultListViewDelegate to OpenResult; - Update AppListViewDelegate: - Add new methods: StartSearch, StopSearch and OpenResult; - Deleted no-longer needed UpdateModel method; - Rename OnAppListItemActivated -> ActivateAppListItem; - Update ash_shell's app_list to support a simple substr match search; - Add a SearchBuilder that implements the search via AutoCompleteController; - Other changes: - Rename AppListModelBuilder -> AppsModelBuilder; - Rename AppListModelView -> AppsGridView; BUG=125964 TEST=Manual. In ash_shell, it searches the 5 example apps. In ash/chrome, it should show similar results as omnibox. Review URL: https://chromiumcodereview.appspot.com/10386224 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138938 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/shell/app_list.cc')
-rw-r--r--ash/shell/app_list.cc148
1 files changed, 138 insertions, 10 deletions
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index 383a450..b9d1174 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 {