blob: 5c2f349b1a114bc525ac3bfaa909bf84b30c3e9e [file] [log] [blame]
[email protected]ae18b9112011-11-07 16:59:131// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]7634f962011-12-23 21:35:525#include "ash/wm/shelf_layout_manager.h"
[email protected]ae18b9112011-11-07 16:59:136
[email protected]7634f962011-12-23 21:35:527#include "ash/launcher/launcher.h"
[email protected]b65bdda2011-12-23 23:35:318#include "ash/shell.h"
[email protected]4bb16502011-12-06 14:44:589#include "base/auto_reset.h"
[email protected]99f07e02011-12-07 00:02:5910#include "ui/aura/root_window.h"
[email protected]ae18b9112011-11-07 16:59:1311#include "ui/aura/screen_aura.h"
12#include "ui/gfx/compositor/layer.h"
13#include "ui/gfx/compositor/layer_animator.h"
[email protected]c13be0d2011-11-22 02:09:5814#include "ui/views/widget/widget.h"
[email protected]ae18b9112011-11-07 16:59:1315
16namespace aura_shell {
17namespace internal {
18
19namespace {
20
21ui::Layer* GetLayer(views::Widget* widget) {
22 return widget->GetNativeView()->layer();
23}
24
25} // namespace
26
[email protected]4bb16502011-12-06 14:44:5827////////////////////////////////////////////////////////////////////////////////
28// ShelfLayoutManager, public:
29
30ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher,
31 views::Widget* status)
[email protected]ae18b9112011-11-07 16:59:1332 : animating_(false),
[email protected]4bb16502011-12-06 14:44:5833 in_layout_(false),
[email protected]ae18b9112011-11-07 16:59:1334 visible_(true),
35 max_height_(-1),
36 launcher_(launcher),
37 status_(status) {
38 gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds();
39 gfx::Rect status_bounds = status->GetWindowScreenBounds();
40 max_height_ = std::max(launcher_bounds.height(), status_bounds.height());
41 GetLayer(launcher)->GetAnimator()->AddObserver(this);
42}
43
[email protected]4bb16502011-12-06 14:44:5844ShelfLayoutManager::~ShelfLayoutManager() {
[email protected]ef589af2011-12-03 01:07:1545 // Do not try to remove observer from layer as the Launcher is
46 // already deleted.
[email protected]ae18b9112011-11-07 16:59:1347}
48
[email protected]4bb16502011-12-06 14:44:5849void ShelfLayoutManager::LayoutShelf() {
50 AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
[email protected]ae18b9112011-11-07 16:59:1351 StopAnimating();
52 TargetBounds target_bounds;
53 float target_opacity = visible_ ? 1.0f : 0.0f;
54 CalculateTargetBounds(visible_, &target_bounds);
55 GetLayer(launcher_)->SetOpacity(target_opacity);
56 GetLayer(status_)->SetOpacity(target_opacity);
57 launcher_->SetBounds(target_bounds.launcher_bounds);
58 status_->SetBounds(target_bounds.status_bounds);
[email protected]22f9d312011-12-15 17:38:5559 Shell::GetInstance()->launcher()->SetStatusWidth(
60 target_bounds.status_bounds.width());
[email protected]99f07e02011-12-07 00:02:5961 aura::RootWindow::GetInstance()->screen()->set_work_area_insets(
[email protected]ae18b9112011-11-07 16:59:1362 target_bounds.work_area_insets);
63}
64
[email protected]4bb16502011-12-06 14:44:5865void ShelfLayoutManager::SetVisible(bool visible) {
[email protected]ae18b9112011-11-07 16:59:1366 bool current_visibility = animating_ ? !visible_ : visible_;
67 if (visible == current_visibility)
68 return; // Nothing changed.
69
70 StopAnimating();
71
72 TargetBounds target_bounds;
73 float target_opacity = visible ? 1.0f : 0.0f;
74 CalculateTargetBounds(visible, &target_bounds);
75 AnimateWidgetTo(launcher_, target_bounds.launcher_bounds, target_opacity);
76 AnimateWidgetTo(status_, target_bounds.status_bounds, target_opacity);
77 animating_ = true;
78 // |visible_| is updated once the animation completes.
79}
80
[email protected]4bb16502011-12-06 14:44:5881////////////////////////////////////////////////////////////////////////////////
82// ShelfLayoutManager, aura::LayoutManager implementation:
83
84void ShelfLayoutManager::OnWindowResized() {
85 LayoutShelf();
86}
87
88void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
89}
90
91void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
92}
93
94void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
95 bool visible) {
96}
97
98void ShelfLayoutManager::SetChildBounds(aura::Window* child,
99 const gfx::Rect& requested_bounds) {
100 SetChildBoundsDirect(child, requested_bounds);
101 if (!in_layout_)
102 LayoutShelf();
103}
104
105////////////////////////////////////////////////////////////////////////////////
106// ShelfLayoutManager, private:
107
108void ShelfLayoutManager::StopAnimating() {
[email protected]ae18b9112011-11-07 16:59:13109 if (animating_) {
110 animating_ = false;
111 visible_ = !visible_;
112 }
113 GetLayer(launcher_)->GetAnimator()->StopAnimating();
[email protected]df5954f2011-12-14 16:19:58114 GetLayer(status_)->GetAnimator()->StopAnimating();
[email protected]ae18b9112011-11-07 16:59:13115}
116
[email protected]4bb16502011-12-06 14:44:58117void ShelfLayoutManager::CalculateTargetBounds(bool visible,
118 TargetBounds* target_bounds) {
[email protected]99f07e02011-12-07 00:02:59119 const gfx::Rect& available_bounds(aura::RootWindow::GetInstance()->bounds());
[email protected]ae18b9112011-11-07 16:59:13120 int y = available_bounds.bottom() - (visible ? max_height_ : 0);
121 gfx::Rect status_bounds(status_->GetWindowScreenBounds());
122 target_bounds->status_bounds = gfx::Rect(
123 available_bounds.right() - status_bounds.width(),
124 y + (max_height_ - status_bounds.height()) / 2,
125 status_bounds.width(), status_bounds.height());
126 gfx::Rect launcher_bounds(launcher_->GetWindowScreenBounds());
127 target_bounds->launcher_bounds = gfx::Rect(
128 available_bounds.x(), y + (max_height_ - launcher_bounds.height()) / 2,
[email protected]a3469db42011-12-14 22:15:16129 available_bounds.width(),
[email protected]ae18b9112011-11-07 16:59:13130 launcher_bounds.height());
131 if (visible)
132 target_bounds->work_area_insets = gfx::Insets(0, 0, max_height_, 0);
133}
134
[email protected]4bb16502011-12-06 14:44:58135void ShelfLayoutManager::AnimateWidgetTo(views::Widget* widget,
136 const gfx::Rect& target_bounds,
137 float target_opacity) {
[email protected]ae18b9112011-11-07 16:59:13138 ui::Layer* layer = GetLayer(widget);
139 ui::LayerAnimator::ScopedSettings animation_setter(layer->GetAnimator());
[email protected]df5954f2011-12-14 16:19:58140 // Don't go through the widget, otherwise we end up back in SetChildBounds and
141 // cancel the animation/layout.
142 layer->SetBounds(target_bounds);
[email protected]ae18b9112011-11-07 16:59:13143 layer->SetOpacity(target_opacity);
144}
145
[email protected]4bb16502011-12-06 14:44:58146void ShelfLayoutManager::OnLayerAnimationEnded(
[email protected]ae18b9112011-11-07 16:59:13147 const ui::LayerAnimationSequence* sequence) {
148 if (!animating_)
149 return;
150 animating_ = false;
151 visible_ = !visible_;
152 TargetBounds target_bounds;
153 CalculateTargetBounds(visible_, &target_bounds);
[email protected]99f07e02011-12-07 00:02:59154 aura::RootWindow::GetInstance()->screen()->set_work_area_insets(
[email protected]ae18b9112011-11-07 16:59:13155 target_bounds.work_area_insets);
156}
157
158} // internal
159} // aura_shell