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 |