OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_BAR_GTK_H_ | |
6 #define CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_BAR_GTK_H_ | |
7 | |
8 #include <gtk/gtk.h> | |
9 | |
10 #include <vector> | |
11 | |
12 #include "base/compiler_specific.h" | |
13 #include "base/gtest_prod_util.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/memory/weak_ptr.h" | |
16 #include "base/prefs/pref_member.h" | |
17 #include "chrome/browser/bookmarks/bookmark_model_observer.h" | |
18 #include "chrome/browser/bookmarks/bookmark_stats.h" | |
19 #include "chrome/browser/ui/bookmarks/bookmark_bar.h" | |
20 #include "chrome/browser/ui/bookmarks/bookmark_bar_instructions_delegate.h" | |
21 #include "chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h" | |
22 #include "chrome/browser/ui/gtk/menu_bar_helper.h" | |
23 #include "content/public/browser/notification_observer.h" | |
24 #include "content/public/browser/notification_registrar.h" | |
25 #include "ui/base/gtk/gtk_signal.h" | |
26 #include "ui/base/gtk/owned_widget_gtk.h" | |
27 #include "ui/gfx/animation/animation.h" | |
28 #include "ui/gfx/animation/animation_delegate.h" | |
29 #include "ui/gfx/animation/slide_animation.h" | |
30 #include "ui/gfx/point.h" | |
31 #include "ui/gfx/size.h" | |
32 | |
33 class BookmarkBarInstructionsGtk; | |
34 class BookmarkMenuController; | |
35 class Browser; | |
36 class BrowserWindowGtk; | |
37 class GtkThemeService; | |
38 class MenuGtk; | |
39 class TabstripOriginProvider; | |
40 | |
41 namespace content { | |
42 class PageNavigator; | |
43 } | |
44 | |
45 class BookmarkBarGtk : public gfx::AnimationDelegate, | |
46 public BookmarkModelObserver, | |
47 public MenuBarHelper::Delegate, | |
48 public content::NotificationObserver, | |
49 public BookmarkBarInstructionsDelegate, | |
50 public BookmarkContextMenuControllerDelegate { | |
51 public: | |
52 BookmarkBarGtk(BrowserWindowGtk* window, | |
53 Browser* browser, | |
54 TabstripOriginProvider* tabstrip_origin_provider); | |
55 virtual ~BookmarkBarGtk(); | |
56 | |
57 // Returns the current browser. | |
58 Browser* browser() const { return browser_; } | |
59 | |
60 // Returns the top level widget. | |
61 GtkWidget* widget() const { return event_box_.get(); } | |
62 | |
63 // Sets the PageNavigator that is used when the user selects an entry on | |
64 // the bookmark bar. | |
65 void SetPageNavigator(content::PageNavigator* navigator); | |
66 | |
67 // Create the contents of the bookmark bar. | |
68 void Init(); | |
69 | |
70 // Changes the state of the bookmark bar. | |
71 void SetBookmarkBarState(BookmarkBar::State state, | |
72 BookmarkBar::AnimateChangeType animate_type); | |
73 | |
74 // Get the current height of the bookmark bar. | |
75 int GetHeight(); | |
76 | |
77 // Returns true if the bookmark bar is showing an animation. | |
78 bool IsAnimating(); | |
79 | |
80 // gfx::AnimationDelegate implementation ------------------------------------- | |
81 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; | |
82 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; | |
83 | |
84 // MenuBarHelper::Delegate implementation ------------------------------------ | |
85 virtual void PopupForButton(GtkWidget* button) OVERRIDE; | |
86 virtual void PopupForButtonNextTo(GtkWidget* button, | |
87 GtkMenuDirectionType dir) OVERRIDE; | |
88 | |
89 // BookmarkContextMenuController::Delegate implementation -------------------- | |
90 virtual void CloseMenu() OVERRIDE; | |
91 | |
92 const gfx::Animation* animation() { return &slide_animation_; } | |
93 | |
94 int max_height() const { return max_height_; } | |
95 | |
96 private: | |
97 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, DisplaysHelpMessageOnEmpty); | |
98 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, | |
99 HidesHelpMessageWithBookmark); | |
100 FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, BuildsButtons); | |
101 | |
102 // Change the visibility of the bookmarks bar. (Starts out hidden, per GTK's | |
103 // default behaviour). There are three visiblity states: | |
104 // | |
105 // Showing - bookmark bar is fully visible. | |
106 // Hidden - bookmark bar is hidden except for a few pixels that give | |
107 // extra padding to the bottom of the toolbar. Buttons are not | |
108 // clickable. | |
109 // Fullscreen - bookmark bar is fully hidden. | |
110 void Show(BookmarkBar::State old_state, | |
111 BookmarkBar::AnimateChangeType animate_type); | |
112 void Hide(BookmarkBar::State old_state, | |
113 BookmarkBar::AnimateChangeType animate_type); | |
114 | |
115 // Calculate maximum height of bookmark bar. | |
116 void CalculateMaxHeight(); | |
117 | |
118 // Helper function which generates GtkToolItems for |bookmark_toolbar_|. | |
119 void CreateAllBookmarkButtons(); | |
120 | |
121 // Sets the visibility of the instructional text based on whether there are | |
122 // any bookmarks in the bookmark bar node. | |
123 void SetInstructionState(); | |
124 | |
125 // Sets the visibility of the overflow chevron. | |
126 void SetChevronState(); | |
127 | |
128 // Shows or hides the other bookmarks button depending on whether there are | |
129 // bookmarks in it. | |
130 void UpdateOtherBookmarksVisibility(); | |
131 | |
132 // Destroys all the bookmark buttons in the GtkToolbar. | |
133 void RemoveAllButtons(); | |
134 | |
135 // Adds the "other bookmarks" and overflow buttons. | |
136 void AddCoreButtons(); | |
137 | |
138 // Removes and recreates all buttons in the bar. | |
139 void ResetButtons(); | |
140 | |
141 // Returns the number of buttons corresponding to starred urls/folders. This | |
142 // is equivalent to the number of children the bookmark bar node from the | |
143 // bookmark bar model has. | |
144 int GetBookmarkButtonCount(); | |
145 | |
146 // Returns BOOKMARK_LAUNCH_LOCATION_DETACHED_BAR or | |
147 // BOOKMARK_LAUNCH_LOCATION_ATTACHED_BAR based on detached state. | |
148 BookmarkLaunchLocation GetBookmarkLaunchLocation() const; | |
149 | |
150 // Set the appearance of the overflow button appropriately (either chromium | |
151 // style or GTK style). | |
152 void SetOverflowButtonAppearance(); | |
153 | |
154 // Returns the index of the first bookmark that is not visible on the bar. | |
155 // Returns -1 if they are all visible. | |
156 // |extra_space| is how much extra space to give the toolbar during the | |
157 // calculation (for the purposes of determining if ditching the chevron | |
158 // would be a good idea). | |
159 // If non-NULL, |showing_folders| will be packed with all the folders that are | |
160 // showing on the bar. | |
161 int GetFirstHiddenBookmark(int extra_space, | |
162 std::vector<GtkWidget*>* showing_folders); | |
163 | |
164 // Update the detached state (either enable or disable it, or do nothing). | |
165 void UpdateDetachedState(BookmarkBar::State old_state); | |
166 | |
167 // Turns on or off the app_paintable flag on |event_box_|, depending on our | |
168 // state. | |
169 void UpdateEventBoxPaintability(); | |
170 | |
171 // Queue a paint on the event box. | |
172 void PaintEventBox(); | |
173 | |
174 // Finds the size of the current web contents, if it exists and sets |size| | |
175 // to the correct value. Returns false if there isn't a WebContents, a | |
176 // condition that can happen during testing. | |
177 bool GetWebContentsSize(gfx::Size* size); | |
178 | |
179 // Connects to the "size-allocate" signal on the given widget, and causes it | |
180 // to throb after allocation. This is called when a new item is added to the | |
181 // bar. We can't call StartThrobbing directly because we don't know if it's | |
182 // visible or not until after the widget is allocated. | |
183 void StartThrobbingAfterAllocation(GtkWidget* item); | |
184 | |
185 // Used by StartThrobbingAfterAllocation. | |
186 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnItemAllocate, GtkAllocation*); | |
187 | |
188 // Makes the appropriate widget on the bookmark bar stop throbbing | |
189 // (a folder, the overflow chevron, or nothing). | |
190 void StartThrobbing(const BookmarkNode* node); | |
191 | |
192 // Set |throbbing_widget_| to |widget|. Also makes sure that | |
193 // |throbbing_widget_| doesn't become stale. | |
194 void SetThrobbingWidget(GtkWidget* widget); | |
195 | |
196 // An item has been dragged over the toolbar, update the drag context | |
197 // and toolbar UI appropriately. | |
198 gboolean ItemDraggedOverToolbar( | |
199 GdkDragContext* context, int index, guint time); | |
200 | |
201 // When dragging in the middle of a folder, assume the user wants to drop | |
202 // on the folder. Towards the edges, assume the user wants to drop on the | |
203 // toolbar. This makes it possible to drop between two folders. This function | |
204 // returns the index on the toolbar the drag should target, or -1 if the | |
205 // drag should hit the folder. | |
206 int GetToolbarIndexForDragOverFolder(GtkWidget* button, gint x); | |
207 | |
208 void ClearToolbarDropHighlighting(); | |
209 | |
210 // Overridden from BookmarkModelObserver: | |
211 virtual void BookmarkModelLoaded(BookmarkModel* model, | |
212 bool ids_reassigned) OVERRIDE; | |
213 virtual void BookmarkModelBeingDeleted(BookmarkModel* model) OVERRIDE; | |
214 virtual void BookmarkNodeMoved(BookmarkModel* model, | |
215 const BookmarkNode* old_parent, | |
216 int old_index, | |
217 const BookmarkNode* new_parent, | |
218 int new_index) OVERRIDE; | |
219 virtual void BookmarkNodeAdded(BookmarkModel* model, | |
220 const BookmarkNode* parent, | |
221 int index) OVERRIDE; | |
222 virtual void BookmarkNodeRemoved(BookmarkModel* model, | |
223 const BookmarkNode* parent, | |
224 int old_index, | |
225 const BookmarkNode* node) OVERRIDE; | |
226 virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE; | |
227 virtual void BookmarkNodeChanged(BookmarkModel* model, | |
228 const BookmarkNode* node) OVERRIDE; | |
229 virtual void BookmarkNodeFaviconChanged(BookmarkModel* model, | |
230 const BookmarkNode* node) OVERRIDE; | |
231 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, | |
232 const BookmarkNode* node) OVERRIDE; | |
233 | |
234 // Overridden from content::NotificationObserver: | |
235 virtual void Observe(int type, | |
236 const content::NotificationSource& source, | |
237 const content::NotificationDetails& details) OVERRIDE; | |
238 | |
239 GtkWidget* CreateBookmarkButton(const BookmarkNode* node); | |
240 GtkToolItem* CreateBookmarkToolItem(const BookmarkNode* node); | |
241 | |
242 void ConnectFolderButtonEvents(GtkWidget* widget, bool is_tool_item); | |
243 | |
244 // Finds the BookmarkNode from the model associated with |button|. | |
245 const BookmarkNode* GetNodeForToolButton(GtkWidget* button); | |
246 | |
247 // Creates and displays a popup menu for BookmarkNode |node|. | |
248 void PopupMenuForNode(GtkWidget* sender, const BookmarkNode* node, | |
249 GdkEventButton* event); | |
250 | |
251 // GtkButton callbacks. | |
252 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, gboolean, OnButtonPressed, | |
253 GdkEventButton*); | |
254 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnClicked); | |
255 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnButtonDragBegin, | |
256 GdkDragContext*); | |
257 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnButtonDragEnd, GdkDragContext*); | |
258 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, void, OnButtonDragGet, | |
259 GdkDragContext*, GtkSelectionData*, guint, guint); | |
260 | |
261 // GtkButton callbacks for folder buttons. | |
262 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnFolderClicked); | |
263 | |
264 // GtkButton callback for apps button. | |
265 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnAppsButtonClicked); | |
266 | |
267 // GtkToolbar callbacks. | |
268 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, gboolean, OnToolbarDragMotion, | |
269 GdkDragContext*, gint, gint, guint); | |
270 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnToolbarSizeAllocate, | |
271 GtkAllocation*); | |
272 | |
273 // Used for both folder buttons and the toolbar. | |
274 CHROMEGTK_CALLBACK_6(BookmarkBarGtk, void, OnDragReceived, | |
275 GdkDragContext*, gint, gint, GtkSelectionData*, | |
276 guint, guint); | |
277 CHROMEGTK_CALLBACK_2(BookmarkBarGtk, void, OnDragLeave, | |
278 GdkDragContext*, guint); | |
279 | |
280 // Used for folder buttons. | |
281 CHROMEGTK_CALLBACK_4(BookmarkBarGtk, gboolean, OnFolderDragMotion, | |
282 GdkDragContext*, gint, gint, guint); | |
283 | |
284 // GtkEventBox callbacks. | |
285 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, gboolean, OnEventBoxExpose, | |
286 GdkEventExpose*); | |
287 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnEventBoxDestroy); | |
288 | |
289 // Callbacks on our parent widget. | |
290 CHROMEGTK_CALLBACK_1(BookmarkBarGtk, void, OnParentSizeAllocate, | |
291 GtkAllocation*); | |
292 | |
293 // |throbbing_widget_| callback. | |
294 CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnThrobbingWidgetDestroy); | |
295 | |
296 // Overriden from BookmarkBarInstructionsDelegate: | |
297 virtual void ShowImportDialog() OVERRIDE; | |
298 | |
299 // Updates the visibility of the apps shortcut button |apps_shortcut_visible_| | |
300 // changes. | |
301 void OnAppsPageShortcutVisibilityChanged(); | |
302 | |
303 // Updates the drag&drop state when |edit_bookmarks_enabled_| changes. | |
304 void OnEditBookmarksEnabledChanged(); | |
305 | |
306 // Used for opening urls. | |
307 content::PageNavigator* page_navigator_; | |
308 | |
309 Browser* browser_; | |
310 BrowserWindowGtk* window_; | |
311 | |
312 // Provides us with the offset into the background theme image. | |
313 TabstripOriginProvider* tabstrip_origin_provider_; | |
314 | |
315 // Model providing details as to the starred entries/folders that should be | |
316 // shown. This is owned by the Profile. | |
317 BookmarkModel* model_; | |
318 | |
319 // Contains |bookmark_hbox_|. Event box exists to prevent leakage of | |
320 // background color from the toplevel application window's GDK window. | |
321 ui::OwnedWidgetGtk event_box_; | |
322 | |
323 // Used to detached the bookmark bar when on the NTP. | |
324 GtkWidget* ntp_padding_box_; | |
325 | |
326 // Used to paint the background of the bookmark bar when in detached mode. | |
327 GtkWidget* paint_box_; | |
328 | |
329 // Used to position all children. | |
330 GtkWidget* bookmark_hbox_; | |
331 | |
332 // Alignment widget that is visible if there are no bookmarks on | |
333 // the bookmar bar. | |
334 GtkWidget* instructions_; | |
335 | |
336 // BookmarkBarInstructionsGtk that holds the label and the link for importing | |
337 // bookmarks when there are no bookmarks on the bookmark bar. | |
338 scoped_ptr<BookmarkBarInstructionsGtk> instructions_gtk_; | |
339 | |
340 // The apps page shortcut button. | |
341 GtkWidget* apps_shortcut_button_; | |
342 | |
343 // GtkToolbar which contains all the bookmark buttons. | |
344 ui::OwnedWidgetGtk bookmark_toolbar_; | |
345 | |
346 // The button that shows extra bookmarks that don't fit on the bookmark | |
347 // bar. | |
348 GtkWidget* overflow_button_; | |
349 | |
350 // A separator between the main bookmark bar area and | |
351 // |other_bookmarks_button_|. | |
352 GtkWidget* other_bookmarks_separator_; | |
353 | |
354 // The other bookmarks button. | |
355 GtkWidget* other_bookmarks_button_; | |
356 | |
357 // Padding for the other bookmarks button. | |
358 GtkWidget* other_padding_; | |
359 | |
360 // The BookmarkNode from the model being dragged. NULL when we aren't | |
361 // dragging. | |
362 const BookmarkNode* dragged_node_; | |
363 | |
364 // The visual representation that follows the cursor during drags. | |
365 GtkWidget* drag_icon_; | |
366 | |
367 // We create a GtkToolbarItem from |dragged_node_| ;or display. | |
368 GtkToolItem* toolbar_drop_item_; | |
369 | |
370 // Theme provider for building buttons. | |
371 GtkThemeService* theme_service_; | |
372 | |
373 // Whether we should show the instructional text in the bookmark bar. | |
374 bool show_instructions_; | |
375 | |
376 MenuBarHelper menu_bar_helper_; | |
377 | |
378 // The last displayed right click menu, or NULL if no menus have been | |
379 // displayed yet. | |
380 // The controller. | |
381 scoped_ptr<BookmarkContextMenuController> current_context_menu_controller_; | |
382 // The view. | |
383 scoped_ptr<MenuGtk> current_context_menu_; | |
384 | |
385 // The last displayed left click menu, or NULL if no menus have been | |
386 // displayed yet. | |
387 scoped_ptr<BookmarkMenuController> current_menu_; | |
388 | |
389 gfx::SlideAnimation slide_animation_; | |
390 | |
391 // Used to optimize out |bookmark_toolbar_| size-allocate events we don't | |
392 // need to respond to. | |
393 int last_allocation_width_; | |
394 | |
395 content::NotificationRegistrar registrar_; | |
396 | |
397 // The size of the web contents last time we forced a paint. We keep track | |
398 // of this so we don't force too many paints. | |
399 gfx::Size last_web_contents_size_; | |
400 | |
401 // The last coordinates recorded by OnButtonPress; used to line up the | |
402 // drag icon during bookmark drags. | |
403 gfx::Point last_pressed_coordinates_; | |
404 | |
405 // The currently throbbing widget. This is NULL if no widget is throbbing. | |
406 // We track it because we only want to allow one widget to throb at a time. | |
407 GtkWidget* throbbing_widget_; | |
408 | |
409 // Tracks whether the apps shortcut button should be shown. | |
410 BooleanPrefMember apps_shortcut_visible_; | |
411 | |
412 // Tracks whether bookmarks can be modified. | |
413 BooleanPrefMember edit_bookmarks_enabled_; | |
414 | |
415 BookmarkBar::State bookmark_bar_state_; | |
416 | |
417 // Maximum height of the bookmark bar. | |
418 int max_height_; | |
419 | |
420 base::WeakPtrFactory<BookmarkBarGtk> weak_factory_; | |
421 | |
422 DISALLOW_COPY_AND_ASSIGN(BookmarkBarGtk); | |
423 }; | |
424 | |
425 #endif // CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_BAR_GTK_H_ | |
OLD | NEW |