| Index: ash/wm/overview/window_selector_panels.cc
|
| diff --git a/ash/wm/overview/window_selector_panels.cc b/ash/wm/overview/window_selector_panels.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..69e4602bc0455c87d276abb559dc66fe53ee5008
|
| --- /dev/null
|
| +++ b/ash/wm/overview/window_selector_panels.cc
|
| @@ -0,0 +1,177 @@
|
| +// Copyright 2013 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/overview/window_selector_panels.h"
|
| +
|
| +#include "ash/screen_ash.h"
|
| +#include "ash/shell.h"
|
| +#include "ash/shell_window_ids.h"
|
| +#include "ash/wm/overview/scoped_transform_overview_window.h"
|
| +#include "ash/wm/panels/panel_layout_manager.h"
|
| +#include "ui/aura/client/screen_position_client.h"
|
| +#include "ui/aura/window.h"
|
| +#include "ui/compositor/layer.h"
|
| +#include "ui/compositor/layer_animation_observer.h"
|
| +#include "ui/compositor/layer_animation_sequence.h"
|
| +#include "ui/views/widget/widget.h"
|
| +
|
| +namespace ash {
|
| +
|
| +namespace {
|
| +
|
| +const int kPanelCalloutFadeInDurationMilliseconds = 50;
|
| +
|
| +// This class extends ScopedTransformOverviewMode to hide and show the callout
|
| +// widget for a panel window when entering / leaving overview mode.
|
| +class ScopedTransformPanelWindow : public ScopedTransformOverviewWindow {
|
| + public:
|
| + ScopedTransformPanelWindow(aura::Window* window);
|
| + virtual ~ScopedTransformPanelWindow();
|
| +
|
| + protected:
|
| + virtual void OnOverviewStarted() OVERRIDE;
|
| +
|
| + private:
|
| + // Returns the callout widget for the transformed panel.
|
| + views::Widget* GetCalloutWidget();
|
| +
|
| + // Restores the callout visibility.
|
| + void RestoreCallout();
|
| +
|
| + // Trigger relayout
|
| + void Relayout();
|
| +
|
| + bool callout_visible_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedTransformPanelWindow);
|
| +};
|
| +
|
| +ScopedTransformPanelWindow::ScopedTransformPanelWindow(aura::Window* window)
|
| + : ScopedTransformOverviewWindow(window) {
|
| +}
|
| +
|
| +ScopedTransformPanelWindow::~ScopedTransformPanelWindow() {
|
| + // window() will be NULL if the window was destroyed.
|
| + if (window())
|
| + RestoreCallout();
|
| +}
|
| +
|
| +void ScopedTransformPanelWindow::OnOverviewStarted() {
|
| + ScopedTransformOverviewWindow::OnOverviewStarted();
|
| + GetCalloutWidget()->GetLayer()->SetOpacity(0.0f);
|
| +}
|
| +
|
| +views::Widget* ScopedTransformPanelWindow::GetCalloutWidget() {
|
| + DCHECK(window()->parent()->id() == internal::kShellWindowId_PanelContainer);
|
| + internal::PanelLayoutManager* panel_layout_manager =
|
| + static_cast<internal::PanelLayoutManager*>(
|
| + window()->parent()->layout_manager());
|
| + return panel_layout_manager->GetCalloutWidgetForPanel(window());
|
| +}
|
| +
|
| +void ScopedTransformPanelWindow::RestoreCallout() {
|
| + scoped_ptr<ui::LayerAnimationSequence> sequence(
|
| + new ui::LayerAnimationSequence);
|
| + ui::LayerAnimationElement::AnimatableProperties paused_properties;
|
| + paused_properties.insert(ui::LayerAnimationElement::OPACITY);
|
| + sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
|
| + paused_properties, base::TimeDelta::FromMilliseconds(
|
| + ScopedTransformOverviewWindow::kTransitionMilliseconds)));
|
| + sequence->AddElement(ui::LayerAnimationElement::CreateOpacityElement(1,
|
| + base::TimeDelta::FromMilliseconds(
|
| + kPanelCalloutFadeInDurationMilliseconds)));
|
| + GetCalloutWidget()->GetLayer()->GetAnimator()->StartAnimation(
|
| + sequence.release());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +WindowSelectorPanels::WindowSelectorPanels() {
|
| +}
|
| +
|
| +WindowSelectorPanels::~WindowSelectorPanels() {
|
| +}
|
| +
|
| +void WindowSelectorPanels::AddWindow(aura::Window* window) {
|
| + transform_windows_.push_back(new ScopedTransformPanelWindow(window));
|
| +}
|
| +
|
| +const aura::RootWindow* WindowSelectorPanels::GetRootWindow() const {
|
| + return transform_windows_.front()->window()->GetRootWindow();
|
| +}
|
| +
|
| +aura::Window* WindowSelectorPanels::TargetedWindow(
|
| + const aura::Window* target) const {
|
| + for (WindowList::const_iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + if ((*iter)->Contains(target))
|
| + return (*iter)->window();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +void WindowSelectorPanels::RestoreWindowOnExit(aura::Window* window) {
|
| + for (WindowList::iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + if ((*iter)->Contains(window)) {
|
| + (*iter)->RestoreWindowOnExit();
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +aura::Window* WindowSelectorPanels::SelectionWindow() const {
|
| + return transform_windows_.front()->window();
|
| +}
|
| +
|
| +void WindowSelectorPanels::RemoveWindow(const aura::Window* window) {
|
| + for (WindowList::iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + if ((*iter)->Contains(window)) {
|
| + (*iter)->OnWindowDestroyed();
|
| + transform_windows_.erase(iter);
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool WindowSelectorPanels::empty() const {
|
| + return transform_windows_.empty();
|
| +}
|
| +
|
| +void WindowSelectorPanels::SetItemBounds(aura::RootWindow* root_window,
|
| + const gfx::Rect& target_bounds) {
|
| + // Panel windows affect the position of each other. Restore all panel windows
|
| + // first in order to have the correct layout.
|
| + for (WindowList::iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + (*iter)->RestoreWindow();
|
| + }
|
| + gfx::Rect bounding_rect;
|
| + for (WindowList::iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + aura::Window* panel = (*iter)->window();
|
| + gfx::Rect bounds = ScreenAsh::ConvertRectToScreen(
|
| + panel->parent(), panel->GetTargetBounds());
|
| + bounding_rect.Union(bounds);
|
| + }
|
| + gfx::Transform bounding_transform =
|
| + ScopedTransformOverviewWindow::GetTransformForRectPreservingAspectRatio(
|
| + bounding_rect, target_bounds);
|
| + for (WindowList::iterator iter = transform_windows_.begin();
|
| + iter != transform_windows_.end(); ++iter) {
|
| + gfx::Transform transform;
|
| + aura::Window* panel = (*iter)->window();
|
| + gfx::Rect bounds = ScreenAsh::ConvertRectToScreen(
|
| + panel->parent(), panel->GetTargetBounds());
|
| + transform.Translate(bounding_rect.x() - bounds.x(),
|
| + bounding_rect.y() - bounds.y());
|
| + transform.PreconcatTransform(bounding_transform);
|
| + transform.Translate(bounds.x() - bounding_rect.x(),
|
| + bounds.y() - bounding_rect.y());
|
| + (*iter)->SetTransform(root_window, transform);
|
| + }
|
| +}
|
| +
|
| +} // namespace ash
|
|
|