summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoralicet@chromium.org <alicet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-20 22:14:00 +0000
committeralicet@chromium.org <alicet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-20 22:14:00 +0000
commit2ceb3bc6aea69b302e1def382d815995d1130b2c (patch)
tree4936e6356b3bc4ba8a0e660982a3855535a702e8 /ash
parent064b9a4dc94e9a5f911d1e474aa23dcd81a929c8 (diff)
downloadchromium_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.cc102
-rw-r--r--ash/wm/compact_layout_manager.h14
-rw-r--r--ash/wm/window_cycle_list.cc4
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.