summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 14:53:34 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 14:53:34 +0000
commit4f08470c76d8bb2b8959d06eac0f58671940b395 (patch)
tree67cbfca6085cc3c2f8b28041d6be44655e8efd3f
parent61f790d9313c405c54159dd65f4dc473fd0c43fa (diff)
downloadchromium_src-4f08470c76d8bb2b8959d06eac0f58671940b395.zip
chromium_src-4f08470c76d8bb2b8959d06eac0f58671940b395.tar.gz
chromium_src-4f08470c76d8bb2b8959d06eac0f58671940b395.tar.bz2
ash: Update app list button.
- Update the icons assets; - Make app list button a ToggleImageButton and wire its toggle state with app list UI visibility; - Make app list button icon vertically center aligned and get rid of the special handling; - Expose toggled state from ToggleImageButton so that it could be checked in test; BUG=235994 R=sky@chromium.org Review URL: https://codereview.chromium.org/13993027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197366 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/launcher/app_list_button.cc29
-rw-r--r--ash/launcher/app_list_button.h9
-rw-r--r--ash/launcher/launcher_unittest.cc54
-rw-r--r--ash/launcher/launcher_view.cc29
-rw-r--r--ash/resources/default_100_percent/common/launcher/launcher_appmenu.pngbin348 -> 368 bytes
-rw-r--r--ash/resources/default_100_percent/common/launcher/launcher_appmenu_hover.pngbin331 -> 343 bytes
-rw-r--r--ash/resources/default_100_percent/common/launcher/launcher_appmenu_pressed.pngbin316 -> 432 bytes
-rw-r--r--ash/resources/default_200_percent/common/launcher/launcher_appmenu.pngbin662 -> 457 bytes
-rw-r--r--ash/resources/default_200_percent/common/launcher/launcher_appmenu_hover.pngbin576 -> 470 bytes
-rw-r--r--ash/resources/default_200_percent/common/launcher/launcher_appmenu_pressed.pngbin547 -> 501 bytes
-rw-r--r--ash/shell.cc26
-rw-r--r--ash/shell.h4
-rw-r--r--ash/wm/app_list_controller.cc61
-rw-r--r--ash/wm/app_list_controller.h22
-rw-r--r--ash/wm/app_list_controller_observer.h29
-rw-r--r--ui/views/controls/button/image_button.h1
16 files changed, 201 insertions, 63 deletions
diff --git a/ash/launcher/app_list_button.cc b/ash/launcher/app_list_button.cc
index 8879a38..bd7bfcf 100644
--- a/ash/launcher/app_list_button.cc
+++ b/ash/launcher/app_list_button.cc
@@ -8,8 +8,11 @@
#include "ash/launcher/launcher_button_host.h"
#include "ash/launcher/launcher_types.h"
+#include "ash/shell.h"
+#include "ash/wm/app_list_controller.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
+#include "ui/aura/window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
@@ -17,6 +20,7 @@
#include "ui/compositor/layer_animation_element.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/views/widget/widget.h"
namespace ash {
namespace internal {
@@ -30,7 +34,7 @@ const int kBorderSize = 9;
AppListButton::AppListButton(views::ButtonListener* listener,
LauncherButtonHost* host)
- : views::ImageButton(listener),
+ : views::ToggleImageButton(listener),
host_(host) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
SetImage(
@@ -44,12 +48,23 @@ AppListButton::AppListButton(views::ButtonListener* listener,
views::CustomButton::STATE_PRESSED,
rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_APPLIST_PUSHED).
ToImageSkia());
+
+ const gfx::ImageSkia* toggled_image =
+ rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_APPLIST_PUSHED).
+ ToImageSkia();
+ SetToggledImage(views::CustomButton::STATE_NORMAL, toggled_image);
+ SetToggledImage(views::CustomButton::STATE_HOVERED, toggled_image);
+ SetToggledImage(views::CustomButton::STATE_PRESSED, toggled_image);
+
SetAccessibleName(l10n_util::GetStringUTF16(IDS_AURA_APP_LIST_TITLE));
SetSize(gfx::Size(kLauncherPreferredSize, kLauncherPreferredSize));
- SetImageAlignment(ImageButton::ALIGN_CENTER, ImageButton::ALIGN_TOP);
+ SetImageAlignment(ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE);
+
+ Shell::GetInstance()->app_list_controller()->AddObserver(this);
}
AppListButton::~AppListButton() {
+ Shell::GetInstance()->app_list_controller()->RemoveObserver(this);
}
void AppListButton::StartLoadingAnimation() {
@@ -130,5 +145,15 @@ void AppListButton::GetAccessibleState(ui::AccessibleViewState* state) {
state->name = host_->GetAccessibleName(this);
}
+void AppListButton::OnAppLauncherVisibilityChanged(
+ bool visible, const aura::RootWindow* root_window) {
+ if (!GetWidget() ||
+ GetWidget()->GetNativeView()->GetRootWindow() != root_window) {
+ return;
+ }
+
+ SetToggled(visible);
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/launcher/app_list_button.h b/ash/launcher/app_list_button.h
index 4d25254..4d1cd63 100644
--- a/ash/launcher/app_list_button.h
+++ b/ash/launcher/app_list_button.h
@@ -5,6 +5,7 @@
#ifndef ASH_LAUNCHER_APP_LIST_BUTTON_H_
#define ASH_LAUNCHER_APP_LIST_BUTTON_H_
+#include "ash/wm/app_list_controller_observer.h"
#include "ui/views/controls/button/image_button.h"
namespace ash {
@@ -13,7 +14,8 @@ namespace internal {
class LauncherButtonHost;
// Button used for the AppList icon on the launcher.
-class AppListButton : public views::ImageButton {
+class AppListButton : public views::ToggleImageButton,
+ public AppListControllerObserver {
public:
AppListButton(views::ButtonListener* listener,
LauncherButtonHost* host);
@@ -34,6 +36,11 @@ class AppListButton : public views::ImageButton {
virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
private:
+ // AppListControllerObserver overrides:
+ virtual void OnAppLauncherVisibilityChanged(
+ bool visible,
+ const aura::RootWindow* root_window) OVERRIDE;
+
LauncherButtonHost* host_;
DISALLOW_COPY_AND_ASSIGN(AppListButton);
diff --git a/ash/launcher/launcher_unittest.cc b/ash/launcher/launcher_unittest.cc
index 59d6a67..06b77ba 100644
--- a/ash/launcher/launcher_unittest.cc
+++ b/ash/launcher/launcher_unittest.cc
@@ -3,10 +3,13 @@
// found in the LICENSE file.
#include "ash/launcher/launcher.h"
+
+#include <vector>
+
+#include "ash/launcher/app_list_button.h"
#include "ash/launcher/launcher_button.h"
#include "ash/launcher/launcher_model.h"
#include "ash/launcher/launcher_view.h"
-
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
@@ -24,6 +27,7 @@
#endif
typedef ash::test::AshTestBase LauncherTest;
+using ash::internal::AppListButton;
using ash::internal::LauncherView;
using ash::internal::LauncherButton;
@@ -57,7 +61,7 @@ TEST_F(LauncherTest, OpenBrowser) {
// Confirm that using the menu will clear the hover attribute. To avoid another
// browser test we check this here.
-TEST_F(LauncherTest, checkHoverAfterMenu) {
+TEST_F(LauncherTest, CheckHoverAfterMenu) {
Launcher* launcher = Launcher::ForPrimaryDisplay();
ASSERT_TRUE(launcher);
LauncherView* launcher_view = launcher->GetLauncherViewForTest();
@@ -116,4 +120,50 @@ TEST_F(LauncherTest, ShowOverflowBubble) {
EXPECT_FALSE(launcher->IsShowingOverflowBubble());
}
+// Tests app list button toggles when app list UI shows up.
+TEST_F(LauncherTest, AppMenuToggle) {
+ AppListButton* app_list_button = static_cast<AppListButton*>(
+ Launcher::ForPrimaryDisplay()->GetLauncherViewForTest()->
+ GetAppListButtonView());
+ Shell* shell = Shell::GetInstance();
+
+ EXPECT_FALSE(shell->GetAppListTargetVisibility());
+ EXPECT_FALSE(app_list_button->toggled());
+ shell->ToggleAppList(NULL);
+ EXPECT_TRUE(shell->GetAppListTargetVisibility());
+ EXPECT_TRUE(app_list_button->toggled());
+}
+
+// Tests only the app list button with a UI is toggled.
+TEST_F(LauncherTest, MultipleAppMenuToggle) {
+ UpdateDisplay("300x300,200x200");
+
+ std::vector<AppListButton*> app_list_buttons;
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (Shell::RootWindowList::const_iterator it = root_windows.begin();
+ it != root_windows.end(); ++it) {
+ AppListButton* button = static_cast<AppListButton*>(
+ Launcher::ForWindow(*it)->GetLauncherViewForTest()->
+ GetAppListButtonView());
+ app_list_buttons.push_back(button);
+ EXPECT_FALSE(button->toggled());
+ }
+
+ Shell* shell = Shell::GetInstance();
+
+ EXPECT_FALSE(shell->GetAppListTargetVisibility());
+ shell->ToggleAppList(root_windows[0]);
+ EXPECT_TRUE(shell->GetAppListTargetVisibility());
+ EXPECT_TRUE(app_list_buttons[0]->toggled());
+ EXPECT_FALSE(app_list_buttons[1]->toggled());
+
+ shell->ToggleAppList(NULL);
+ EXPECT_FALSE(shell->GetAppListTargetVisibility());
+
+ shell->ToggleAppList(root_windows[1]);
+ EXPECT_TRUE(shell->GetAppListTargetVisibility());
+ EXPECT_FALSE(app_list_buttons[0]->toggled());
+ EXPECT_TRUE(app_list_buttons[1]->toggled());
+}
+
} // namespace ash
diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc
index 810baed..e324624 100644
--- a/ash/launcher/launcher_view.cc
+++ b/ash/launcher/launcher_view.cc
@@ -420,22 +420,7 @@ void LauncherView::OnShelfAlignmentChanged() {
UpdateFirstButtonPadding();
overflow_button_->OnShelfAlignmentChanged();
LayoutToIdealBounds();
- for (int i=0; i < view_model_->view_size(); ++i) {
- // TODO: remove when AppIcon is a Launcher Button.
- if (TYPE_APP_LIST == model_->items()[i].type) {
- ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
- static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment(
- shelf->SelectValueForShelfAlignment(
- views::ImageButton::ALIGN_CENTER,
- views::ImageButton::ALIGN_LEFT,
- views::ImageButton::ALIGN_RIGHT,
- views::ImageButton::ALIGN_CENTER),
- shelf->SelectValueForShelfAlignment(
- views::ImageButton::ALIGN_TOP,
- views::ImageButton::ALIGN_MIDDLE,
- views::ImageButton::ALIGN_MIDDLE,
- views::ImageButton::ALIGN_BOTTOM));
- }
+ for (int i = 0; i < view_model_->view_size(); ++i) {
if (i >= first_visible_index_ && i <= last_visible_index_)
view_model_->view_at(i)->Layout();
}
@@ -763,18 +748,6 @@ views::View* LauncherView::CreateViewForItem(const LauncherItem& item) {
case TYPE_APP_LIST: {
// TODO(dave): turn this into a LauncherButton too.
AppListButton* button = new AppListButton(this, this);
- ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager();
- button->SetImageAlignment(
- shelf->SelectValueForShelfAlignment(
- views::ImageButton::ALIGN_CENTER,
- views::ImageButton::ALIGN_LEFT,
- views::ImageButton::ALIGN_RIGHT,
- views::ImageButton::ALIGN_CENTER),
- shelf->SelectValueForShelfAlignment(
- views::ImageButton::ALIGN_TOP,
- views::ImageButton::ALIGN_MIDDLE,
- views::ImageButton::ALIGN_MIDDLE,
- views::ImageButton::ALIGN_BOTTOM));
view = button;
break;
}
diff --git a/ash/resources/default_100_percent/common/launcher/launcher_appmenu.png b/ash/resources/default_100_percent/common/launcher/launcher_appmenu.png
index 13118c8..7e17571 100644
--- a/ash/resources/default_100_percent/common/launcher/launcher_appmenu.png
+++ b/ash/resources/default_100_percent/common/launcher/launcher_appmenu.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/launcher/launcher_appmenu_hover.png b/ash/resources/default_100_percent/common/launcher/launcher_appmenu_hover.png
index bafb356..4b0e80f 100644
--- a/ash/resources/default_100_percent/common/launcher/launcher_appmenu_hover.png
+++ b/ash/resources/default_100_percent/common/launcher/launcher_appmenu_hover.png
Binary files differ
diff --git a/ash/resources/default_100_percent/common/launcher/launcher_appmenu_pressed.png b/ash/resources/default_100_percent/common/launcher/launcher_appmenu_pressed.png
index c6f0ce0..87ebbc8 100644
--- a/ash/resources/default_100_percent/common/launcher/launcher_appmenu_pressed.png
+++ b/ash/resources/default_100_percent/common/launcher/launcher_appmenu_pressed.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_appmenu.png b/ash/resources/default_200_percent/common/launcher/launcher_appmenu.png
index 8a3ba66a..d504bfc4 100644
--- a/ash/resources/default_200_percent/common/launcher/launcher_appmenu.png
+++ b/ash/resources/default_200_percent/common/launcher/launcher_appmenu.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_appmenu_hover.png b/ash/resources/default_200_percent/common/launcher/launcher_appmenu_hover.png
index 5758ec9..4875b5b 100644
--- a/ash/resources/default_200_percent/common/launcher/launcher_appmenu_hover.png
+++ b/ash/resources/default_200_percent/common/launcher/launcher_appmenu_hover.png
Binary files differ
diff --git a/ash/resources/default_200_percent/common/launcher/launcher_appmenu_pressed.png b/ash/resources/default_200_percent/common/launcher/launcher_appmenu_pressed.png
index dd40409..35cb32f 100644
--- a/ash/resources/default_200_percent/common/launcher/launcher_appmenu_pressed.png
+++ b/ash/resources/default_200_percent/common/launcher/launcher_appmenu_pressed.png
Binary files differ
diff --git a/ash/shell.cc b/ash/shell.cc
index 9297b0e..93cd61f 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -259,11 +259,11 @@ Shell::~Shell() {
// TooltipController is deleted with the Shell so removing its references.
RemovePreTargetHandler(tooltip_controller_.get());
- // AppList needs to be released before shelf layout manager, which is
- // destroyed with launcher container in the loop below. However, app list
- // container is now on top of launcher container and released after it.
- // TODO(xiyuan): Move it back when app list container is no longer needed.
- app_list_controller_.reset();
+ // AppList needs to clean up it dependency on Shell and closes its opened
+ // UI (if any) before closing all RootWindows. However, the controller
+ // instance is still needed so that sub views (e.g. app menu button on
+ // the shelf) could properly clean up.
+ app_list_controller_->Shutdown();
// Destroy SystemTrayDelegate before destroying the status area(s).
system_tray_delegate_->Shutdown();
@@ -586,6 +586,10 @@ void Shell::Init() {
if (!system_tray_delegate_)
system_tray_delegate_.reset(SystemTrayDelegate::CreateDummyDelegate());
+ // Creates app_list_controller_ before the launcher because app list
+ // button observes it for UI visibility.
+ app_list_controller_.reset(new internal::AppListController(this));
+
// Creates StatusAreaWidget.
root_window_controller->InitForPrimaryDisplay();
@@ -636,21 +640,15 @@ void Shell::ShowContextMenu(const gfx::Point& location_in_screen) {
}
void Shell::ToggleAppList(aura::Window* window) {
- // If the context window is not given, show it on the active root window.
- if (!window)
- window = GetActiveRootWindow();
- if (!app_list_controller_)
- app_list_controller_.reset(new internal::AppListController);
- app_list_controller_->SetVisible(!app_list_controller_->IsVisible(), window);
+ app_list_controller_->Toggle(window);
}
bool Shell::GetAppListTargetVisibility() const {
- return app_list_controller_.get() &&
- app_list_controller_->GetTargetVisibility();
+ return app_list_controller_->GetTargetVisibility();
}
aura::Window* Shell::GetAppListWindow() {
- return app_list_controller_.get() ? app_list_controller_->GetWindow() : NULL;
+ return app_list_controller_->GetWindow();
}
bool Shell::IsSystemModalWindowOpen() const {
diff --git a/ash/shell.h b/ash/shell.h
index 67551c8..27e94a0 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -444,6 +444,10 @@ class ASH_EXPORT Shell
return launcher_model_.get();
}
+ internal::AppListController* app_list_controller() {
+ return app_list_controller_.get();
+ }
+
// Returns the launcher delegate, creating if necesary.
LauncherDelegate* GetLauncherDelegate();
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index 7fcf76c..6776b60 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -10,6 +10,7 @@
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
+#include "ash/wm/app_list_controller_observer.h"
#include "ash/wm/property_util.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/pagination_model.h"
@@ -52,10 +53,11 @@ views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) {
views::BubbleBorder::TOP_CENTER);
}
-// Offset given |rect| towards shelf.
-gfx::Rect OffsetTowardsShelf(const gfx::Rect& rect, views::Widget* widget) {
- DCHECK(Shell::HasInstance());
- ShelfAlignment shelf_alignment = Shell::GetInstance()->GetShelfAlignment(
+// Offsets the given |rect| towards shelf.
+gfx::Rect OffsetTowardsShelf(Shell* shell,
+ const gfx::Rect& rect,
+ views::Widget* widget) {
+ ShelfAlignment shelf_alignment = shell->GetShelfAlignment(
widget->GetNativeView()->GetRootWindow());
gfx::Rect offseted(rect);
switch (shelf_alignment) {
@@ -81,23 +83,31 @@ gfx::Rect OffsetTowardsShelf(const gfx::Rect& rect, views::Widget* widget) {
////////////////////////////////////////////////////////////////////////////////
// AppListController, public:
-AppListController::AppListController()
- : pagination_model_(new app_list::PaginationModel),
+AppListController::AppListController(Shell* shell)
+ : shell_(shell),
+ pagination_model_(new app_list::PaginationModel),
is_visible_(false),
view_(NULL),
should_snap_back_(false) {
- Shell::GetInstance()->AddShellObserver(this);
+ shell_->AddShellObserver(this);
pagination_model_->AddObserver(this);
}
AppListController::~AppListController() {
+ Shutdown();
+ pagination_model_->RemoveObserver(this);
+}
+
+void AppListController::Shutdown() {
// Ensures app list view goes before the controller since pagination model
// lives in the controller and app list view would access it on destruction.
if (view_ && view_->GetWidget())
view_->GetWidget()->CloseNow();
- Shell::GetInstance()->RemoveShellObserver(this);
- pagination_model_->RemoveObserver(this);
+ if (shell_) {
+ shell_->RemoveShellObserver(this);
+ shell_ = NULL;
+ }
}
void AppListController::SetVisible(bool visible, aura::Window* window) {
@@ -111,14 +121,18 @@ void AppListController::SetVisible(bool visible, aura::Window* window) {
Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
UpdateAutoHideState();
+ // Determine the root window to show the UI.
+ aura::RootWindow* root_window =
+ window ? window->GetRootWindow() : Shell::GetActiveRootWindow();
+
if (view_) {
ScheduleAnimation();
} else if (is_visible_) {
// AppListModel and AppListViewDelegate are owned by AppListView. They
// will be released with AppListView on close.
app_list::AppListView* view = new app_list::AppListView(
- Shell::GetInstance()->delegate()->CreateAppListViewDelegate());
- aura::Window* container = GetRootWindowController(window->GetRootWindow())->
+ shell_->delegate()->CreateAppListViewDelegate());
+ aura::Window* container = GetRootWindowController(root_window)->
GetContainer(kShellWindowId_AppListContainer);
view->InitAsBubble(
container,
@@ -129,16 +143,32 @@ void AppListController::SetVisible(bool visible, aura::Window* window) {
true /* border_accepts_events */);
SetView(view);
}
+
+ FOR_EACH_OBSERVER(AppListControllerObserver,
+ observers_,
+ OnAppLauncherVisibilityChanged(is_visible_, root_window));
}
bool AppListController::IsVisible() const {
return view_ && view_->GetWidget()->IsVisible();
}
+void AppListController::Toggle(aura::Window* window) {
+ SetVisible(!IsVisible(), window);
+}
+
aura::Window* AppListController::GetWindow() {
return is_visible_ && view_ ? view_->GetWidget()->GetNativeWindow() : NULL;
}
+void AppListController::AddObserver(AppListControllerObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void AppListController::RemoveObserver(AppListControllerObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
////////////////////////////////////////////////////////////////////////////////
// AppListController, private:
@@ -149,7 +179,7 @@ void AppListController::SetView(app_list::AppListView* view) {
view_ = view;
views::Widget* widget = view_->GetWidget();
widget->AddObserver(this);
- Shell::GetInstance()->AddPreTargetHandler(this);
+ shell_->AddPreTargetHandler(this);
Launcher::ForWindow(widget->GetNativeWindow())->AddIconObserver(this);
widget->GetNativeView()->GetRootWindow()->AddRootWindowObserver(this);
aura::client::GetFocusClient(widget->GetNativeView())->AddObserver(this);
@@ -164,7 +194,7 @@ void AppListController::ResetView() {
views::Widget* widget = view_->GetWidget();
widget->RemoveObserver(this);
GetLayer(widget)->GetAnimator()->RemoveObserver(this);
- Shell::GetInstance()->RemovePreTargetHandler(this);
+ shell_->RemovePreTargetHandler(this);
Launcher::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this);
widget->GetNativeView()->GetRootWindow()->RemoveRootWindowObserver(this);
aura::client::GetFocusClient(widget->GetNativeView())->RemoveObserver(this);
@@ -182,9 +212,10 @@ void AppListController::ScheduleAnimation() {
gfx::Rect target_bounds;
if (is_visible_) {
target_bounds = widget->GetWindowBoundsInScreen();
- widget->SetBounds(OffsetTowardsShelf(target_bounds, widget));
+ widget->SetBounds(OffsetTowardsShelf(shell_, target_bounds, widget));
} else {
- target_bounds = OffsetTowardsShelf(widget->GetWindowBoundsInScreen(),
+ target_bounds = OffsetTowardsShelf(shell_,
+ widget->GetWindowBoundsInScreen(),
widget);
}
diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h
index d2408d8..385e1e5 100644
--- a/ash/wm/app_list_controller.h
+++ b/ash/wm/app_list_controller.h
@@ -9,6 +9,7 @@
#include "ash/shell_observer.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/observer_list.h"
#include "base/timer.h"
#include "ui/app_list/pagination_model_observer.h"
#include "ui/aura/client/focus_change_observer.h"
@@ -28,8 +29,13 @@ class LocatedEvent;
}
namespace ash {
+
+class Shell;
+
namespace internal {
+class AppListControllerObserver;
+
// AppListController is a controller that manages app list UI for shell.
// It creates AppListView and schedules showing/hiding animation.
// While the UI is visible, it monitors things such as app list widget's
@@ -43,9 +49,12 @@ class AppListController : public ui::EventHandler,
public LauncherIconObserver,
public app_list::PaginationModelObserver {
public:
- AppListController();
+ explicit AppListController(Shell* shell);
virtual ~AppListController();
+ // Closes opened app list and cleans up its dependency on shell.
+ void Shutdown();
+
// Show/hide app list window. The |window| is used to deterime in
// which display (in which the |window| exists) the app list should
// be shown.
@@ -54,6 +63,10 @@ class AppListController : public ui::EventHandler,
// Whether app list window is visible (shown or being shown).
bool IsVisible() const;
+ // Convenience wrapper to toggle visibility using the SetVisible() and
+ // IsVisible().
+ void Toggle(aura::Window* window);
+
// Returns target visibility. This differs from IsVisible() if an animation
// is ongoing.
bool GetTargetVisibility() const { return is_visible_; }
@@ -61,6 +74,9 @@ class AppListController : public ui::EventHandler,
// Returns app list window or NULL if it is not visible.
aura::Window* GetWindow();
+ void AddObserver(AppListControllerObserver* observer);
+ void RemoveObserver(AppListControllerObserver* observer);
+
private:
// Sets the app list view and attempts to show it.
void SetView(app_list::AppListView* view);
@@ -105,6 +121,8 @@ class AppListController : public ui::EventHandler,
virtual void SelectedPageChanged(int old_selected, int new_selected) OVERRIDE;
virtual void TransitionChanged() OVERRIDE;
+ Shell* shell_;
+
scoped_ptr<app_list::PaginationModel> pagination_model_;
// Whether we should show or hide app list widget.
@@ -119,6 +137,8 @@ class AppListController : public ui::EventHandler,
// Whether should schedule snap back animation.
bool should_snap_back_;
+ ObserverList<AppListControllerObserver, true> observers_;
+
DISALLOW_COPY_AND_ASSIGN(AppListController);
};
diff --git a/ash/wm/app_list_controller_observer.h b/ash/wm/app_list_controller_observer.h
new file mode 100644
index 0000000..0ea0400
--- /dev/null
+++ b/ash/wm/app_list_controller_observer.h
@@ -0,0 +1,29 @@
+// Copyright 2013 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_WM_APP_LIST_CONTROLLER_OBSERVER_H_
+#define ASH_WM_APP_LIST_CONTROLLER_OBSERVER_H_
+
+namespace aura {
+class RootWindow;
+}
+
+namespace ash {
+namespace internal {
+
+class AppListControllerObserver {
+ public:
+ // Invoked when app launcher bubble is toggled on the given root window.
+ virtual void OnAppLauncherVisibilityChanged(
+ bool visible,
+ const aura::RootWindow* root_window) = 0;
+
+ protected:
+ virtual ~AppListControllerObserver() {}
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif // ASH_WM_APP_LIST_CONTROLLER_OBSERVER_H_
diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h
index 4015def..44f5cfb 100644
--- a/ui/views/controls/button/image_button.h
+++ b/ui/views/controls/button/image_button.h
@@ -109,6 +109,7 @@ class VIEWS_EXPORT ToggleImageButton : public ImageButton {
// Change the toggled state.
void SetToggled(bool toggled);
+ bool toggled() const { return toggled_; }
// Like ImageButton::SetImage(), but to set the graphics used for the
// "has been toggled" state. Must be called for each button state