summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-21 22:52:44 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-21 22:52:44 +0000
commitae4987d641566c6036fc10e9a284df687d8db4ab (patch)
treebc7f62e7bcf10b23102bd8a4e53fcc57b6d8462b /ui
parent8e937860d73f45a2fde92a736fd5f43a9e35e185 (diff)
downloadchromium_src-ae4987d641566c6036fc10e9a284df687d8db4ab.zip
chromium_src-ae4987d641566c6036fc10e9a284df687d8db4ab.tar.gz
chromium_src-ae4987d641566c6036fc10e9a284df687d8db4ab.tar.bz2
[Aura] Refactor and update app list window.
- Move showing, dimissing, animation observer, click monitoring code tha into an AppList controller in aura_shell; - Change ShellDelegate::ShowApps to an inteface to request app list widget and having a callback to notify app list controller when the widget is ready; - Click outside to dismiss the window. - Hide default container when app list is visible; BUG=98308 TEST=Verify click outside applist window to dismiss it. Browser windows should be hidden when app list window is shown and should be visible when app list is gone. Review URL: http://codereview.chromium.org/8558031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111021 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura_shell/app_list.cc175
-rw-r--r--ui/aura_shell/app_list.h83
-rw-r--r--ui/aura_shell/aura_shell.gyp2
-rw-r--r--ui/aura_shell/examples/aura_shell_main.cc35
-rw-r--r--ui/aura_shell/launcher/launcher_view.cc2
-rw-r--r--ui/aura_shell/shell.cc7
-rw-r--r--ui/aura_shell/shell.h6
-rw-r--r--ui/aura_shell/shell_delegate.h9
8 files changed, 314 insertions, 5 deletions
diff --git a/ui/aura_shell/app_list.cc b/ui/aura_shell/app_list.cc
new file mode 100644
index 0000000..0218713
--- /dev/null
+++ b/ui/aura_shell/app_list.cc
@@ -0,0 +1,175 @@
+// 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 "ui/aura_shell/app_list.h"
+
+#include "base/bind.h"
+#include "ui/aura/event.h"
+#include "ui/aura/window.h"
+#include "ui/aura_shell/shell.h"
+#include "ui/aura_shell/shell_delegate.h"
+#include "ui/aura_shell/shell_window_ids.h"
+#include "ui/gfx/screen.h"
+
+namespace aura_shell {
+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;
+
+ gfx::Point cursor = gfx::Screen::GetCursorScreenPoint();
+ gfx::Rect work_area = gfx::Screen::GetMonitorWorkAreaNearestPoint(cursor);
+ gfx::Rect widget_bounds(work_area);
+ widget_bounds.Inset(150, 100);
+ if (!show)
+ widget_bounds.Offset(0, kMoveUpAnimationOffset);
+
+ return widget_bounds;
+}
+
+ui::Layer* GetLayer(views::Widget* widget) {
+ return widget->GetNativeView()->layer();
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// AppList, public:
+
+AppList::AppList()
+ : aura::EventFilter(NULL),
+ is_visible_(false),
+ widget_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(set_widget_factory_(this)) {
+}
+
+AppList::~AppList() {
+ ResetWidget();
+}
+
+void AppList::SetVisible(bool visible) {
+ if (visible == is_visible_)
+ return;
+
+ is_visible_ = visible;
+
+ if (widget_) {
+ ScheduleAnimation();
+ } else if (is_visible_ && !set_widget_factory_.HasWeakPtrs()) {
+ Shell::GetInstance()->delegate()->RequestAppListWidget(
+ base::Bind(&AppList::SetWidget, set_widget_factory_.GetWeakPtr()));
+ }
+}
+
+bool AppList::IsVisible() {
+ return widget_ && widget_->IsVisible();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AppList, private:
+
+void AppList::SetWidget(views::Widget* widget) {
+ DCHECK(widget_ == NULL);
+ set_widget_factory_.InvalidateWeakPtrs();
+
+ if (is_visible_) {
+ widget_ = widget;
+ widget_->AddObserver(this);
+ GetLayer(widget_)->GetAnimator()->AddObserver(this);
+ Shell::GetInstance()->AddDesktopEventFilter(this);
+
+ widget_->SetBounds(GetPreferredBounds(false));
+ widget_->SetOpacity(0);
+ ScheduleAnimation();
+
+ widget_->Show();
+ widget_->Activate();
+ } else {
+ widget->Close();
+ }
+}
+
+void AppList::ResetWidget() {
+ if (!widget_)
+ return;
+
+ widget_->RemoveObserver(this);
+ GetLayer(widget_)->GetAnimator()->RemoveObserver(this);
+ Shell::GetInstance()->RemoveDesktopEventFilter(this);
+ widget_ = NULL;
+}
+
+void AppList::ScheduleAnimation() {
+ ui::Layer* layer = GetLayer(widget_);
+ ui::LayerAnimator::ScopedSettings app_list_animation(layer->GetAnimator());
+ layer->SetBounds(GetPreferredBounds(is_visible_));
+ layer->SetOpacity(is_visible_ ? 1.0 : 0.0);
+
+ ui::Layer* default_container_layer = Shell::GetInstance()->GetContainer(
+ internal::kShellWindowId_DefaultContainer)->layer();
+ ui::LayerAnimator::ScopedSettings default_container_animation(
+ default_container_layer->GetAnimator());
+ default_container_layer->SetOpacity(is_visible_ ? 0.0 : 1.0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AppList, aura::EventFilter implementation:
+
+bool AppList::PreHandleKeyEvent(aura::Window* target,
+ aura::KeyEvent* event) {
+ return false;
+}
+
+bool AppList::PreHandleMouseEvent(aura::Window* target,
+ 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()))
+ SetVisible(false);
+ }
+ return false;
+}
+
+ui::TouchStatus AppList::PreHandleTouchEvent(aura::Window* target,
+ aura::TouchEvent* event) {
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AppList, ui::LayerAnimationObserver implementation:
+
+void AppList::OnLayerAnimationEnded(
+ const ui::LayerAnimationSequence* sequence) {
+ if (!is_visible_ )
+ widget_->Close();
+}
+
+void AppList::OnLayerAnimationAborted(
+ const ui::LayerAnimationSequence* sequence) {
+}
+
+void AppList::OnLayerAnimationScheduled(
+ const ui::LayerAnimationSequence* sequence) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AppList, views::Widget::Observer implementation:
+
+void AppList::OnWidgetClosing(views::Widget* widget) {
+ DCHECK(widget_ == widget);
+ ResetWidget();
+}
+
+void AppList::OnWidgetActivationChanged(views::Widget* widget, bool active) {
+ DCHECK(widget_ == widget);
+ if (widget_ && is_visible_ && !active)
+ SetVisible(false);
+}
+
+} // namespace internal
+} // namespace aura_shell
diff --git a/ui/aura_shell/app_list.h b/ui/aura_shell/app_list.h
new file mode 100644
index 0000000..eb2b886
--- /dev/null
+++ b/ui/aura_shell/app_list.h
@@ -0,0 +1,83 @@
+// 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 UI_AURA_SHELL_APP_LIST_H_
+#define UI_AURA_SHELL_APP_LIST_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/aura/event_filter.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
+#include "views/widget/widget.h"
+
+namespace aura_shell {
+namespace internal {
+
+// AppList is a controller that manages app list UI for shell. To show the UI,
+// it requests app list widget from ShellDelegate and shows it when ready.
+// 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 ui::LayerAnimationObserver,
+ public views::Widget::Observer {
+ public:
+ AppList();
+ virtual ~AppList();
+
+ // Show/hide app list window.
+ void SetVisible(bool visible);
+
+ // Whether app list window is visible (shown or being shown).
+ bool IsVisible();
+
+ private:
+ // Sets app list widget. If we are in visible mode, start showing animation.
+ // Otherwise, we just close the widget.
+ void SetWidget(views::Widget* widget);
+
+ // Forgets the widget.
+ void ResetWidget();
+
+ // Starts show/hide animation.
+ void ScheduleAnimation();
+
+ // aura::EventFilter overrides:
+ virtual bool PreHandleKeyEvent(aura::Window* target,
+ aura::KeyEvent* event) OVERRIDE;
+ virtual bool PreHandleMouseEvent(aura::Window* target,
+ aura::MouseEvent* event) OVERRIDE;
+ virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
+ aura::TouchEvent* event) OVERRIDE;
+
+ // ui::LayerAnimationObserver overrides:
+ virtual void OnLayerAnimationEnded(
+ const ui::LayerAnimationSequence* sequence) OVERRIDE;
+ virtual void OnLayerAnimationAborted(
+ const ui::LayerAnimationSequence* sequence) OVERRIDE;
+ virtual void OnLayerAnimationScheduled(
+ const ui::LayerAnimationSequence* sequence) OVERRIDE;
+
+ // views::Widget::Observer overrides:
+ virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
+ virtual void OnWidgetActivationChanged(views::Widget* widget,
+ bool active) OVERRIDE;
+
+ // Whether we should show or hide app list widget.
+ bool is_visible_;
+
+ // App list widget we get from ShellDelegate.
+ views::Widget* widget_;
+
+ // A weak ptr factory for callbacks that ShellDelegate used to set widget.
+ base::WeakPtrFactory<AppList> set_widget_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppList);
+};
+
+} // namespace internal
+} // namespace aura_shell
+
+#endif // UI_AURA_SHELL_APP_LIST_H_
diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp
index 345b999..dd42888 100644
--- a/ui/aura_shell/aura_shell.gyp
+++ b/ui/aura_shell/aura_shell.gyp
@@ -35,6 +35,8 @@
# All .cc, .h under views, except unittests
'always_on_top_controller.cc',
'always_on_top_controller.h',
+ 'app_list.cc',
+ 'app_list.h',
'default_container_event_filter.cc',
'default_container_event_filter.h',
'default_container_layout_manager.cc',
diff --git a/ui/aura_shell/examples/aura_shell_main.cc b/ui/aura_shell/examples/aura_shell_main.cc
index 9cacb3b..17e3923 100644
--- a/ui/aura_shell/examples/aura_shell_main.cc
+++ b/ui/aura_shell/examples/aura_shell_main.cc
@@ -15,10 +15,40 @@
#include "ui/aura_shell/shell_factory.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
+#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/test/compositor_test_support.h"
+#include "views/widget/widget_delegate.h"
+#include "views/widget/widget.h"
namespace {
+class AppListWindow : public views::WidgetDelegateView {
+ public:
+ AppListWindow() {
+ }
+
+ // static
+ static views::Widget* Create() {
+ AppListWindow* app_list = new AppListWindow;
+
+ views::Widget::InitParams widget_params(
+ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ widget_params.delegate = app_list;
+ widget_params.keep_on_top = true;
+ widget_params.transparent = true;
+
+ views::Widget* widget = new views::Widget;
+ widget->Init(widget_params);
+ widget->SetContentsView(app_list);
+ return widget;
+ }
+
+ // Overridden from views::View:
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+ canvas->FillRect(SkColorSetARGB(0x4F, 0xFF, 0, 0), bounds());
+ }
+};
+
class ShellDelegateImpl : public aura_shell::ShellDelegate {
public:
ShellDelegateImpl() {
@@ -35,8 +65,9 @@ class ShellDelegateImpl : public aura_shell::ShellDelegate {
return aura_shell::internal::CreateStatusArea();
}
- virtual void ShowApps() OVERRIDE {
- NOTIMPLEMENTED();
+ virtual void RequestAppListWidget(
+ const SetWidgetCallback& callback) OVERRIDE {
+ callback.Run(AppListWindow::Create());
}
virtual void LauncherItemClicked(
diff --git a/ui/aura_shell/launcher/launcher_view.cc b/ui/aura_shell/launcher/launcher_view.cc
index b6fb445..46a0b07 100644
--- a/ui/aura_shell/launcher/launcher_view.cc
+++ b/ui/aura_shell/launcher/launcher_view.cc
@@ -598,7 +598,7 @@ void LauncherView::ButtonPressed(views::Button* sender,
if (sender == new_browser_button_) {
delegate->CreateNewWindow();
} else if (sender == show_apps_button_) {
- delegate->ShowApps();
+ Shell::GetInstance()->ToggleAppList();
} else if (sender == overflow_button_) {
ShowOverflowMenu();
} else {
diff --git a/ui/aura_shell/shell.cc b/ui/aura_shell/shell.cc
index 8a63f21..ddd08b5 100644
--- a/ui/aura_shell/shell.cc
+++ b/ui/aura_shell/shell.cc
@@ -12,6 +12,7 @@
#include "ui/aura/desktop.h"
#include "ui/aura/window.h"
#include "ui/aura/window_types.h"
+#include "ui/aura_shell/app_list.h"
#include "ui/aura_shell/default_container_event_filter.h"
#include "ui/aura_shell/default_container_layout_manager.h"
#include "ui/aura_shell/desktop_event_filter.h"
@@ -219,6 +220,12 @@ void Shell::ToggleOverview() {
workspace_controller_->ToggleOverview();
}
+void Shell::ToggleAppList() {
+ if (!app_list_.get())
+ app_list_.reset(new internal::AppList);
+ app_list_->SetVisible(!app_list_->IsVisible());
+}
+
////////////////////////////////////////////////////////////////////////////////
// Shell, private:
diff --git a/ui/aura_shell/shell.h b/ui/aura_shell/shell.h
index 3f4e3ac..0ab72bc 100644
--- a/ui/aura_shell/shell.h
+++ b/ui/aura_shell/shell.h
@@ -30,6 +30,7 @@ class Launcher;
class ShellDelegate;
namespace internal {
+class AppList;
class DragDropController;
class ShadowController;
class ShelfLayoutController;
@@ -62,6 +63,9 @@ class AURA_SHELL_EXPORT Shell {
// Toggles between overview mode and normal mode.
void ToggleOverview();
+ // Toggles app list.
+ void ToggleAppList();
+
ShellDelegate* delegate() { return delegate_.get(); }
Launcher* launcher() { return launcher_.get(); }
@@ -91,6 +95,8 @@ class AURA_SHELL_EXPORT Shell {
scoped_ptr<Launcher> launcher_;
+ scoped_ptr<internal::AppList> app_list_;
+
scoped_ptr<internal::DragDropController> drag_drop_controller_;
scoped_ptr<internal::WorkspaceController> workspace_controller_;
scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_;
diff --git a/ui/aura_shell/shell_delegate.h b/ui/aura_shell/shell_delegate.h
index b316669..28eb602 100644
--- a/ui/aura_shell/shell_delegate.h
+++ b/ui/aura_shell/shell_delegate.h
@@ -6,6 +6,7 @@
#define UI_AURA_SHELL_SHELL_DELEGATE_H_
#pragma once
+#include "base/callback.h"
#include "ui/aura_shell/aura_shell_export.h"
namespace views {
@@ -19,6 +20,9 @@ struct LauncherItem;
// Delegate of the Shell.
class AURA_SHELL_EXPORT ShellDelegate {
public:
+ // Callback to pass back a widget used by RequestAppListWidget.
+ typedef base::Callback<void(views::Widget*)> SetWidgetCallback;
+
// The Shell owns the delegate.
virtual ~ShellDelegate() {}
@@ -29,8 +33,9 @@ class AURA_SHELL_EXPORT ShellDelegate {
// Invoked to create a new status area. Can return NULL.
virtual views::Widget* CreateStatusArea() = 0;
- // Invoked when the user clicks the app list button on the launcher.
- virtual void ShowApps() = 0;
+ // Invoked to create app list widget. The Delegate calls the callback
+ // when the widget is ready to show.
+ virtual void RequestAppListWidget(const SetWidgetCallback& callback) = 0;
// Invoked when the user clicks on a window entry in the launcher.
virtual void LauncherItemClicked(const LauncherItem& item) = 0;