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.
32 class ToolbarActionsModel
: public extensions::ExtensionActionAPI::Observer
,
33 public extensions::ExtensionRegistryObserver
,
36 // The different options for highlighting.
43 // The different types of actions.
50 // An action id and its corresponding ActionType.
52 ToolbarItem() : type(UNKNOWN_ACTION
) {}
53 ToolbarItem(std::string action_id
, ActionType action_type
)
54 : id(action_id
), type(action_type
) {}
56 bool operator==(const ToolbarItem
& other
) { return other
.id
== id
; }
62 ToolbarActionsModel(Profile
* profile
,
63 extensions::ExtensionPrefs
* extension_prefs
);
64 ~ToolbarActionsModel() override
;
66 // A class which is informed of changes to the model; represents the view of
67 // MVC. Also used for signaling view changes such as showing extension popups.
68 // TODO(devlin): Should this really be an observer? It acts more like a
72 // Signals that an action with |id| has been added to the toolbar at
73 // |index|. This will *only* be called after the toolbar model has been
75 virtual void OnToolbarActionAdded(const std::string
& id
, int index
) = 0;
77 // Signals that the given action with |id| has been removed from the
79 virtual void OnToolbarActionRemoved(const std::string
& id
) = 0;
81 // Signals that the given action with |id| has been moved to |index|.
82 // |index| is the desired *final* index of the action (that is, in the
83 // adjusted order, action should be at |index|).
84 virtual void OnToolbarActionMoved(const std::string
& id
, int index
) = 0;
86 // Signals that the browser action with |id| has been updated.
87 virtual void OnToolbarActionUpdated(const std::string
& id
) = 0;
89 // Signals when the container needs to be redrawn because of a size change,
90 // and when the model has finished loading.
91 virtual void OnToolbarVisibleCountChanged() = 0;
93 // Signals that the model has entered or exited highlighting mode, or that
94 // the actions being highlighted have (probably*) changed. Highlighting
95 // mode indicates that only a subset of the toolbar actions are actively
96 // displayed, and those actions should be highlighted for extra emphasis.
97 // * probably, because if we are in highlight mode and receive a call to
98 // highlight a new set of actions, we do not compare the current set with
99 // the new set (and just assume the new set is different).
100 virtual void OnToolbarHighlightModeChanged(bool is_highlighting
) = 0;
102 // Signals that the toolbar model has been initialized, so that if any
103 // observers were postponing animation during the initialization stage, they
105 virtual void OnToolbarModelInitialized() = 0;
108 virtual ~Observer() {}
111 // Convenience function to get the ToolbarActionsModel for a Profile.
112 static ToolbarActionsModel
* Get(Profile
* profile
);
114 // Adds or removes an observer.
115 void AddObserver(Observer
* observer
);
116 void RemoveObserver(Observer
* observer
);
118 // Moves the given action with |id|'s icon to the given |index|.
119 void MoveActionIcon(const std::string
& id
, size_t index
);
121 // Sets the number of action icons that should be visible.
122 // If count == size(), this will set the visible icon count to -1, meaning
123 // "show all actions".
124 void SetVisibleIconCount(size_t count
);
126 size_t visible_icon_count() const {
127 // We have guards around this because |visible_icon_count_| can be set by
128 // prefs/sync, and we want to ensure that the icon count returned is within
130 return visible_icon_count_
== -1
131 ? toolbar_items().size()
132 : std::min(static_cast<size_t>(visible_icon_count_
),
133 toolbar_items().size());
136 bool all_icons_visible() const {
137 return visible_icon_count() == toolbar_items().size();
140 bool actions_initialized() const { return actions_initialized_
; }
142 ScopedVector
<ToolbarActionViewController
> CreateActions(
144 ToolbarActionsBar
* bar
);
146 const std::vector
<ToolbarItem
>& toolbar_items() const {
147 return is_highlighting() ? highlighted_items_
: toolbar_items_
;
150 bool is_highlighting() const { return highlight_type_
!= HIGHLIGHT_NONE
; }
151 HighlightType
highlight_type() const { return highlight_type_
; }
153 void OnActionToolbarPrefChange();
155 // Highlights the actions specified by |action_ids|. This will cause
156 // the ToolbarModel to only display those actions.
157 // Highlighting mode is only entered if there is at least one action to be
159 // Returns true if highlighting mode is entered, false otherwise.
160 bool HighlightActions(const std::vector
<std::string
>& action_ids
,
163 // Stop highlighting actions. All actions can be shown again, and the
164 // number of visible icons will be reset to what it was before highlighting.
165 void StopHighlighting();
167 // Returns true if the toolbar model is running with the redesign and is
168 // showing new icons as a result.
169 bool RedesignIsShowingNewIcons() const;
172 // Callback when actions are ready.
175 // ExtensionRegistryObserver:
176 void OnExtensionLoaded(content::BrowserContext
* browser_context
,
177 const extensions::Extension
* extension
) override
;
178 void OnExtensionUnloaded(
179 content::BrowserContext
* browser_context
,
180 const extensions::Extension
* extension
,
181 extensions::UnloadedExtensionInfo::Reason reason
) override
;
182 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
183 const extensions::Extension
* extension
,
184 extensions::UninstallReason reason
) override
;
186 // ExtensionActionAPI::Observer:
187 void OnExtensionActionUpdated(
188 ExtensionAction
* extension_action
,
189 content::WebContents
* web_contents
,
190 content::BrowserContext
* browser_context
) override
;
191 void OnExtensionActionVisibilityChanged(const std::string
& extension_id
,
192 bool is_now_visible
) override
;
194 // To be called after the extension service is ready; gets loaded extensions
195 // from the ExtensionRegistry and their saved order from the pref service
196 // and constructs |toolbar_items_| from these data. IncognitoPopulate()
197 // takes the shortcut - looking at the regular model's content and modifying
199 void InitializeActionList();
201 void IncognitoPopulate();
203 // Save the model to prefs.
206 // Updates action with |action|'s id's browser action visibility pref if the
207 // browser action is in the overflow menu and should be considered hidden.
208 void MaybeUpdateVisibilityPref(const ToolbarItem
& action
, size_t index
);
210 // Calls MaybeUpdateVisibilityPref() for each action in |toolbar_items|.
211 void MaybeUpdateVisibilityPrefs();
213 // Finds the last known visible position of the icon for |action|. The value
214 // returned is a zero-based index into the vector of visible items.
215 size_t FindNewPositionFromLastKnownGood(const ToolbarItem
& action
);
217 // Returns true if the given |extension| should be added to the toolbar.
218 bool ShouldAddExtension(const extensions::Extension
* extension
);
220 // Adds or removes the given |extension| from the toolbar model.
221 void AddExtension(const extensions::Extension
* extension
);
222 void RemoveExtension(const extensions::Extension
* extension
);
224 // Looks up and returns the extension with the given |id| in the set of
225 // enabled extensions.
226 const extensions::Extension
* GetExtensionById(const std::string
& id
) const;
229 base::ObserverList
<Observer
> observers_
;
231 // The Profile this toolbar model is for.
234 extensions::ExtensionPrefs
* extension_prefs_
;
237 // The ExtensionActionAPI object, cached for convenience.
238 extensions::ExtensionActionAPI
* extension_action_api_
;
240 // The ExtensionRegistry object, cached for convenience.
241 extensions::ExtensionRegistry
* extension_registry_
;
243 // True if we've handled the initial EXTENSIONS_READY notification.
244 bool actions_initialized_
;
246 // If true, we include all actions in the toolbar model.
249 // Ordered list of browser actions.
250 std::vector
<ToolbarItem
> toolbar_items_
;
252 // List of browser actions which should be highlighted.
253 std::vector
<ToolbarItem
> highlighted_items_
;
255 // The current type of highlight (with HIGHLIGHT_NONE indicating no current
257 HighlightType highlight_type_
;
259 // A list of action ids ordered to correspond with their last known
261 std::vector
<std::string
> last_known_positions_
;
263 // The number of icons visible (the rest should be hidden in the overflow
264 // chevron). A value of -1 indicates that all icons should be visible.
265 // Instead of using this variable directly, use visible_icon_count() if
267 // TODO(devlin): Make a new variable to indicate that all icons should be
268 // visible, instead of overloading this one.
269 int visible_icon_count_
;
271 ScopedObserver
<extensions::ExtensionActionAPI
,
272 extensions::ExtensionActionAPI::Observer
>
273 extension_action_observer_
;
275 // Listen to extension load, unloaded notifications.
276 ScopedObserver
<extensions::ExtensionRegistry
, ExtensionRegistryObserver
>
277 extension_registry_observer_
;
279 // For observing change of toolbar order preference by external entity (sync).
280 PrefChangeRegistrar pref_change_registrar_
;
281 base::Closure pref_change_callback_
;
283 base::WeakPtrFactory
<ToolbarActionsModel
> weak_ptr_factory_
;
285 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsModel
);
288 #endif // CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTIONS_MODEL_H_