Infobar material design refresh: layout
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / toolbar_actions_model.h
blobaf7b0bd16cdbb336a5db199a9c59e5c0cadf6d93
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.
32 class ToolbarActionsModel : public extensions::ExtensionActionAPI::Observer,
33 public extensions::ExtensionRegistryObserver,
34 public KeyedService {
35 public:
36 // The different options for highlighting.
37 enum HighlightType {
38 HIGHLIGHT_NONE,
39 HIGHLIGHT_INFO,
40 HIGHLIGHT_WARNING,
43 // The different types of actions.
44 enum ActionType {
45 UNKNOWN_ACTION,
46 COMPONENT_ACTION,
47 EXTENSION_ACTION,
50 // An action id and its corresponding ActionType.
51 struct ToolbarItem {
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; }
58 std::string id;
59 ActionType type;
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
69 // delegate.
70 class Observer {
71 public:
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
74 // initialized.
75 virtual void OnToolbarActionAdded(const std::string& id, int index) = 0;
77 // Signals that the given action with |id| has been removed from the
78 // toolbar.
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
104 // can catch up.
105 virtual void OnToolbarModelInitialized() = 0;
107 protected:
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
129 // bounds.
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(
143 Browser* browser,
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
158 // shown.
159 // Returns true if highlighting mode is entered, false otherwise.
160 bool HighlightActions(const std::vector<std::string>& action_ids,
161 HighlightType type);
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;
171 private:
172 // Callback when actions are ready.
173 void OnReady();
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
198 // it.
199 void InitializeActionList();
200 void Populate();
201 void IncognitoPopulate();
203 // Save the model to prefs.
204 void UpdatePrefs();
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;
228 // Our observers.
229 base::ObserverList<Observer> observers_;
231 // The Profile this toolbar model is for.
232 Profile* profile_;
234 extensions::ExtensionPrefs* extension_prefs_;
235 PrefService* 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.
247 bool use_redesign_;
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
256 // highlight).
257 HighlightType highlight_type_;
259 // A list of action ids ordered to correspond with their last known
260 // positions.
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
266 // possible.
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_