1 // Copyright 2019 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_DESKS_DESKS_BAR_VIEW_H_
6 #define ASH_WM_DESKS_DESKS_BAR_VIEW_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "ash/ash_export.h"
12 #include "ash/wm/desks/desks_controller.h"
13 #include "base/macros.h"
14 #include "ui/views/view.h"
15 
16 namespace ash {
17 
18 class DeskMiniView;
19 class NewDeskButton;
20 class DeskBarHoverObserver;
21 class OverviewGrid;
22 
23 // A bar that resides at the top portion of the overview mode's ShieldView,
24 // which contains the virtual desks mini_views, as well as the new desk button.
25 class ASH_EXPORT DesksBarView : public views::View,
26                                 public DesksController::Observer {
27  public:
28   explicit DesksBarView(OverviewGrid* overview_grid);
29   ~DesksBarView() override;
30 
31   // Returns the height of the desk bar view which is based on the given |width|
32   // of the overview grid that exists on |root| (which is the same as the width
33   // of the bar) and |desks_bar_view|'s content (since they may not fit the
34   // given |width| forcing us to use the compact layout).
35   // If |desks_bar_view| is nullptr, the height returned will be solely based on
36   // the |width|.
37   static int GetBarHeightForWidth(aura::Window* root,
38                                   const DesksBarView* desks_bar_view,
39                                   int width);
40 
41   // Creates and returns the widget that contains the DeskBarView in overview
42   // mode. The returned widget has no content view yet, and hasn't been shown
43   // yet.
44   static std::unique_ptr<views::Widget> CreateDesksWidget(
45       aura::Window* root,
46       const gfx::Rect& bounds);
47 
background_view()48   views::View* background_view() const { return background_view_; }
49 
new_desk_button()50   NewDeskButton* new_desk_button() const { return new_desk_button_; }
51 
mini_views()52   const std::vector<DeskMiniView*>& mini_views() const { return mini_views_; }
53 
last_dragged_item_screen_location()54   const gfx::Point& last_dragged_item_screen_location() const {
55     return last_dragged_item_screen_location_;
56   }
57 
dragged_item_over_bar()58   bool dragged_item_over_bar() const { return dragged_item_over_bar_; }
59 
60   // Initializes and creates mini_views for any pre-existing desks, before the
61   // bar was created. This should only be called after this view has been added
62   // to a widget, as it needs to call `GetWidget()` when it's performing a
63   // layout.
64   void Init();
65 
66   // Returns true if a desk name is being modified using its mini view's
67   // DeskNameView on this bar.
68   bool IsDeskNameBeingModified() const;
69 
70   // Returns the scale factor by which a window's size will be scaled down when
71   // it is dragged and hovered on this desks bar.
72   float GetOnHoverWindowSizeScaleFactor() const;
73 
74   // Updates the visibility state of the close buttons on all the mini_views as
75   // a result of mouse and gesture events.
76   void OnHoverStateMayHaveChanged();
77   void OnGestureTap(const gfx::Rect& screen_rect, bool is_long_gesture);
78 
79   // Called when an item is being dragged in overview mode to update whether it
80   // is currently intersecting with this view, and the |screen_location| of the
81   // current drag position.
82   void SetDragDetails(const gfx::Point& screen_location,
83                       bool dragged_item_over_bar);
84 
85   // views::View:
86   const char* GetClassName() const override;
87   void Layout() override;
88   bool OnMousePressed(const ui::MouseEvent& event) override;
89   void OnGestureEvent(ui::GestureEvent* event) override;
90   void OnThemeChanged() override;
91 
92   // Returns true if the width of the DesksBarView is below a defined
93   // threshold or the contents no longer fit within this object's bounds in
94   // default mode, suggesting a compact small screens layout should be used for
95   // both itself and its children.
96   bool UsesCompactLayout() const;
97 
98   // DesksController::Observer:
99   void OnDeskAdded(const Desk* desk) override;
100   void OnDeskRemoved(const Desk* desk) override;
101   void OnDeskActivationChanged(const Desk* activated,
102                                const Desk* deactivated) override;
103   void OnDeskSwitchAnimationLaunching() override;
104   void OnDeskSwitchAnimationFinished() override;
105 
106  private:
107   // This is called on initialization or when a new desk is created to create
108   // the needed new mini_views. If |animate| is true, the mini_views will be
109   // animated to their final positions.
110   void UpdateNewMiniViews(bool animate);
111 
112   // Returns the mini_view associated with |desk| or nullptr if no mini_view
113   // has been created for it yet.
114   DeskMiniView* FindMiniViewForDesk(const Desk* desk) const;
115 
116   // Returns the X offset of the first mini_view on the left (if there's one),
117   // or the X offset of this view's center point when there are no mini_views.
118   // This offset is used to calculate the amount by which the mini_views should
119   // be moved when performing the mini_view creation or deletion animations.
120   int GetFirstMiniViewXOffset() const;
121 
122   // Updates the cached minimum width required to fit all contents.
123   void UpdateMinimumWidthToFitContents();
124 
125   // A view that shows a dark gary transparent background that can be animated
126   // when the very first mini_views are created.
127   views::View* background_view_;
128 
129   NewDeskButton* new_desk_button_;
130 
131   // The views representing desks mini_views. They're owned by views hierarchy.
132   std::vector<DeskMiniView*> mini_views_;
133 
134   // Observes mouse events on the desks bar widget and updates the states of the
135   // mini_views accordingly.
136   std::unique_ptr<DeskBarHoverObserver> hover_observer_;
137 
138   // The screen location of the most recent drag position. This value is valid
139   // only when the below `dragged_item_on_bar_` is true.
140   gfx::Point last_dragged_item_screen_location_;
141 
142   // True when the drag location of the overview item is intersecting with this
143   // view.
144   bool dragged_item_over_bar_ = false;
145 
146   // The OverviewGrid that contains this object.
147   OverviewGrid* overview_grid_;
148 
149   // Caches the calculated minimum width to fit contents.
150   int min_width_to_fit_contents_ = 0;
151 
152   DISALLOW_COPY_AND_ASSIGN(DesksBarView);
153 };
154 
155 }  // namespace ash
156 
157 #endif  // ASH_WM_DESKS_DESKS_BAR_VIEW_H_
158