15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_node_data.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_utils.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/browser_window_gtk.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/custom_button.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/event_utils.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_chrome_button.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_theme_service.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_util.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/hover_controller_gtk.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/menu_gtk.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/rounded_window.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/tabstrip_origin_provider.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/view_id_util.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/ntp_background_util.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/url_constants.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_drop_types.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/gtk_dnd_util.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_compat.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas_skia_paint.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/cairo_cached_surface.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::PageNavigator; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The showing height of the bar. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBookmarkBarHeight = 29; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding for when the bookmark bar is detached. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTopBottomNTPPadding = 12; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLeftRightNTPPadding = 8; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding around the bar's content area when the bookmark bar is detached. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNTPPadding = 2; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of pixels of rounding on the corners of the bookmark bar content 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// area when in detached mode. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNTPRoundedness = 3; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The height of the bar when it is "hidden". It is usually not completely 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hidden because even when it is closed it forms the bottom few pixels of 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the toolbar. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBookmarkBarMinimumHeight = 3; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Left-padding for the instructional text. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInstructionsPadding = 6; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding around the "Other Bookmarks" button. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kOtherBookmarksPaddingHorizontal = 2; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kOtherBookmarksPaddingVertical = 1; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The targets accepted by the toolbar and folder buttons for DnD. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDestTargetList[] = { ui::CHROME_BOOKMARK_ITEM, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::CHROME_NAMED_URL, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TEXT_URI_LIST, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::NETSCAPE_URL, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TEXT_PLAIN, -1 }; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Acceptable drag actions for the bookmark bar drag destinations. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GdkDragAction kDragAction = 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetToolBarStyle() { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool style_was_set = false; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style_was_set) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style_was_set = true; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_rc_parse_string( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "style \"chrome-bookmark-toolbar\" {" 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " xthickness = 0\n" 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ythickness = 0\n" 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GtkWidget::focus-padding = 0\n" 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GtkContainer::border-width = 0\n" 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GtkToolbar::internal-padding = 1\n" 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GtkToolbar::shadow-type = GTK_SHADOW_NONE\n" 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "widget \"*chrome-bookmark-toolbar\" style \"chrome-bookmark-toolbar\""); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RecordAppLaunch(Profile* profile, const GURL& url) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile->GetExtensionService()); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension* extension = 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile->GetExtensionService()->GetInstalledApp(url); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 136558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CoreAppLauncherHandler::RecordAppLaunchType( 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::APP_LAUNCH_BOOKMARK_BAR, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarGtk::BookmarkBarGtk(BrowserWindowGtk* window, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabstripOriginProvider* tabstrip_origin_provider) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : page_navigator_(NULL), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_(window), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabstrip_origin_provider_(tabstrip_origin_provider), 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_(NULL), 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_(NULL), 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dragged_node_(NULL), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_icon_(NULL), 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_drop_item_(NULL), 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_service_(GtkThemeService::GetFrom(browser->profile())), 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_instructions_(true), 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_(this), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slide_animation_(this), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_allocation_width_(-1), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_widget_(NULL), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_(this), 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_(BookmarkBar::DETACHED), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_height_(0) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force an update by simulating being in the wrong state. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BrowserWindowGtk sets our true state after we're created. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetBookmarkBarState(BookmarkBar::SHOW, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::DONT_ANIMATE_STATE_CHANGE); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<ThemeService>(theme_service_)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch apps_shortcut_visible_.Init( 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch prefs::kShowAppsShortcutInBookmarkBar, 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_->profile()->GetPrefs(), 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&BookmarkBarGtk::OnAppsPageShortcutVisibilityChanged, 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this))); 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnAppsPageShortcutVisibilityChanged(); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) edit_bookmarks_enabled_.Init( 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs::kEditBookmarksEnabled, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->profile()->GetPrefs(), 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&BookmarkBarGtk::OnEditBookmarksEnabledChanged, 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnEditBookmarksEnabledChanged(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarGtk::~BookmarkBarGtk() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllButtons(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_toolbar_.Destroy(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_box_.Destroy(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetPageNavigator(PageNavigator* navigator) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_ = navigator; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::Init() { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_box_.Own(gtk_event_box_new()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(event_box_.get(), "destroy", 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnEventBoxDestroyThunk), this); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(event_box_.get(), "button-press-event", 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnButtonPressedThunk), this); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ntp_padding_box_ = gtk_alignment_new(0, 0, 1, 1); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(event_box_.get()), ntp_padding_box_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) paint_box_ = gtk_event_box_new(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(ntp_padding_box_), paint_box_); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkColor paint_box_color = 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_service_->GetGdkColor(ThemeProperties::COLOR_TOOLBAR); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_modify_bg(paint_box_, GTK_STATE_NORMAL, &paint_box_color); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_add_events(paint_box_, GDK_POINTER_MOTION_MASK | 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GDK_BUTTON_PRESS_MASK); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_hbox_ = gtk_hbox_new(FALSE, 0); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(paint_box_), bookmark_hbox_); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch apps_shortcut_button_ = theme_service_->BuildChromeButton(); 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bookmark_utils::ConfigureAppsShortcutButton(apps_shortcut_button_, 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch theme_service_); 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch g_signal_connect(apps_shortcut_button_, "clicked", 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch G_CALLBACK(OnAppsButtonClickedThunk), this); 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Accept middle mouse clicking. 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gtk_util::SetButtonClickableByMouseButtons( 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch apps_shortcut_button_, true, true, false); 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gtk_box_pack_start(GTK_BOX(bookmark_hbox_), apps_shortcut_button_, 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FALSE, FALSE, 0); 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_ = gtk_alignment_new(0, 0, 1, 1); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_alignment_set_padding(GTK_ALIGNMENT(instructions_), 0, 0, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInstructionsPadding, 0); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser_->profile(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_gtk_.reset(new BookmarkBarInstructionsGtk(this, profile)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(instructions_), instructions_gtk_->widget()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_box_pack_start(GTK_BOX(bookmark_hbox_), instructions_, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRUE, TRUE, 0); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_set(instructions_, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkDestDefaults(GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_MOTION), 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, kDragAction); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetDestTargetList(instructions_, kDestTargetList); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(instructions_, "drag-data-received", 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnDragReceivedThunk), this); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(event_box_.get(), "expose-event", 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnEventBoxExposeThunk), this); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateEventBoxPaintability(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_toolbar_.Own(gtk_toolbar_new()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetToolBarStyle(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar"); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::SuppressDefaultPainting(bookmark_toolbar_.get()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(bookmark_toolbar_.get(), "size-allocate", 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnToolbarSizeAllocateThunk), this); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(), 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRUE, TRUE, 0); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_ = theme_service_->BuildChromeButton(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_set_data(G_OBJECT(overflow_button_), "left-align-popup", 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<void*>(true)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetOverflowButtonAppearance(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectFolderButtonEvents(overflow_button_, false); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_box_pack_start(GTK_BOX(bookmark_hbox_), overflow_button_, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, FALSE, 0); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, kDragAction); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetDestTargetList(bookmark_toolbar_.get(), kDestTargetList); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(bookmark_toolbar_.get(), "drag-motion", 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnToolbarDragMotionThunk), this); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(bookmark_toolbar_.get(), "drag-leave", 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnDragLeaveThunk), this); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(bookmark_toolbar_.get(), "drag-data-received", 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnDragReceivedThunk), this); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarks_separator_ = theme_service_->CreateToolbarSeparator(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_box_pack_start(GTK_BOX(bookmark_hbox_), other_bookmarks_separator_, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, FALSE, 0); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We pack the button manually (rather than using gtk_button_set_*) so that 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can have finer control over its label. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarks_button_ = theme_service_->BuildChromeButton(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(other_bookmarks_button_); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectFolderButtonEvents(other_bookmarks_button_, false); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_padding_ = gtk_alignment_new(0, 0, 1, 1); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_alignment_set_padding(GTK_ALIGNMENT(other_padding_), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kOtherBookmarksPaddingVertical, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kOtherBookmarksPaddingVertical, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kOtherBookmarksPaddingHorizontal, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kOtherBookmarksPaddingHorizontal); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(other_padding_), other_bookmarks_button_); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_box_pack_start(GTK_BOX(bookmark_hbox_), other_padding_, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, FALSE, 0); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_no_show_all(other_padding_, TRUE); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_size_request(event_box_.get(), -1, kBookmarkBarMinimumHeight); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewIDUtil::SetID(other_bookmarks_button_, VIEW_ID_OTHER_BOOKMARKS); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewIDUtil::SetID(widget(), VIEW_ID_BOOKMARK_BAR); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(widget()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(widget()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddCoreButtons(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erg): Handle extensions 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_ = BookmarkModelFactory::GetForProfile(profile); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (model_->loaded()) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Loaded(model_, false); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // else case: we'll receive notification back from the BookmarkModel when done 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loading, then we'll populate the bar. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetBookmarkBarState( 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::State state, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::AnimateChangeType animate_type) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("ui::gtk", "BookmarkBarGtk::SetBookmarkBarState"); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE && 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state == BookmarkBar::DETACHED || 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ == BookmarkBar::DETACHED)) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): animate the transition between detached and non or remove 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detached entirely. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animate_type = BookmarkBar::DONT_ANIMATE_STATE_CHANGE; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::State old_state = bookmark_bar_state_; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ = state; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == BookmarkBar::SHOW || state == BookmarkBar::DETACHED) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Show(old_state, animate_type); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Hide(old_state, animate_type); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarGtk::GetHeight() { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation allocation; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_get_allocation(event_box_.get(), &allocation); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return allocation.height - kBookmarkBarMinimumHeight; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarGtk::IsAnimating() { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return slide_animation_.is_animating(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::CalculateMaxHeight() { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (theme_service_->UsingNativeTheme()) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the requisition of our single child instead of the event box itself 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because the event box probably already has a size request. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkRequisition req; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_size_request(ntp_padding_box_, &req); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_height_ = req.height; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_height_ = (bookmark_bar_state_ == BookmarkBar::DETACHED) ? 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kNTPBookmarkBarHeight : kBookmarkBarHeight; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::AnimationProgressed(const ui::Animation* animation) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(animation, &slide_animation_); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint height = 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<gint>(animation->GetCurrentValue() * 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (max_height_ - kBookmarkBarMinimumHeight)) + 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBookmarkBarMinimumHeight; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_size_request(event_box_.get(), -1, height); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::AnimationEnded(const ui::Animation* animation) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(animation, &slide_animation_); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slide_animation_.IsShowing()) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(bookmark_hbox_); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can be windowless during unit tests. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because of our constant resizing and our toolbar/bookmark bar overlap 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shenanigans, gtk+ gets confused, partially draws parts of the bookmark 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bar into the toolbar and than doesn't queue a redraw to fix it. So do 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it manually by telling the toolbar area to redraw itself. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_->QueueToolbarRedraw(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MenuBarHelper::Delegate implementation -------------------------------------- 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::PopupForButton(GtkWidget* button) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(button); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_navigator_); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int first_hidden = GetFirstHiddenBookmark(0, NULL); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_hidden == -1) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No overflow exists: don't show anything for the overflow button. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button == overflow_button_) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overflow exists: don't show anything for an overflowed folder button. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button != overflow_button_ && button != other_bookmarks_button_ && 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node->parent()->GetIndexOf(node) >= first_hidden) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_menu_.reset( 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BookmarkMenuController(browser_, page_navigator_, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_WINDOW(gtk_widget_get_toplevel(button)), 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button == overflow_button_ ? first_hidden : 0)); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.MenuStartedShowing(button, current_menu_->widget()); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEvent* event = gtk_get_current_event(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_menu_->Popup(button, event->button.button, event->button.time); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_event_free(event); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::PopupForButtonNextTo(GtkWidget* button, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkMenuDirectionType dir) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* relative_node = GetNodeForToolButton(button); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(relative_node); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find out the order of the buttons. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GtkWidget*> folder_list; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int first_hidden = GetFirstHiddenBookmark(0, &folder_list); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_hidden != -1) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) folder_list.push_back(overflow_button_); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) folder_list.push_back(other_bookmarks_button_); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the position of |button|. 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_idx = -1; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < folder_list.size(); ++i) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (folder_list[i] == button) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_idx = i; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(button_idx, -1); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the GtkWidget* for the actual target button. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shift = dir == GTK_MENU_DIR_PARENT ? -1 : 1; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_idx = (button_idx + shift + folder_list.size()) % folder_list.size(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupForButton(folder_list[button_idx]); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::CloseMenu() { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_context_menu_->Cancel(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::Show(BookmarkBar::State old_state, 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::AnimateChangeType animate_type) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(widget()); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDetachedState(old_state); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateMaxHeight(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slide_animation_.Show(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slide_animation_.Reset(1); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimationProgressed(&slide_animation_); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (model_ && model_->loaded()) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide out behind the findbar. This is rather fragile code, it could 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // probably be improved. 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (theme_service_->UsingNativeTheme()) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* parent = gtk_widget_get_parent(event_box_.get()); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gtk_widget_get_realized(parent)) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_window_lower(gtk_widget_get_window(parent)); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gtk_widget_get_realized(event_box_.get())) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_window_lower(gtk_widget_get_window(event_box_.get())); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { // Chromium theme mode. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gtk_widget_get_realized(paint_box_)) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_window_lower(gtk_widget_get_window(paint_box_)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event box won't stay below its children's GdkWindows unless we 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toggle the above-child property here. If the event box doesn't stay 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // below its children then events will be routed to it rather than the 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // children. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box_.get()), TRUE); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box_.get()), FALSE); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maybe show the instructions 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(bookmark_toolbar_.get(), !show_instructions_); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(instructions_, show_instructions_); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::Hide(BookmarkBar::State old_state, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::AnimateChangeType animate_type) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDetachedState(old_state); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After coming out of fullscreen, the browser window sets the bookmark bar 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the "hidden" state, which means we need to show our minimum height. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window_->IsFullscreen()) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show(widget()); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateMaxHeight(); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sometimes we get called without a matching call to open. If that happens 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then force hide. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slide_animation_.IsShowing() && 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animate_type == BookmarkBar::ANIMATE_STATE_CHANGE) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slide_animation_.Hide(); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(bookmark_hbox_); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slide_animation_.Reset(0); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimationProgressed(&slide_animation_); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetInstructionState() { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_instructions_ = model_->bookmark_bar_node()->empty(); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(bookmark_toolbar_.get(), !show_instructions_); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(instructions_, show_instructions_); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetChevronState() { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!gtk_widget_get_visible(bookmark_hbox_)) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show_instructions_) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(overflow_button_); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_space = 0; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gtk_widget_get_visible(overflow_button_)) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation allocation; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_get_allocation(overflow_button_, &allocation); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_space = allocation.width; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int overflow_idx = GetFirstHiddenBookmark(extra_space, NULL); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_idx == -1) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(overflow_button_); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(overflow_button_); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::UpdateOtherBookmarksVisibility() { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_other_children = !model_->other_node()->empty(); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(other_padding_, has_other_children); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_visible(other_bookmarks_separator_, has_other_children); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::RemoveAllButtons() { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::RemoveAllChildren(bookmark_toolbar_.get()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Clear(); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::AddCoreButtons() { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Add(other_bookmarks_button_); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Add(overflow_button_); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::ResetButtons() { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllButtons(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddCoreButtons(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bar = model_->bookmark_bar_node(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bar && model_->other_node()); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a button for each of the children on the bookmark bar. 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bar->child_count(); ++i) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = bar->GetChild(i); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkToolItem* item = CreateBookmarkToolItem(node); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), item, -1); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_folder()) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Add(gtk_bin_get_child(GTK_BIN(item))); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_utils::ConfigureButtonForNode(model_->other_node(), 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_, other_bookmarks_button_, theme_service_); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInstructionState(); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarGtk::GetBookmarkButtonCount() { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GList* children = gtk_container_get_children( 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_CONTAINER(bookmark_toolbar_.get())); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = g_list_length(children); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_list_free(children); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bookmark_utils::BookmarkLaunchLocation 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkBarGtk::GetBookmarkLaunchLocation() const { 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bookmark_bar_state_ == BookmarkBar::DETACHED ? 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::LAUNCH_DETACHED_BAR : 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::LAUNCH_ATTACHED_BAR; 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetOverflowButtonAppearance() { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(overflow_button_)); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (former_child) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_destroy(former_child); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* new_child; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (theme_service_->UsingNativeTheme()) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_child = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Image& image = ui::ResourceBundle::GetSharedInstance(). 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNativeImageNamed(IDR_BOOKMARK_BAR_CHEVRONS, 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle::RTL_ENABLED); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_child = gtk_image_new_from_pixbuf(image.ToGdkPixbuf()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(overflow_button_), new_child); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarGtk::GetFirstHiddenBookmark(int extra_space, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GtkWidget*>* showing_folders) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = 0; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're going to keep track of how much width we've used as we move along 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the bookmark bar. If we ever surpass the width of the bookmark bar, we'll 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know that's the first hidden bookmark. 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width_used = 0; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GTK appears to require one pixel of padding to the side of the first and 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // last buttons on the bar. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gideonwald): figure out the precise source of these extra two pixels 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and make this calculation more reliable. 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation allocation; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_get_allocation(bookmark_toolbar_.get(), &allocation); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_width = allocation.width - 2; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool overflow = false; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkRequisition requested_size_; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GList* toolbar_items = 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_get_children(GTK_CONTAINER(bookmark_toolbar_.get())); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (GList* iter = toolbar_items; iter; iter = g_list_next(iter)) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* tool_item = reinterpret_cast<GtkWidget*>(iter->data); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_size_request(tool_item, &requested_size_); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width_used += requested_size_.width; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extra_space| is available if we can remove the chevron, which happens 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only if there are no more potential overflow bookmarks after this one. 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow = width_used > total_width + (g_list_next(iter) ? 0 : extra_space); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (showing_folders && 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->bookmark_bar_node()->GetChild(rv)->is_folder()) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) showing_folders->push_back(gtk_bin_get_child(GTK_BIN(tool_item))); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv++; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_list_free(toolbar_items); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!overflow) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::UpdateDetachedState(BookmarkBar::State old_state) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool old_detached = old_state == BookmarkBar::DETACHED; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool detached = bookmark_bar_state_ == BookmarkBar::DETACHED; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (detached == old_detached) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (detached) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), TRUE); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkColor stroke_color = theme_service_->UsingNativeTheme() ? 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_service_->GetBorderColor() : 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_service_->GetGdkColor(ThemeProperties::COLOR_NTP_HEADER); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::ActAsRoundedWindow(paint_box_, stroke_color, kNTPRoundedness, 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::ROUNDED_ALL, gtk_util::BORDER_ALL); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_alignment_set_padding(GTK_ALIGNMENT(ntp_padding_box_), 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTopBottomNTPPadding, kTopBottomNTPPadding, 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLeftRightNTPPadding, kLeftRightNTPPadding); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), kNTPPadding); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::StopActingAsRoundedWindow(paint_box_); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), FALSE); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_alignment_set_padding(GTK_ALIGNMENT(ntp_padding_box_), 0, 0, 0, 0); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), 0); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateEventBoxPaintability(); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |window_| can be NULL during testing. 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Listen for parent size allocations. Only connect once. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_ && detached) { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* parent = gtk_widget_get_parent(widget()); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent && 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_handler_find(parent, G_SIGNAL_MATCH_FUNC, 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 0, NULL, reinterpret_cast<gpointer>(OnParentSizeAllocateThunk), 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL) == 0) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(parent, "size-allocate", 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnParentSizeAllocateThunk), this); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::UpdateEventBoxPaintability() { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_app_paintable( 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_box_.get(), 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!theme_service_->UsingNativeTheme() || 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ == BookmarkBar::DETACHED)); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When using the GTK+ theme, we need to have the event box be visible so 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buttons don't get a halo color from the background. When using Chromium 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // themes, we want to let the background show through the toolbar. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_service_->UsingNativeTheme()); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::PaintEventBox() { 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size web_contents_size; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetWebContentsSize(&web_contents_size) && 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents_size != last_web_contents_size_) { 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_web_contents_size_ = web_contents_size; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_queue_draw(event_box_.get()); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BookmarkBarGtk::GetWebContentsSize(gfx::Size* size) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = browser_; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!web_contents) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is possible to have a browser but no WebContents while under testing, 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so don't NOTREACHED() and error the program. 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!web_contents->GetView()) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = web_contents->GetView()->GetContainerSize(); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::StartThrobbingAfterAllocation(GtkWidget* item) { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect_after( 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item, "size-allocate", G_CALLBACK(OnItemAllocateThunk), this); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnItemAllocate(GtkWidget* item, 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation* allocation) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only want to fire on the item's first allocation. 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_handlers_disconnect_by_func( 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item, reinterpret_cast<gpointer>(&OnItemAllocateThunk), this); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* button = gtk_bin_get_child(GTK_BIN(item)); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(button); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(node); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::StartThrobbing(const BookmarkNode* node) { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent_on_bb = NULL; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const BookmarkNode* parent = node; parent; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = parent->parent()) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent->parent() == model_->bookmark_bar_node()) { 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_on_bb = parent; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* widget_to_throb = NULL; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parent_on_bb) { 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Descendant of "Other Bookmarks". 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_to_throb = other_bookmarks_button_; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int hidden = GetFirstHiddenBookmark(0, NULL); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idx = model_->bookmark_bar_node()->GetIndexOf(parent_on_bb); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hidden >= 0 && hidden <= idx) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_to_throb = overflow_button_; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_to_throb = gtk_bin_get_child(GTK_BIN(gtk_toolbar_get_nth_item( 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOLBAR(bookmark_toolbar_.get()), idx))); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetThrobbingWidget(widget_to_throb); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::SetThrobbingWidget(GtkWidget* widget) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (throbbing_widget_) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk* hover_controller = 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk::GetHoverControllerGtk(throbbing_widget_); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hover_controller) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hover_controller->StartThrobbing(0); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_handlers_disconnect_by_func( 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_widget_, 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<gpointer>(OnThrobbingWidgetDestroyThunk), 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(throbbing_widget_); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_widget_ = NULL; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_widget_ = widget; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref(throbbing_widget_); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(throbbing_widget_, "destroy", 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnThrobbingWidgetDestroyThunk), this); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk* hover_controller = 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk::GetHoverControllerGtk(throbbing_widget_); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hover_controller) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hover_controller->StartThrobbing(4); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean BookmarkBarGtk::ItemDraggedOverToolbar(GdkDragContext* context, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint time) { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!edit_bookmarks_enabled_.GetValue()) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkAtom target_type = 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_find_target(bookmark_toolbar_.get(), context, NULL); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_type == GDK_NONE) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't act like a drop target when something that we can't deal 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with is dragged over the toolbar. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!toolbar_drop_item_) { 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dragged_node_) { 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_drop_item_ = CreateBookmarkToolItem(dragged_node_); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref_sink(GTK_OBJECT(toolbar_drop_item_)); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a fake item the size of other_node(). 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erg): Maybe somehow figure out the real size for the drop target? 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_drop_item_ = 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBookmarkToolItem(model_->other_node()); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref_sink(GTK_OBJECT(toolbar_drop_item_)); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(bookmark_toolbar_.get()), 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOL_ITEM(toolbar_drop_item_), 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_type == ui::GetAtomForTarget(ui::CHROME_BOOKMARK_ITEM)) { 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_drag_status(context, GDK_ACTION_MOVE, time); 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_drag_status(context, GDK_ACTION_COPY, time); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarGtk::GetToolbarIndexForDragOverFolder(GtkWidget* button, 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint x) { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation allocation; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_get_allocation(button, &allocation); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int margin = std::min(15, static_cast<int>(0.3 * allocation.width)); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x > margin && x < (allocation.width - margin)) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* parent = gtk_widget_get_parent(button); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint index = gtk_toolbar_get_item_index(GTK_TOOLBAR(bookmark_toolbar_.get()), 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOL_ITEM(parent)); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x > margin) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index++; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::ClearToolbarDropHighlighting() { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (toolbar_drop_item_) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(toolbar_drop_item_); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_drop_item_ = NULL; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(bookmark_toolbar_.get()), 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::Loaded(BookmarkModel* model, bool ids_reassigned) { 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |instructions_| has been nulled, we are in the middle of browser 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown. Do nothing. 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!instructions_) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetButtons(); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkModelBeingDeleted(BookmarkModel* model) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The bookmark model should never be deleted before us. This code exists 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to check for regressions in shutdown code and not crash. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do minimal cleanup, presumably we'll be deleted shortly. 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_ = NULL; 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeMoved(BookmarkModel* model, 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* old_parent, 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* new_parent, 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_index) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = new_parent->GetChild(new_index); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeRemoved(model, old_parent, old_index, node); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeAdded(model, new_parent, new_index); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeAdded(BookmarkModel* model, 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = parent->GetChild(index); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent != model_->bookmark_bar_node()) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(node); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkToolItem* item = CreateBookmarkToolItem(node); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_toolbar_insert(GTK_TOOLBAR(bookmark_toolbar_.get()), 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item, index); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_folder()) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Add(gtk_bin_get_child(GTK_BIN(item))); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInstructionState(); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbingAfterAllocation(GTK_WIDGET(item)); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeRemoved(BookmarkModel* model, 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent != model_->bookmark_bar_node()) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(old_index >= 0 && old_index < GetBookmarkButtonCount()); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* to_remove = GTK_WIDGET(gtk_toolbar_get_nth_item( 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOLBAR(bookmark_toolbar_.get()), old_index)); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_folder()) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_bar_helper_.Remove(gtk_bin_get_child(GTK_BIN(to_remove))); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_remove(GTK_CONTAINER(bookmark_toolbar_.get()), 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_remove); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInstructionState(); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BookmarkBarGtk::BookmarkAllNodesRemoved(BookmarkModel* model) { 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UpdateOtherBookmarksVisibility(); 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResetButtons(); 966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model, 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->parent() != model_->bookmark_bar_node()) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->bookmark_bar_node()->GetIndexOf(node); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index != -1); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkToolItem* item = gtk_toolbar_get_nth_item( 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOLBAR(bookmark_toolbar_.get()), index); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* button = gtk_bin_get_child(GTK_BIN(item)); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_utils::ConfigureButtonForNode(node, model, button, theme_service_); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeFaviconChanged(BookmarkModel* model, 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeChanged(model, node); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::BookmarkNodeChildrenReordered(BookmarkModel* model, 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node != model_->bookmark_bar_node()) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We only care about reordering of the bookmark bar node. 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetButtons(); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::Observe(int type, 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) { 1001b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (model_ && model_->loaded()) { 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Regenerate the bookmark bar with all new objects with their theme 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // properties set correctly for the new theme. 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetButtons(); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resize the bookmark bar since the target height may have changed. 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateMaxHeight(); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AnimationProgressed(&slide_animation_); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateEventBoxPaintability(); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkColor paint_box_color = 10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_service_->GetGdkColor(ThemeProperties::COLOR_TOOLBAR); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_modify_bg(paint_box_, GTK_STATE_NORMAL, &paint_box_color); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkColor stroke_color = theme_service_->UsingNativeTheme() ? 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_service_->GetBorderColor() : 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_service_->GetGdkColor(ThemeProperties::COLOR_NTP_HEADER); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::SetRoundedWindowBorderColor(paint_box_, stroke_color); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetOverflowButtonAppearance(); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) { 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* button = theme_service_->BuildChromeButton(); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_utils::ConfigureButtonForNode(node, model_, button, theme_service_); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The tool item is also a source for dragging 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_source_set(button, GDK_BUTTON1_MASK, NULL, 0, 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<GdkDragAction>(GDK_ACTION_MOVE | GDK_ACTION_COPY)); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target_mask = bookmark_utils::GetCodeMask(node->is_folder()); 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetSourceTargetListFromCodeMask(button, target_mask); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(button, "drag-begin", 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnButtonDragBeginThunk), this); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(button, "drag-end", 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnButtonDragEndThunk), this); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(button, "drag-data-get", 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnButtonDragGetThunk), this); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We deliberately don't connect to "drag-data-delete" because the action of 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // moving a button will regenerate all the contents of the bookmarks bar 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // anyway. 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to 'button-release-event' instead of 'clicked' because we need 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // access to the modifier keys and we do different things on each 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button. 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(button, "button-press-event", 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnButtonPressedThunk), this); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(button, "clicked", 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnClickedThunk), this); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::SetButtonTriggersNavigation(button); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectFolderButtonEvents(button, true); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GtkToolItem* BookmarkBarGtk::CreateBookmarkToolItem(const BookmarkNode* node) { 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* button = CreateBookmarkButton(node); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_set_data(G_OBJECT(button), "left-align-popup", 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<void*>(true)); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkToolItem* item = gtk_tool_item_new(); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(item), button); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(GTK_WIDGET(item)); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::ConnectFolderButtonEvents(GtkWidget* widget, 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_tool_item) { 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For toolbar items (i.e. not the overflow button or other bookmarks 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button), we handle motion and highlighting manually. 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_set(widget, 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_tool_item ? GTK_DEST_DEFAULT_DROP : 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_DEST_DEFAULT_ALL, 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDragAction); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetDestTargetList(widget, kDestTargetList); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(widget, "drag-data-received", 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnDragReceivedThunk), this); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_tool_item) { 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(widget, "drag-motion", 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnFolderDragMotionThunk), this); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(widget, "drag-leave", 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(&OnDragLeaveThunk), this); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(widget, "button-press-event", 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnButtonPressedThunk), this); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(widget, "clicked", 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) G_CALLBACK(OnFolderClickedThunk), this); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accept middle mouse clicking (which opens all). This must be called after 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // connecting to "button-press-event" because the handler it attaches stops 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the propagation of that signal. 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::SetButtonClickableByMouseButtons(widget, true, true, false); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BookmarkNode* BookmarkBarGtk::GetNodeForToolButton(GtkWidget* widget) { 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First check to see if |button| is special cased. 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget == other_bookmarks_button_) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->other_node(); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (widget == event_box_.get() || widget == overflow_button_) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node(); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search the contents of |bookmark_toolbar_| for the corresponding widget 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and find its index. 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* item_to_find = gtk_widget_get_parent(widget); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index_to_use = -1; 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = 0; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GList* children = gtk_container_get_children( 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_CONTAINER(bookmark_toolbar_.get())); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (GList* item = children; item; item = item->next, index++) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item->data == item_to_find) { 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_to_use = index; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_list_free(children); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index_to_use != -1) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node()->GetChild(index_to_use); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::PopupMenuForNode(GtkWidget* sender, 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node, 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEventButton* event) { 1137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_->loaded()) { 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't do anything if the model isn't loaded. 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = NULL; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == other_bookmarks_button_) { 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(node); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->bookmark_bar_node(); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (sender != bookmark_toolbar_.get()) { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(node); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = node->parent(); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->bookmark_bar_node(); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(parent); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(sender)); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_context_menu_controller_.reset( 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BookmarkContextMenuController( 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window, this, browser_, browser_->profile(), page_navigator_, parent, 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes)); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_context_menu_.reset( 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new MenuGtk(NULL, current_context_menu_controller_->menu_model())); 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_context_menu_->PopupAsContext( 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point(event->x_root, event->y_root), 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->time); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean BookmarkBarGtk::OnButtonPressed(GtkWidget* sender, 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEventButton* event) { 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_pressed_coordinates_ = gfx::Point(event->x, event->y); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->button == 3 && gtk_widget_get_visible(bookmark_hbox_)) { 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(sender); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_navigator_); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupMenuForNode(sender, node, event); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnClicked(GtkWidget* sender) { 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(sender); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node->is_url()); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_navigator_); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunch(browser_->profile(), node->url()); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::OpenAll(window_->GetNativeWindow(), page_navigator_, node, 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_utils::DispositionForCurrentButtonPressEvent(), 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->profile()); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::RecordBookmarkLaunch(GetBookmarkLaunchLocation()); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnButtonDragBegin(GtkWidget* button, 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* drag_context) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkWidget* button_parent = gtk_widget_get_parent(button); 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The parent tool item might be removed during the drag. Ref it so |button| 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // won't get destroyed. 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref(button_parent); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(button); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!dragged_node_); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dragged_node_ = node; 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dragged_node_); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_icon_ = bookmark_utils::GetDragRepresentationForNode( 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node, model_, theme_service_); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have to jump through some hoops to get the drag icon to line up because 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is a different size than the button. 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkRequisition req; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_size_request(drag_icon_, &req); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect button_rect = gtk_util::WidgetBounds(button); 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point drag_icon_relative = 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect(req.width, req.height).CenterPoint() + 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (last_pressed_coordinates_ - button_rect.CenterPoint()); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_set_icon_widget(drag_context, drag_icon_, 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_icon_relative.x(), 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_icon_relative.y()); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide our node, but reserve space for it on the toolbar. 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = gtk_toolbar_get_item_index(GTK_TOOLBAR(bookmark_toolbar_.get()), 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOL_ITEM(button_parent)); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_hide(button); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_drop_item_ = CreateBookmarkToolItem(dragged_node_); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_ref_sink(GTK_OBJECT(toolbar_drop_item_)); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(bookmark_toolbar_.get()), 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOL_ITEM(toolbar_drop_item_), index); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure it stays hidden for the duration of the drag. 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_no_show_all(button, TRUE); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnButtonDragEnd(GtkWidget* button, 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* drag_context) { 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show(button); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_no_show_all(button, FALSE); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearToolbarDropHighlighting(); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dragged_node_); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dragged_node_ = NULL; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(drag_icon_); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_destroy(drag_icon_); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_icon_ = NULL; 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(gtk_widget_get_parent(button)); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnButtonDragGet(GtkWidget* widget, 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* context, 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* selection_data, 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint target_type, 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint time) { 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type, 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->profile()); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BookmarkBarGtk::OnAppsButtonClicked(GtkWidget* sender) { 12637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::OpenURLParams params( 12647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GURL(chrome::kChromeUIAppsURL), 12657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::Referrer(), 12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch event_utils::DispositionForCurrentButtonPressEvent(), 12677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::PAGE_TRANSITION_AUTO_BOOKMARK, 12687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch false); 12697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_->OpenURL(params); 12707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bookmark_utils::RecordAppsPageOpen(GetBookmarkLaunchLocation()); 12717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 12727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnFolderClicked(GtkWidget* sender) { 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop its throbbing, if any. 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk* hover_controller = 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HoverControllerGtk::GetHoverControllerGtk(sender); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hover_controller) 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hover_controller->StartThrobbing(0); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEvent* event = gtk_get_current_event(); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->button.button == 1 || 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (event->button.button == 2 && sender == overflow_button_)) { 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::RecordBookmarkFolderOpen(GetBookmarkLaunchLocation()); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopupForButton(sender); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (event->button.button == 2) { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = GetNodeForToolButton(sender); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::OpenAll(window_->GetNativeWindow(), page_navigator_, node, 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NEW_BACKGROUND_TAB, browser_->profile()); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gdk_event_free(event); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean BookmarkBarGtk::OnToolbarDragMotion(GtkWidget* toolbar, 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* context, 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint x, 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint y, 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint time) { 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint index = gtk_toolbar_get_drop_index(GTK_TOOLBAR(toolbar), x, y); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ItemDraggedOverToolbar(context, index, time); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnToolbarSizeAllocate(GtkWidget* widget, 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation* allocation) { 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (allocation->width == last_allocation_width_) { 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the width hasn't changed, then the visibility of the chevron 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // doesn't need to change. This check prevents us from getting stuck in a 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loop where allocates are queued indefinitely while the visibility of 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overflow chevron toggles without actual resizes of the toolbar. 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_allocation_width_ = allocation->width; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetChevronState(); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnDragReceived(GtkWidget* widget, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* context, 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint x, gint y, 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* selection_data, 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint target_type, guint time) { 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!edit_bookmarks_enabled_.GetValue()) { 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_finish(context, FALSE, FALSE, time); 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gboolean dnd_success = FALSE; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gboolean delete_selection_data = FALSE; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* dest_node = model_->bookmark_bar_node(); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint index; 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (widget == bookmark_toolbar_.get()) { 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = gtk_toolbar_get_drop_index( 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_TOOLBAR(bookmark_toolbar_.get()), x, y); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (widget == instructions_) { 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_node = model_->bookmark_bar_node(); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = 0; 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = GetToolbarIndexForDragOverFolder(widget, x); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index < 0) { 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_node = GetNodeForToolButton(widget); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = dest_node->child_count(); 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (target_type) { 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::CHROME_BOOKMARK_ITEM: { 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint length = gtk_selection_data_get_length(selection_data); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(reinterpret_cast<const char*>( 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_data(selection_data)), length); 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeData drag_data; 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drag_data.ReadFromPickle(&pickle)) { 13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dnd_success = chrome::DropBookmarks(browser_->profile(), 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) drag_data, dest_node, index) != ui::DragDropTypes::DRAG_NONE; 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::CHROME_NAMED_URL: { 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_success = bookmark_utils::CreateNewBookmarkFromNamedUrl( 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selection_data, model_, dest_node, index); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::TEXT_URI_LIST: { 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_success = bookmark_utils::CreateNewBookmarksFromURIList( 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selection_data, model_, dest_node, index); 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::NETSCAPE_URL: { 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_success = bookmark_utils::CreateNewBookmarkFromNetscapeURL( 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selection_data, model_, dest_node, index); 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::TEXT_PLAIN: { 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guchar* text = gtk_selection_data_get_text(selection_data); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!text) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(reinterpret_cast<char*>(text)); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(text); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): It would be nice to head this case off at drag motion, 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that it doesn't look like we can drag onto the bookmark bar. 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 title = bookmark_utils::GetNameForURL(url); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddURL(dest_node, index, title, url); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_success = TRUE; 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_finish(context, dnd_success, delete_selection_data, time); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnDragLeave(GtkWidget* sender, 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* context, 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint time) { 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GTK_IS_BUTTON(sender)) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_unhighlight(sender); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearToolbarDropHighlighting(); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean BookmarkBarGtk::OnFolderDragMotion(GtkWidget* button, 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkDragContext* context, 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint x, 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint y, 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint time) { 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!edit_bookmarks_enabled_.GetValue()) 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkAtom target_type = gtk_drag_dest_find_target(button, context, NULL); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_type == GDK_NONE) 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = GetToolbarIndexForDragOverFolder(button, x); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index < 0) { 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearToolbarDropHighlighting(); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drag is over middle of folder. 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_highlight(button); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_type == ui::GetAtomForTarget(ui::CHROME_BOOKMARK_ITEM)) { 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_drag_status(context, GDK_ACTION_MOVE, time); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_drag_status(context, GDK_ACTION_COPY, time); 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRUE; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove previous highlighting. 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_unhighlight(button); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ItemDraggedOverToolbar(context, index, time); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean BookmarkBarGtk::OnEventBoxExpose(GtkWidget* widget, 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEventExpose* event) { 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("ui::gtk", "BookmarkBarGtk::OnEventBoxExpose"); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkThemeService* theme_provider = theme_service_; 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need to render the toolbar image in GTK mode, except when 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detached. 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (theme_provider->UsingNativeTheme() && 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ != BookmarkBar::DETACHED) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_state_ != BookmarkBar::DETACHED) { 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget)); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_cairo_rectangle(cr, &event->area); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_clip(cr); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Paint the background theme image. 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point tabstrip_origin = 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabstrip_origin_provider_->GetTabStripOriginForWidget(widget); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_util::DrawThemedToolbarBackground(widget, cr, event, tabstrip_origin, 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_provider); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_destroy(cr); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size web_contents_size; 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetWebContentsSize(&web_contents_size)) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::CanvasSkiaPaint canvas(event, true); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation allocation; 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_get_allocation(widget, &allocation); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect area = gtk_widget_get_has_window(widget) ? 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect(0, 0, allocation.width, allocation.height) : 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect(allocation); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NtpBackgroundUtil::PaintBackgroundDetachedMode(theme_provider, &canvas, 14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) area, web_contents_size.height()); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FALSE; // Propagate expose to children. 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnEventBoxDestroy(GtkWidget* widget) { 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnParentSizeAllocate(GtkWidget* widget, 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkAllocation* allocation) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In detached mode, our layout depends on the size of the tab contents. 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We get the size-allocate signal before the tab contents does, hence we 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to post a delayed task so we will paint correctly. Note that 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // gtk_widget_queue_draw by itself does not work, despite that it claims to 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be asynchronous. 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 1491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BookmarkBarGtk::PaintEventBox, weak_factory_.GetWeakPtr())); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnThrobbingWidgetDestroy(GtkWidget* widget) { 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetThrobbingWidget(NULL); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::ShowImportDialog() { 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowImportDialog(browser_); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid BookmarkBarGtk::OnAppsPageShortcutVisibilityChanged() { 15067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const bool visible = 15077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch chrome::ShouldShowAppsShortcutInBookmarkBar(browser_->profile()); 15087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gtk_widget_set_visible(apps_shortcut_button_, visible); 15097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gtk_widget_set_no_show_all(apps_shortcut_button_, !visible); 15107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 15117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarGtk::OnEditBookmarksEnabledChanged() { 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkDestDefaults dest_defaults = 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *edit_bookmarks_enabled_ ? GTK_DEST_DEFAULT_ALL : 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GTK_DEST_DEFAULT_DROP; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_set(overflow_button_, dest_defaults, NULL, 0, kDragAction); 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_drag_dest_set(other_bookmarks_button_, dest_defaults, 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0, kDragAction); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetDestTargetList(overflow_button_, kDestTargetList); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SetDestTargetList(other_bookmarks_button_, kDestTargetList); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1522