Index: ash/wm/shelf_layout_manager.cc |
diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc |
index db3264706dd5b5bfb660daf6286ad58c3b7f7b45..191a5d0f116e30c2b2b2da4bc2790063219fd391 100644 |
--- a/ash/wm/shelf_layout_manager.cc |
+++ b/ash/wm/shelf_layout_manager.cc |
@@ -20,6 +20,9 @@ namespace internal { |
namespace { |
+// Height of the shelf when auto-hidden. |
+const int kAutoHideHeight = 2; |
+ |
ui::Layer* GetLayer(views::Widget* widget) { |
return widget->GetNativeView()->layer(); |
} |
@@ -32,70 +35,109 @@ const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2; |
//////////////////////////////////////////////////////////////////////////////// |
// ShelfLayoutManager, public: |
-ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher, |
- views::Widget* status) |
+ShelfLayoutManager::ShelfLayoutManager(views::Widget* status) |
: in_layout_(false), |
- visible_(true), |
- max_height_(-1), |
- launcher_(launcher), |
- status_(status) { |
- gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds(); |
+ shelf_height_(-1), |
+ launcher_(NULL), |
+ status_(status), |
+ window_overlaps_shelf_(false), |
+ root_window_(NULL) { |
gfx::Rect status_bounds = status->GetWindowScreenBounds(); |
- max_height_ = std::max(launcher_bounds.height(), status_bounds.height()); |
- root_window_ = launcher->GetNativeView()->GetRootWindow(); |
+ shelf_height_ = status_bounds.height(); |
+ root_window_ = status->GetNativeView()->GetRootWindow(); |
} |
ShelfLayoutManager::~ShelfLayoutManager() { |
} |
+gfx::Rect ShelfLayoutManager::GetMaximizedWindowBounds( |
+ aura::Window* window) const { |
+ // TODO: needs to be multi-mon aware. |
+ gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(window)); |
+ bounds.set_height(bounds.height() - kAutoHideHeight); |
+ return bounds; |
+} |
+ |
+gfx::Rect ShelfLayoutManager::GetUnmaximizedWorkAreaBounds( |
+ aura::Window* window) const { |
+ // TODO: needs to be multi-mon aware. |
+ gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(window)); |
+ bounds.set_height(bounds.height() - shelf_height_ - |
+ kWorkspaceAreaBottomInset); |
+ return bounds; |
+} |
+ |
void ShelfLayoutManager::LayoutShelf() { |
AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
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); |
+ CalculateTargetBounds(state_, &target_bounds); |
+ if (launcher()) { |
+ GetLayer(launcher())->SetOpacity(target_bounds.opacity); |
+ launcher()->SetBounds(target_bounds.launcher_bounds); |
+ launcher_->SetStatusWidth( |
+ target_bounds.status_bounds.width()); |
+ } |
+ GetLayer(status_)->SetOpacity(target_bounds.opacity); |
status_->SetBounds(target_bounds.status_bounds); |
- Shell::GetInstance()->launcher()->SetStatusWidth( |
- target_bounds.status_bounds.width()); |
Shell::GetInstance()->SetMonitorWorkAreaInsets( |
Shell::GetRootWindow(), |
target_bounds.work_area_insets); |
} |
-void ShelfLayoutManager::SetVisible(bool visible) { |
- ui::Layer* launcher_layer = GetLayer(launcher_); |
- ui::Layer* status_layer = GetLayer(status_); |
+void ShelfLayoutManager::SetState(VisibilityState visibility_state, |
+ AutoHideState auto_hide_state) { |
+ State state; |
+ state.visibility_state = visibility_state; |
+ state.auto_hide_state = auto_hide_state; |
- // TODO(vollick): once visibility is animatable, use GetTargetVisibility. |
- bool current_visibility = visible_ && |
- launcher_layer->GetTargetOpacity() > 0.0f && |
- status_layer->GetTargetOpacity() > 0.0f; |
- |
- if (visible == current_visibility) |
+ if (state_.Equals(state)) |
return; // Nothing changed. |
+ // Animating the background when transitioning from auto-hide & hidden to |
+ // visibile is janking. Update the background immediately in this case. |
+ Launcher::BackgroundChangeSpeed speed = |
+ (state_.visibility_state == AUTO_HIDE && |
+ state_.auto_hide_state == AUTO_HIDE_HIDDEN && |
+ state.visibility_state == VISIBLE) ? |
+ Launcher::CHANGE_IMMEDIATE : Launcher::CHANGE_ANIMATE; |
StopAnimating(); |
- |
- visible_ = visible; |
+ state_ = state; |
TargetBounds target_bounds; |
- float target_opacity = visible ? 1.0f : 0.0f; |
- CalculateTargetBounds(visible, &target_bounds); |
- |
- ui::ScopedLayerAnimationSettings launcher_animation_setter( |
- launcher_layer->GetAnimator()); |
+ CalculateTargetBounds(state_, &target_bounds); |
+ if (launcher()) { |
+ ui::ScopedLayerAnimationSettings launcher_animation_setter( |
+ GetLayer(launcher())->GetAnimator()); |
+ launcher_animation_setter.SetTransitionDuration( |
+ base::TimeDelta::FromMilliseconds(130)); |
+ launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
+ GetLayer(launcher())->SetBounds(target_bounds.launcher_bounds); |
+ GetLayer(launcher())->SetOpacity(target_bounds.opacity); |
+ } |
ui::ScopedLayerAnimationSettings status_animation_setter( |
- status_layer->GetAnimator()); |
+ GetLayer(status_)->GetAnimator()); |
+ status_animation_setter.SetTransitionDuration( |
+ base::TimeDelta::FromMilliseconds(130)); |
+ status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
+ GetLayer(status_)->SetBounds(target_bounds.status_bounds); |
+ GetLayer(status_)->SetOpacity(target_bounds.opacity); |
+ Shell::GetInstance()->SetMonitorWorkAreaInsets( |
+ Shell::GetRootWindow(), |
+ target_bounds.work_area_insets); |
+ launcher_->SetRendersBackground(GetShelfRendersBackground(), speed); |
+} |
- launcher_animation_setter.AddObserver(this); |
- status_animation_setter.AddObserver(this); |
+void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { |
+ window_overlaps_shelf_ = value; |
+ launcher_->SetRendersBackground(GetShelfRendersBackground(), |
+ Launcher::CHANGE_ANIMATE); |
+} |
- launcher_layer->SetBounds(target_bounds.launcher_bounds); |
- launcher_layer->SetOpacity(target_opacity); |
- status_layer->SetBounds(target_bounds.status_bounds); |
- status_layer->SetOpacity(target_opacity); |
+void ShelfLayoutManager::SetLauncher(Launcher* launcher) { |
+ launcher_ = launcher; |
+ gfx::Rect launcher_bounds = launcher_->widget()->GetWindowScreenBounds(); |
+ gfx::Rect status_bounds = status_->GetWindowScreenBounds(); |
+ shelf_height_ = std::max(launcher_bounds.height(), status_bounds.height()); |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -126,37 +168,51 @@ void ShelfLayoutManager::SetChildBounds(aura::Window* child, |
// ShelfLayoutManager, private: |
void ShelfLayoutManager::StopAnimating() { |
- StopObservingImplicitAnimations(); |
- GetLayer(launcher_)->GetAnimator()->StopAnimating(); |
+ if (launcher()) |
+ GetLayer(launcher())->GetAnimator()->StopAnimating(); |
GetLayer(status_)->GetAnimator()->StopAnimating(); |
} |
-void ShelfLayoutManager::CalculateTargetBounds(bool visible, |
- TargetBounds* target_bounds) { |
+void ShelfLayoutManager::CalculateTargetBounds( |
+ const State& state, |
+ TargetBounds* target_bounds) const { |
const gfx::Rect& available_bounds(root_window_->bounds()); |
- int y = available_bounds.bottom() - (visible ? max_height_ : 0); |
+ int y = available_bounds.bottom(); |
+ int shelf_height = 0; |
+ int work_area_delta = 0; |
+ if (state.visibility_state == VISIBLE || |
+ (state.visibility_state == AUTO_HIDE && |
+ state.auto_hide_state == AUTO_HIDE_SHOWN)) { |
+ shelf_height = shelf_height_; |
+ work_area_delta = kWorkspaceAreaBottomInset; |
+ } else if (state.visibility_state == AUTO_HIDE && |
+ state.auto_hide_state == AUTO_HIDE_HIDDEN) { |
+ shelf_height = kAutoHideHeight; |
+ } |
+ y -= shelf_height; |
gfx::Rect status_bounds(status_->GetWindowScreenBounds()); |
// The status widget should extend to the bottom and right edges. |
target_bounds->status_bounds = gfx::Rect( |
available_bounds.right() - status_bounds.width(), |
- y + max_height_ - status_bounds.height(), |
+ y + shelf_height_ - status_bounds.height(), |
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(), |
- launcher_bounds.height()); |
- if (visible) |
- target_bounds->work_area_insets = gfx::Insets( |
- 0, 0, max_height_ + kWorkspaceAreaBottomInset, 0); |
+ if (launcher()) { |
+ gfx::Rect launcher_bounds(launcher()->GetWindowScreenBounds()); |
+ target_bounds->launcher_bounds = gfx::Rect( |
+ available_bounds.x(), |
+ y + (shelf_height_ - launcher_bounds.height()) / 2, |
+ available_bounds.width(), |
+ launcher_bounds.height()); |
+ } |
+ target_bounds->opacity = |
+ (state.visibility_state == VISIBLE || |
+ state.visibility_state == AUTO_HIDE) ? 1.0f : 0.0f; |
+ target_bounds->work_area_insets = |
+ gfx::Insets(0, 0, shelf_height + work_area_delta, 0); |
} |
-void ShelfLayoutManager::OnImplicitAnimationsCompleted() { |
- TargetBounds target_bounds; |
- CalculateTargetBounds(visible_, &target_bounds); |
- Shell::GetInstance()->SetMonitorWorkAreaInsets( |
- Shell::GetRootWindow(), |
- target_bounds.work_area_insets); |
+bool ShelfLayoutManager::GetShelfRendersBackground() const { |
+ return window_overlaps_shelf_ || state_.visibility_state == AUTO_HIDE; |
} |
} // namespace internal |