1 // Copyright (c) 2012 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_MODEL_H_
6 #define CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_MODEL_H_
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/observer_list.h"
11 #include "base/prefs/pref_change_registrar.h"
12 #include "base/scoped_observer.h"
13 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
14 #include "chrome/browser/extensions/extension_action.h"
15 #include "components/keyed_service/core/keyed_service.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/browser/extension_registry_observer.h"
18 #include "extensions/common/extension.h"
23 class ToolbarActionsBar
;
24 class ToolbarActionViewController
;
26 namespace extensions
{
27 class ExtensionRegistry
;
31 // Model for the browser actions toolbar. This is a per-profile instance, and
32 // manages the user's global preferences.
33 // Each browser window will attempt to show browser actions as specified by this
34 // model, but if the window is too narrow, actions may end up pushed into the
35 // overflow menu on a per-window basis. Callers interested in the arrangement of
36 // actions in a particular window should check that window's instance of
37 // ToolbarActionsBar, which is responsible for the per-window layout.
38 class ToolbarActionsModel
: public extensions::ExtensionActionAPI::Observer
,
39 public extensions::ExtensionRegistryObserver
,
42 // The different options for highlighting.
49 // The different types of actions.
56 // An action id and its corresponding ActionType.
58 ToolbarItem() : type(UNKNOWN_ACTION
) {}
59 ToolbarItem(std::string action_id
, ActionType action_type
)
60 : id(action_id
), type(action_type
) {}
62 bool operator==(const ToolbarItem
& other
) { return other
.id
== id
; }
68 ToolbarActionsModel(Profile
* profile
,
69 extensions::ExtensionPrefs
* extension_prefs
);
70 ~ToolbarActionsModel() override
;
72 // A class which is informed of changes to the model; represents the view of
73 // MVC. Also used for signaling view changes such as showing extension popups.
74 // TODO(devlin): Should this really be an observer? It acts more like a
78 // Signals that an action with |id| has been added to the toolbar at
79 // |index|. This will *only* be called after the toolbar model has been
81 virtual void OnToolbarActionAdded(const std::string
& id
, int index
) = 0;
83 // Signals that the given action with |id| has been removed from the
85 virtual void OnToolbarActionRemoved(const std::string
& id
) = 0;
87 // Signals that the given action with |id| has been moved to |index|.
88 // |index| is the desired *final* index of the action (that is, in the
89 // adjusted order, action should be at |index|).
90 virtual void OnToolbarActionMoved(const std::string
& id
, int index
) = 0;
92 // Signals that the browser action with |id| has been updated.
93 virtual void OnToolbarActionUpdated(const std::string
& id
) = 0;
95 // Signals when the container needs to be redrawn because of a size change,
96 // and when the model has finished loading.
97 virtual void OnToolbarVisibleCountChanged() = 0;
99 // Signals that the model has entered or exited highlighting mode, or that
100 // the actions being highlighted have (probably*) changed. Highlighting
101 // mode indicates that only a subset of the toolbar actions are actively
102 // displayed, and those actions should be highlighted for extra emphasis.
103 // * probably, because if we are in highlight mode and receive a call to
104 // highlight a new set of actions, we do not compare the current set with
105 // the new set (and just assume the new set is different).
106 virtual void OnToolbarHighlightModeChanged(bool is_highlighting
) = 0;
108 // Signals that the toolbar model has been initialized, so that if any
109 // observers were postponing animation during the initialization stage, they
111 virtual void OnToolbarModelInitialized() = 0;
114 virtual ~Observer() {}
117 // Convenience function to get the ToolbarActionsModel for a Profile.
118 static ToolbarActionsModel
* Get(Profile
* profile
);
120 // Adds or removes an observer.
121 void AddObserver(Observer
* observer
);
122 void RemoveObserver(Observer
* observer
);
124 // Moves the given action with |id|'s icon to the given |index|.
125 void MoveActionIcon(const std::string
& id
, size_t index
);
127 // Sets the number of action icons that should be visible.
128 // If count == size(), this will set the visible icon count to -1, meaning
129 // "show all actions".
130 void SetVisibleIconCount(size_t count
);
132 // Note that this (and all_icons_visible()) are the global default, but are
133 // inappropriate for determining a specific window's state - for that, use
134 // the ToolbarActionsBar.
135 size_t visible_icon_count() const {
136 // We have guards around this because |visible_icon_count_| can be set by
137 // prefs/sync, and we want to ensure that the icon count returned is within
139 return visible_icon_count_
== -1
140 ? toolbar_items().size()
141 : std::min(static_cast<size_t>(visible_icon_count_
),
142 toolbar_items().size());
144 bool all_icons_visible() const {
145 return visible_icon_count() == toolbar_items().size();
148 bool actions_initialized() const { return actions_initialized_
; }
150 ScopedVector
<ToolbarActionViewController
> CreateActions(
152 ToolbarActionsBar
* bar
);
154 const std::vector
<ToolbarItem
>& toolbar_items() const {
155 return is_highlighting() ? highlighted_items_
: toolbar_items_
;
158 bool is_highlighting() const { return highlight_type_
!= HIGHLIGHT_NONE
; }
159 HighlightType
highlight_type() const { return highlight_type_
; }
161 void OnActionToolbarPrefChange();
163 // Highlights the actions specified by |action_ids|. This will cause
164 // the ToolbarModel to only display those actions.
165 // Highlighting mode is only entered if there is at least one action to be
167 // Returns true if highlighting mode is entered, false otherwise.
168 bool HighlightActions(const std::vector
<std::string
>& action_ids
,
171 // Stop highlighting actions. All actions can be shown again, and the
172 // number of visible icons will be reset to what it was before highlighting.
173 void StopHighlighting();
175 // Returns true if the toolbar model is running with the redesign and is
176 // showing new icons as a result.
177 bool RedesignIsShowingNewIcons() const;
180 // Callback when actions are ready.
183 // ExtensionRegistryObserver:
184 void OnExtensionLoaded(content::BrowserContext
* browser_context
,
185 const extensions::Extension
* extension
) override
;
186 void OnExtensionUnloaded(
187 content::BrowserContext
* browser_context
,
188 const extensions::Extension
* extension
,
189 extensions::UnloadedExtensionInfo::Reason reason
) override
;
190 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
191 const extensions::Extension
* extension
,
192 extensions::UninstallReason reason
) override
;
194 // ExtensionActionAPI::Observer:
195 void OnExtensionActionUpdated(
196 ExtensionAction
* extension_action
,
197 content::WebContents
* web_contents
,
198 content::BrowserContext
* browser_context
) override
;
199 void OnExtensionActionVisibilityChanged(const std::string
& extension_id
,
200 bool is_now_visible
) override
;
202 // To be called after the extension service is ready; gets loaded extensions
203 // from the ExtensionRegistry and their saved order from the pref service
204 // and constructs |toolbar_items_| from these data. IncognitoPopulate()
205 // takes the shortcut - looking at the regular model's content and modifying
207 void InitializeActionList();
209 void IncognitoPopulate();
211 // Save the model to prefs.
214 // Updates action with |action|'s id's browser action visibility pref if the
215 // browser action is in the overflow menu and should be considered hidden.
216 void MaybeUpdateVisibilityPref(const ToolbarItem
& action
, size_t index
);
218 // Calls MaybeUpdateVisibilityPref() for each action in |toolbar_items|.
219 void MaybeUpdateVisibilityPrefs();
221 // Finds the last known visible position of the icon for |action|. The value
222 // returned is a zero-based index into the vector of visible items.
223 size_t FindNewPositionFromLastKnownGood(const ToolbarItem
& action
);
225 // Returns true if the given |extension| should be added to the toolbar.
226 bool ShouldAddExtension(const extensions::Extension
* extension
);
228 // Adds or removes the given |extension| from the toolbar model.
229 void AddExtension(const extensions::Extension
* extension
);
230 void RemoveExtension(const extensions::Extension
* extension
);
232 // Looks up and returns the extension with the given |id| in the set of
233 // enabled extensions.
234 const extensions::Extension
* GetExtensionById(const std::string
& id
) const;
237 base::ObserverList
<Observer
> observers_
;
239 // The Profile this toolbar model is for.
242 extensions::ExtensionPrefs
* extension_prefs_
;
245 // The ExtensionActionAPI object, cached for convenience.
246 extensions::ExtensionActionAPI
* extension_action_api_
;
248 // The ExtensionRegistry object, cached for convenience.
249 extensions::ExtensionRegistry
* extension_registry_
;
251 // True if we've handled the initial EXTENSIONS_READY notification.
252 bool actions_initialized_
;
254 // If true, we include all actions in the toolbar model.
257 // Ordered list of browser actions.
258 std::vector
<ToolbarItem
> toolbar_items_
;
260 // List of browser actions which should be highlighted.
261 std::vector
<ToolbarItem
> highlighted_items_
;
263 // The current type of highlight (with HIGHLIGHT_NONE indicating no current
265 HighlightType highlight_type_
;
267 // A list of action ids ordered to correspond with their last known
269 std::vector
<std::string
> last_known_positions_
;
271 // The number of icons visible (the rest should be hidden in the overflow
272 // chevron). A value of -1 indicates that all icons should be visible.
273 // Instead of using this variable directly, use visible_icon_count() if
275 // TODO(devlin): Make a new variable to indicate that all icons should be
276 // visible, instead of overloading this one.
277 int visible_icon_count_
;
279 ScopedObserver
<extensions::ExtensionActionAPI
,
280 extensions::ExtensionActionAPI::Observer
>
281 extension_action_observer_
;
283 // Listen to extension load, unloaded notifications.
284 ScopedObserver
<extensions::ExtensionRegistry
, ExtensionRegistryObserver
>
285 extension_registry_observer_
;
287 // For observing change of toolbar order preference by external entity (sync).
288 PrefChangeRegistrar pref_change_registrar_
;
289 base::Closure pref_change_callback_
;
291 base::WeakPtrFactory
<ToolbarActionsModel
> weak_ptr_factory_
;
293 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsModel
);
296 #endif // CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_MODEL_H_