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