| Index: ash/wm/workspace/workspace_layout_manager_backdrop.cc
|
| diff --git a/ash/wm/workspace/workspace_layout_manager_backdrop.cc b/ash/wm/workspace/workspace_layout_manager_backdrop.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..26a41c68f4824b0af4aca8fec863d3e20e00d141
|
| --- /dev/null
|
| +++ b/ash/wm/workspace/workspace_layout_manager_backdrop.cc
|
| @@ -0,0 +1,129 @@
|
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ash/wm/workspace/workspace_layout_manager_backdrop.h"
|
| +
|
| +#include "ash/wm/window_animations.h"
|
| +#include "ui/aura/window.h"
|
| +#include "ui/compositor/layer.h"
|
| +#include "ui/compositor/scoped_layer_animation_settings.h"
|
| +#include "ui/views/background.h"
|
| +#include "ui/views/corewm/window_util.h"
|
| +#include "ui/views/widget/widget.h"
|
| +
|
| +namespace ash {
|
| +
|
| +namespace internal {
|
| +
|
| +namespace {
|
| +
|
| +// The opacity of the backdrop.
|
| +const float kBackdropOpacity = 0.5f;
|
| +
|
| +} // namespace
|
| +
|
| +WorkspaceLayoutManagerBackdrop::WorkspaceLayoutManagerBackdrop(
|
| + aura::Window* container)
|
| + : background_(NULL),
|
| + container_(container),
|
| + inside_(false) {
|
| + background_ = new views::Widget;
|
| + views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
|
| + params.parent = container_;
|
| + params.bounds = container_->bounds();
|
| + // To disallow the MRU list from picking this window up it should not be
|
| + // activateable.
|
| + params.can_activate = false;
|
| + background_->Init(params);
|
| + background_->GetNativeView()->SetName("WorkspaceLayoutManagerBackdrop");
|
| + views::View* contents_view = new views::View();
|
| + contents_view->set_background(
|
| + views::Background::CreateSolidBackground(SK_ColorBLACK));
|
| + contents_view->SetEnabled(true);
|
| + background_->SetContentsView(contents_view);
|
| + Show();
|
| + RestackOrHideWindow();
|
| + container_->AddObserver(this);
|
| +}
|
| +
|
| +WorkspaceLayoutManagerBackdrop::~WorkspaceLayoutManagerBackdrop() {
|
| + container_->RemoveObserver(this);
|
| + ui::ScopedLayerAnimationSettings settings(
|
| + background_->GetNativeView()->layer()->GetAnimator());
|
| + background_->Close();
|
| + settings.AddObserver(views::corewm::CreateHidingWindowAnimationObserver(
|
| + background_->GetNativeView()));
|
| + background_->GetNativeView()->layer()->SetOpacity(0.0f);
|
| +}
|
| +
|
| +void WorkspaceLayoutManagerBackdrop::RestackOrHideWindow() {
|
| + // Avoid recursive calls.
|
| + if (inside_)
|
| + return;
|
| + // We are stuffing the backdrop behind the first visible & qualifying
|
| + // window in the given container.
|
| + const aura::Window::Windows& windows = container_->children();
|
| + for (aura::Window::Windows::const_reverse_iterator window_iter =
|
| + windows.rbegin();
|
| + window_iter != windows.rend(); ++window_iter) {
|
| + aura::Window* window = *window_iter;
|
| + if (window->IsVisible() &&
|
| + window->type() == ui::wm::WINDOW_TYPE_NORMAL) {
|
| + // Check if the window has already the backdrop directly behind it.
|
| + if (++window_iter != windows.rend()) {
|
| + if (*window_iter == background_->GetNativeWindow() &&
|
| + background_->IsVisible()) {
|
| + return;
|
| + }
|
| + }
|
| + // We are changing the order of windows which will cause recursion.
|
| + inside_ = true;
|
| + if (!background_->IsVisible())
|
| + Show();
|
| + // Since the backdrop needs to be immediately behind the window and the
|
| + // stacking functions only guarantee a "it's above or below", we need
|
| + // to re-arrange the two windows twice.
|
| + container_->StackChildAbove(background_->GetNativeView(), window);
|
| + container_->StackChildAbove(window, background_->GetNativeView());
|
| + inside_ = false;
|
| + return;
|
| + }
|
| + }
|
| + // Hide backdrop since no suitable window was found.
|
| + if (background_->IsVisible())
|
| + background_->Hide();
|
| +}
|
| +
|
| +void WorkspaceLayoutManagerBackdrop::OnWindowBoundsChanged(aura::Window* window,
|
| + const gfx::Rect& old_bounds,
|
| + const gfx::Rect& new_bounds) OVERRIDE {
|
| + // The container size has changed and the layer needs to be adapt to it.
|
| + AdjustToContainerBounds();
|
| +}
|
| +
|
| +void WorkspaceLayoutManagerBackdrop::AdjustToContainerBounds() {
|
| + // Cover the entire container window.
|
| + gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size());
|
| + if (target_rect != background_->GetNativeWindow()->bounds()) {
|
| + // This needs to be instantly.
|
| + ui::ScopedLayerAnimationSettings settings(
|
| + background_->GetNativeView()->layer()->GetAnimator());
|
| + settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0));
|
| + background_->GetNativeWindow()->SetBounds(target_rect);
|
| + if (!background_->IsVisible())
|
| + background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity);
|
| + }
|
| +}
|
| +
|
| +void WorkspaceLayoutManagerBackdrop::Show() {
|
| + background_->GetNativeView()->layer()->SetOpacity(0.0f);
|
| + background_->Show();
|
| + ui::ScopedLayerAnimationSettings settings(
|
| + background_->GetNativeView()->layer()->GetAnimator());
|
| + background_->Show();
|
| + background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity);
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace ash
|
|
|