1 // Copyright (c) 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_PUBLIC_CPP_SHELF_CONFIG_H_
6 #define ASH_PUBLIC_CPP_SHELF_CONFIG_H_
7 
8 #include "ash/ash_export.h"
9 #include "ash/public/cpp/app_list/app_list_controller_observer.h"
10 #include "ash/public/cpp/shelf_types.h"
11 #include "ash/public/cpp/tablet_mode_observer.h"
12 #include "ash/style/ash_color_provider.h"
13 #include "ash/system/model/virtual_keyboard_model.h"
14 #include "ash/wm/overview/overview_observer.h"
15 #include "base/macros.h"
16 #include "base/observer_list.h"
17 #include "base/observer_list_types.h"
18 #include "third_party/skia/include/core/SkColor.h"
19 #include "ui/display/display_observer.h"
20 #include "ui/gfx/animation/tween.h"
21 
22 namespace ash {
23 
24 // Provides layout and drawing config for the Shelf. Note That some of these
25 // values could change at runtime.
26 class ASH_EXPORT ShelfConfig : public TabletModeObserver,
27                                public AppListControllerObserver,
28                                public display::DisplayObserver,
29                                public VirtualKeyboardModel::Observer,
30                                public OverviewObserver {
31  public:
32   class Observer : public base::CheckedObserver {
33    public:
34     // Invoked when shelf config values are changed.
OnShelfConfigUpdated()35     virtual void OnShelfConfigUpdated() {}
36   };
37 
38   ShelfConfig();
39   ~ShelfConfig() override;
40 
41   static ShelfConfig* Get();
42 
43   void AddObserver(Observer* observer);
44   void RemoveObserver(Observer* observer);
45 
46   // Add observers to this objects's dependencies.
47   void Init();
48 
49   // Remove observers from this object's dependencies.
50   void Shutdown();
51 
52   // OverviewObserver:
53   void OnOverviewModeWillStart() override;
54   void OnOverviewModeEnding(OverviewSession* overview_session) override;
55 
56   // TabletModeObserver:
57   void OnTabletModeStarting() override;
58   void OnTabletModeEnding() override;
59 
60   // DisplayObserver:
61   void OnDisplayMetricsChanged(const display::Display& display,
62                                uint32_t changed_metrics) override;
63 
64   // VirtualKeyboardModel::Observer:
65   void OnVirtualKeyboardVisibilityChanged() override;
66 
67   // AppListControllerObserver:
68   void OnAppListVisibilityWillChange(bool shown, int64_t display_id) override;
69 
70   // Whether the shelf control buttons must be shown for accessibility
71   // reasons.
72   bool ShelfControlsForcedShownForAccessibility() const;
73 
74   // Returns the optimal shelf button size for the given hotseat density.
75   int GetShelfButtonSize(HotseatDensity density) const;
76 
77   // Returns the optimal shelf icon size for the given hotseat density.
78   int GetShelfButtonIconSize(HotseatDensity density) const;
79 
80   // Returns the hotseat height for the given hotseat density.
81   // NOTE: This may not match the actual hotseat size, as hotseat may get scaled
82   // down if it does not fit in available bounds within the shelf. Use
83   // HotseatWidget::GetHotseatSize() to get the actual widget size.
84   int GetHotseatSize(HotseatDensity density) const;
85 
86   // Size of the shelf when visible (height when the shelf is horizontal and
87   // width when the shelf is vertical).
88   int shelf_size() const;
89 
90   // Size of the shelf when an app is visible in tablet mode.
91   int in_app_shelf_size() const;
92 
93   // Size of the shelf when not in tablet mode, or when no apps are visible.
94   int system_shelf_size() const;
95 
96   // The shelf size within which the drag handle should be centered.
97   int shelf_drag_handle_centering_size() const;
98 
99   // The size of the gap between the hotseat and shelf when the hotseat is
100   // extended.
101   int hotseat_bottom_padding() const;
102 
103   // Size of the space between buttons on the shelf.
104   int button_spacing() const;
105 
106   // Size for controls like the home button, back button, etc.
107   int control_size() const;
108 
109   // The radius of shelf control buttons.
110   int control_border_radius() const;
111 
112   // The spacing between the edge of the shelf and the control buttons. When
113   // shelf is horizontal, the left/right edges of the shelf are considered a
114   // primary axis edge. When shelf is vertical, the top/bottom edges are
115   // considered the primary axis edge.
116   int control_button_edge_spacing(bool is_primary_axis_edge) const;
117 
118   // The duration of the hotseat background animations in ms.
119   base::TimeDelta hotseat_background_animation_duration() const;
120 
121   // The duration of the shelf show/hide animation in ms.
122   base::TimeDelta shelf_animation_duration() const;
123 
124   // The extra padding added to status area tray buttons on the shelf.
125   int status_area_hit_region_padding() const;
126 
127   // Returns whether the in app shelf should be shown.
128   bool is_in_app() const;
129 
130   // The threshold relative to the size of the shelf that is used to determine
131   // if the shelf visibility should change during a drag.
132   float drag_hide_ratio_threshold() const;
133 
shelf_focus_border_color()134   SkColor shelf_focus_border_color() const { return shelf_focus_border_color_; }
workspace_area_visible_inset()135   int workspace_area_visible_inset() const {
136     return workspace_area_visible_inset_;
137   }
workspace_area_auto_hide_inset()138   int workspace_area_auto_hide_inset() const {
139     return workspace_area_auto_hide_inset_;
140   }
hidden_shelf_in_screen_portion()141   int hidden_shelf_in_screen_portion() const {
142     return hidden_shelf_in_screen_portion_;
143   }
status_indicator_offset_from_shelf_edge()144   int status_indicator_offset_from_shelf_edge() const {
145     return status_indicator_offset_from_shelf_edge_;
146   }
scrollable_shelf_ripple_padding()147   int scrollable_shelf_ripple_padding() const {
148     return scrollable_shelf_ripple_padding_;
149   }
shelf_tooltip_preview_height()150   int shelf_tooltip_preview_height() const {
151     return shelf_tooltip_preview_height_;
152   }
shelf_tooltip_preview_max_width()153   int shelf_tooltip_preview_max_width() const {
154     return shelf_tooltip_preview_max_width_;
155   }
shelf_tooltip_preview_max_ratio()156   float shelf_tooltip_preview_max_ratio() const {
157     return shelf_tooltip_preview_max_ratio_;
158   }
shelf_tooltip_preview_min_ratio()159   float shelf_tooltip_preview_min_ratio() const {
160     return shelf_tooltip_preview_min_ratio_;
161   }
shelf_blur_radius()162   int shelf_blur_radius() const { return shelf_blur_radius_; }
mousewheel_scroll_offset_threshold()163   int mousewheel_scroll_offset_threshold() const {
164     return mousewheel_scroll_offset_threshold_;
165   }
in_app_control_button_height_inset()166   int in_app_control_button_height_inset() const {
167     return in_app_control_button_height_inset_;
168   }
169 
is_dense()170   bool is_dense() const { return is_dense_; }
171 
shelf_controls_shown()172   bool shelf_controls_shown() const { return shelf_controls_shown_; }
173 
is_virtual_keyboard_shown()174   bool is_virtual_keyboard_shown() const { return is_virtual_keyboard_shown_; }
175 
in_tablet_mode()176   bool in_tablet_mode() const { return in_tablet_mode_; }
177 
in_overview_mode()178   bool in_overview_mode() const { return overview_mode_; }
179 
180   // Gets the current color for the shelf control buttons.
181   SkColor GetShelfControlButtonColor() const;
182 
183   // Gets the shelf color when the app list is open, used in clamshell mode.
184   SkColor GetShelfWithAppListColor() const;
185 
186   // Gets the shelf color when a window is maximized.
187   SkColor GetMaximizedShelfColor() const;
188 
189   // Gets the base layer type for shelf color.
190   AshColorProvider::BaseLayerType GetShelfBaseLayerType() const;
191 
192   // Gets the default shelf color, calculated using the wallpaper color if
193   // available.
194   SkColor GetDefaultShelfColor() const;
195 
196   // Returns the current blur radius to use for the control buttons.
197   int GetShelfControlButtonBlurRadius() const;
198 
199   // The padding between the app icon and the end of the scrollable shelf.
200   int GetAppIconEndPadding() const;
201 
202   // Returns the margin on either side of the group of app icons.
203   int GetAppIconGroupMargin() const;
204 
205   // The animation time for dimming shelf icons, widgets, and buttons.
206   base::TimeDelta DimAnimationDuration() const;
207 
208   // The tween type for dimming shelf icons, widgets, and buttons.
209   gfx::Tween::Type DimAnimationTween() const;
210 
211   // The size of the shelf drag handle.
212   gfx::Size DragHandleSize() const;
213 
214  private:
215   friend class ShelfConfigTest;
216 
217   class ShelfAccessibilityObserver;
218 
219   // Called whenever something has changed in the shelf configuration. Notifies
220   // all observers.
221   void OnShelfConfigUpdated();
222 
223   // Updates |is_dense_|, |is_app_list_visible_|, and |shelf_controls_shown_|
224   // and notifies all observers of the update if the state changes.
225   // |new_is_app_list_visible| - The new app list visibility state.
226   // |tablet_mode_changed| should be set to true if this config is being updated
227   // as a result of a change in tablet mode state.
228   void UpdateConfig(bool new_is_app_list_visible, bool tablet_mode_changed);
229 
230   // Gets the current shelf size.
231   // |ignore_in_app_state| - Whether the returned shelf size should be
232   //                         calculated as if is_in_app() returns false.
233   int GetShelfSize(bool ignore_in_app_state) const;
234 
235   // Updates shelf config - called when the accessibility state changes.
236   void UpdateConfigForAccessibilityState();
237 
238   // Whether the in app shelf should be shown in overview mode.
239   bool use_in_app_shelf_in_overview_;
240 
241   // True if device is currently in overview mode.
242   bool overview_mode_;
243 
244   // True if device is currently in tablet mode.
245   bool in_tablet_mode_;
246 
247   // Whether shelf is currently standard or dense.
248   bool is_dense_;
249 
250   // Whether the shelf buttons (navigation controls, and overview tray button)
251   // should be shown.
252   bool shelf_controls_shown_;
253 
254   // Whether virtual IME keyboard is shown.
255   bool is_virtual_keyboard_shown_;
256 
257   // Whether the app list (or home launcher in tablet mode) is visible.
258   bool is_app_list_visible_;
259 
260   // Size of the icons within shelf buttons.
261   const int shelf_button_icon_size_;
262   const int shelf_button_icon_size_median_;
263   const int shelf_button_icon_size_dense_;
264 
265   // Size allocated for each app button on the shelf.
266   const int shelf_button_size_;
267   const int shelf_button_size_median_;
268   const int shelf_button_size_dense_;
269 
270   // Size of the space between buttons on the shelf.
271   const int shelf_button_spacing_;
272 
273   // The extra padding added to status area tray buttons on the shelf.
274   const int shelf_status_area_hit_region_padding_;
275   const int shelf_status_area_hit_region_padding_dense_;
276 
277   // The margin on either side of the group of app icons in tablet/clamshell.
278   const int app_icon_group_margin_tablet_;
279   const int app_icon_group_margin_clamshell_;
280 
281   const SkColor shelf_focus_border_color_;
282 
283   // We reserve a small area on the edge of the workspace area to ensure that
284   // the resize handle at the edge of the window can be hit.
285   const int workspace_area_visible_inset_;
286 
287   // When autohidden we extend the touch hit target onto the screen so that the
288   // user can drag the shelf out.
289   const int workspace_area_auto_hide_inset_;
290 
291   // Portion of the shelf that's within the screen bounds when auto-hidden.
292   const int hidden_shelf_in_screen_portion_;
293 
294   // The distance between the edge of the shelf and the status indicators.
295   const int status_indicator_offset_from_shelf_edge_;
296 
297   // Padding between the shelf container view and the edging app icon in order
298   // to show the app icon's ripple correctly.
299   const int scrollable_shelf_ripple_padding_;
300 
301   // Dimensions for hover previews.
302   const int shelf_tooltip_preview_height_;
303   const int shelf_tooltip_preview_max_width_;
304   const float shelf_tooltip_preview_max_ratio_;
305   const float shelf_tooltip_preview_min_ratio_;
306 
307   // The blur radius used for the shelf.
308   const int shelf_blur_radius_;
309 
310   // The threshold at which mousewheel and touchpad scrolls are either ignored
311   // or acted upon.
312   const int mousewheel_scroll_offset_threshold_;
313 
314   // The height inset on the control buttons when in-app shelf is shown.
315   const int in_app_control_button_height_inset_;
316 
317   // The padding between the app icon and the end of the scrollable shelf in
318   // tablet mode.
319   const int app_icon_end_padding_;
320 
321   // Object responsible for observing accessibility settings relevant to shelf
322   // config.
323   std::unique_ptr<ShelfAccessibilityObserver> accessibility_observer_;
324 
325   base::ObserverList<Observer> observers_;
326 
327   DISALLOW_COPY_AND_ASSIGN(ShelfConfig);
328 };
329 
330 }  // namespace ash
331 
332 #endif  // ASH_PUBLIC_CPP_SHELF_CONFIG_H_
333