Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: chrome/browser/gtk/bookmark_bar_gtk.cc

Issue 187001: GTK: Implement the bookmark bar chevron.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: update in more places Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/bookmark_bar_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "chrome/browser/gtk/bookmark_bar_gtk.h" 5 #include "chrome/browser/gtk/bookmark_bar_gtk.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "app/gfx/text_elider.h" 9 #include "app/gfx/text_elider.h"
10 #include "app/gtk_dnd_util.h" 10 #include "app/gtk_dnd_util.h"
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 G_CALLBACK(&OnDragReceived), this); 177 G_CALLBACK(&OnDragReceived), this);
178 178
179 gtk_widget_set_app_paintable(widget(), TRUE); 179 gtk_widget_set_app_paintable(widget(), TRUE);
180 g_signal_connect(G_OBJECT(widget()), "expose-event", 180 g_signal_connect(G_OBJECT(widget()), "expose-event",
181 G_CALLBACK(&OnEventBoxExpose), this); 181 G_CALLBACK(&OnEventBoxExpose), this);
182 182
183 bookmark_toolbar_.Own(gtk_toolbar_new()); 183 bookmark_toolbar_.Own(gtk_toolbar_new());
184 SetToolBarStyle(); 184 SetToolBarStyle();
185 gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar"); 185 gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar");
186 gtk_widget_set_app_paintable(bookmark_toolbar_.get(), TRUE); 186 gtk_widget_set_app_paintable(bookmark_toolbar_.get(), TRUE);
187 g_signal_connect(G_OBJECT(bookmark_toolbar_.get()), "expose-event", 187 g_signal_connect(bookmark_toolbar_.get(), "expose-event",
188 G_CALLBACK(&OnToolbarExpose), this); 188 G_CALLBACK(&OnToolbarExpose), this);
189 g_signal_connect(bookmark_toolbar_.get(), "size-allocate",
190 G_CALLBACK(&OnToolbarSizeAllocate), this);
189 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(), 191 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(),
190 TRUE, TRUE, 0); 192 TRUE, TRUE, 0);
191 193
194 overflow_button_ = theme_provider_->BuildChromeButton();
195 g_object_set_data(G_OBJECT(overflow_button_), "left-align-popup",
196 reinterpret_cast<void*>(true));
197 SetOverflowButtonAppearance();
198 ConnectFolderButtonEvents(overflow_button_);
199 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), overflow_button_,
200 FALSE, FALSE, 0);
201
192 gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP, 202 gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP,
193 NULL, 0, kDragAction); 203 NULL, 0, kDragAction);
194 GtkDndUtil::SetDestTargetList(bookmark_toolbar_.get(), kDestTargetList); 204 GtkDndUtil::SetDestTargetList(bookmark_toolbar_.get(), kDestTargetList);
195 g_signal_connect(bookmark_toolbar_.get(), "drag-motion", 205 g_signal_connect(bookmark_toolbar_.get(), "drag-motion",
196 G_CALLBACK(&OnToolbarDragMotion), this); 206 G_CALLBACK(&OnToolbarDragMotion), this);
197 g_signal_connect(bookmark_toolbar_.get(), "drag-leave", 207 g_signal_connect(bookmark_toolbar_.get(), "drag-leave",
198 G_CALLBACK(&OnToolbarDragLeave), this); 208 G_CALLBACK(&OnToolbarDragLeave), this);
199 g_signal_connect(bookmark_toolbar_.get(), "drag-data-received", 209 g_signal_connect(bookmark_toolbar_.get(), "drag-data-received",
200 G_CALLBACK(&OnDragReceived), this); 210 G_CALLBACK(&OnDragReceived), this);
201 211
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // We only care about nodes on the bookmark bar. 307 // We only care about nodes on the bookmark bar.
298 return; 308 return;
299 } 309 }
300 DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); 310 DCHECK(index >= 0 && index <= GetBookmarkButtonCount());
301 311
302 GtkToolItem* item = CreateBookmarkToolItem(parent->GetChild(index)); 312 GtkToolItem* item = CreateBookmarkToolItem(parent->GetChild(index));
303 gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), 313 gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()),
304 item, index); 314 item, index);
305 315
306 SetInstructionState(); 316 SetInstructionState();
317 SetChevronState();
307 } 318 }
308 319
309 void BookmarkBarGtk::BookmarkNodeRemoved(BookmarkModel* model, 320 void BookmarkBarGtk::BookmarkNodeRemoved(BookmarkModel* model,
310 const BookmarkNode* parent, 321 const BookmarkNode* parent,
311 int old_index, 322 int old_index,
312 const BookmarkNode* node) { 323 const BookmarkNode* node) {
313 if (parent != model_->GetBookmarkBarNode()) { 324 if (parent != model_->GetBookmarkBarNode()) {
314 // We only care about nodes on the bookmark bar. 325 // We only care about nodes on the bookmark bar.
315 return; 326 return;
316 } 327 }
317 DCHECK(old_index >= 0 && old_index < GetBookmarkButtonCount()); 328 DCHECK(old_index >= 0 && old_index < GetBookmarkButtonCount());
318 329
319 GtkWidget* to_remove = GTK_WIDGET(gtk_toolbar_get_nth_item( 330 GtkWidget* to_remove = GTK_WIDGET(gtk_toolbar_get_nth_item(
320 GTK_TOOLBAR(bookmark_toolbar_.get()), old_index)); 331 GTK_TOOLBAR(bookmark_toolbar_.get()), old_index));
321 gtk_container_remove(GTK_CONTAINER(bookmark_toolbar_.get()), 332 gtk_container_remove(GTK_CONTAINER(bookmark_toolbar_.get()),
322 to_remove); 333 to_remove);
323 334
324 SetInstructionState(); 335 SetInstructionState();
336 SetChevronState();
325 } 337 }
326 338
327 void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model, 339 void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model,
328 const BookmarkNode* node) { 340 const BookmarkNode* node) {
329 if (node->GetParent() != model_->GetBookmarkBarNode()) { 341 if (node->GetParent() != model_->GetBookmarkBarNode()) {
330 // We only care about nodes on the bookmark bar. 342 // We only care about nodes on the bookmark bar.
331 return; 343 return;
332 } 344 }
333 int index = model_->GetBookmarkBarNode()->IndexOfChild(node); 345 int index = model_->GetBookmarkBarNode()->IndexOfChild(node);
334 DCHECK(index != -1); 346 DCHECK(index != -1);
335 347
336 GtkToolItem* item = gtk_toolbar_get_nth_item( 348 GtkToolItem* item = gtk_toolbar_get_nth_item(
337 GTK_TOOLBAR(bookmark_toolbar_.get()), index); 349 GTK_TOOLBAR(bookmark_toolbar_.get()), index);
338 GtkWidget* button = gtk_bin_get_child(GTK_BIN(item)); 350 GtkWidget* button = gtk_bin_get_child(GTK_BIN(item));
339 bookmark_utils::ConfigureButtonForNode(node, model, button, theme_provider_); 351 bookmark_utils::ConfigureButtonForNode(node, model, button, theme_provider_);
352 SetChevronState();
340 } 353 }
341 354
342 void BookmarkBarGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model, 355 void BookmarkBarGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model,
343 const BookmarkNode* node) { 356 const BookmarkNode* node) {
344 BookmarkNodeChanged(model, node); 357 BookmarkNodeChanged(model, node);
345 } 358 }
346 359
347 void BookmarkBarGtk::BookmarkNodeChildrenReordered(BookmarkModel* model, 360 void BookmarkBarGtk::BookmarkNodeChildrenReordered(BookmarkModel* model,
348 const BookmarkNode* node) { 361 const BookmarkNode* node) {
349 if (node != model_->GetBookmarkBarNode()) 362 if (node != model_->GetBookmarkBarNode())
(...skipping 11 matching lines...) Expand all
361 // Create a button for each of the children on the bookmark bar. 374 // Create a button for each of the children on the bookmark bar.
362 for (int i = 0; i < node->GetChildCount(); ++i) { 375 for (int i = 0; i < node->GetChildCount(); ++i) {
363 GtkToolItem* item = CreateBookmarkToolItem(node->GetChild(i)); 376 GtkToolItem* item = CreateBookmarkToolItem(node->GetChild(i));
364 gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), item, -1); 377 gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), item, -1);
365 } 378 }
366 379
367 bookmark_utils::ConfigureButtonForNode(model_->other_node(), 380 bookmark_utils::ConfigureButtonForNode(model_->other_node(),
368 model_, other_bookmarks_button_, theme_provider_); 381 model_, other_bookmarks_button_, theme_provider_);
369 382
370 SetInstructionState(); 383 SetInstructionState();
384 SetChevronState();
371 } 385 }
372 386
373 void BookmarkBarGtk::SetInstructionState() { 387 void BookmarkBarGtk::SetInstructionState() {
374 show_instructions_ = (model_->GetBookmarkBarNode()->GetChildCount() == 0); 388 show_instructions_ = (model_->GetBookmarkBarNode()->GetChildCount() == 0);
375 if (show_instructions_) { 389 if (show_instructions_) {
376 gtk_widget_show_all(instructions_); 390 gtk_widget_show_all(instructions_);
377 } else { 391 } else {
378 gtk_widget_hide(instructions_); 392 gtk_widget_hide(instructions_);
379 } 393 }
380 } 394 }
381 395
396 void BookmarkBarGtk::SetChevronState() {
397 int extra_space = 0;
398
399 if (GTK_WIDGET_VISIBLE(overflow_button_))
400 extra_space = overflow_button_->allocation.width;
401
402 int overflow_idx = GetFirstHiddenBookmark(extra_space);
403 if (overflow_idx == -1)
404 gtk_widget_hide(overflow_button_);
405 else
406 gtk_widget_show_all(overflow_button_);
407 }
408
382 void BookmarkBarGtk::RemoveAllBookmarkButtons() { 409 void BookmarkBarGtk::RemoveAllBookmarkButtons() {
383 gtk_util::RemoveAllChildren(bookmark_toolbar_.get()); 410 gtk_util::RemoveAllChildren(bookmark_toolbar_.get());
384 } 411 }
385 412
386 int BookmarkBarGtk::GetBookmarkButtonCount() { 413 int BookmarkBarGtk::GetBookmarkButtonCount() {
387 GList* children = gtk_container_get_children( 414 GList* children = gtk_container_get_children(
388 GTK_CONTAINER(bookmark_toolbar_.get())); 415 GTK_CONTAINER(bookmark_toolbar_.get()));
389 int count = g_list_length(children); 416 int count = g_list_length(children);
390 g_list_free(children); 417 g_list_free(children);
391 return count; 418 return count;
392 } 419 }
393 420
421 void BookmarkBarGtk::SetOverflowButtonAppearance() {
422 GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(overflow_button_));
423 if (former_child)
424 gtk_widget_destroy(former_child);
425
426 GtkWidget* new_child = theme_provider_->UseGtkTheme() ?
427 gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE) :
Elliot Glaysher 2009/09/02 01:19:39 This arrow, by default, is pretty big, no? You may
428 gtk_image_new_from_pixbuf(ResourceBundle::GetSharedInstance().
429 GetRTLEnabledPixbufNamed(IDR_BOOKMARK_BAR_CHEVRONS));
430
431 gtk_container_add(GTK_CONTAINER(overflow_button_), new_child);
432 SetChevronState();
433 }
434
435 int BookmarkBarGtk::GetFirstHiddenBookmark(int extra_space) {
436 int rv = 0;
437 bool overflow = false;
438 GList* toolbar_items =
439 gtk_container_get_children(GTK_CONTAINER(bookmark_toolbar_.get()));
440 for (GList* iter = toolbar_items; iter; iter = g_list_next(iter)) {
441 GtkWidget* tool_item = reinterpret_cast<GtkWidget*>(iter->data);
442 if (tool_item->allocation.x + tool_item->allocation.width >
443 bookmark_toolbar_.get()->allocation.width + extra_space) {
444 overflow = true;
445 break;
446 }
447 rv++;
448 }
449
450 g_list_free(toolbar_items);
451
452 if (!overflow)
453 return -1;
454
455 return rv;
456 }
457
394 bool BookmarkBarGtk::IsAlwaysShown() { 458 bool BookmarkBarGtk::IsAlwaysShown() {
395 return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); 459 return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
396 } 460 }
397 461
398 void BookmarkBarGtk::AnimationProgressed(const Animation* animation) { 462 void BookmarkBarGtk::AnimationProgressed(const Animation* animation) {
399 DCHECK_EQ(animation, slide_animation_.get()); 463 DCHECK_EQ(animation, slide_animation_.get());
400 464
401 gint height = animation->GetCurrentValue() * 465 gint height = animation->GetCurrentValue() *
402 (kBookmarkBarHeight - kBookmarkBarMinimumHeight) + 466 (kBookmarkBarHeight - kBookmarkBarMinimumHeight) +
403 kBookmarkBarMinimumHeight; 467 kBookmarkBarMinimumHeight;
(...skipping 19 matching lines...) Expand all
423 } else { 487 } else {
424 DLOG(ERROR) << "Received a theme change notification while we " 488 DLOG(ERROR) << "Received a theme change notification while we "
425 << "don't have a BookmarkModel. Taking no action."; 489 << "don't have a BookmarkModel. Taking no action.";
426 } 490 }
427 491
428 // When using the GTK+ theme, we need to have the event box be visible so 492 // When using the GTK+ theme, we need to have the event box be visible so
429 // buttons don't get a halo color from the background. When using Chromium 493 // buttons don't get a halo color from the background. When using Chromium
430 // themes, we want to let the background show through the toolbar. 494 // themes, we want to let the background show through the toolbar.
431 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), 495 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()),
432 theme_provider_->UseGtkTheme()); 496 theme_provider_->UseGtkTheme());
497
498 SetOverflowButtonAppearance();
433 } 499 }
434 } 500 }
435 501
436 GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) { 502 GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) {
437 GtkWidget* button = theme_provider_->BuildChromeButton(); 503 GtkWidget* button = theme_provider_->BuildChromeButton();
438 bookmark_utils::ConfigureButtonForNode(node, model_, button, theme_provider_); 504 bookmark_utils::ConfigureButtonForNode(node, model_, button, theme_provider_);
439 505
440 // The tool item is also a source for dragging 506 // The tool item is also a source for dragging
441 gtk_drag_source_set(button, GDK_BUTTON1_MASK, 507 gtk_drag_source_set(button, GDK_BUTTON1_MASK,
442 NULL, 0, GDK_ACTION_MOVE); 508 NULL, 0, GDK_ACTION_MOVE);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 g_signal_connect(G_OBJECT(widget), "clicked", 563 g_signal_connect(G_OBJECT(widget), "clicked",
498 G_CALLBACK(OnFolderClicked), this); 564 G_CALLBACK(OnFolderClicked), this);
499 565
500 ViewIDUtil::SetID(widget, VIEW_ID_BOOKMARK_MENU); 566 ViewIDUtil::SetID(widget, VIEW_ID_BOOKMARK_MENU);
501 } 567 }
502 568
503 const BookmarkNode* BookmarkBarGtk::GetNodeForToolButton(GtkWidget* widget) { 569 const BookmarkNode* BookmarkBarGtk::GetNodeForToolButton(GtkWidget* widget) {
504 // First check to see if |button| is special cased. 570 // First check to see if |button| is special cased.
505 if (widget == other_bookmarks_button_) 571 if (widget == other_bookmarks_button_)
506 return model_->other_node(); 572 return model_->other_node();
507 else if (widget == event_box_.get()) 573 else if (widget == event_box_.get() || widget == overflow_button_)
508 return model_->GetBookmarkBarNode(); 574 return model_->GetBookmarkBarNode();
509 575
510 // Search the contents of |bookmark_toolbar_| for the corresponding widget 576 // Search the contents of |bookmark_toolbar_| for the corresponding widget
511 // and find its index. 577 // and find its index.
512 GtkWidget* item_to_find = gtk_widget_get_parent(widget); 578 GtkWidget* item_to_find = gtk_widget_get_parent(widget);
513 int index_to_use = -1; 579 int index_to_use = -1;
514 int index = 0; 580 int index = 0;
515 GList* children = gtk_container_get_children( 581 GList* children = gtk_container_get_children(
516 GTK_CONTAINER(bookmark_toolbar_.get())); 582 GTK_CONTAINER(bookmark_toolbar_.get()));
517 for (GList* item = children; item; item = item->next, index++) { 583 for (GList* item = children; item; item = item->next, index++) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 bar->profile_); 710 bar->profile_);
645 } 711 }
646 712
647 // static 713 // static
648 void BookmarkBarGtk::OnFolderClicked(GtkWidget* sender, 714 void BookmarkBarGtk::OnFolderClicked(GtkWidget* sender,
649 BookmarkBarGtk* bar) { 715 BookmarkBarGtk* bar) {
650 const BookmarkNode* node = bar->GetNodeForToolButton(sender); 716 const BookmarkNode* node = bar->GetNodeForToolButton(sender);
651 DCHECK(node); 717 DCHECK(node);
652 DCHECK(bar->page_navigator_); 718 DCHECK(bar->page_navigator_);
653 719
720 int start_child_idx = 0;
721 if (sender == bar->overflow_button_)
722 start_child_idx = bar->GetFirstHiddenBookmark(0);
723
654 bar->current_menu_.reset( 724 bar->current_menu_.reset(
655 new BookmarkMenuController(bar->browser_, bar->profile_, 725 new BookmarkMenuController(bar->browser_, bar->profile_,
656 bar->page_navigator_, 726 bar->page_navigator_,
657 GTK_WINDOW(gtk_widget_get_toplevel(sender)), 727 GTK_WINDOW(gtk_widget_get_toplevel(sender)),
658 node, 728 node,
659 0, 729 start_child_idx,
660 false)); 730 false));
661 GdkEventButton* event = 731 GdkEventButton* event =
662 reinterpret_cast<GdkEventButton*>(gtk_get_current_event()); 732 reinterpret_cast<GdkEventButton*>(gtk_get_current_event());
663 bar->current_menu_->Popup(sender, event->button, event->time); 733 bar->current_menu_->Popup(sender, event->button, event->time);
664 } 734 }
665 735
666 // static 736 // static
667 gboolean BookmarkBarGtk::OnToolbarExpose(GtkWidget* widget, 737 gboolean BookmarkBarGtk::OnToolbarExpose(GtkWidget* widget,
668 GdkEventExpose* event, 738 GdkEventExpose* event,
669 BookmarkBarGtk* bar) { 739 BookmarkBarGtk* bar) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 BookmarkBarGtk* bar) { 803 BookmarkBarGtk* bar) {
734 if (bar->toolbar_drop_item_) { 804 if (bar->toolbar_drop_item_) {
735 g_object_unref(bar->toolbar_drop_item_); 805 g_object_unref(bar->toolbar_drop_item_);
736 bar->toolbar_drop_item_ = NULL; 806 bar->toolbar_drop_item_ = NULL;
737 } 807 }
738 808
739 gtk_toolbar_set_drop_highlight_item(toolbar, NULL, 0); 809 gtk_toolbar_set_drop_highlight_item(toolbar, NULL, 0);
740 } 810 }
741 811
742 // static 812 // static
813 void BookmarkBarGtk::OnToolbarSizeAllocate(GtkWidget* widget,
814 GtkAllocation* allocation,
815 BookmarkBarGtk* bar) {
816 bar->SetChevronState();
817 }
818
819 // static
743 void BookmarkBarGtk::OnDragReceived(GtkWidget* widget, 820 void BookmarkBarGtk::OnDragReceived(GtkWidget* widget,
744 GdkDragContext* context, 821 GdkDragContext* context,
745 gint x, gint y, 822 gint x, gint y,
746 GtkSelectionData* selection_data, 823 GtkSelectionData* selection_data,
747 guint target_type, guint time, 824 guint target_type, guint time,
748 BookmarkBarGtk* bar) { 825 BookmarkBarGtk* bar) {
749 gboolean dnd_success = FALSE; 826 gboolean dnd_success = FALSE;
750 gboolean delete_selection_data = FALSE; 827 gboolean delete_selection_data = FALSE;
751 828
752 const BookmarkNode* dest_node; 829 const BookmarkNode* dest_node;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 cairo_set_line_width(cr, 1.0); 957 cairo_set_line_width(cr, 1.0);
881 cairo_move_to(cr, start_x, widget->allocation.y); 958 cairo_move_to(cr, start_x, widget->allocation.y);
882 cairo_line_to(cr, start_x, 959 cairo_line_to(cr, start_x,
883 widget->allocation.y + widget->allocation.height); 960 widget->allocation.y + widget->allocation.height);
884 cairo_stroke(cr); 961 cairo_stroke(cr);
885 cairo_destroy(cr); 962 cairo_destroy(cr);
886 cairo_pattern_destroy(pattern); 963 cairo_pattern_destroy(pattern);
887 964
888 return TRUE; 965 return TRUE;
889 } 966 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/bookmark_bar_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698