diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-07 16:59:13 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-07 16:59:13 +0000 |
commit | ae18b9118e18fc29268e32c537a2982c6a839c02 (patch) | |
tree | a1417583c62a2f01ff445c9826e786d7262b54e4 /ui/aura_shell | |
parent | 0edc5541930fd448b66f454375ee7ee8e1851e62 (diff) | |
download | chromium_src-ae18b9118e18fc29268e32c537a2982c6a839c02.zip chromium_src-ae18b9118e18fc29268e32c537a2982c6a839c02.tar.gz chromium_src-ae18b9118e18fc29268e32c537a2982c6a839c02.tar.bz2 |
Adds class to manage layout of the launcher and status area. When
entering fullscreen the shelf is hidden and exiting makes the shelf
visible. Transitions are animated, but it likely needs some tweaks.
BUG=none
TEST=none
R=ben@chromium.org
Review URL: http://codereview.chromium.org/8475012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108877 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura_shell')
-rw-r--r-- | ui/aura_shell/aura_shell.gyp | 2 | ||||
-rw-r--r-- | ui/aura_shell/desktop_layout_manager.cc | 19 | ||||
-rw-r--r-- | ui/aura_shell/desktop_layout_manager.h | 16 | ||||
-rw-r--r-- | ui/aura_shell/shelf_layout_controller.cc | 118 | ||||
-rw-r--r-- | ui/aura_shell/shelf_layout_controller.h | 83 | ||||
-rw-r--r-- | ui/aura_shell/shell.cc | 19 | ||||
-rw-r--r-- | ui/aura_shell/shell.h | 3 | ||||
-rw-r--r-- | ui/aura_shell/status_area_view.h | 1 | ||||
-rw-r--r-- | ui/aura_shell/toplevel_layout_manager.cc | 23 | ||||
-rw-r--r-- | ui/aura_shell/toplevel_layout_manager.h | 10 |
10 files changed, 259 insertions, 35 deletions
diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp index bea8aff..17e7145 100644 --- a/ui/aura_shell/aura_shell.gyp +++ b/ui/aura_shell/aura_shell.gyp @@ -59,6 +59,8 @@ 'launcher/view_model_utils.h', 'property_util.cc', 'property_util.h', + 'shelf_layout_controller.cc', + 'shelf_layout_controller.h', 'shell.cc', 'shell.h', 'shell_delegate.h', diff --git a/ui/aura_shell/desktop_layout_manager.cc b/ui/aura_shell/desktop_layout_manager.cc index 32db2ba..fbcdb17 100644 --- a/ui/aura_shell/desktop_layout_manager.cc +++ b/ui/aura_shell/desktop_layout_manager.cc @@ -4,6 +4,7 @@ #include "ui/aura_shell/desktop_layout_manager.h" +#include "ui/aura_shell/shelf_layout_controller.h" #include "ui/aura/window.h" #include "views/widget/widget.h" @@ -16,8 +17,7 @@ namespace internal { DesktopLayoutManager::DesktopLayoutManager(aura::Window* owner) : owner_(owner), background_widget_(NULL), - launcher_widget_(NULL), - status_area_widget_(NULL) { + shelf_(NULL) { } DesktopLayoutManager::~DesktopLayoutManager() { @@ -36,19 +36,8 @@ void DesktopLayoutManager::OnWindowResized() { background_widget_->SetBounds(fullscreen_bounds); - gfx::Rect status_area_bounds = status_area_widget_->GetWindowScreenBounds(); - status_area_widget_->SetBounds( - gfx::Rect(owner_->bounds().right() - status_area_bounds.width(), - owner_->bounds().bottom() - status_area_bounds.height(), - status_area_bounds.width(), - status_area_bounds.height())); - - // Give the launcher the available width minus the status area. - gfx::Rect launcher_bounds = launcher_widget_->GetWindowScreenBounds(); - launcher_widget_->SetBounds( - gfx::Rect(0, owner_->bounds().bottom() - launcher_bounds.height(), - owner_->bounds().width() - status_area_bounds.width(), - launcher_bounds.height())); + if (shelf_) + shelf_->LayoutShelf(); } void DesktopLayoutManager::OnWindowAdded(aura::Window* child) { diff --git a/ui/aura_shell/desktop_layout_manager.h b/ui/aura_shell/desktop_layout_manager.h index 74c00c5..08bc16c 100644 --- a/ui/aura_shell/desktop_layout_manager.h +++ b/ui/aura_shell/desktop_layout_manager.h @@ -23,6 +23,8 @@ class Widget; namespace aura_shell { namespace internal { +class ShelfLayoutController; + // A layout manager for the root window. // Resizes all of its immediate children to fill the bounds of the root window. class DesktopLayoutManager : public aura::LayoutManager { @@ -30,18 +32,12 @@ class DesktopLayoutManager : public aura::LayoutManager { explicit DesktopLayoutManager(aura::Window* owner); virtual ~DesktopLayoutManager(); + void set_shelf(ShelfLayoutController* shelf) { shelf_ = shelf; } + void set_background_widget(views::Widget* background_widget) { background_widget_ = background_widget; } - void set_launcher_widget(views::Widget* launcher_widget) { - launcher_widget_ = launcher_widget; - } - - void set_status_area_widget(views::Widget* status_area_widget) { - status_area_widget_ = status_area_widget; - } - // Overridden from aura::LayoutManager: virtual void OnWindowResized() OVERRIDE; virtual void OnWindowAdded(aura::Window* child) OVERRIDE; @@ -55,8 +51,8 @@ class DesktopLayoutManager : public aura::LayoutManager { aura::Window* owner_; views::Widget* background_widget_; - views::Widget* launcher_widget_; - views::Widget* status_area_widget_; + + ShelfLayoutController* shelf_; DISALLOW_COPY_AND_ASSIGN(DesktopLayoutManager); }; diff --git a/ui/aura_shell/shelf_layout_controller.cc b/ui/aura_shell/shelf_layout_controller.cc new file mode 100644 index 0000000..9e8d01a --- /dev/null +++ b/ui/aura_shell/shelf_layout_controller.cc @@ -0,0 +1,118 @@ +// 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/shelf_layout_controller.h" + +#include "ui/aura/desktop.h" +#include "ui/aura/screen_aura.h" +#include "ui/gfx/compositor/layer.h" +#include "ui/gfx/compositor/layer_animator.h" +#include "views/widget/widget.h" + +namespace aura_shell { +namespace internal { + +namespace { + +ui::Layer* GetLayer(views::Widget* widget) { + return widget->GetNativeView()->layer(); +} + +} // namespace + +ShelfLayoutController::ShelfLayoutController(views::Widget* launcher, + views::Widget* status) + : animating_(false), + visible_(true), + max_height_(-1), + launcher_(launcher), + status_(status) { + gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds(); + gfx::Rect status_bounds = status->GetWindowScreenBounds(); + max_height_ = std::max(launcher_bounds.height(), status_bounds.height()); + GetLayer(launcher)->GetAnimator()->AddObserver(this); +} + +ShelfLayoutController::~ShelfLayoutController() { + GetLayer(launcher_)->GetAnimator()->RemoveObserver(this); +} + +void ShelfLayoutController::LayoutShelf() { + StopAnimating(); + TargetBounds target_bounds; + float target_opacity = visible_ ? 1.0f : 0.0f; + CalculateTargetBounds(visible_, &target_bounds); + GetLayer(launcher_)->SetOpacity(target_opacity); + GetLayer(status_)->SetOpacity(target_opacity); + launcher_->SetBounds(target_bounds.launcher_bounds); + status_->SetBounds(target_bounds.status_bounds); + aura::Desktop::GetInstance()->screen()->set_work_area_insets( + target_bounds.work_area_insets); +} + +void ShelfLayoutController::SetVisible(bool visible) { + bool current_visibility = animating_ ? !visible_ : visible_; + if (visible == current_visibility) + return; // Nothing changed. + + StopAnimating(); + + TargetBounds target_bounds; + float target_opacity = visible ? 1.0f : 0.0f; + CalculateTargetBounds(visible, &target_bounds); + AnimateWidgetTo(launcher_, target_bounds.launcher_bounds, target_opacity); + AnimateWidgetTo(status_, target_bounds.status_bounds, target_opacity); + animating_ = true; + // |visible_| is updated once the animation completes. +} + +void ShelfLayoutController::StopAnimating() { + if (animating_) { + animating_ = false; + visible_ = !visible_; + } + GetLayer(launcher_)->GetAnimator()->StopAnimating(); +} + +void ShelfLayoutController::CalculateTargetBounds(bool visible, + TargetBounds* target_bounds) { + const gfx::Rect& available_bounds(aura::Desktop::GetInstance()->bounds()); + int y = available_bounds.bottom() - (visible ? max_height_ : 0); + gfx::Rect status_bounds(status_->GetWindowScreenBounds()); + target_bounds->status_bounds = gfx::Rect( + available_bounds.right() - status_bounds.width(), + y + (max_height_ - status_bounds.height()) / 2, + status_bounds.width(), status_bounds.height()); + gfx::Rect launcher_bounds(launcher_->GetWindowScreenBounds()); + target_bounds->launcher_bounds = gfx::Rect( + available_bounds.x(), y + (max_height_ - launcher_bounds.height()) / 2, + available_bounds.width() - status_bounds.width(), + launcher_bounds.height()); + if (visible) + target_bounds->work_area_insets = gfx::Insets(0, 0, max_height_, 0); +} + +void ShelfLayoutController::AnimateWidgetTo(views::Widget* widget, + const gfx::Rect& target_bounds, + float target_opacity) { + ui::Layer* layer = GetLayer(widget); + ui::LayerAnimator::ScopedSettings animation_setter(layer->GetAnimator()); + widget->SetBounds(target_bounds); + layer->SetOpacity(target_opacity); +} + +void ShelfLayoutController::OnLayerAnimationEnded( + const ui::LayerAnimationSequence* sequence) { + if (!animating_) + return; + animating_ = false; + visible_ = !visible_; + TargetBounds target_bounds; + CalculateTargetBounds(visible_, &target_bounds); + aura::Desktop::GetInstance()->screen()->set_work_area_insets( + target_bounds.work_area_insets); +} + +} // internal +} // aura_shell diff --git a/ui/aura_shell/shelf_layout_controller.h b/ui/aura_shell/shelf_layout_controller.h new file mode 100644 index 0000000..a675699 --- /dev/null +++ b/ui/aura_shell/shelf_layout_controller.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_SHELF_LAYOUT_CONTROLLER_H_ +#define UI_AURA_SHELL_SHELF_LAYOUT_CONTROLLER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/gfx/compositor/layer_animation_observer.h" +#include "ui/gfx/insets.h" +#include "ui/gfx/rect.h" + +namespace views { +class Widget; +} + +namespace aura_shell { +namespace internal { + +// ShelfLayoutController is responsible for showing and hiding the launcher and +// status area as well as positioning them. +class ShelfLayoutController : public ui::LayerAnimationObserver { + public: + ShelfLayoutController(views::Widget* launcher, + views::Widget* status); + virtual ~ShelfLayoutController(); + + // Stops any animations and sets the bounds of the launcher and status + // widgets. + void LayoutShelf(); + + // Sets the visbility of the shelf to |visible|. + void SetVisible(bool visible); + + private: + struct TargetBounds { + gfx::Rect launcher_bounds; + gfx::Rect status_bounds; + gfx::Insets work_area_insets; + }; + + // Stops any animations. + void StopAnimating(); + + // Calculates the target bounds assuming visibility of |visibile|. + void CalculateTargetBounds(bool visible, + TargetBounds* target_bounds); + + // Animates |widget| to the specified bounds and opacity. + void AnimateWidgetTo(views::Widget* widget, + const gfx::Rect& target_bounds, + float target_opacity); + + // 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 {} + + // Are we animating? + bool animating_; + + // Current visibility. When the visibility changes this field is reset once + // the animation completes. + bool visible_; + + // Max height needed. + int max_height_; + + views::Widget* launcher_; + views::Widget* status_; + + DISALLOW_COPY_AND_ASSIGN(ShelfLayoutController); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // UI_AURA_SHELL_SHELF_LAYOUT_CONTROLLER_H_ diff --git a/ui/aura_shell/shell.cc b/ui/aura_shell/shell.cc index 705e0ac..b2a3a98 100644 --- a/ui/aura_shell/shell.cc +++ b/ui/aura_shell/shell.cc @@ -8,7 +8,6 @@ #include "base/command_line.h" #include "ui/aura/aura_switches.h" #include "ui/aura/desktop.h" -#include "ui/aura/screen_aura.h" #include "ui/aura/toplevel_window_container.h" #include "ui/aura/window.h" #include "ui/aura/window_types.h" @@ -16,6 +15,7 @@ #include "ui/aura_shell/default_container_layout_manager.h" #include "ui/aura_shell/desktop_layout_manager.h" #include "ui/aura_shell/launcher/launcher.h" +#include "ui/aura_shell/shelf_layout_controller.h" #include "ui/aura_shell/shell_delegate.h" #include "ui/aura_shell/shell_factory.h" #include "ui/aura_shell/shell_window_ids.h" @@ -115,16 +115,19 @@ void Shell::Init() { GetContainer(internal::kShellWindowId_DefaultContainer)-> AsToplevelWindowContainer(); launcher_.reset(new Launcher(toplevel_container)); - desktop_layout->set_launcher_widget(launcher_->widget()); - desktop_layout->set_status_area_widget(internal::CreateStatusArea()); - desktop_window->screen()->set_work_area_insets(gfx::Insets( - 0, 0, launcher_->widget()->GetWindowScreenBounds().height(), 0)); + shelf_layout_controller_.reset(new internal::ShelfLayoutController( + launcher_->widget(), internal::CreateStatusArea())); + desktop_layout->set_shelf(shelf_layout_controller_.get()); - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraWindows)) + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraWindows)) { EnableWorkspaceManager(); - else - toplevel_container->SetLayoutManager(new internal::ToplevelLayoutManager()); + } else { + internal::ToplevelLayoutManager* toplevel_layout_manager = + new internal::ToplevelLayoutManager(); + toplevel_container->SetLayoutManager(toplevel_layout_manager); + toplevel_layout_manager->set_shelf(shelf_layout_controller_.get()); + } // Force a layout. desktop_layout->OnWindowResized(); diff --git a/ui/aura_shell/shell.h b/ui/aura_shell/shell.h index 4f872ab..bc294bb 100644 --- a/ui/aura_shell/shell.h +++ b/ui/aura_shell/shell.h @@ -30,6 +30,7 @@ class Launcher; class ShellDelegate; namespace internal { +class ShelfLayoutController; class WorkspaceController; } @@ -81,6 +82,8 @@ class AURA_SHELL_EXPORT Shell : public aura::DesktopDelegate { scoped_ptr<internal::WorkspaceController> workspace_controller_; + scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_; + DISALLOW_COPY_AND_ASSIGN(Shell); }; diff --git a/ui/aura_shell/status_area_view.h b/ui/aura_shell/status_area_view.h index 873acc7..68d0799 100644 --- a/ui/aura_shell/status_area_view.h +++ b/ui/aura_shell/status_area_view.h @@ -19,6 +19,7 @@ class StatusAreaView : public views::WidgetDelegateView { // Overridden from views::View: virtual gfx::Size GetPreferredSize() OVERRIDE; + private: virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; diff --git a/ui/aura_shell/toplevel_layout_manager.cc b/ui/aura_shell/toplevel_layout_manager.cc index ade2fe0..6846547 100644 --- a/ui/aura_shell/toplevel_layout_manager.cc +++ b/ui/aura_shell/toplevel_layout_manager.cc @@ -7,6 +7,7 @@ #include "ui/aura/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura_shell/property_util.h" +#include "ui/aura_shell/shelf_layout_controller.h" #include "ui/aura_shell/workspace/workspace.h" #include "ui/aura_shell/workspace/workspace_manager.h" #include "ui/base/ui_base_types.h" @@ -15,7 +16,7 @@ namespace aura_shell { namespace internal { -ToplevelLayoutManager::ToplevelLayoutManager() { +ToplevelLayoutManager::ToplevelLayoutManager() : shelf_(NULL) { } ToplevelLayoutManager::~ToplevelLayoutManager() { @@ -36,10 +37,12 @@ void ToplevelLayoutManager::OnWindowAdded(aura::Window* child) { void ToplevelLayoutManager::OnWillRemoveWindow(aura::Window* child) { windows_.erase(child); child->RemoveObserver(this); + UpdateShelfVisibility(); } void ToplevelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, bool visibile) { + UpdateShelfVisibility(); } void ToplevelLayoutManager::SetChildBounds(aura::Window* child, @@ -73,12 +76,28 @@ void ToplevelLayoutManager::WindowStateChanged(aura::Window* window) { case ui::SHOW_STATE_FULLSCREEN: SetRestoreBoundsIfNotSet(window); window->SetBounds(gfx::Screen::GetMonitorAreaNearestWindow(window)); - // TODO: need to hide the launcher. break; default: break; } + + UpdateShelfVisibility(); +} + +void ToplevelLayoutManager::UpdateShelfVisibility() { + if (!shelf_) + return; + + bool has_fullscreen_window = false; + for (Windows::const_iterator i = windows_.begin(); i != windows_.end(); ++i) { + if ((*i)->GetIntProperty(aura::kShowStateKey) == + ui::SHOW_STATE_FULLSCREEN) { + has_fullscreen_window = true; + break; + } + } + shelf_->SetVisible(!has_fullscreen_window); } } // namespace internal diff --git a/ui/aura_shell/toplevel_layout_manager.h b/ui/aura_shell/toplevel_layout_manager.h index 8921b63..5c080aa 100644 --- a/ui/aura_shell/toplevel_layout_manager.h +++ b/ui/aura_shell/toplevel_layout_manager.h @@ -17,6 +17,8 @@ namespace aura_shell { namespace internal { +class ShelfLayoutController; + // ToplevelLayoutManager is the LayoutManager installed on the // ToplevelWindowContainer. It is used if the WorkspaceManager is not // enabled. ToplevelLayoutManager listens for changes to kShowStateKey and @@ -27,6 +29,8 @@ class AURA_SHELL_EXPORT ToplevelLayoutManager : public aura::LayoutManager, ToplevelLayoutManager(); virtual ~ToplevelLayoutManager(); + void set_shelf(ShelfLayoutController* shelf) { shelf_ = shelf; } + // LayoutManager overrides: virtual void OnWindowResized() OVERRIDE; virtual void OnWindowAdded(aura::Window* child) OVERRIDE; @@ -47,9 +51,15 @@ class AURA_SHELL_EXPORT ToplevelLayoutManager : public aura::LayoutManager, // If necessary adjusts the bounds of window based on it's show state. void WindowStateChanged(aura::Window* window); + // Updates the visbility of the shelf based on if there are any full screen + // windows. + void UpdateShelfVisibility(); + // Set of windows we're listening to. Windows windows_; + ShelfLayoutController* shelf_; + DISALLOW_COPY_AND_ASSIGN(ToplevelLayoutManager); }; |