summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-02 16:12:40 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-02 16:12:40 +0000
commit41247fdcdeceecef93a0f04f2240abf0e4b4e283 (patch)
tree915ef725b646d7bb57357c60da5a0407573cfefb /ash
parentf656805bcc1e3996d3f6fccaa385ea2438d70003 (diff)
downloadchromium_src-41247fdcdeceecef93a0f04f2240abf0e4b4e283.zip
chromium_src-41247fdcdeceecef93a0f04f2240abf0e4b4e283.tar.gz
chromium_src-41247fdcdeceecef93a0f04f2240abf0e4b4e283.tar.bz2
aura: Implement app list M19 mock.
- Make AppListModel flat, i.e. remove AppListItemGroupModel and its view; - Move BuildAppListModel from ShellDelegate into AppListViewDelegate; - Make AppListModelBuilder ready to support simple query; - Make AppListItemView based on CustomButton and get rid of its listener interface since we can use ButtonListener for that now; - Update UI based on M19 mock: - AppListItemView show label on its right instead of bottom; - AppListItemView has a mouse hover effect now; - AppListModelView show AppListItemView tiles alphabetically from top to bottom instead of from left to right; - AppListView to occupy full screen include area behind the launcher; - AppListView to have a 0.4 black shade; BUG=98308 TEST=Verify applist should look like M19 mock. Review URL: https://chromiumcodereview.appspot.com/9559005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124661 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/app_list/app_list.cc41
-rw-r--r--ash/app_list/app_list.h5
-rw-r--r--ash/app_list/app_list_groups_view.cc243
-rw-r--r--ash/app_list/app_list_groups_view.h84
-rw-r--r--ash/app_list/app_list_item_group_model.cc25
-rw-r--r--ash/app_list/app_list_item_group_model.h46
-rw-r--r--ash/app_list/app_list_item_group_view.cc115
-rw-r--r--ash/app_list/app_list_item_group_view.h65
-rw-r--r--ash/app_list/app_list_item_view.cc143
-rw-r--r--ash/app_list/app_list_item_view.h31
-rw-r--r--ash/app_list/app_list_item_view_listener.h27
-rw-r--r--ash/app_list/app_list_model.cc15
-rw-r--r--ash/app_list/app_list_model.h22
-rw-r--r--ash/app_list/app_list_model_view.cc120
-rw-r--r--ash/app_list/app_list_model_view.h50
-rw-r--r--ash/app_list/app_list_view.cc77
-rw-r--r--ash/app_list/app_list_view.h28
-rw-r--r--ash/app_list/app_list_view_delegate.h9
-rw-r--r--ash/ash.gyp9
-rw-r--r--ash/shell/app_list.cc56
-rw-r--r--ash/shell/shell_main.cc4
-rw-r--r--ash/shell_delegate.h4
-rw-r--r--ash/test/test_shell_delegate.cc3
-rw-r--r--ash/test/test_shell_delegate.h1
24 files changed, 388 insertions, 835 deletions
diff --git a/ash/app_list/app_list.cc b/ash/app_list/app_list.cc
index d9e30d1..da9384a 100644
--- a/ash/app_list/app_list.cc
+++ b/ash/app_list/app_list.cc
@@ -4,15 +4,12 @@
#include "ash/app_list/app_list.h"
-#include "ash/app_list/app_list_model.h"
#include "ash/app_list/app_list_view.h"
-#include "ash/ash_switches.h"
#include "ash/shell_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
-#include "base/bind.h"
-#include "base/command_line.h"
#include "ui/aura/event.h"
+#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/screen.h"
@@ -22,19 +19,11 @@ namespace internal {
namespace {
-// Gets preferred bounds of app list window in show/hide state.
-gfx::Rect GetPreferredBounds(bool show) {
- // The y-axis offset used at the beginning of showing animation.
- static const int kMoveUpAnimationOffset = 50;
-
+// Gets preferred bounds of app list window.
+gfx::Rect GetPreferredBounds() {
gfx::Point cursor = gfx::Screen::GetCursorScreenPoint();
- gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestPoint(cursor);
- gfx::Rect widget_bounds(work_area);
- widget_bounds.Inset(100, 100);
- if (!show)
- widget_bounds.Offset(0, kMoveUpAnimationOffset);
-
- return widget_bounds;
+ // Use full monitor rect so that the app list shade goes behind the launcher.
+ return gfx::Screen::GetMonitorAreaNearestPoint(cursor);
}
ui::Layer* GetLayer(views::Widget* widget) {
@@ -62,15 +51,11 @@ void AppList::SetVisible(bool visible) {
if (widget_) {
ScheduleAnimation();
} else if (is_visible_) {
- scoped_ptr<AppListModel> model(new AppListModel);
- Shell::GetInstance()->delegate()->BuildAppListModel(model.get());
-
// AppListModel and AppListViewDelegate are owned by AppListView. They
// will be released with AppListView on close.
AppListView* app_list_view = new AppListView(
- model.release(),
Shell::GetInstance()->delegate()->CreateAppListViewDelegate(),
- GetPreferredBounds(false));
+ GetPreferredBounds());
SetWidget(app_list_view->GetWidget());
}
}
@@ -89,12 +74,13 @@ void AppList::SetWidget(views::Widget* widget) {
widget_ = widget;
widget_->AddObserver(this);
Shell::GetInstance()->AddRootWindowEventFilter(this);
+ Shell::GetRootWindow()->AddRootWindowObserver(this);
- widget_->SetBounds(GetPreferredBounds(false));
widget_->SetOpacity(0);
ScheduleAnimation();
widget_->Show();
+ widget_->Activate();
} else {
widget->Close();
}
@@ -107,6 +93,7 @@ void AppList::ResetWidget() {
widget_->RemoveObserver(this);
GetLayer(widget_)->GetAnimator()->RemoveObserver(this);
Shell::GetInstance()->RemoveRootWindowEventFilter(this);
+ Shell::GetRootWindow()->RemoveRootWindowObserver(this);
widget_ = NULL;
}
@@ -124,7 +111,6 @@ void AppList::ScheduleAnimation() {
ui::ScopedLayerAnimationSettings app_list_animation(layer->GetAnimator());
app_list_animation.AddObserver(this);
- layer->SetBounds(GetPreferredBounds(is_visible_));
layer->SetOpacity(is_visible_ ? 1.0 : 0.0);
ui::Layer* default_container_layer = default_container->layer();
@@ -143,7 +129,7 @@ bool AppList::PreHandleKeyEvent(aura::Window* target,
}
bool AppList::PreHandleMouseEvent(aura::Window* target,
- aura::MouseEvent* event) {
+ aura::MouseEvent* event) {
if (widget_ && is_visible_ && event->type() == ui::ET_MOUSE_PRESSED) {
aura::MouseEvent translated(*event, target, widget_->GetNativeView());
if (!widget_->GetNativeView()->ContainsPoint(translated.location()))
@@ -164,6 +150,13 @@ ui::GestureStatus AppList::PreHandleGestureEvent(
}
////////////////////////////////////////////////////////////////////////////////
+// AppList, ura::RootWindowObserver implementation:
+void AppList::OnRootWindowResized(const gfx::Size& new_size) {
+ if (widget_ && is_visible_)
+ widget_->SetBounds(gfx::Rect(new_size));
+}
+
+////////////////////////////////////////////////////////////////////////////////
// AppList, ui::ImplicitAnimationObserver implementation:
void AppList::OnImplicitAnimationsCompleted() {
diff --git a/ash/app_list/app_list.h b/ash/app_list/app_list.h
index b499498..a786c35 100644
--- a/ash/app_list/app_list.h
+++ b/ash/app_list/app_list.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/aura/event_filter.h"
+#include "ui/aura/root_window_observer.h"
#include "ui/gfx/compositor/layer_animation_observer.h"
#include "ui/views/widget/widget.h"
@@ -20,6 +21,7 @@ namespace internal {
// While the UI is visible, it monitors things such as app list widget's
// activation state and desktop mouse click to auto dismiss the UI.
class AppList : public aura::EventFilter,
+ public aura::RootWindowObserver,
public ui::ImplicitAnimationObserver,
public views::Widget::Observer {
public:
@@ -54,6 +56,9 @@ class AppList : public aura::EventFilter,
aura::Window* target,
aura::GestureEvent* event) OVERRIDE;
+ // aura::RootWindowObserver overrides:
+ virtual void OnRootWindowResized(const gfx::Size& new_size) OVERRIDE;
+
// ui::ImplicitAnimationObserver overrides:
virtual void OnImplicitAnimationsCompleted() OVERRIDE;
diff --git a/ash/app_list/app_list_groups_view.cc b/ash/app_list/app_list_groups_view.cc
deleted file mode 100644
index 01571f1..0000000
--- a/ash/app_list/app_list_groups_view.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/app_list/app_list_groups_view.h"
-
-#include "ash/app_list/app_list_item_group_model.h"
-#include "ash/app_list/app_list_item_group_view.h"
-#include "ash/app_list/app_list_item_view.h"
-#include "ash/app_list/app_list_model.h"
-#include "base/utf_string_conversions.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/views/animation/bounds_animator.h"
-#include "ui/views/controls/button/text_button.h"
-#include "ui/views/layout/box_layout.h"
-
-namespace ash {
-
-namespace {
-
-const SkColor kPageHeaderColor = SkColorSetARGB(0xFF, 0xB2, 0xB2, 0xB2);
-const SkColor kSelectedPageHeaderColor = SK_ColorWHITE;
-
-// Creates page headers view that hosts page title buttons.
-views::View* CreatePageHeader() {
- views::View* header = new views::View;
- header->SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
- return header;
-}
-
-// Creates page header button view that shows page title.
-views::View* CreatePageHeaderButton(views::ButtonListener* listener,
- const std::string& title ) {
- views::TextButton* button = new views::TextButton(listener,
- UTF8ToUTF16(title));
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- button->SetFont(rb.GetFont(ResourceBundle::BaseFont).DeriveFont(
- 2, gfx::Font::BOLD));
- button->SetEnabledColor(kPageHeaderColor);
- return button;
-}
-
-// Gets preferred bounds of buttons and page.
-void GetPageAndHeaderBounds(views::View* parent,
- views::View* buttons,
- views::View* page,
- gfx::Rect* buttons_bounds,
- gfx::Rect* page_bounds) {
- gfx::Rect content_bounds = parent->GetContentsBounds();
-
- if (buttons) {
- gfx::Size buttons_size = buttons->GetPreferredSize();
- if (buttons_bounds) {
- buttons_bounds->SetRect(
- (content_bounds.width() - buttons_size.width()) / 2,
- content_bounds.bottom() - buttons_size.height(),
- buttons_size.width(), buttons_size.height());
- }
-
- content_bounds.set_height(
- std::max(0, content_bounds.height() - buttons_size.height()));
- }
-
- if (page_bounds) {
- gfx::Size page_size = page->GetPreferredSize();
- *page_bounds = content_bounds.Center(page_size);
- }
-}
-
-} // namespace
-
-AppListGroupsView::AppListGroupsView(AppListModel* model,
- AppListItemViewListener* listener)
- : model_(model),
- listener_(listener),
- page_buttons_(NULL),
- current_page_(0) {
- animator_.reset(new views::BoundsAnimator(this));
- model_->AddObserver(this);
- Update();
-}
-
-AppListGroupsView::~AppListGroupsView() {
- model_->RemoveObserver(this);
-}
-
-views::View* AppListGroupsView::GetFocusedTile() const {
- AppListItemGroupView* page = GetCurrentPageView();
- return page ? page->GetFocusedTile() : NULL;
-}
-
-void AppListGroupsView::Update() {
- current_page_ = 0;
- page_buttons_ = NULL;
- RemoveAllChildViews(true);
-
- int page_count = model_->group_count();
- if (!page_count)
- return;
-
- if (page_count > 1)
- AddChildView(page_buttons_ = CreatePageHeader());
-
- for (int i = 0; i < page_count; ++i) {
- AppListItemGroupModel* group = model_->GetGroup(i);
- AddPage(group->title(), new AppListItemGroupView(group, listener_));
- }
-
- if (!size().IsEmpty())
- Layout();
- SetCurrentPage(0);
-}
-
-void AppListGroupsView::AddPage(const std::string& title,
- AppListItemGroupView* page) {
- pages_.push_back(page);
- AddChildView(page);
-
- if (page_buttons_)
- page_buttons_->AddChildView(CreatePageHeaderButton(this, title));
-}
-
-int AppListGroupsView::GetPreferredTilesPerRow() const {
- return std::max(1, width() / AppListItemView::kTileSize);
-}
-
-AppListItemGroupView* AppListGroupsView::GetCurrentPageView() const {
- return static_cast<size_t>(current_page_) < pages_.size() ?
- pages_[current_page_] : NULL;
-}
-
-void AppListGroupsView::SetCurrentPage(int page) {
- int previous_page = current_page_;
- current_page_ = page;
-
- // Updates page buttons.
- if (page_buttons_) {
- for (int i = 0; i < page_buttons_->child_count(); ++i) {
- views::TextButton* button = static_cast<views::TextButton*>(
- page_buttons_->child_at(i));
-
- button->SetEnabledColor(i == current_page_ ?
- kSelectedPageHeaderColor : kPageHeaderColor);
- }
- page_buttons_->SchedulePaint();
- }
-
- // Gets sliding animation direction.
- int dir = previous_page < current_page_ ? -1 :
- previous_page > current_page_ ? 1 : 0;
-
- // Skips animation if no sliding needed or no valid size.
- if (dir == 0 || size().IsEmpty())
- return;
-
- animator_->Cancel();
-
- // Makes sure new page has correct layout and focus to its focused tile.
- AppListItemGroupView* current_view = GetCurrentPageView();
- current_view->SetTilesPerRow(GetPreferredTilesPerRow());
- views::View* tile = current_view->GetFocusedTile();
- if (tile)
- tile->RequestFocus();
-
- // Prepares current page before animation.
- gfx::Rect current_page_bounds;
- GetPageAndHeaderBounds(this, page_buttons_, current_view,
- NULL, &current_page_bounds);
- current_page_bounds.Offset(- dir * width(), 0);
- current_view->SetBoundsRect(current_page_bounds);
-
- // Schedules animations to slide out previous page and slide in current page.
- AppListItemGroupView* previous_view = pages_[previous_page];
- gfx::Rect previous_page_bounds = previous_view->bounds();
- previous_page_bounds.Offset(dir * width(), 0);
- animator_->AnimateViewTo(previous_view, previous_page_bounds);
-
- current_page_bounds.Offset(dir * width(), 0);
- animator_->AnimateViewTo(current_view, current_page_bounds);
-}
-
-void AppListGroupsView::Layout() {
- AppListItemGroupView* page = GetCurrentPageView();
- if (!page)
- return;
-
- page->SetTilesPerRow(GetPreferredTilesPerRow());
-
- gfx::Rect buttons_bounds;
- gfx::Rect page_bounds;
- GetPageAndHeaderBounds(this, page_buttons_, page,
- &buttons_bounds, &page_bounds);
-
- if (page_buttons_)
- page_buttons_->SetBoundsRect(buttons_bounds);
-
- page->SetBoundsRect(page_bounds);
-}
-
-bool AppListGroupsView::OnKeyPressed(const views::KeyEvent& event) {
- if (event.IsControlDown()) {
- switch (event.key_code()) {
- case ui::VKEY_LEFT:
- if (current_page_ > 0)
- SetCurrentPage(current_page_ - 1);
- return true;
- case ui::VKEY_RIGHT:
- if (static_cast<size_t>(current_page_ + 1) < pages_.size())
- SetCurrentPage(current_page_ + 1);
- return true;
- default:
- break;
- }
- }
-
- return false;
-}
-
-void AppListGroupsView::ButtonPressed(views::Button* sender,
- const views::Event& event) {
- DCHECK(page_buttons_);
- for (int i = 0; i < page_buttons_->child_count(); ++i) {
- if (page_buttons_->child_at(i) == sender)
- SetCurrentPage(i);
- }
-}
-
-void AppListGroupsView::ListItemsAdded(int start, int count) {
- Update();
-}
-
-void AppListGroupsView::ListItemsRemoved(int start, int count) {
- Update();
-}
-
-void AppListGroupsView::ListItemsChanged(int start, int count) {
- NOTREACHED();
-}
-
-} // namespace ash
diff --git a/ash/app_list/app_list_groups_view.h b/ash/app_list/app_list_groups_view.h
deleted file mode 100644
index e08660c..0000000
--- a/ash/app_list/app_list_groups_view.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_APP_LIST_APP_LIST_GROUPS_VIEW_H_
-#define ASH_APP_LIST_APP_LIST_GROUPS_VIEW_H_
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include "ash/ash_export.h"
-#include "ui/base/models/list_model_observer.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/view.h"
-
-namespace views {
-class BoundsAnimator;
-}
-
-namespace ash {
-
-class AppListItemGroupView;
-class AppListItemViewListener;
-class AppListModel;
-
-// AppListGroupsView displays the UI for an AppListModel. If there are more than
-// one group in the model , a button strip is displayed to allow user to switch
-// between pages.
-class ASH_EXPORT AppListGroupsView : public views::View,
- public views::ButtonListener,
- public ui::ListModelObserver {
- public:
- AppListGroupsView(AppListModel* model,
- AppListItemViewListener* listener);
- virtual ~AppListGroupsView();
-
- // Gets current focused tile.
- views::View* GetFocusedTile() const;
-
- private:
- // Updates from model.
- void Update();
-
- // Adds a result group page.
- void AddPage(const std::string& title, AppListItemGroupView* page);
-
- // Gets preferred number of tiles per row.
- int GetPreferredTilesPerRow() const;
-
- // Gets current result page.
- AppListItemGroupView* GetCurrentPageView() const;
-
- // Sets current result page.
- void SetCurrentPage(int page);
-
- // Overridden from views::View:
- virtual void Layout() OVERRIDE;
- virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
-
- // Overridden from views::ButtonListener:
- virtual void ButtonPressed(views::Button* sender,
- const views::Event& event) OVERRIDE;
-
- // Overridden from ListModelObserver:
- virtual void ListItemsAdded(int start, int count) OVERRIDE;
- virtual void ListItemsRemoved(int start, int count) OVERRIDE;
- virtual void ListItemsChanged(int start, int count) OVERRIDE;
-
- AppListModel* model_; // Owned by parent AppListView.
- AppListItemViewListener* listener_;
-
- std::vector<AppListItemGroupView*> pages_;
- views::View* page_buttons_;
- int current_page_;
-
- scoped_ptr<views::BoundsAnimator> animator_;
-
- DISALLOW_COPY_AND_ASSIGN(AppListGroupsView);
-};
-
-} // namespace ash
-
-#endif // ASH_APP_LIST_APP_LIST_GROUPS_VIEW_H_
diff --git a/ash/app_list/app_list_item_group_model.cc b/ash/app_list/app_list_item_group_model.cc
deleted file mode 100644
index c2fce3a..0000000
--- a/ash/app_list/app_list_item_group_model.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/app_list/app_list_item_group_model.h"
-
-namespace ash {
-
-AppListItemGroupModel::AppListItemGroupModel(const std::string& title)
- : title_(title) {
-}
-
-AppListItemGroupModel::~AppListItemGroupModel() {
-}
-
-void AppListItemGroupModel::AddItem(AppListItemModel* item) {
- items_.Add(item);
-}
-
-AppListItemModel* AppListItemGroupModel::GetItem(int index) {
- DCHECK(index >= 0 && index < item_count());
- return items_.item_at(index);
-}
-
-} // namespace ash
diff --git a/ash/app_list/app_list_item_group_model.h b/ash/app_list/app_list_item_group_model.h
deleted file mode 100644
index 665f4a1..0000000
--- a/ash/app_list/app_list_item_group_model.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_APP_LIST_APP_LIST_ITEM_GROUP_MODEL_H_
-#define ASH_APP_LIST_APP_LIST_ITEM_GROUP_MODEL_H_
-#pragma once
-
-#include <string>
-
-#include "ash/app_list/app_list_item_model.h"
-#include "base/basictypes.h"
-#include "ash/ash_export.h"
-#include "ui/base/models/list_model.h"
-
-namespace ash {
-
-// AppListItemGroupModel holds a list of AppListItemModels.
-class ASH_EXPORT AppListItemGroupModel {
- public:
- typedef ui::ListModel<AppListItemModel> Items;
-
- explicit AppListItemGroupModel(const std::string& title);
- virtual ~AppListItemGroupModel();
-
- void AddItem(AppListItemModel* item);
- AppListItemModel* GetItem(int index);
-
- const std::string& title() const {
- return title_;
- }
-
- int item_count() const {
- return items_.item_count();
- }
-
- private:
- const std::string title_;
- Items items_;
-
- DISALLOW_COPY_AND_ASSIGN(AppListItemGroupModel);
-};
-
-} // namespace ash
-
-#endif // ASH_APP_LIST_APP_LIST_ITEM_GROUP_MODEL_H_
diff --git a/ash/app_list/app_list_item_group_view.cc b/ash/app_list/app_list_item_group_view.cc
deleted file mode 100644
index ed34983..0000000
--- a/ash/app_list/app_list_item_group_view.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/app_list/app_list_item_group_view.h"
-
-#include "ash/app_list/app_list_item_group_model.h"
-#include "ash/app_list/app_list_item_view.h"
-#include "ui/views/layout/grid_layout.h"
-
-namespace ash {
-
-AppListItemGroupView::AppListItemGroupView(AppListItemGroupModel* model,
- AppListItemViewListener* listener)
- : model_(model),
- listener_(listener),
- tiles_per_row_(0),
- focused_index_(0) {
- Update();
-}
-
-AppListItemGroupView::~AppListItemGroupView() {
-}
-
-void AppListItemGroupView::SetTilesPerRow(int tiles_per_row) {
- if (tiles_per_row_ == tiles_per_row)
- return;
-
- tiles_per_row_ = tiles_per_row;
- Update();
-}
-
-void AppListItemGroupView::Update() {
- RemoveAllChildViews(true);
- if (model_->item_count() == 0 || tiles_per_row_ == 0)
- return;
-
- views::GridLayout* layout = new views::GridLayout(this);
- SetLayoutManager(layout);
-
- const int kTileColumnSetId = 0;
- views::ColumnSet* column_set = layout->AddColumnSet(kTileColumnSetId);
- for (int i = 0; i < tiles_per_row_; ++i) {
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
- views::GridLayout::USE_PREF, 0, 0);
- }
-
- for (int i = 0; i < model_->item_count(); ++i) {
- if (i % tiles_per_row_ == 0)
- layout->StartRow(0, kTileColumnSetId);
-
- layout->AddView(new AppListItemView(model_->GetItem(i), listener_));
- }
-}
-
-views::View* AppListItemGroupView::GetFocusedTile() {
- return focused_index_ < child_count() ? child_at(focused_index_) : NULL;
-}
-
-void AppListItemGroupView::UpdateFocusedTile(views::View* tile) {
- for (int i = 0; i < child_count(); ++i) {
- if (child_at(i) == tile) {
- focused_index_ = i;
- break;
- }
- }
-}
-
-void AppListItemGroupView::SetFocusedTileByIndex(int index) {
- index = std::max(0, std::min(child_count() - 1, index));
- if (index != focused_index_)
- child_at(index)->RequestFocus();
-}
-
-bool AppListItemGroupView::OnKeyPressed(const views::KeyEvent& event) {
- if (!event.IsControlDown() && !event.IsShiftDown() && !event.IsAltDown()) {
- // Arrow keys navigates in tile grid.
- switch (event.key_code()) {
- case ui::VKEY_LEFT:
- if (focused_index_ > 0)
- SetFocusedTileByIndex(focused_index_ - 1);
- return true;
- case ui::VKEY_RIGHT:
- if (focused_index_ + 1 < child_count())
- SetFocusedTileByIndex(focused_index_ + 1);
- return true;
- case ui::VKEY_UP:
- if (focused_index_ - tiles_per_row_ >= 0)
- SetFocusedTileByIndex(focused_index_ - tiles_per_row_);
- return true;
- case ui::VKEY_DOWN:
- if (focused_index_ + tiles_per_row_ < child_count())
- SetFocusedTileByIndex(focused_index_ + tiles_per_row_);
- return true;
- default:
- break;
- }
- }
-
- return false;
-}
-
-void AppListItemGroupView::ListItemsAdded(int start, int count) {
- Update();
-}
-
-void AppListItemGroupView::ListItemsRemoved(int start, int count) {
- Update();
-}
-
-void AppListItemGroupView::ListItemsChanged(int start, int count) {
- NOTREACHED();
-}
-
-} // namespace ash
diff --git a/ash/app_list/app_list_item_group_view.h b/ash/app_list/app_list_item_group_view.h
deleted file mode 100644
index 834fb59..0000000
--- a/ash/app_list/app_list_item_group_view.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_APP_LIST_APP_LIST_ITEM_GROUP_VIEW_H_
-#define ASH_APP_LIST_APP_LIST_ITEM_GROUP_VIEW_H_
-#pragma once
-
-#include "ash/ash_export.h"
-#include "ui/base/models/list_model_observer.h"
-#include "ui/views/view.h"
-
-namespace ash {
-
-class AppListItemGroupModel;
-class AppListItemViewListener;
-
-// AppListItemGroupView displays its children tiles in a grid.
-class ASH_EXPORT AppListItemGroupView
- : public views::View,
- public ui::ListModelObserver {
- public:
- AppListItemGroupView(AppListItemGroupModel* model,
- AppListItemViewListener* listener);
- virtual ~AppListItemGroupView();
-
- // Sets tiles per row.
- void SetTilesPerRow(int tiles_per_row);
-
- // Gets currently focused tile.
- views::View* GetFocusedTile();
-
- // Updates tiles page when a tile gets focus.
- void UpdateFocusedTile(views::View* tile);
-
- private:
- // Updates from model.
- void Update();
-
- // Sets focused tile by index.
- void SetFocusedTileByIndex(int index);
-
- // Overridden from views::View:
- virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
-
- // Overridden from ListModelObserver:
- virtual void ListItemsAdded(int start, int count) OVERRIDE;
- virtual void ListItemsRemoved(int start, int count) OVERRIDE;
- virtual void ListItemsChanged(int start, int count) OVERRIDE;
-
- AppListItemGroupModel* model_;
- AppListItemViewListener* listener_;
-
- // Tiles per row.
- int tiles_per_row_;
-
- // Index of focused tile view.
- int focused_index_;
-
- DISALLOW_COPY_AND_ASSIGN(AppListItemGroupView);
-};
-
-} // namespace ash
-
-#endif // ASH_APP_LIST_APP_LIST_ITEM_GROUP_VIEW_H_
diff --git a/ash/app_list/app_list_item_view.cc b/ash/app_list/app_list_item_view.cc
index 41c1f89..ed50a86 100644
--- a/ash/app_list/app_list_item_view.cc
+++ b/ash/app_list/app_list_item_view.cc
@@ -1,53 +1,68 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/app_list/app_list_item_view.h"
-#include "ash/app_list/app_list_item_group_view.h"
#include "ash/app_list/app_list_item_model.h"
-#include "ash/app_list/app_list_item_view_listener.h"
#include "ash/app_list/drop_shadow_label.h"
#include "base/utf_string_conversions.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/animation/throb_animation.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/widget/widget.h"
namespace ash {
namespace {
-const double kFocusedScale = 1.1;
+const int kIconTitleSpacing = 5;
const SkColor kTitleColor = SK_ColorWHITE;
+const SkColor kHoverColor = SkColorSetARGB(0x33, 0xFF, 0xFF, 0xFF); // 0.2 white
gfx::Font GetTitleFont() {
static gfx::Font* font = NULL;
if (!font) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
font = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont).DeriveFont(
- 2, gfx::Font::BOLD));
+ 1, gfx::Font::BOLD));
}
return *font;
}
+// An image view that is not interactive.
+class StaticImageView : public views::ImageView {
+ public:
+ StaticImageView() : ImageView() {
+ }
+
+ private:
+ // views::View overrides:
+ virtual bool HitTest(const gfx::Point& l) const OVERRIDE {
+ return false;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(StaticImageView);
+};
+
} // namespace
+// static
+const char AppListItemView::kViewClassName[] = "ash/app_list/AppListItemView";
+
AppListItemView::AppListItemView(AppListItemModel* model,
- AppListItemViewListener* listener)
- : model_(model),
- listener_(listener),
- icon_(new views::ImageView),
+ views::ButtonListener* listener)
+ : CustomButton(listener),
+ model_(model),
+ icon_(new StaticImageView),
title_(new DropShadowLabel) {
- set_focusable(true);
-
title_->SetFont(GetTitleFont());
title_->SetBackgroundColor(0);
title_->SetEnabledColor(kTitleColor);
+ title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
AddChildView(icon_);
AddChildView(title_);
@@ -61,11 +76,6 @@ AppListItemView::~AppListItemView() {
model_->RemoveObserver(this);
}
-void AppListItemView::NotifyActivated(int event_flags) {
- if (listener_)
- listener_->AppListItemActivated(this, event_flags);
-}
-
void AppListItemView::ItemIconChanged() {
icon_->SetImage(model_->icon());
}
@@ -74,89 +84,42 @@ void AppListItemView::ItemTitleChanged() {
title_->SetText(UTF8ToUTF16(model_->title()));
}
-gfx::Size AppListItemView::GetPreferredSize() {
- return gfx::Size(kTileSize, kTileSize);
+std::string AppListItemView::GetClassName() const {
+ return kViewClassName;
}
-void AppListItemView::Layout() {
- gfx::Rect rect(GetContentsBounds());
+gfx::Size AppListItemView::GetPreferredSize() {
+ gfx::Size icon_size = icon_->GetPreferredSize();
gfx::Size title_size = title_->GetPreferredSize();
- if (!HasFocus()) {
- const int horiz_padding = (kTileSize - kIconSize) / 2;
- const int vert_padding = (kTileSize - title_size.height() - kIconSize) / 2;
- rect.Inset(horiz_padding, vert_padding);
- }
-
- icon_->SetBounds(rect.x(), rect.y(),
- rect.width(), rect.height() - title_size.height());
-
- title_->SetBounds(rect.x(), rect.bottom() - title_size.height(),
- rect.width(), title_size.height());
+ return gfx::Size(icon_size.width() + kIconTitleSpacing + title_size.width(),
+ std::max(icon_size.height(), title_size.height()));
}
-void AppListItemView::OnFocus() {
- View::OnFocus();
-
- gfx::Size icon_size = icon_->GetPreferredSize();
- icon_size.set_width(icon_size.width() * kFocusedScale);
- icon_size.set_height(icon_size.height() * kFocusedScale);
-
- gfx::Size max_size = GetPreferredSize();
- if (icon_size.width() > max_size.width() ||
- icon_size.height() > max_size.height()) {
- double aspect =
- static_cast<double>(icon_size.width()) / icon_size.height();
-
- if (aspect > 1) {
- icon_size.set_width(max_size.width());
- icon_size.set_height(icon_size.width() / aspect);
- } else {
- icon_size.set_height(max_size.height());
- icon_size.set_width(icon_size.height() * aspect);
- }
- }
+void AppListItemView::Layout() {
+ gfx::Rect rect(GetContentsBounds());
+ int preferred_icon_size = rect.height() - 2 * kPadding;
+ gfx::Size icon_size(preferred_icon_size, preferred_icon_size);
icon_->SetImageSize(icon_size);
- Layout();
-
- AppListItemGroupView* group_view =
- static_cast<AppListItemGroupView*>(parent());
- group_view->UpdateFocusedTile(this);
-}
-
-void AppListItemView::OnBlur() {
- icon_->ResetImageSize();
- Layout();
- SchedulePaint();
+ icon_->SetBounds(rect.x() + kPadding, rect.y(),
+ icon_size.width(), rect.height());
+
+ title_->SetBounds(
+ icon_->bounds().right() + kIconTitleSpacing,
+ rect.y(),
+ rect.right() - kPadding - icon_->bounds().right() - kIconTitleSpacing,
+ rect.height());
}
-bool AppListItemView::OnKeyPressed(const views::KeyEvent& event) {
- if (event.key_code() == ui::VKEY_RETURN) {
- NotifyActivated(event.flags());
- return true;
+void AppListItemView::OnPaint(gfx::Canvas* canvas) {
+ gfx::Rect rect(GetContentsBounds());
+ if (hover_animation_->is_animating()) {
+ int alpha = SkColorGetA(kHoverColor) * hover_animation_->GetCurrentValue();
+ canvas->FillRect(rect, SkColorSetA(kHoverColor, alpha));
+ } else if (state() == BS_HOT) {
+ canvas->FillRect(rect, kHoverColor);
}
-
- return false;
-}
-
-bool AppListItemView::OnMousePressed(const views::MouseEvent& event) {
- views::View* hit_view = GetEventHandlerForPoint(event.location());
- bool hit = hit_view != this;
- if (hit)
- RequestFocus();
-
- return hit;
-}
-
-void AppListItemView::OnMouseReleased(const views::MouseEvent& event) {
- views::View* hit_view = GetEventHandlerForPoint(event.location());
- if (hit_view != this)
- NotifyActivated(event.flags());
-}
-
-void AppListItemView::OnPaintFocusBorder(gfx::Canvas* canvas) {
- // No focus border for AppListItemView.
}
} // namespace ash
diff --git a/ash/app_list/app_list_item_view.h b/ash/app_list/app_list_item_view.h
index 120d97c..c4ef19d 100644
--- a/ash/app_list/app_list_item_view.h
+++ b/ash/app_list/app_list_item_view.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,7 +8,7 @@
#include "ash/app_list/app_list_item_model_observer.h"
#include "ash/ash_export.h"
-#include "ui/views/view.h"
+#include "ui/views/controls/button/custom_button.h"
class SkBitmap;
@@ -20,46 +20,37 @@ class Label;
namespace ash {
class AppListItemModel;
-class AppListItemViewListener;
-class ASH_EXPORT AppListItemView : public views::View,
- public AppListItemModelObserver {
+class ASH_EXPORT AppListItemView : public views::CustomButton,
+ public AppListItemModelObserver {
public:
AppListItemView(AppListItemModel* model,
- AppListItemViewListener* listener);
+ views::ButtonListener* listener);
virtual ~AppListItemView();
AppListItemModel* model() const {
return model_;
}
- // Tile size
- static const int kTileSize = 180;
+ // Icon padding
+ static const int kPadding = 5;
- // Preferred icon size.
- static const int kIconSize = 128;
+ // Internal class name.
+ static const char kViewClassName[];
protected:
- // Notifies listener when activated.
- void NotifyActivated(int event_flags);
-
// AppListItemModelObserver overrides:
virtual void ItemIconChanged() OVERRIDE;
virtual void ItemTitleChanged() OVERRIDE;
// views::View overrides:
+ virtual std::string GetClassName() const OVERRIDE;
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual void Layout() OVERRIDE;
- virtual void OnFocus() OVERRIDE;
- virtual void OnBlur() OVERRIDE;
- virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
- virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
- virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
- virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
private:
AppListItemModel* model_;
- AppListItemViewListener* listener_;
views::ImageView* icon_;
views::Label* title_;
diff --git a/ash/app_list/app_list_item_view_listener.h b/ash/app_list/app_list_item_view_listener.h
deleted file mode 100644
index a008f72..0000000
--- a/ash/app_list/app_list_item_view_listener.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_APP_LIST_APP_LIST_ITEM_VIEW_LISTENER_H_
-#define ASH_APP_LIST_APP_LIST_ITEM_VIEW_LISTENER_H_
-#pragma once
-
-#include "ash/ash_export.h"
-
-namespace ash {
-
-class AppListItemView;
-
-class ASH_EXPORT AppListItemViewListener {
- public:
- // Invoked when an AppListeItemModelView is activated by click or enter key.
- virtual void AppListItemActivated(AppListItemView* sender,
- int event_flags) = 0;
-
- protected:
- virtual ~AppListItemViewListener() {}
-};
-
-} // namespace ash
-
-#endif // ASH_APP_LIST_APP_LIST_ITEM_VIEW_LISTENER_H_
diff --git a/ash/app_list/app_list_model.cc b/ash/app_list/app_list_model.cc
index 8362dd6..2d93fbe 100644
--- a/ash/app_list/app_list_model.cc
+++ b/ash/app_list/app_list_model.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,21 +12,20 @@ AppListModel::AppListModel() {
AppListModel::~AppListModel() {
}
-void AppListModel::AddGroup(AppListItemGroupModel* group) {
- groups_.Add(group);
+void AppListModel::AddItem(AppListItemModel* item) {
+ items_.Add(item);
}
-AppListItemGroupModel* AppListModel::GetGroup(int index) {
- DCHECK(index >= 0 && index < group_count());
- return groups_.item_at(index);
+AppListItemModel* AppListModel::GetItem(int index) {
+ return items_.item_at(index);
}
void AppListModel::AddObserver(ui::ListModelObserver* observer) {
- groups_.AddObserver(observer);
+ items_.AddObserver(observer);
}
void AppListModel::RemoveObserver(ui::ListModelObserver* observer) {
- groups_.RemoveObserver(observer);
+ items_.RemoveObserver(observer);
}
} // namespace ash
diff --git a/ash/app_list/app_list_model.h b/ash/app_list/app_list_model.h
index bb797a1..fbced97a 100644
--- a/ash/app_list/app_list_model.h
+++ b/ash/app_list/app_list_model.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,32 +6,36 @@
#define ASH_APP_LIST_APP_LIST_MODEL_H_
#pragma once
-#include "ash/app_list/app_list_item_group_model.h"
#include "base/basictypes.h"
+#include "ash/app_list/app_list_item_model.h"
#include "ash/ash_export.h"
#include "ui/base/models/list_model.h"
namespace ash {
-// Model for AppListView. It is consisted of a list of AppListItemGroupModels,
-// which in turn owns a list of AppListItemModels.
+class AppListItemModel;
+
+// Model for AppListModelView that owns a list of AppListItemModels.
class ASH_EXPORT AppListModel {
public:
AppListModel();
virtual ~AppListModel();
- void AddGroup(AppListItemGroupModel* group);
- AppListItemGroupModel* GetGroup(int index);
+ // Adds an item to the model. The model takes ownership of |item|.
+ void AddItem(AppListItemModel* item);
+
+ AppListItemModel* GetItem(int index);
void AddObserver(ui::ListModelObserver* observer);
void RemoveObserver(ui::ListModelObserver* observer);
- int group_count() const {
- return groups_.item_count();
+ int item_count() const {
+ return items_.item_count();
}
private:
- ui::ListModel<AppListItemGroupModel> groups_;
+ typedef ui::ListModel<AppListItemModel> Items;
+ Items items_;
DISALLOW_COPY_AND_ASSIGN(AppListModel);
};
diff --git a/ash/app_list/app_list_model_view.cc b/ash/app_list/app_list_model_view.cc
new file mode 100644
index 0000000..8667c66
--- /dev/null
+++ b/ash/app_list/app_list_model_view.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/app_list/app_list_model_view.h"
+
+#include "ash/app_list/app_list_item_view.h"
+#include "ash/app_list/app_list_model.h"
+#include "base/utf_string_conversions.h"
+
+namespace ash {
+
+namespace {
+
+// Minimum label width.
+const int kMinLabelWidth = 150;
+
+// Calculate preferred tile size for given |content_size| and |num_of_tiles|.
+gfx::Size CalculateTileSize(const gfx::Size& content_size, int num_of_tiles) {
+ // Icon sizes to try.
+ const int kIconSizes[] = { 64, 48, 32, 16 };
+
+ int tile_height = 0;
+ int tile_width = 0;
+ int rows = 0;
+ int cols = 0;
+
+ // Chooses the biggest icon size that could fit all tiles.
+ for (size_t i = 0; i < arraysize(kIconSizes); ++i) {
+ int icon_size = kIconSizes[i];
+ tile_height = icon_size + 2 * AppListItemView::kPadding;
+ tile_width = icon_size + std::min(kMinLabelWidth, icon_size * 2) +
+ 2 * AppListItemView::kPadding;
+
+ rows = content_size.height() / tile_height;
+ cols = std::min(content_size.width() / tile_width,
+ (num_of_tiles - 1) / rows + 1);
+ if (rows * cols >= num_of_tiles)
+ break;
+ }
+
+ if (rows && cols) {
+ // Adjusts tile width to fit |content_size| as much as possible.
+ tile_width = std::max(tile_width, content_size.width() / cols);
+ return gfx::Size(tile_width, tile_height);
+ }
+
+ return gfx::Size();
+}
+
+} // namespace
+
+AppListModelView::AppListModelView(views::ButtonListener* listener)
+ : model_(NULL),
+ listener_(listener) {
+}
+
+AppListModelView::~AppListModelView() {
+ if (model_)
+ model_->RemoveObserver(this);
+}
+
+void AppListModelView::SetModel(AppListModel* model) {
+ DCHECK(model);
+
+ if (model_)
+ model_->RemoveObserver(this);
+
+ model_ = model;
+ model_->AddObserver(this);
+ Update();
+}
+
+void AppListModelView::Update() {
+ RemoveAllChildViews(true);
+ if (!model_ || model_->item_count() == 0)
+ return;
+
+ for (int i = 0; i < model_->item_count(); ++i)
+ AddChildView(new AppListItemView(model_->GetItem(i), listener_));
+
+ Layout();
+ SchedulePaint();
+}
+
+void AppListModelView::Layout() {
+ gfx::Rect rect(GetContentsBounds());
+ if (rect.IsEmpty())
+ return;
+
+ gfx::Size tile_size = CalculateTileSize(rect.size(), child_count());
+
+ int col_bottom = rect.bottom();
+ gfx::Rect current_tile(rect.origin(), tile_size);
+
+ for (int i = 0; i < child_count(); ++i) {
+ views::View* view = child_at(i);
+ view->SetBoundsRect(current_tile);
+
+ current_tile.Offset(0, tile_size.height());
+ if (current_tile.bottom() >= col_bottom) {
+ current_tile.set_x(current_tile.x() + tile_size.width());
+ current_tile.set_y(rect.y());
+ }
+ }
+}
+
+void AppListModelView::ListItemsAdded(int start, int count) {
+ Update();
+}
+
+void AppListModelView::ListItemsRemoved(int start, int count) {
+ Update();
+}
+
+void AppListModelView::ListItemsChanged(int start, int count) {
+ NOTREACHED();
+}
+
+} // namespace ash
diff --git a/ash/app_list/app_list_model_view.h b/ash/app_list/app_list_model_view.h
new file mode 100644
index 0000000..55d69f7
--- /dev/null
+++ b/ash/app_list/app_list_model_view.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_APP_LIST_APP_LIST_MODEL_VIEW_H_
+#define ASH_APP_LIST_APP_LIST_MODEL_VIEW_H_
+#pragma once
+
+#include "ui/base/models/list_model_observer.h"
+#include "ui/views/view.h"
+
+namespace views {
+class ButtonListener;
+}
+
+namespace ash {
+
+class AppListModel;
+
+// AppListModelView displays the UI for an AppListModel.
+class AppListModelView : public views::View,
+ public ui::ListModelObserver {
+ public:
+ explicit AppListModelView(views::ButtonListener* listener);
+ virtual ~AppListModelView();
+
+ // Sets |model| to use. Note this does not take ownership of |model|.
+ void SetModel(AppListModel* model);
+
+ private:
+ // Updates from model.
+ void Update();
+
+ // Overridden from views::View:
+ virtual void Layout() OVERRIDE;
+
+ // Overridden from ListModelObserver:
+ virtual void ListItemsAdded(int start, int count) OVERRIDE;
+ virtual void ListItemsRemoved(int start, int count) OVERRIDE;
+ virtual void ListItemsChanged(int start, int count) OVERRIDE;
+
+ AppListModel* model_; // Owned by parent AppListView.
+ views::ButtonListener* listener_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppListModelView);
+};
+
+} // namespace ash
+
+#endif // ASH_APP_LIST_APP_LIST_MODEL_VIEW_H_
diff --git a/ash/app_list/app_list_view.cc b/ash/app_list/app_list_view.cc
index 9aa34108..c68312e 100644
--- a/ash/app_list/app_list_view.cc
+++ b/ash/app_list/app_list_view.cc
@@ -4,22 +4,33 @@
#include "ash/app_list/app_list_view.h"
-#include "ash/app_list/app_list_groups_view.h"
#include "ash/app_list/app_list_item_view.h"
#include "ash/app_list/app_list_model.h"
+#include "ash/app_list/app_list_model_view.h"
#include "ash/app_list/app_list_view_delegate.h"
#include "ash/shell.h"
-#include "ui/views/layout/fill_layout.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/background.h"
#include "ui/views/widget/widget.h"
namespace ash {
+namespace {
+
+// Margins in pixels from work area edges.
+const int kMargin = 50;
+
+// 0.4 black
+const SkColor kBackgroundColor = SkColorSetARGB(0x66, 0, 0, 0);
+
+} // namespace
+
AppListView::AppListView(
- AppListModel* model,
AppListViewDelegate* delegate,
const gfx::Rect& bounds)
- : model_(model),
- delegate_(delegate) {
+ : delegate_(delegate),
+ model_view_(NULL) {
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
Init(bounds);
}
@@ -32,13 +43,11 @@ void AppListView::Close() {
}
void AppListView::Init(const gfx::Rect& bounds) {
- SetLayoutManager(new views::FillLayout);
- AppListGroupsView* groups_view = new AppListGroupsView(model_.get(), this);
- AddChildView(groups_view);
+ model_view_ = new AppListModelView(this);
+ AddChildView(model_view_);
views::Widget::InitParams widget_params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- widget_params.bounds = bounds;
widget_params.delegate = this;
widget_params.keep_on_top = true;
widget_params.transparent = true;
@@ -46,9 +55,41 @@ void AppListView::Init(const gfx::Rect& bounds) {
views::Widget* widget = new views::Widget;
widget->Init(widget_params);
widget->SetContentsView(this);
+ widget->SetBounds(bounds);
+
+ UpdateModel();
+}
+
+void AppListView::UpdateModel() {
+ if (delegate_.get()) {
+ scoped_ptr<AppListModel> new_model(new AppListModel);
+ delegate_->BuildAppListModel(std::string(), new_model.get());
+ model_view_->SetModel(new_model.get());
+ model_.reset(new_model.release());
+ }
+}
+
+views::View* AppListView::GetInitiallyFocusedView() {
+ return model_view_;
+}
+
+void AppListView::Layout() {
+ gfx::Rect rect(GetContentsBounds());
+ if (rect.IsEmpty())
+ return;
- if (groups_view->GetFocusedTile())
- groups_view->GetFocusedTile()->RequestFocus();
+ // Gets work area rect, which is in screen coordinates.
+ gfx::Rect workarea = gfx::Screen::GetMonitorWorkAreaNearestWindow(
+ GetWidget()->GetNativeView());
+
+ // Converts |workarea| into view's coordinates.
+ gfx::Point origin(workarea.origin());
+ views::View::ConvertPointFromScreen(this, &origin);
+ workarea.Offset(-origin.x(), -origin.y());
+
+ rect = rect.Intersect(workarea);
+ rect.Inset(kMargin, kMargin);
+ model_view_->SetBoundsRect(rect);
}
bool AppListView::OnKeyPressed(const views::KeyEvent& event) {
@@ -67,10 +108,16 @@ bool AppListView::OnMousePressed(const views::MouseEvent& event) {
return true;
}
-void AppListView::AppListItemActivated(AppListItemView* sender,
- int event_flags) {
- if (delegate_.get())
- delegate_->OnAppListItemActivated(sender->model(), event_flags);
+void AppListView::ButtonPressed(views::Button* sender,
+ const views::Event& event) {
+ if (sender->GetClassName() != AppListItemView::kViewClassName)
+ return;
+
+ if (delegate_.get()) {
+ delegate_->OnAppListItemActivated(
+ static_cast<AppListItemView*>(sender)->model(),
+ event.flags());
+ }
Close();
}
diff --git a/ash/app_list/app_list_view.h b/ash/app_list/app_list_view.h
index 17bfcec..528f26c 100644
--- a/ash/app_list/app_list_view.h
+++ b/ash/app_list/app_list_view.h
@@ -6,9 +6,8 @@
#define ASH_APP_LIST_APP_LIST_VIEW_H_
#pragma once
-#include "ash/app_list/app_list_item_view_listener.h"
-#include "ash/ash_export.h"
#include "base/memory/scoped_ptr.h"
+#include "ui/views/controls/button/button.h"
#include "ui/views/widget/widget_delegate.h"
namespace views {
@@ -18,16 +17,16 @@ class View;
namespace ash {
class AppListModel;
+class AppListModelView;
class AppListViewDelegate;
// AppListView is the top-level view and controller of app list UI. It creates
// and hosts a AppListModelView and passes AppListModel to it for display.
-class ASH_EXPORT AppListView : public views::WidgetDelegateView,
- public AppListItemViewListener {
+class AppListView : public views::WidgetDelegateView,
+ public views::ButtonListener {
public:
- // Takes ownership of |model| and |delegate|.
- AppListView(AppListModel* model,
- AppListViewDelegate* delegate,
+ // Takes ownership of |delegate|.
+ AppListView(AppListViewDelegate* delegate,
const gfx::Rect& bounds);
virtual ~AppListView();
@@ -38,18 +37,27 @@ class ASH_EXPORT AppListView : public views::WidgetDelegateView,
// Initializes the window.
void Init(const gfx::Rect& bounds);
+ // Updates model using query text in search box.
+ void UpdateModel();
+
+ // Overridden from views::WidgetDelegateView:
+ virtual views::View* GetInitiallyFocusedView() OVERRIDE;
+
// Overridden from views::View:
+ virtual void Layout() OVERRIDE;
virtual bool OnKeyPressed(const views::KeyEvent& event) OVERRIDE;
virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
- // Overridden from AppListItemModelViewListener:
- virtual void AppListItemActivated(AppListItemView* sender,
- int event_flags) OVERRIDE;
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender,
+ const views::Event& event) OVERRIDE;
scoped_ptr<AppListModel> model_;
scoped_ptr<AppListViewDelegate> delegate_;
+ AppListModelView* model_view_;
+
DISALLOW_COPY_AND_ASSIGN(AppListView);
};
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h
index 875fa6b..112bfcf 100644
--- a/ash/app_list/app_list_view_delegate.h
+++ b/ash/app_list/app_list_view_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,17 +6,24 @@
#define ASH_APP_LIST_APP_LIST_VIEW_DELEGATE_H_
#pragma once
+#include <string>
+
#include "ash/ash_export.h"
namespace ash {
class AppListItemModel;
+class AppListModel;
class ASH_EXPORT AppListViewDelegate {
public:
// AppListView owns the delegate.
virtual ~AppListViewDelegate() {}
+ // Invoked to ask the delegate to populate the |model| for given |query|.
+ virtual void BuildAppListModel(const std::string& query,
+ AppListModel* model) = 0;
+
// Invoked an AppListeItemModelView is activated by click or enter key.
virtual void OnAppListItemActivated(AppListItemModel* item,
int event_flags) = 0;
diff --git a/ash/ash.gyp b/ash/ash.gyp
index db04b49..a0116b6 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -47,20 +47,15 @@
'accelerators/nested_dispatcher_controller.h',
'app_list/app_list.cc',
'app_list/app_list.h',
- 'app_list/app_list_groups_view.cc',
- 'app_list/app_list_groups_view.h',
- 'app_list/app_list_item_group_model.cc',
- 'app_list/app_list_item_group_model.h',
- 'app_list/app_list_item_group_view.cc',
- 'app_list/app_list_item_group_view.h',
'app_list/app_list_item_model.cc',
'app_list/app_list_item_model.h',
'app_list/app_list_item_model_observer.h',
'app_list/app_list_item_view.cc',
'app_list/app_list_item_view.h',
- 'app_list/app_list_item_view_listener.h',
'app_list/app_list_model.cc',
'app_list/app_list_model.h',
+ 'app_list/app_list_model_view.cc',
+ 'app_list/app_list_model_view.h',
'app_list/app_list_view.cc',
'app_list/app_list_view.h',
'app_list/app_list_view_delegate.h',
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index eaa4ffa..f4f8bd6 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ash/app_list/app_list_item_group_model.h"
#include "ash/app_list/app_list_item_model.h"
#include "ash/app_list/app_list_item_view.h"
#include "ash/app_list/app_list_model.h"
@@ -36,17 +35,16 @@ class WindowTypeLauncherItem : public ash::AppListItemModel {
static SkBitmap GetIcon(Type type) {
static const SkColor kColors[] = {
- SkColorSetA(SK_ColorRED, 0x4F),
- SkColorSetA(SK_ColorGREEN, 0x4F),
- SkColorSetA(SK_ColorBLUE, 0x4F),
- SkColorSetA(SK_ColorYELLOW, 0x4F),
- SkColorSetA(SK_ColorCYAN, 0x4F),
+ SK_ColorRED,
+ SK_ColorGREEN,
+ SK_ColorBLUE,
+ SK_ColorYELLOW,
+ SK_ColorCYAN,
};
+ const int kIconSize = 128;
SkBitmap icon;
- icon.setConfig(SkBitmap::kARGB_8888_Config,
- ash::AppListItemView::kIconSize,
- ash::AppListItemView::kIconSize);
+ icon.setConfig(SkBitmap::kARGB_8888_Config, kIconSize, kIconSize);
icon.allocPixels();
icon.eraseColor(kColors[static_cast<int>(type) % arraysize(kColors)]);
return icon;
@@ -111,6 +109,21 @@ class ExampleAppListViewDelegate : public ash::AppListViewDelegate {
ExampleAppListViewDelegate() {}
private:
+ // Overridden from ash::AppListViewDelegate:
+ virtual void BuildAppListModel(const std::string& query,
+ AppListModel* model) OVERRIDE {
+ 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);
+ if (title.find(query) != std::string::npos)
+ model->AddItem(new WindowTypeLauncherItem(type));
+ }
+ }
+
virtual void OnAppListItemActivated(ash::AppListItemModel* item,
int event_flags) OVERRIDE {
static_cast<WindowTypeLauncherItem*>(item)->Activate(event_flags);
@@ -119,33 +132,8 @@ class ExampleAppListViewDelegate : public ash::AppListViewDelegate {
DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
};
-ash::AppListItemGroupModel* CreateGroup(
- const std::string& title,
- WindowTypeLauncherItem::Type start_type,
- WindowTypeLauncherItem::Type end_type) {
- ash::AppListItemGroupModel* group =
- new ash::AppListItemGroupModel(title);
- for (int i = static_cast<int>(start_type);
- i < static_cast<int>(end_type);
- ++i) {
- WindowTypeLauncherItem::Type type =
- static_cast<WindowTypeLauncherItem::Type>(i);
- group->AddItem(new WindowTypeLauncherItem(type));
- }
- return group;
-}
-
} // namespace
-void BuildAppListModel(ash::AppListModel* model) {
- model->AddGroup(CreateGroup("Windows",
- WindowTypeLauncherItem::TOPLEVEL_WINDOW,
- WindowTypeLauncherItem::WIDGETS_WINDOW));
- model->AddGroup(CreateGroup("Samples",
- WindowTypeLauncherItem::WIDGETS_WINDOW,
- WindowTypeLauncherItem::LAST_TYPE));
-}
-
ash::AppListViewDelegate* CreateAppListViewDelegate() {
return new ExampleAppListViewDelegate;
}
diff --git a/ash/shell/shell_main.cc b/ash/shell/shell_main.cc
index a5dbccf..7cf509fa 100644
--- a/ash/shell/shell_main.cc
+++ b/ash/shell/shell_main.cc
@@ -178,10 +178,6 @@ class ShellDelegateImpl : public ash::ShellDelegate {
MessageLoopForUI::current()->Quit();
}
- virtual void BuildAppListModel(ash::AppListModel* model) OVERRIDE {
- ash::shell::BuildAppListModel(model);
- }
-
virtual ash::AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE {
return ash::shell::CreateAppListViewDelegate();
}
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index 08caa35..c5ec41b 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -23,7 +23,6 @@ class Widget;
namespace ash {
-class AppListModel;
class AppListViewDelegate;
class LauncherDelegate;
class LauncherModel;
@@ -63,9 +62,6 @@ class ASH_EXPORT ShellDelegate {
// Invoked when a user uses Ctrl-Shift-Q to close chrome.
virtual void Exit() = 0;
- // Invoked to ask the delegate to populate the |model|.
- virtual void BuildAppListModel(AppListModel* model) = 0;
-
// Invoked to create an AppListViewDelegate. Shell takes the ownership of
// the created delegate.
virtual AppListViewDelegate* CreateAppListViewDelegate() = 0;
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 883f073..0379e5e 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -40,9 +40,6 @@ void TestShellDelegate::LockScreen() {
void TestShellDelegate::Exit() {
}
-void TestShellDelegate::BuildAppListModel(AppListModel* model) {
-}
-
AppListViewDelegate* TestShellDelegate::CreateAppListViewDelegate() {
return NULL;
}
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index 9455da0..30f6f44 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -25,7 +25,6 @@ class TestShellDelegate : public ShellDelegate {
virtual void LockScreen() OVERRIDE;
#endif
virtual void Exit() OVERRIDE;
- virtual void BuildAppListModel(AppListModel* model) OVERRIDE;
virtual AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE;
virtual std::vector<aura::Window*> GetCycleWindowList(
CycleSource source,