1 // Copyright 2017 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_SPLITVIEW_SPLIT_VIEW_UTILS_H_ 6 #define ASH_WM_SPLITVIEW_SPLIT_VIEW_UTILS_H_ 7 8 #include "ash/ash_export.h" 9 #include "ash/wm/splitview/split_view_controller.h" 10 #include "base/optional.h" 11 #include "ui/aura/window_observer.h" 12 #include "ui/compositor/layer_animation_observer.h" 13 #include "ui/gfx/transform.h" 14 15 namespace aura { 16 class Window; 17 } // namespace aura 18 19 namespace ui { 20 class Layer; 21 } // namespace ui 22 23 namespace ash { 24 25 // Enum of the different splitview mode animations. Sorted by property 26 // (opacity/transform) and then alphabetically. 27 enum SplitviewAnimationType { 28 // Used to fade in and out the highlights on either side which indicate where 29 // to drag a selector item. 30 SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN, 31 SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN_CANNOT_SNAP, 32 SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT, 33 // Used to fade in and out the other highlight. There are normally two 34 // highlights, one on each side. When entering a state with a preview 35 // highlight, one highlight is the preview highlight, and the other highlight 36 // is the other highlight. 37 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_IN, 38 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_IN_CANNOT_SNAP, 39 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT, 40 // Used to fade in and out the label on the overview item which warns users 41 // the item cannot be snapped. The label appears on the overview item after 42 // another window has been snapped. 43 SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN, 44 SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT, 45 // Used to fade in and out the preview area highlight which indicates the 46 // bounds of the window that is about to get snapped. 47 SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN, 48 SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT, 49 // Used to fade in and out the labels which appear on either side of overview 50 // mode when a overview item is selected. They indicate where to drag the 51 // selector item if it is snappable, or if an item cannot be snapped. 52 SPLITVIEW_ANIMATION_TEXT_FADE_IN, 53 SPLITVIEW_ANIMATION_TEXT_FADE_OUT, 54 // Used when the text fades in or out with the highlights, as opposed to 55 // fading in when the highlights change bounds. Has slightly different 56 // animation values. 57 SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT, 58 SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT, 59 // Used to slide in and out the other highlight. 60 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_IN, 61 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_OUT, 62 // Used to slide in and out the text label on the other highlight. 63 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_TEXT_SLIDE_IN, 64 SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_TEXT_SLIDE_OUT, 65 // Used to animate the inset of the preview area to nothing. 66 SPLITVIEW_ANIMATION_PREVIEW_AREA_NIX_INSET, 67 // Used to slide in and out the preview area highlight. 68 SPLITVIEW_ANIMATION_PREVIEW_AREA_SLIDE_IN, 69 SPLITVIEW_ANIMATION_PREVIEW_AREA_SLIDE_OUT, 70 // Used to slide in and out the text label on the preview area highlight. 71 SPLITVIEW_ANIMATION_PREVIEW_AREA_TEXT_SLIDE_IN, 72 SPLITVIEW_ANIMATION_PREVIEW_AREA_TEXT_SLIDE_OUT, 73 // Used to apply window transform on the selector item after it gets snapped 74 // or on the dragged window after the drag ends. 75 SPLITVIEW_ANIMATION_SET_WINDOW_TRANSFORM, 76 }; 77 78 // This class observes the window transform animation and relayout the window's 79 // transient bubble dialogs when animation is completed. This is needed in some 80 // splitview and overview cases as in splitview or overview, the window can have 81 // an un-identity transform in place when its bounds changed. And when this 82 // happens, its transient bubble dialogs won't have the correct bounds as the 83 // bounds are calculated based on the transformed window bounds. We'll need to 84 // manually relayout the bubble dialogs after the window's transform reset to 85 // the identity transform so that the bubble dialogs can have correct bounds. 86 class ASH_EXPORT WindowTransformAnimationObserver 87 : public ui::ImplicitAnimationObserver, 88 public aura::WindowObserver { 89 public: 90 explicit WindowTransformAnimationObserver(aura::Window* window); 91 ~WindowTransformAnimationObserver() override; 92 93 // ui::ImplicitAnimationObserver: 94 void OnImplicitAnimationsCompleted() override; 95 96 // aura::WindowObserver: 97 void OnWindowDestroying(aura::Window* window) override; 98 99 private: 100 aura::Window* const window_; 101 102 WindowTransformAnimationObserver(const WindowTransformAnimationObserver&) = 103 delete; 104 WindowTransformAnimationObserver& operator=( 105 const WindowTransformAnimationObserver&) = delete; 106 }; 107 108 // Animates |layer|'s opacity based on |type|. 109 void DoSplitviewOpacityAnimation(ui::Layer* layer, SplitviewAnimationType type); 110 111 // Animates |layer|'s transform based on |type|. 112 void DoSplitviewTransformAnimation( 113 ui::Layer* layer, 114 SplitviewAnimationType type, 115 const gfx::Transform& target_transform, 116 std::unique_ptr<ui::ImplicitAnimationObserver> animation_observer); 117 118 // Animates |layer|'s clip rect based on |type|. 119 void DoSplitviewClipRectAnimation( 120 ui::Layer* layer, 121 SplitviewAnimationType type, 122 const gfx::Rect& target_clip_rect, 123 std::unique_ptr<ui::ImplicitAnimationObserver> animation_observer); 124 125 // Restores split view and overview based on the current split view's state. 126 // If |refresh_snapped_windows| is true, it will update the left and right 127 // snapped windows based on the MRU windows snapped states. 128 void MaybeRestoreSplitView(bool refresh_snapped_windows); 129 130 // Returns true if we allow dragging an overview window to snap to split view in 131 // clamshell mode. 132 ASH_EXPORT bool IsClamshellSplitViewModeEnabled(); 133 134 // Checks multi-display support for overview and split view. 135 ASH_EXPORT bool AreMultiDisplayOverviewAndSplitViewEnabled(); 136 137 // Returns true if split view mode is supported. 138 ASH_EXPORT bool ShouldAllowSplitView(); 139 140 // Displays a toast notifying users the application selected for split view is 141 // not compatible. 142 ASH_EXPORT void ShowAppCannotSnapToast(); 143 144 // Calculates the snap position for a dragged window at |location_in_screen|, 145 // ignoring any properties of the window itself. The |root_window| is of the 146 // current screen. |initial_location_in_screen| is the location at drag start if 147 // the drag began in |root_window|, and is empty otherwise. To be snappable 148 // (meaning the return value is not |SplitViewController::NONE|), 149 // |location_in_screen| must be either inside |snap_distance_from_edge| or 150 // dragged toward the edge for at least |minimum_drag_distance| distance until 151 // it's dragged into a suitable edge of the work area of |root_window| (i.e., 152 // |horizontal_edge_inset| if dragged horizontally to snap, or 153 // |vertical_edge_inset| if dragged vertically). 154 ASH_EXPORT SplitViewController::SnapPosition GetSnapPositionForLocation( 155 aura::Window* root_window, 156 const gfx::Point& location_in_screen, 157 const base::Optional<gfx::Point>& initial_location_in_screen, 158 int snap_distance_from_edge, 159 int minimum_drag_distance, 160 int horizontal_edge_inset, 161 int vertical_edge_inset); 162 163 // Returns the desired snap position. To be snappable, |window| must 1) 164 // satisfy |SplitViewController::CanSnapWindow| for |root_window|, and 165 // 2) be snappable according to |GetSnapPositionForLocation| above. 166 // |initial_location_in_screen| is the window location at drag start in 167 // its initial window. Otherwise, the arguments are the same as above. 168 ASH_EXPORT SplitViewController::SnapPosition GetSnapPosition( 169 aura::Window* root_window, 170 aura::Window* window, 171 const gfx::Point& location_in_screen, 172 const gfx::Point& initial_location_in_screen, 173 int snap_distance_from_edge, 174 int minimum_drag_distance, 175 int horizontal_edge_inset, 176 int vertical_edge_inset); 177 178 } // namespace ash 179 180 #endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_UTILS_H_ 181