1 // Copyright 2014 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.
5 #ifndef CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_BAR_H_
6 #define CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_BAR_H_
8 #include "base/macros.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/scoped_observer.h"
11 #include "chrome/browser/extensions/extension_toolbar_model.h"
12 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h"
13 #include "ui/gfx/animation/tween.h"
14 #include "ui/gfx/geometry/size.h"
16 namespace extensions
{
20 namespace user_prefs
{
21 class PrefRegistrySyncable
;
24 class ToolbarActionsBarDelegate
;
25 class ToolbarActionViewController
;
27 // A platform-independent version of the container for toolbar actions,
28 // including extension actions and component actions.
29 // This class manages the order of the actions, the actions' state, and owns the
30 // action controllers, in addition to (for extensions) interfacing with the
31 // extension toolbar model. Further, it manages dimensions for the bar,
32 // excluding animations.
33 // This can come in two flavors, main and "overflow". The main bar is visible
34 // next to the omnibox, and the overflow bar is visible inside the chrome
35 // (fka wrench) menu. The main bar can have only a single row of icons with
36 // flexible width, whereas the overflow bar has multiple rows of icons with a
37 // fixed width (the width of the menu).
38 class ToolbarActionsBar
: public extensions::ExtensionToolbarModel::Observer
,
39 public ToolbarActionsBarBubbleDelegate
{
41 // A struct to contain the platform settings.
42 struct PlatformSettings
{
43 explicit PlatformSettings(bool in_overflow_mode
);
45 // The padding that comes before the first icon in the container.
47 // The padding following the final icon in the container.
49 // The spacing between each of the icons.
51 // The number of icons per row in the overflow menu.
52 int icons_per_overflow_menu_row
;
53 // Whether or not the overflow menu is displayed as a chevron (this is being
58 // The type of drag that occurred in a drag-and-drop operation.
60 // The icon was dragged to the same container it started in.
62 // The icon was dragged from the main container to the overflow.
64 // The icon was dragged from the overflow container to the main.
68 ToolbarActionsBar(ToolbarActionsBarDelegate
* delegate
,
70 ToolbarActionsBar
* main_bar
);
71 ~ToolbarActionsBar() override
;
73 // Returns the width of a browser action icon, optionally including the
75 static int IconWidth(bool include_padding
);
77 // Returns the height of a browser action icon.
78 static int IconHeight();
80 // Registers profile preferences.
81 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
83 // Returns the preferred size for the toolbar; this does *not* reflect any
84 // animations that may be running.
85 gfx::Size
GetPreferredSize() const;
87 // Returns the [minimum|maximum] possible width for the toolbar.
88 int GetMinimumWidth() const;
89 int GetMaximumWidth() const;
91 // Returns the width for the given number of icons.
92 int IconCountToWidth(int icons
) const;
94 // Returns the number of icons that can fit within the given width.
95 size_t WidthToIconCount(int width
) const;
97 // Returns the number of icons that should be displayed.
98 size_t GetIconCount() const;
100 // Creates the toolbar actions.
101 void CreateActions();
103 // Deletes all toolbar actions.
104 void DeleteActions();
106 // Updates all the toolbar actions.
109 // Sets the width for the overflow menu rows.
110 void SetOverflowRowWidth(int width
);
112 // Notifies the ToolbarActionsBar that a user completed a resize gesture, and
113 // the new width is |width|.
114 void OnResizeComplete(int width
);
116 // Notifies the ToolbarActionsBar that a user completed a drag and drop event,
117 // and dragged the view from |dragged_index| to |dropped_index|.
118 // |drag_type| indicates whether or not the icon was dragged between the
119 // overflow and main containers.
120 // The main container should handle all drag/drop notifications.
121 void OnDragDrop(int dragged_index
,
125 // Returns true if the info bubble about the toolbar redesign should be shown.
126 bool ShouldShowInfoBubble();
128 const std::vector
<ToolbarActionViewController
*>& toolbar_actions() const {
129 return toolbar_actions_
.get();
131 bool enabled() const { return model_
!= nullptr; }
132 bool suppress_layout() const { return suppress_layout_
; }
133 bool suppress_animation() const {
134 return suppress_animation_
|| disable_animations_for_testing_
;
136 bool is_highlighting() const { return model_
&& model_
->is_highlighting(); }
137 const PlatformSettings
& platform_settings() const {
138 return platform_settings_
;
141 ToolbarActionsBarDelegate
* delegate_for_test() { return delegate_
; }
143 static void set_pop_out_actions_to_run_for_testing(
144 bool pop_out_actions_to_run
) {
145 pop_out_actions_to_run_
= pop_out_actions_to_run
;
148 static void set_send_overflowed_action_changes_for_testing(
149 bool send_overflowed_action_changes
) {
150 send_overflowed_action_changes_
= send_overflowed_action_changes
;
153 // During testing we can disable animations by setting this flag to true,
154 // so that the bar resizes instantly, instead of having to poll it while it
155 // animates to open/closed status.
156 static bool disable_animations_for_testing_
;
159 class TabOrderHelper
;
161 using ToolbarActions
= ScopedVector
<ToolbarActionViewController
>;
163 // ExtensionToolbarModel::Observer:
164 void OnToolbarExtensionAdded(const extensions::Extension
* extension
,
166 void OnToolbarExtensionRemoved(
167 const extensions::Extension
* extension
) override
;
168 void OnToolbarExtensionMoved(const extensions::Extension
* extension
,
170 void OnToolbarExtensionUpdated(
171 const extensions::Extension
* extension
) override
;
172 bool ShowExtensionActionPopup(const extensions::Extension
* extension
,
173 bool grant_active_tab
) override
;
174 void OnToolbarVisibleCountChanged() override
;
175 void OnToolbarHighlightModeChanged(bool is_highlighting
) override
;
176 void OnToolbarModelInitialized() override
;
177 Browser
* GetBrowser() override
;
179 // ToolbarActionsBarBubbleDelegate:
180 void OnToolbarActionsBarBubbleShown() override
;
181 void OnToolbarActionsBarBubbleClosed(CloseAction action
) override
;
183 // Resizes the delegate (if necessary) to the preferred size using the given
184 // |tween_type| and optionally suppressing the chevron.
185 void ResizeDelegate(gfx::Tween::Type tween_type
, bool suppress_chevron
);
187 // Returns the action for the given |id|, if one exists.
188 ToolbarActionViewController
* GetActionForId(const std::string
& id
);
190 // Returns the current web contents.
191 content::WebContents
* GetCurrentWebContents();
193 // Reorders the toolbar actions to reflect the model and, optionally, to
194 // "pop out" any overflowed actions that want to run (depending on the
195 // value of |pop_out_actions_to_run|.
196 void ReorderActions();
198 // Sets |overflowed_action_wants_to_run_| to the proper value.
199 void SetOverflowedActionWantsToRun();
201 // Shows an extension message bubble, if any should be shown.
202 void MaybeShowExtensionBubble();
204 bool in_overflow_mode() const { return main_bar_
!= nullptr; }
206 // The delegate for this object (in a real build, this is the view).
207 ToolbarActionsBarDelegate
* delegate_
;
209 // The associated browser.
212 // The observed toolbar model.
213 extensions::ExtensionToolbarModel
* model_
;
215 // The controller for the main toolbar actions bar. This will be null if this
217 ToolbarActionsBar
* main_bar_
;
219 // Platform-specific settings for dimensions and the overflow chevron.
220 PlatformSettings platform_settings_
;
222 // The toolbar actions.
223 ToolbarActions toolbar_actions_
;
225 // The TabOrderHelper that manages popping out actions that want to act.
226 // This is only non-null if |pop_out_actions_to_run| is true.
227 scoped_ptr
<TabOrderHelper
> tab_order_helper_
;
229 ScopedObserver
<extensions::ExtensionToolbarModel
,
230 extensions::ExtensionToolbarModel::Observer
> model_observer_
;
232 // True if we should suppress layout, such as when we are creating or
233 // adjusting a lot of actions at once.
234 bool suppress_layout_
;
236 // True if we should suppress animation; we do this when first creating the
237 // toolbar, and also when switching tabs changes the state of the icons.
238 bool suppress_animation_
;
240 // If this is true, actions that want to run (e.g., an extension's page
241 // action) will pop out of overflow to draw more attention.
242 // See also TabOrderHelper in the .cc file.
243 static bool pop_out_actions_to_run_
;
245 // If set to false, notifications for OnOverflowedActionWantsToRunChanged()
246 // will not be sent. Used because in unit tests there is no wrench menu to
248 static bool send_overflowed_action_changes_
;
250 // True if an action in the overflow menu wants to run.
251 bool overflowed_action_wants_to_run_
;
253 // True if we have checked to see if there is an extension bubble that should
254 // be displayed, and, if there is, shown that bubble.
255 bool checked_extension_bubble_
;
257 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsBar
);
260 #endif // CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_BAR_H_