1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_
6 #define ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "ash/ash_export.h"
12 #include "ash/wm/overview/overview_session.h"
13 #include "ash/wm/overview/overview_types.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/optional.h"
17 #include "ui/aura/client/transient_window_client_observer.h"
18 #include "ui/aura/window_observer.h"
19 #include "ui/gfx/geometry/rect.h"
20 #include "ui/gfx/geometry/rect_f.h"
21 #include "ui/gfx/geometry/size.h"
22 #include "ui/gfx/transform.h"
23 
24 namespace aura {
25 class ScopedWindowEventTargetingBlocker;
26 class Window;
27 }  // namespace aura
28 
29 namespace ash {
30 class OverviewItem;
31 class ScopedOverviewAnimationSettings;
32 class ScopedOverviewHideWindows;
33 
34 // Manages a window, and its transient children, in the overview mode. This
35 // class allows transforming the windows with a helper to determine the best
36 // fit in certain bounds. The window's state is restored when this object is
37 // destroyed.
38 class ASH_EXPORT ScopedOverviewTransformWindow
39     : public aura::client::TransientWindowClientObserver,
40       public aura::WindowObserver {
41  public:
42   using ScopedAnimationSettings =
43       std::vector<std::unique_ptr<ScopedOverviewAnimationSettings>>;
44 
45   // Information needed to do a clip on |window_|.
46   enum class ClippingType {
47     kEnter,   // Clips away the header if it exists.
48     kExit,    // Removes or resets clip.
49     kCustom,  // Clips to custom given bounds.
50   };
51   using ClippingData = std::pair<ClippingType, gfx::SizeF>;
52 
53   // Calculates and returns an optimal scale ratio. This is only taking into
54   // account |size.height()| as the width can vary.
55   static float GetItemScale(const gfx::SizeF& source,
56                             const gfx::SizeF& target,
57                             int top_view_inset,
58                             int title_height);
59 
60   static OverviewGridWindowFillMode GetWindowDimensionsType(
61       const gfx::Size& size);
62 
63   ScopedOverviewTransformWindow(OverviewItem* overview_item,
64                                 aura::Window* window);
65   ScopedOverviewTransformWindow(const ScopedOverviewTransformWindow&) = delete;
66   ScopedOverviewTransformWindow& operator=(
67       const ScopedOverviewTransformWindow&) = delete;
68   ~ScopedOverviewTransformWindow() override;
69 
70   // Starts an animation sequence which will use animation settings specified by
71   // |animation_type|. The |animation_settings| container is populated with
72   // scoped entities and the container should be destroyed at the end of the
73   // animation sequence.
74   //
75   // Example:
76   //  ScopedOverviewTransformWindow overview_window(window);
77   //  ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
78   //  overview_window.BeginScopedAnimation(
79   //      OVERVIEW_ANIMATION_RESTORE_WINDOW, &animation_settings);
80   //  // Calls to SetTransform & SetOpacity will use the same animation settings
81   //  // until animation_settings is destroyed.
82   //  OverviewUtil::SetTransform(root_window, new_transform);
83   //  overview_window.SetOpacity(1);
84   void BeginScopedAnimation(OverviewAnimationType animation_type,
85                             ScopedAnimationSettings* animation_settings);
86 
87   // Returns true if this overview window contains the |target|.
88   bool Contains(const aura::Window* target) const;
89 
90   // Returns transformed bounds of the overview window. See
91   // OverviewUtil::GetTransformedBounds for more details.
92   gfx::RectF GetTransformedBounds() const;
93 
94   // Returns the kTopViewInset property of |window_| unless there are transient
95   // ancestors, in which case returns 0.
96   int GetTopInset() const;
97 
98   // Restores and animates the managed window to its non overview mode state.
99   // If |reset_transform| equals false, the window's transform will not be reset
100   // to identity transform when exiting the overview mode. See
101   // OverviewItem::RestoreWindow() for details why we need this.
102   void RestoreWindow(bool reset_transform);
103 
104   // Prepares for overview mode by doing any necessary actions before entering.
105   void PrepareForOverview();
106 
107   // Sets the opacity of the managed windows.
108   void SetOpacity(float opacity);
109 
110   // Apply clipping on the managed windows.
111   void SetClipping(const ClippingData& clipping_data);
112 
113   // Returns |rect| having been shrunk to fit within |bounds| (preserving the
114   // aspect ratio). Takes into account a window header that is |top_view_inset|
115   // tall in the original window getting replaced by a window caption that is
116   // |title_height| tall in the transformed window.
117   gfx::RectF ShrinkRectToFitPreservingAspectRatio(const gfx::RectF& rect,
118                                                   const gfx::RectF& bounds,
119                                                   int top_view_inset,
120                                                   int title_height);
121 
122   // Returns the window used to show the content in overview mode.
123   // For minimized window this will be a window that hosts mirrored layers.
124   aura::Window* GetOverviewWindow() const;
125 
126   // Closes the transient root of the window managed by |this|.
127   void Close();
128 
129   bool IsMinimized() const;
130 
131   // Ensures that a window is visible by setting its opacity to 1.
132   void EnsureVisible();
133 
134   // Called via OverviewItem from OverviewGrid when |window_|'s bounds
135   // change. Must be called before PositionWindows in OverviewGrid.
136   void UpdateWindowDimensionsType();
137 
138   // Updates the rounded corners on |window_|.
139   void UpdateRoundedCorners(bool show);
140 
141   // aura::client::TransientWindowClientObserver:
142   void OnTransientChildWindowAdded(aura::Window* parent,
143                                    aura::Window* transient_child) override;
144   void OnTransientChildWindowRemoved(aura::Window* parent,
145                                      aura::Window* transient_child) override;
146 
147   // aura::WindowObserver:
148   void OnWindowPropertyChanged(aura::Window* window,
149                                const void* key,
150                                intptr_t old) override;
151   void OnWindowBoundsChanged(aura::Window* window,
152                              const gfx::Rect& old_bounds,
153                              const gfx::Rect& new_bounds,
154                              ui::PropertyChangeReason reason) override;
155 
window()156   aura::Window* window() const { return window_; }
157 
type()158   OverviewGridWindowFillMode type() const { return type_; }
159 
160  private:
161   friend class OverviewHighlightControllerTest;
162   friend class OverviewSessionTest;
163   FRIEND_TEST_ALL_PREFIXES(OverviewSessionTest, CloseAnimationShadow);
164   class LayerCachingAndFilteringObserver;
165 
166   // If true, makes Close() execute synchronously when used in tests.
167   static void SetImmediateCloseForTests(bool immediate);
168 
169   // Closes the window managed by |this|.
170   void CloseWidget();
171 
172   // Adds transient windows that should be hidden to the hidden window list. The
173   // windows are hidden in overview mode and the visibility of the windows is
174   // recovered after overview mode.
175   void AddHiddenTransientWindows(
176       const std::vector<aura::Window*>& transient_windows);
177 
178   // A weak pointer to the overview item that owns |this|. Guaranteed to be not
179   // null for the lifetime of |this|.
180   OverviewItem* overview_item_;
181 
182   // A weak pointer to the real window in the overview.
183   aura::Window* window_;
184 
185   // The original opacity of the window before entering overview mode.
186   float original_opacity_;
187 
188   // Specifies how the window is laid out in the grid.
189   OverviewGridWindowFillMode type_ = OverviewGridWindowFillMode::kNormal;
190 
191   // The observers associated with the layers we requested caching render
192   // surface and trilinear filtering. The requests will be removed in dtor if
193   // the layer has not been destroyed.
194   std::vector<std::unique_ptr<LayerCachingAndFilteringObserver>>
195       cached_and_filtered_layer_observers_;
196 
197   // For the duration of this object |window_| and its transient childrens'
198   // event targeting policy will be sent to NONE. Store the originals so we can
199   // change it back when destroying |this|.
200   base::flat_map<aura::Window*,
201                  std::unique_ptr<aura::ScopedWindowEventTargetingBlocker>>
202       event_targeting_blocker_map_;
203 
204   // The original clipping on the layer of the window before entering overview
205   // mode.
206   gfx::Rect original_clip_rect_;
207 
208   std::unique_ptr<ScopedOverviewHideWindows> hidden_transient_children_;
209 
210   ScopedObserver<aura::Window, aura::WindowObserver> window_observer_{this};
211 
212   base::WeakPtrFactory<ScopedOverviewTransformWindow> weak_ptr_factory_{this};
213 };
214 
215 }  // namespace ash
216 
217 #endif  // ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_
218