diff options
author | alicet@chromium.org <alicet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 22:14:00 +0000 |
---|---|---|
committer | alicet@chromium.org <alicet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 22:14:00 +0000 |
commit | 2ceb3bc6aea69b302e1def382d815995d1130b2c (patch) | |
tree | 4936e6356b3bc4ba8a0e660982a3855535a702e8 /ash | |
parent | 064b9a4dc94e9a5f911d1e474aa23dcd81a929c8 (diff) | |
download | chromium_src-2ceb3bc6aea69b302e1def382d815995d1130b2c.zip chromium_src-2ceb3bc6aea69b302e1def382d815995d1130b2c.tar.gz chromium_src-2ceb3bc6aea69b302e1def382d815995d1130b2c.tar.bz2 |
Add slide sequence for aura windows in compact mode.
This mimics the creation and alt+tab scrolling in classic chromeos.
BUG=109042
TEST=on alex and lumpy in compact mode.
Review URL: http://codereview.chromium.org/9187020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118513 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/wm/compact_layout_manager.cc | 102 | ||||
-rw-r--r-- | ash/wm/compact_layout_manager.h | 14 | ||||
-rw-r--r-- | ash/wm/window_cycle_list.cc | 4 |
3 files changed, 119 insertions, 1 deletions
diff --git a/ash/wm/compact_layout_manager.cc b/ash/wm/compact_layout_manager.cc index 867cd30..dda8d24 100644 --- a/ash/wm/compact_layout_manager.cc +++ b/ash/wm/compact_layout_manager.cc @@ -4,18 +4,49 @@ #include "ash/wm/compact_layout_manager.h" +#include "ash/shell.h" +#include "ash/shell_delegate.h" +#include "ash/shell_window_ids.h" #include "ash/wm/window_util.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/window.h" +#include "ui/gfx/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/screen.h" #include "ui/views/widget/widget.h" namespace ash { namespace internal { +namespace { +// Convenience method to get the layer of this container. +ui::Layer* GetDefaultContainerLayer() { + return Shell::GetInstance()->GetContainer( + internal::kShellWindowId_DefaultContainer)->layer(); +} + +// Whether it is a window that should be animated on entrance. +bool ShouldAnimateOnEntrance(aura::Window* window) { + return window && + window->type() == aura::client::WINDOW_TYPE_NORMAL && + window_util::IsWindowMaximized(window); +} + +// Adjust layer bounds to grow or shrink in |delta_width|. +void AdjustContainerLayerWidth(int delta_width) { + gfx::Rect bounds(GetDefaultContainerLayer()->bounds()); + bounds.set_width(bounds.width() + delta_width); + GetDefaultContainerLayer()->SetBounds(bounds); + GetDefaultContainerLayer()->GetCompositor()->WidgetSizeChanged( + GetDefaultContainerLayer()->bounds().size()); +} +} // namespace + ///////////////////////////////////////////////////////////////////////////// // CompactLayoutManager, public: CompactLayoutManager::CompactLayoutManager() - : status_area_widget_(NULL) { + : status_area_widget_(NULL), + current_window_(NULL) { } CompactLayoutManager::~CompactLayoutManager() { @@ -27,17 +58,50 @@ CompactLayoutManager::~CompactLayoutManager() { void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) { BaseLayoutManager::OnWindowAddedToLayout(child); UpdateStatusAreaVisibility(); + if (windows().size() > 1 && + child->type() == aura::client::WINDOW_TYPE_NORMAL) { + // The first window is already contained in the current layer, + // add subsequent windows to layer bounds calculation. + AdjustContainerLayerWidth(child->bounds().width()); + } } void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { BaseLayoutManager::OnWillRemoveWindowFromLayout(child); UpdateStatusAreaVisibility(); + if (windows().size() > 1 && ShouldAnimateOnEntrance(child)) { + AdjustContainerLayerWidth(-child->bounds().width()); + } } void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, bool visible) { BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible); UpdateStatusAreaVisibility(); + if (ShouldAnimateOnEntrance(child)) { + LayoutWindows(visible ? NULL : child); + if (visible) { + AnimateSlideTo(child->bounds().x()); + current_window_ = child; + } + } +} + +void CompactLayoutManager::SetChildBounds(aura::Window* child, + const gfx::Rect& requested_bounds) { + gfx::Rect child_bounds(requested_bounds); + // Avoid a janky resize on startup by ensuring the initial bounds fill the + // screen. + if (window_util::IsWindowMaximized(child)) + child_bounds = gfx::Screen::GetMonitorWorkAreaNearestWindow(child); + else if (window_util::IsWindowFullscreen(child)) + child_bounds = gfx::Screen::GetMonitorAreaNearestWindow(child); + else if (current_window_) { + // All other windows should be offset by the current viewport. + int offset_x = current_window_->bounds().x(); + child_bounds.Offset(offset_x, 0); + } + SetChildBoundsDirect(child, child_bounds); } ///////////////////////////////////////////////////////////////////////////// @@ -51,6 +115,13 @@ void CompactLayoutManager::OnWindowPropertyChanged(aura::Window* window, UpdateStatusAreaVisibility(); } +void CompactLayoutManager::OnWindowStackingChanged(aura::Window* window) { + if (current_window_ != window && ShouldAnimateOnEntrance(window)) { + AnimateSlideTo(window->bounds().x()); + current_window_ = window; + } +} + ////////////////////////////////////////////////////////////////////////////// // CompactLayoutManager, private: @@ -64,5 +135,34 @@ void CompactLayoutManager::UpdateStatusAreaVisibility() { status_area_widget_->Show(); } +void CompactLayoutManager::AnimateSlideTo(int offset_x) { + ui::ScopedLayerAnimationSettings settings( + GetDefaultContainerLayer()->GetAnimator()); + ui::Transform transform; + transform.ConcatTranslate(-offset_x, 0); + GetDefaultContainerLayer()->SetTransform(transform); // Will be animated! +} + +void CompactLayoutManager::LayoutWindows(aura::Window* skip) { + ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); + const std::vector<aura::Window*>& windows_list = + shell_delegate->GetCycleWindowList( + ShellDelegate::SOURCE_KEYBOARD, + ShellDelegate::ORDER_LINEAR); + int new_x = 0; + for (std::vector<aura::Window*>::const_iterator const_it = + windows_list.begin(); + const_it != windows_list.end(); + ++const_it) { + (*const_it)->Show(); + if (*const_it == skip) + continue; + gfx::Rect new_bounds((*const_it)->bounds()); + new_bounds.set_x(new_x); + SetChildBoundsDirect(*const_it, new_bounds); + new_x += (*const_it)->bounds().width(); + } +} + } // namespace internal } // namespace ash diff --git a/ash/wm/compact_layout_manager.h b/ash/wm/compact_layout_manager.h index 7ce87dd..6fce2e7 100644 --- a/ash/wm/compact_layout_manager.h +++ b/ash/wm/compact_layout_manager.h @@ -36,21 +36,35 @@ class ASH_EXPORT CompactLayoutManager : public BaseLayoutManager { virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE; virtual void OnChildWindowVisibilityChanged(aura::Window* child, bool visibile) OVERRIDE; + virtual void SetChildBounds(aura::Window* child, + const gfx::Rect& requested_bounds) OVERRIDE; // WindowObserver overrides: virtual void OnWindowPropertyChanged(aura::Window* window, const char* name, void* old) OVERRIDE; + virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE; private: // Hides the status area if we are managing it and full screen windows are // visible. void UpdateStatusAreaVisibility(); + // Start a slide in / out animation sequence for the layer. + // The underlying layer is translated to -|offset_x| position. + void AnimateSlideTo(int offset_x); + + // Layout all browser windows currently in the window cycle list. + // skip |skip_this_window| if we do not want the window to be laid out. + void LayoutWindows(aura::Window* skip_this_window); + // Status area with clock, network, battery, etc. icons. May be NULL if the // shelf is managing the status area. views::Widget* status_area_widget_; + // The browser window currently in the viewport. + aura::Window* current_window_; + DISALLOW_COPY_AND_ASSIGN(CompactLayoutManager); }; diff --git a/ash/wm/window_cycle_list.cc b/ash/wm/window_cycle_list.cc index f7c6eb7..1701690 100644 --- a/ash/wm/window_cycle_list.cc +++ b/ash/wm/window_cycle_list.cc @@ -37,6 +37,10 @@ void WindowCycleList::Step(Direction direction) { if (windows_.empty()) return; + // Don't cycle through a list of one. + if (windows_.size() == 1) + return; + if (current_index_ == -1) { // We weren't able to find our active window in the shell delegate's // provided window list. Just switch to the first (or last) one. |