Vectorize sad tab image.
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / toolbar_actions_model.h
bloba92068cfb4e12f78d5a67b5d6baf08c707fc133d
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"
20 class Browser;
21 class PrefService;
22 class Profile;
23 class ToolbarActionsBar;
24 class ToolbarActionViewController;
26 namespace extensions {
27 class ExtensionRegistry;
28 class ExtensionSet;
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,
40 public KeyedService {
41 public:
42 // The different options for highlighting.
43 enum HighlightType {
44 HIGHLIGHT_NONE,
45 HIGHLIGHT_INFO,
46 HIGHLIGHT_WARNING,
49 // The different types of actions.
50 enum ActionType {
51 UNKNOWN_ACTION,
52 COMPONENT_ACTION,
53 EXTENSION_ACTION,
56 // An action id and its corresponding ActionType.
57 struct ToolbarItem {
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; }
64 std::string id;
65 ActionType type;
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
75 // delegate.
76 class Observer {
77 public:
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
80 // initialized.
81 virtual void OnToolbarActionAdded(const std::string& id, int index) = 0;
83 // Signals that the given action with |id| has been removed from the
84 // toolbar.
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
110 // can catch up.
111 virtual void OnToolbarModelInitialized() = 0;
113 protected:
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
138 // bounds.
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(
151 Browser* browser,
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
166 // shown.
167 // Returns true if highlighting mode is entered, false otherwise.
168 bool HighlightActions(const std::vector<std::string>& action_ids,
169 HighlightType type);
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;
179 private:
180 // Callback when actions are ready.
181 void OnReady();
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
206 // it.
207 void InitializeActionList();
208 void Populate();
209 void IncognitoPopulate();
211 // Save the model to prefs.
212 void UpdatePrefs();
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;
236 // Our observers.
237 base::ObserverList<Observer> observers_;
239 // The Profile this toolbar model is for.
240 Profile* profile_;
242 extensions::ExtensionPrefs* extension_prefs_;
243 PrefService* 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.
255 bool use_redesign_;
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
264 // highlight).
265 HighlightType highlight_type_;
267 // A list of action ids ordered to correspond with their last known
268 // positions.
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
274 // possible.
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_