blob: 7e7f851a68ed3a7e064679ea0e3ff1e70dc1e976 [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
5#include "ui/aura_shell/shelf_layout_controller.h"
6
7#include "ui/aura/desktop.h"
8#include "ui/aura/screen_aura.h"
9#include "ui/gfx/compositor/layer.h"
10#include "ui/gfx/compositor/layer_animator.h"
[email protected]c13be0d2011-11-22 02:09:5811#include "ui/views/widget/widget.h"
[email protected]ae18b9112011-11-07 16:59:1312
13namespace aura_shell {
14namespace internal {
15
16namespace {
17
18ui::Layer* GetLayer(views::Widget* widget) {
19 return widget->GetNativeView()->layer();
20}
21
22} // namespace
23
24ShelfLayoutController::ShelfLayoutController(views::Widget* launcher,
25 views::Widget* status)
26 : animating_(false),
27 visible_(true),
28 max_height_(-1),
29 launcher_(launcher),
30 status_(status) {
31 gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds();
32 gfx::Rect status_bounds = status->GetWindowScreenBounds();
33 max_height_ = std::max(launcher_bounds.height(), status_bounds.height());
34 GetLayer(launcher)->GetAnimator()->AddObserver(this);
35}
36
37ShelfLayoutController::~ShelfLayoutController() {
38 GetLayer(launcher_)->GetAnimator()->RemoveObserver(this);
39}
40
41void ShelfLayoutController::LayoutShelf() {
42 StopAnimating();
43 TargetBounds target_bounds;
44 float target_opacity = visible_ ? 1.0f : 0.0f;
45 CalculateTargetBounds(visible_, &target_bounds);
46 GetLayer(launcher_)->SetOpacity(target_opacity);
47 GetLayer(status_)->SetOpacity(target_opacity);
48 launcher_->SetBounds(target_bounds.launcher_bounds);
49 status_->SetBounds(target_bounds.status_bounds);
50 aura::Desktop::GetInstance()->screen()->set_work_area_insets(
51 target_bounds.work_area_insets);
52}
53
54void ShelfLayoutController::SetVisible(bool visible) {
55 bool current_visibility = animating_ ? !visible_ : visible_;
56 if (visible == current_visibility)
57 return; // Nothing changed.
58
59 StopAnimating();
60
61 TargetBounds target_bounds;
62 float target_opacity = visible ? 1.0f : 0.0f;
63 CalculateTargetBounds(visible, &target_bounds);
64 AnimateWidgetTo(launcher_, target_bounds.launcher_bounds, target_opacity);
65 AnimateWidgetTo(status_, target_bounds.status_bounds, target_opacity);
66 animating_ = true;
67 // |visible_| is updated once the animation completes.
68}
69
70void ShelfLayoutController::StopAnimating() {
71 if (animating_) {
72 animating_ = false;
73 visible_ = !visible_;
74 }
75 GetLayer(launcher_)->GetAnimator()->StopAnimating();
76}
77
78void ShelfLayoutController::CalculateTargetBounds(bool visible,
79 TargetBounds* target_bounds) {
80 const gfx::Rect& available_bounds(aura::Desktop::GetInstance()->bounds());
81 int y = available_bounds.bottom() - (visible ? max_height_ : 0);
82 gfx::Rect status_bounds(status_->GetWindowScreenBounds());
83 target_bounds->status_bounds = gfx::Rect(
84 available_bounds.right() - status_bounds.width(),
85 y + (max_height_ - status_bounds.height()) / 2,
86 status_bounds.width(), status_bounds.height());
87 gfx::Rect launcher_bounds(launcher_->GetWindowScreenBounds());
88 target_bounds->launcher_bounds = gfx::Rect(
89 available_bounds.x(), y + (max_height_ - launcher_bounds.height()) / 2,
90 available_bounds.width() - status_bounds.width(),
91 launcher_bounds.height());
92 if (visible)
93 target_bounds->work_area_insets = gfx::Insets(0, 0, max_height_, 0);
94}
95
96void ShelfLayoutController::AnimateWidgetTo(views::Widget* widget,
97 const gfx::Rect& target_bounds,
98 float target_opacity) {
99 ui::Layer* layer = GetLayer(widget);
100 ui::LayerAnimator::ScopedSettings animation_setter(layer->GetAnimator());
101 widget->SetBounds(target_bounds);
102 layer->SetOpacity(target_opacity);
103}
104
105void ShelfLayoutController::OnLayerAnimationEnded(
106 const ui::LayerAnimationSequence* sequence) {
107 if (!animating_)
108 return;
109 animating_ = false;
110 visible_ = !visible_;
111 TargetBounds target_bounds;
112 CalculateTargetBounds(visible_, &target_bounds);
113 aura::Desktop::GetInstance()->screen()->set_work_area_insets(
114 target_bounds.work_area_insets);
115}
116
117} // internal
118} // aura_shell