| // 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. |
| |
| #ifndef ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_ |
| #define ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_ |
| |
| #include <memory> |
| |
| #include "ash/ash_export.h" |
| #include "ash/wm/overview/caption_container_view.h" |
| #include "ash/wm/overview/overview_session.h" |
| #include "ash/wm/overview/scoped_overview_transform_window.h" |
| #include "base/macros.h" |
| #include "ui/aura/window_observer.h" |
| #include "ui/compositor/layer_animation_observer.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| #include "ui/views/controls/button/button.h" |
| |
| namespace ui { |
| class Shadow; |
| } // namespace ui |
| |
| namespace views { |
| class Widget; |
| } // namespace views |
| |
| namespace ash { |
| class OverviewGrid; |
| class RoundedLabelWidget; |
| |
| // This class represents an item in overview mode. |
| class ASH_EXPORT OverviewItem : public CaptionContainerView::EventDelegate, |
| public aura::WindowObserver, |
| public ui::ImplicitAnimationObserver { |
| public: |
| OverviewItem(aura::Window* window, |
| OverviewSession* overview, |
| OverviewGrid* overview_grid); |
| ~OverviewItem() override; |
| |
| aura::Window* GetWindow(); |
| |
| // Returns the native window of the |transformed_window_|'s minimized widget |
| // if the original window is in minimized state, or the original window |
| // otherwise. |
| aura::Window* GetWindowForStacking(); |
| |
| // Returns the root window on which this item is shown. |
| aura::Window* root_window() { return root_window_; } |
| |
| // Returns true if |target| is contained in this OverviewItem. |
| bool Contains(const aura::Window* target) const; |
| |
| // Restores and animates the managed window to its non overview mode state. |
| // If |reset_transform| equals false, the window's transform will not be |
| // reset to identity transform when exiting overview mode. It's needed when |
| // dragging an Arc app window in overview mode to put it in split screen. In |
| // this case the restore of its transform needs to be deferred until the Arc |
| // app window is snapped successfully, otherwise the animation will look very |
| // ugly (the Arc app window enlarges itself to maximized window bounds and |
| // then shrinks to its snapped window bounds). Note if the window's transform |
| // is not reset here, it must be reset by someone else at some point. |
| void RestoreWindow(bool reset_transform); |
| |
| // Ensures that a possibly minimized window becomes visible after restore. |
| void EnsureVisible(); |
| |
| // Restores stacking of window captions above the windows, then fades out. |
| void Shutdown(); |
| |
| // Dispatched before beginning window overview. This will do any necessary |
| // one time actions such as restoring minimized windows. |
| void PrepareForOverview(); |
| |
| // Calculates and returns an optimal scale ratio. With MD this is only |
| // taking into account |size.height()| as the width can vary. Without MD this |
| // returns the scale that allows the item to fully fit within |size|. |
| float GetItemScale(const gfx::Size& size); |
| |
| // Returns the union of the original target bounds of all transformed windows |
| // managed by |this| item, i.e. all regular (normal or panel transient |
| // descendants of the window returned by GetWindow()). |
| gfx::RectF GetTargetBoundsInScreen() const; |
| |
| // Returns the transformed bound of |transform_window_|. |
| gfx::RectF GetTransformedBounds() const; |
| |
| // Sets the bounds of this overview item to |target_bounds| in the |
| // |root_window_| root window. The bounds change will be animated as specified |
| // by |animation_type|. |
| void SetBounds(const gfx::RectF& target_bounds, |
| OverviewAnimationType animation_type); |
| |
| // Activates or deactivates selection depending on |selected|. |
| // In selected state the item's caption is shown transparent and blends with |
| // the selection widget. |
| void set_selected(bool selected) { selected_ = selected; } |
| |
| // Sends an accessibility event indicating that this window became selected |
| // so that it is highlighted and announced. |
| void SendAccessibleSelectionEvent(); |
| |
| // Slides the item up or down and then closes the associated window. Used by |
| // overview swipe to close. |
| void AnimateAndCloseWindow(bool up); |
| |
| // Closes |transform_window_|. |
| void CloseWindow(); |
| |
| // Called when the window is minimized or unminimized. |
| void OnMinimizedStateChanged(); |
| |
| // Shows the cannot snap warning if currently in splitview, and the associated |
| // window cannot be snapped. |
| void UpdateCannotSnapWarningVisibility(); |
| |
| // Called when a OverviewItem on any grid is dragged. Hides the close button |
| // when a drag is started, and reshows it when a drag is finished. |
| // Additionally hides the title and window icon if |item| is this. |
| void OnSelectorItemDragStarted(OverviewItem* item); |
| void OnSelectorItemDragEnded(bool snap); |
| |
| ScopedOverviewTransformWindow::GridWindowFillMode GetWindowDimensionsType() |
| const; |
| |
| // Recalculates the window dimensions type of |transform_window_|. Called when |
| // |window_|'s bounds change. |
| void UpdateWindowDimensionsType(); |
| |
| // TODO(minch): Do not actually scale up the item to get the bounds. |
| // http://crbug.com/876567. |
| // Returns the bounds of the selected item, which will be scaled up a little |
| // bit and header view will be hidden after being selected. Note, the item |
| // will be restored back after scaled up. |
| gfx::Rect GetBoundsOfSelectedItem(); |
| |
| // Increases the bounds of the dragged item. |
| void ScaleUpSelectedItem(OverviewAnimationType animation_type); |
| |
| const gfx::RectF& target_bounds() const { return target_bounds_; } |
| |
| // Shift the window item up and then animates it to its original spot. Used |
| // to transition from the home launcher. |
| void SlideWindowIn(); |
| |
| // Translate and fade the window (or minimized widget) and |item_widget_|. It |
| // should remain in the same spot relative to the grids origin, which is given |
| // by |new_grid_y|. Returns the settings object of the layer the caller should |
| // observe. |
| std::unique_ptr<ui::ScopedLayerAnimationSettings> UpdateYPositionAndOpacity( |
| int new_grid_y, |
| float opacity, |
| OverviewSession::UpdateAnimationSettingsCallback callback); |
| |
| // If the window item represents a minimized window, update its content view. |
| void UpdateItemContentViewForMinimizedWindow(); |
| |
| // Checks if this item is current being dragged. |
| bool IsDragItem(); |
| |
| // Called after a positioning transform animation ends. Checks to see if the |
| // animation was triggered by a drag end event. If so, inserts the window back |
| // to its original stacking order so that the order of windows is the same as |
| // when entering overview. |
| void OnDragAnimationCompleted(); |
| |
| // Sets the bounds of the window shadow. If |bounds_in_screen| is nullopt, |
| // the shadow is hidden. |
| void SetShadowBounds(base::Optional<gfx::Rect> bounds_in_screen); |
| |
| // Updates the mask and shadow on this overview window item. |
| void UpdateMaskAndShadow(); |
| |
| // Called when the starting animation is completed, or called immediately |
| // if there was no starting animation. |
| void OnStartingAnimationComplete(); |
| |
| // Changes the opacity of all the windows the item owns. |
| void SetOpacity(float opacity); |
| float GetOpacity(); |
| |
| OverviewAnimationType GetExitOverviewAnimationType(); |
| OverviewAnimationType GetExitTransformAnimationType(); |
| |
| // CaptionContainerView::EventDelegate: |
| void HandlePressEvent(const gfx::PointF& location_in_screen) override; |
| void HandleReleaseEvent(const gfx::PointF& location_in_screen) override; |
| void HandleDragEvent(const gfx::PointF& location_in_screen) override; |
| void HandleLongPressEvent(const gfx::PointF& location_in_screen) override; |
| void HandleFlingStartEvent(const gfx::PointF& location_in_screen, |
| float velocity_x, |
| float velocity_y) override; |
| void HandleTapEvent() override; |
| void HandleGestureEndEvent() override; |
| void HandleCloseButtonClicked() override; |
| bool ShouldIgnoreGestureEvents() override; |
| |
| // aura::WindowObserver: |
| void OnWindowBoundsChanged(aura::Window* window, |
| const gfx::Rect& old_bounds, |
| const gfx::Rect& new_bounds, |
| ui::PropertyChangeReason reason) override; |
| void OnWindowDestroying(aura::Window* window) override; |
| void OnWindowTitleChanged(aura::Window* window) override; |
| |
| // ui::ImplicitAnimationObserver: |
| void OnImplicitAnimationsCompleted() override; |
| |
| OverviewGrid* overview_grid() { return overview_grid_; } |
| |
| void set_should_animate_when_entering(bool should_animate) { |
| should_animate_when_entering_ = should_animate; |
| } |
| bool should_animate_when_entering() const { |
| return should_animate_when_entering_; |
| } |
| |
| void set_should_animate_when_exiting(bool should_animate) { |
| should_animate_when_exiting_ = should_animate; |
| } |
| bool should_animate_when_exiting() const { |
| return should_animate_when_exiting_; |
| } |
| |
| void set_should_restack_on_animation_end(bool val) { |
| should_restack_on_animation_end_ = val; |
| } |
| |
| bool animating_to_close() const { return animating_to_close_; } |
| void set_animating_to_close(bool val) { animating_to_close_ = val; } |
| |
| void set_disable_mask(bool disable) { disable_mask_ = disable; } |
| |
| float GetCloseButtonVisibilityForTesting() const; |
| float GetTitlebarOpacityForTesting() const; |
| gfx::Rect GetShadowBoundsForTesting(); |
| RoundedLabelWidget* cannot_snap_widget_for_testing() { |
| return cannot_snap_widget_.get(); |
| } |
| |
| private: |
| friend class OverviewSessionTest; |
| class WindowSurfaceCacheObserver; |
| FRIEND_TEST_ALL_PREFIXES(SplitViewOverviewSessionTest, |
| OverviewUnsnappableIndicatorVisibility); |
| |
| // Sets the bounds of this overview item to |target_bounds| in |root_window_|. |
| // The bounds change will be animated as specified by |animation_type|. |
| void SetItemBounds(const gfx::RectF& target_bounds, |
| OverviewAnimationType animation_type); |
| |
| // Creates the window label. |
| void CreateWindowLabel(); |
| |
| // Updates the |item_widget|'s bounds. Any change in bounds will be animated |
| // from the current bounds to the new bounds as per the |animation_type|. |
| void UpdateHeaderLayout(OverviewAnimationType animation_type); |
| |
| // Animates opacity of the |transform_window_| and its caption to |opacity| |
| // using |animation_type|. |
| void AnimateOpacity(float opacity, OverviewAnimationType animation_type); |
| |
| // Allows a test to directly set animation state. |
| gfx::SlideAnimation* GetBackgroundViewAnimation(); |
| |
| // Called before dragging. Scales up the window a little bit to indicate its |
| // selection and stacks the window at the top of the Z order in order to keep |
| // it visible while dragging around. |
| void StartDrag(); |
| |
| // The root window this item is being displayed on. |
| aura::Window* root_window_; |
| |
| // The contained Window's wrapper. |
| ScopedOverviewTransformWindow transform_window_; |
| |
| // The target bounds this overview item is fit within. |
| gfx::RectF target_bounds_; |
| |
| // True if running SetItemBounds. This prevents recursive calls resulting from |
| // the bounds update when calling ::wm::RecreateWindowLayers to copy |
| // a window layer for display on another monitor. |
| bool in_bounds_update_ = false; |
| |
| // True when |this| item is visually selected. Item header is made transparent |
| // when the item is selected. |
| bool selected_ = false; |
| |
| // A widget stacked under the |transform_window_|. The widget has |
| // |caption_container_view_| as its contents view. The widget is backed by a |
| // NOT_DRAWN layer since most of its surface is transparent. |
| std::unique_ptr<views::Widget> item_widget_; |
| |
| // The view associated with |item_widget_|. Contains a title, close button and |
| // maybe a backdrop. Forwards certain events to |this|. |
| CaptionContainerView* caption_container_view_ = nullptr; |
| |
| // A widget with text that may show up on top of |transform_window_| to notify |
| // users this window cannot be snapped. |
| std::unique_ptr<RoundedLabelWidget> cannot_snap_widget_; |
| |
| // Pointer to the Overview that owns the OverviewGrid containing |this|. |
| // Guaranteed to be non-null for the lifetime of |this|. |
| OverviewSession* overview_session_; |
| |
| // Pointer to the OverviewGrid that contains |this|. Guaranteed to be non-null |
| // for the lifetime of |this|. |
| OverviewGrid* overview_grid_; |
| |
| // True if the contained window should animate during the entering animation. |
| bool should_animate_when_entering_ = true; |
| |
| // True if the contained window should animate during the exiting animation. |
| bool should_animate_when_exiting_ = true; |
| |
| // True if after an animation, we need to reorder the stacking order of the |
| // widgets. |
| bool should_restack_on_animation_end_ = false; |
| |
| // True if the windows are still alive so they can have a closing animation. |
| // These windows should not be used in calculations for |
| // OverviewGrid::PositionWindows. |
| bool animating_to_close_ = false; |
| |
| // True if this overview item is currently being dragged around. |
| bool is_being_dragged_ = false; |
| |
| // True to always disable mask regardless of the state. |
| bool disable_mask_ = false; |
| |
| // The shadow around the overview window. Shadows the original window, not |
| // |item_widget_|. Done here instead of on the original window because of the |
| // rounded edges mask applied on entering overview window. |
| std::unique_ptr<ui::Shadow> shadow_; |
| |
| // The observer to observe the window that has cached its render surface. |
| std::unique_ptr<WindowSurfaceCacheObserver> window_surface_cache_observers_; |
| |
| DISALLOW_COPY_AND_ASSIGN(OverviewItem); |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_ |