Chromium Code Reviews| 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..2236051de7dc7e4ae9671f4b45136871091d19dc |
| --- /dev/null |
| +++ b/ash/wm/overview/window_selector_panels.cc |
| @@ -0,0 +1,178 @@ |
| +// 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()); |
| +} |
| + |
| +} |
|
sky
2013/09/13 21:46:44
// namespace
flackr
2013/09/13 22:28:38
Done.
|
| + |
| +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::SetBounds(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(); |
| + } |
| + WindowSelectorItem::SetBounds(root_window, target_bounds); |
| + 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 |