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/views/bookmarks/bookmark_bar_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/bookmarks/chrome_bookmark_client.h" 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/defaults.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h" 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/elide_url.h" 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/omnibox/omnibox_view.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/view_ids.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_bar_instructions_view.h" 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view_observer.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h" 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.h" 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/event_utils.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h" 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h" 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/metrics/metrics_service.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/page_navigator.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/browser/extension_registry.h" 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/extension.h" 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/extension_set.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_utils.h" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data.h" 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/theme_provider.h" 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h" 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h" 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/gfx/text_constants.h" 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/text_elider.h" 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h" 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/button_drag_utils.h" 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/controls/button/label_button.h" 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/controls/button/label_button_border.h" 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h" 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/drag_utils.h" 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/metrics.h" 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_constants.h" 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/tooltip_manager.h" 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/window/non_client_view.h" 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction; 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using bookmarks::BookmarkNodeData; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::PageNavigator; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::Referrer; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::DropTargetEvent; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using views::CustomButton; 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using views::LabelButtonBorder; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::MenuButton; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::View; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Margins around the content. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDetachedTopMargin = 1; // When attached, we use 0 and let the 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toolbar above serve as the margin. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBottomMargin = 2; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kLeftMargin = 1; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kRightMargin = 1; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char BookmarkBarView::kViewClassName[] = "BookmarkBarView"; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding between buttons. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kButtonPadding = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Icon to display when one isn't found for the page. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static gfx::ImageSkia* kDefaultFavicon = NULL; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Icon used for folders. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static gfx::ImageSkia* kFolderIcon = NULL; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Color of the drop indicator. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const SkColor kDropIndicatorColor = SK_ColorBLACK; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Width of the drop indicator. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDropIndicatorWidth = 2; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Distance between the bottom of the bar and the separator. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorMargin = 1; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Width of the separator between the recently bookmarked button and the 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// overflow indicator. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorWidth = 4; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starting x-coordinate of the separator line within a separator. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorStartX = 2; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Left-padding for the instructional text. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kInstructionsPadding = 6; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tag for the 'Other bookmarks' button. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kOtherFolderButtonTag = 1; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tag for the 'Apps Shortcut' button. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kAppsShortcutButtonTag = 2; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Preferred padding between text and edge. 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const int kButtonPaddingHorizontal = 6; 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const int kButtonPaddingVertical = 4; 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Tag for the 'Managed bookmarks' button. 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const int kManagedFolderButtonTag = 3; 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if !defined(OS_WIN) 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const gfx::ElideBehavior kElideBehavior = gfx::FADE_TAIL; 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Windows fade eliding causes text to darken; see http://crbug.com/388084 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const gfx::ElideBehavior kElideBehavior = gfx::ELIDE_TAIL; 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To enable/disable BookmarkBar animations during testing. In production 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animations are enabled by default. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool animations_enabled = true; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BookmarkButtonBase ----------------------------------------------- 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Base class for buttons used on the bookmark bar. 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class BookmarkButtonBase : public views::LabelButton { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkButtonBase(views::ButtonListener* listener, 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title) 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : LabelButton(listener, title) { 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetElideBehavior(kElideBehavior); 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) show_animation_.reset(new gfx::SlideAnimation(this)); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For some reason during testing the events generated by animating 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // throw off the test. So, don't animate while testing. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show_animation_->Reset(1); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show_animation_->Show(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual View* GetTooltipHandlerForPoint(const gfx::Point& point) OVERRIDE { 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return HitTestPoint(point) && CanProcessEventsWithinSubtree() ? this : NULL; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual scoped_ptr<LabelButtonBorder> CreateDefaultBorder() const OVERRIDE { 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<LabelButtonBorder> border = LabelButton::CreateDefaultBorder(); 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) border->set_insets(gfx::Insets(kButtonPaddingVertical, 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kButtonPaddingHorizontal, 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kButtonPaddingVertical, 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kButtonPaddingHorizontal)); 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return border.Pass(); 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE { 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return e.type() == ui::ET_GESTURE_TAP || 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.type() == ui::ET_GESTURE_TAP_DOWN || 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_utils::IsPossibleDispositionEvent(e); 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<gfx::SlideAnimation> show_animation_; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkButtonBase); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkButton ------------------------------------------------------------- 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Buttons used for the bookmarks on the bookmark bar. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BookmarkButton : public BookmarkButtonBase { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The internal view class name. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kViewClassName[]; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkButton(views::ButtonListener* listener, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkButtonBase(listener, title), 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_(url), 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_(profile) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetTooltipText(const gfx::Point& p, 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* tooltip) const OVERRIDE { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point location(p); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPointToScreen(this, &location); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tooltip = BookmarkBarView::CreateToolTipForURLAndTitle( 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetWidget(), location, url_, GetText(), profile_); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !tooltip->empty(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual const char* GetClassName() const OVERRIDE { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url_; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile_; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkButton); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static 251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char BookmarkButton::kViewClassName[] = "BookmarkButton"; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShortcutButton ------------------------------------------------------------- 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Buttons used for the shortcuts on the bookmark bar. 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShortcutButton : public BookmarkButtonBase { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The internal view class name. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kViewClassName[]; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShortcutButton(views::ButtonListener* listener, 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkButtonBase(listener, title) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual const char* GetClassName() const OVERRIDE { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kViewClassName; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShortcutButton); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static 276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char ShortcutButton::kViewClassName[] = "ShortcutButton"; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkFolderButton ------------------------------------------------------- 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Buttons used for folders on the bookmark bar, including the 'other folders' 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// button. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkFolderButton : public views::MenuButton { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkFolderButton(views::ButtonListener* listener, 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButtonListener* menu_button_listener, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool show_menu_marker) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : MenuButton(listener, title, menu_button_listener, show_menu_marker) { 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetElideBehavior(kElideBehavior); 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) show_animation_.reset(new gfx::SlideAnimation(this)); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For some reason during testing the events generated by animating 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // throw off the test. So, don't animate while testing. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_animation_->Reset(1); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_animation_->Show(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetTooltipText(const gfx::Point& p, 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* tooltip) const OVERRIDE { 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (label()->GetPreferredSize().width() > label()->size().width()) 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *tooltip = GetText(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !tooltip->empty(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Left clicks and taps should show the menu contents and right clicks 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should show the context menu. They should not trigger the opening of 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underlying urls. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (e.type() == ui::ET_GESTURE_TAP || 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (e.IsMouseEvent() && (e.flags() & 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)))) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (e.IsMouseEvent()) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ui::DispositionFromEventFlags(e.flags()) != CURRENT_TAB; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<gfx::SlideAnimation> show_animation_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkFolderButton); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OverFlowButton (chevron) -------------------------------------------------- 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OverFlowButton : public views::MenuButton { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit OverFlowButton(BookmarkBarView* owner) 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : MenuButton(NULL, base::string16(), owner, false), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_(owner) {} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMousePressed(const ui::MouseEvent& e) OVERRIDE { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_->StopThrobbing(true); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return views::MenuButton::OnMousePressed(e); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBarView* owner_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OverFlowButton); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RecordAppLaunch(Profile* profile, GURL url) { 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const extensions::Extension* extension = 348a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionRegistry::Get(profile) 349a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->enabled_extensions().GetAppByURL(url); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!extension) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 353558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CoreAppLauncherHandler::RecordAppLaunchType( 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::APP_LAUNCH_BOOKMARK_BAR, 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension->GetType()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DropLocation --------------------------------------------------------------- 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct BookmarkBarView::DropLocation { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation() 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : index(-1), 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation(ui::DragDropTypes::DRAG_NONE), 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on(false), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_type(DROP_BOOKMARK) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Equals(const DropLocation& other) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((other.index == index) && (other.on == on) && 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (other.button_type == button_type)); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Index into the model the drop is over. This is relative to the root node. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drop constants. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int operation; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, the user is dropping on a folder. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool on; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Type of button. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropButtonType button_type; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DropInfo ------------------------------------------------------------------- 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks drops on the BookmarkBarView. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct BookmarkBarView::DropInfo { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropInfo() 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : valid(false), 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_menu_showing(false), 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x(0), 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y(0) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the data is valid. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool valid; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, the menu is being shown. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_menu_showing; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Coordinates of the drag (in terms of the BookmarkBarView). 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DropData for the drop. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeData data; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation location; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ButtonSeparatorView -------------------------------------------------------- 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkBarView::ButtonSeparatorView : public views::View { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ButtonSeparatorView() {} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ButtonSeparatorView() {} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::PaintVerticalDivider( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas, kSeparatorStartX, height(), 1, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::kEdgeDividerColor, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::kMiddleDividerColor, 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR)); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We get the full height of the bookmark bar, so that the height returned 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here doesn't matter. 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(kSeparatorWidth, 1); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_SEPARATOR); 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_SPLITTER; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ButtonSeparatorView); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkBarView ------------------------------------------------------------ 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int BookmarkBarView::kMaxButtonWidth = 150; 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int BookmarkBarView::kNewtabHorizontalPadding = 2; 451a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const int BookmarkBarView::kToolbarAttachedBookmarkBarOverlap = 3; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const gfx::ImageSkia& GetDefaultFavicon() { 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!kDefaultFavicon) { 455d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 456d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) kDefaultFavicon = rb->GetImageSkiaNamed(IDR_DEFAULT_FAVICON); 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *kDefaultFavicon; 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const gfx::ImageSkia& GetFolderIcon() { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!kFolderIcon) { 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 464d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) kFolderIcon = rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *kFolderIcon; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarView::BookmarkBarView(Browser* browser, BrowserView* browser_view) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : page_navigator_(NULL), 471f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_(NULL), 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_(NULL), 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_(NULL), 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_(NULL), 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_(NULL), 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_(NULL), 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_(NULL), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_(NULL), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_(NULL), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_(browser_view), 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobar_visible_(false), 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_(NULL), 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_(BookmarkBar::SHOW), 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci animating_detached_(false), 4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci show_folder_method_factory_(this) { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_id(VIEW_ID_BOOKMARK_BAR); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Reset(1); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarView::~BookmarkBarView() { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible for the menu to outlive us, reset the observer to make sure 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it doesn't have a reference to us. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_menu_) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->set_observer(NULL); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->SetPageNavigator(NULL); 502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bookmark_menu_->clear_bookmark_bar(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_menu_.get()) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_->SetPageNavigator(NULL); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::DisableAnimationsForTesting(bool disabled) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animations_enabled = !disabled; 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BookmarkBarView::AddObserver(BookmarkBarViewObserver* observer) { 5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci observers_.AddObserver(observer); 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BookmarkBarView::RemoveObserver(BookmarkBarViewObserver* observer) { 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci observers_.RemoveObserver(observer); 5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_ = navigator; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_menu_) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->SetPageNavigator(navigator); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_menu_.get()) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_->SetPageNavigator(navigator); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::SetBookmarkBarState( 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::State state, 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkBar::AnimateChangeType animate_type) { 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE && 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) animations_enabled) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animating_detached_ = (state == BookmarkBar::DETACHED || 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ == BookmarkBar::DETACHED); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == BookmarkBar::SHOW) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Show(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Hide(); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Reset(state == BookmarkBar::SHOW ? 1 : 0); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ = state; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint BookmarkBarView::GetFullyDetachedToolbarOverlap() const { 549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!infobar_visible_ && browser_->window()->IsFullscreen()) { 550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // There is no client edge to overlap when detached in fullscreen with no 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // infobars visible. 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return views::NonClientFrameView::kClientEdgeThickness; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::is_animating() { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_animation_->is_animating(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BookmarkNode* BookmarkBarView::GetNodeForButtonAtModelIndex( 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& loc, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* model_start_index) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *model_start_index = 0; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point adjusted_loc(GetMirroredXInView(loc.x()), loc.y()); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Check the managed button first. 572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (managed_bookmarks_button_->visible() && 573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->bounds().Contains(adjusted_loc)) { 574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return client_->managed_node(); 575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Then check the bookmark buttons. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!child->visible()) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->bounds().Contains(adjusted_loc)) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node()->GetChild(i); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then the overflow button. 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_button_->visible() && 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->bounds().Contains(adjusted_loc)) { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *model_start_index = GetFirstHiddenNodeIndex(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node(); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And finally the other folder. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible() && 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->bounds().Contains(adjusted_loc)) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->other_node(); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuButton* BookmarkBarView::GetMenuButtonForNode( 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (node == client_->managed_node()) 605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return managed_bookmarks_button_; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->other_node()) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other_bookmarked_button_; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->bookmark_bar_node()) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_button_; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->bookmark_bar_node()->GetIndexOf(node); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == -1 || !node->is_folder()) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<views::MenuButton*>(child_at(index)); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::GetAnchorPositionForButton( 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* button, 6185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuAnchorPosition* anchor) { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button == other_bookmarked_button_ || button == overflow_button_) 6205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *anchor = views::MENU_ANCHOR_TOPRIGHT; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *anchor = views::MENU_ANCHOR_TOPLEFT; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetMenu() { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_menu_ ? bookmark_menu_->menu() : NULL; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetContextMenu() { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetDropMenu() { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StopThrobbing(bool immediate) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!throbbing_view_) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If not immediate, cycle through 2 more complete cycles. 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StartThrobbing(immediate ? 0 : 4); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = NULL; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 BookmarkBarView::CreateToolTipForURLAndTitle( 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const views::Widget* widget, 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& screen_loc, 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title, 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile) { 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int max_width = views::TooltipManager::GetMaxWidth( 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) screen_loc.x(), 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) screen_loc.y(), 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) widget->GetNativeView()); 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::FontList tt_fonts = widget->GetTooltipManager()->GetFontList(); 658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 result; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First the title. 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title.empty()) { 662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 localized_title = title; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::AdjustStringForLocaleDirection(&localized_title); 66446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) result.append(gfx::ElideText(localized_title, tt_fonts, max_width, 66546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gfx::ELIDE_TAIL)); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only show the URL if the url and title differ. 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (title != base::UTF8ToUTF16(url.spec())) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.empty()) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back('\n'); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to explicitly specify the directionality of the URL's text to 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure it is treated as an LTR string when the context is RTL. For 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // example, the URL "http://www.yahoo.com/" appears as 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "/http://www.yahoo.com" when rendered, as is, in an RTL context since 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Unicode BiDi algorithm puts certain characters on the left by 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string languages = profile->GetPrefs()->GetString( 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs::kAcceptLanguages); 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 elided_url(ElideUrl(url, tt_fonts, max_width, languages)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(elided_url); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::IsDetached() const { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (bookmark_bar_state_ == BookmarkBar::DETACHED) || 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (animating_detached_ && size_animation_->is_animating()); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double BookmarkBarView::GetAnimationValue() const { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_animation_->GetCurrentValue(); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetToolbarOverlap() const { 698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int attached_overlap = kToolbarAttachedBookmarkBarOverlap + 699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::NonClientFrameView::kClientEdgeThickness; 700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!IsDetached()) 701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return attached_overlap; 702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int detached_overlap = GetFullyDetachedToolbarOverlap(); 704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Do not animate the overlap when the infobar is above us (i.e. when we're 706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // detached), since drawing over the infobar looks weird. 707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (infobar_visible_) 708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return detached_overlap; 709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // When detached with no infobar, animate the overlap between the attached and 711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // detached states. 712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return detached_overlap + static_cast<int>( 713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (attached_overlap - detached_overlap) * 714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_animation_->GetCurrentValue()); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size BookmarkBarView::GetPreferredSize() const { 718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Size prefsize; 719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (IsDetached()) { 720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefsize.set_height( 721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::kBookmarkBarHeight + 722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<int>( 723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (chrome::kNTPBookmarkBarHeight - chrome::kBookmarkBarHeight) * 724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (1 - size_animation_->GetCurrentValue()))); 725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prefsize.set_height(static_cast<int>(chrome::kBookmarkBarHeight * 727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_animation_->GetCurrentValue())); 728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return prefsize; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool BookmarkBarView::CanProcessEventsWithinSubtree() const { 73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the bookmark bar is attached and the omnibox popup is open (on top of 73446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the bar), prevent events from targeting the bookmark bar or any of its 73546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // descendants. This will prevent hovers/clicks just above the omnibox popup 73646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // from activating the top few pixels of items on the bookmark bar. 7377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!IsDetached() && browser_view_ && 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_view_->GetLocationBar()->GetOmniboxView()->model()-> 7397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch popup_model()->IsOpen()) { 7407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 7417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 74246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return true; 7437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size BookmarkBarView::GetMinimumSize() const { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The minimum width of the bookmark bar should at least contain the overflow 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button, by which one can access all the Bookmark Bar items, and the "Other 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bookmarks" folder, along with appropriate margins and button padding. 749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // It should also contain the Managed Bookmarks folder, if it's visible. 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = kLeftMargin; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int height = chrome::kBookmarkBarHeight; 753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (IsDetached()) { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double current_state = 1 - size_animation_->GetCurrentValue(); 755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch width += 2 * static_cast<int>(kNewtabHorizontalPadding * current_state); 756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch height += static_cast<int>( 75758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (chrome::kNTPBookmarkBarHeight - chrome::kBookmarkBarHeight) * 758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch current_state); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (managed_bookmarks_button_->visible()) { 762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size size = managed_bookmarks_button_->GetPreferredSize(); 763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) width += size.width() + kButtonPadding; 764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (other_bookmarked_button_->visible()) { 766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size size = other_bookmarked_button_->GetPreferredSize(); 767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) width += size.width() + kButtonPadding; 768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (overflow_button_->visible()) { 770f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size size = overflow_button_->GetPreferredSize(); 771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) width += size.width() + kButtonPadding; 772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (bookmarks_separator_view_->visible()) { 774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size size = bookmarks_separator_view_->GetPreferredSize(); 775f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) width += size.width(); 776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (apps_page_shortcut_->visible()) { 778f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size size = apps_page_shortcut_->GetPreferredSize(); 779f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) width += size.width() + kButtonPadding; 780f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return gfx::Size(width, height); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::Layout() { 786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LayoutItems(); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 789a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void BookmarkBarView::ViewHierarchyChanged( 790a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const ViewHierarchyChangedDetails& details) { 791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (details.is_add && details.child == this) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may get inserted into a hierarchy with a profile - this typically 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs when the bar's contents get populated fast enough that the 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buttons are created before the bar is attached to a frame. 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (height() > 0) { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only layout while parented. When we become parented, if our bounds 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // haven't changed, OnBoundsChanged() won't get invoked and we won't 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layout. Therefore we always force a layout when added. 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BookmarkBarView::PaintChildren(gfx::Canvas* canvas, 807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::CullSet& cull_set) { 808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) View::PaintChildren(canvas, cull_set); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_.get() && drop_info_->valid && 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.operation != 0 && drop_info_->location.index != -1 && 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.button_type != DROP_OVERFLOW && 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !drop_info_->location.on) { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = drop_info_->location.index; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index <= GetBookmarkButtonCount()); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = 0; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = 0; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h = height(); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == GetBookmarkButtonCount()) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == 0) { 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = kLeftMargin; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = GetBookmarkButton(index - 1)->x() + 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarkButton(index - 1)->width(); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = GetBookmarkButton(index)->x(); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetBookmarkButtonCount() > 0 && GetBookmarkButton(0)->visible()) { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = GetBookmarkButton(0)->y(); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = GetBookmarkButton(0)->height(); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the drop indicator is painted directly onto the canvas, we must 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure it is painted in the right location if the locale is RTL. 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y, 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDropIndicatorWidth, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indicator_bounds.set_x(GetMirroredXForRect(indicator_bounds)); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky/glen): make me pretty! 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->FillRect(indicator_bounds, kDropIndicatorColor); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::GetDropFormats( 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* formats, 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { 850b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_ || !model_->loaded()) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *formats = ui::OSExchangeData::URL; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) custom_formats->insert(BookmarkNodeData::GetBookmarkCustomFormat()); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::AreDropTypesRequired() { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::CanDrop(const ui::OSExchangeData& data) { 862b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_ || !model_->loaded() || 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !browser_->profile()->GetPrefs()->GetBoolean( 8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmarks::prefs::kEditBookmarksEnabled)) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get()) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(new DropInfo()); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only accept drops of 1 node, which is the case for all data dragged from 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bookmark bar and menus. 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->data.Read(data) && drop_info_->data.size() == 1; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnDragEntered(const DropTargetEvent& event) { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::OnDragUpdated(const DropTargetEvent& event) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get()) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->valid && 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (drop_info_->x == event.x() && drop_info_->y == event.y())) { 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The location of the mouse didn't change, return the last operation. 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->x = event.x(); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->y = event.y(); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation location; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateDropLocation(event, drop_info_->data, &location); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->valid && drop_info_->location.Equals(location)) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The position we're going to drop didn't change, return the last drag 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation we calculated. Copy of the operation in case it changed. 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.operation = location.operation; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): Optimize paint region. 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location = location; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->valid = true; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->is_menu_showing) { 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->is_menu_showing = false; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location.on || location.button_type == DROP_OVERFLOW || 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location.button_type == DROP_OTHER_FOLDER) { 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location.button_type == DROP_OTHER_FOLDER) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (location.button_type == DROP_OVERFLOW) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node(); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(location.index); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartShowFolderDropMenuTimer(node); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnDragExited() { 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: we don't hide the menu on exit as it's possible the user moved the 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mouse over the menu, which triggers an exit on us. 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->valid = false; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->location.index != -1) { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): optimize the paint region. 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get() || !drop_info_->location.operation) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* root = 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (drop_info_->location.button_type == DROP_OTHER_FOLDER) ? 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->other_node() : model_->bookmark_bar_node(); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = drop_info_->location.index; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): optimize the SchedulePaint region. 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent_node; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->location.button_type == DROP_OTHER_FOLDER) { 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = parent_node->child_count(); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (drop_info_->location.on) { 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root->GetChild(index); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = parent_node->child_count(); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNodeData data = drop_info_->data; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data.is_valid()); 975f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool copy = drop_info_->location.operation == ui::DragDropTypes::DRAG_COPY; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(); 977f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return chrome::DropBookmarks( 978f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_->profile(), data, parent_node, index, copy); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnThemeChanged() { 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* BookmarkBarView::GetClassName() const { 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BookmarkBarView::SetVisible(bool v) { 9901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (v == visible()) 9911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 9921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci View::SetVisible(v); 9941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FOR_EACH_OBSERVER(BookmarkBarViewObserver, observers_, 9951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnBookmarkBarVisibilityChanged()); 9961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 9971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BookmarkBarView::GetAccessibleState(ui::AXViewState* state) { 999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_TOOLBAR; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1003d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void BookmarkBarView::AnimationProgressed(const gfx::Animation* animation) { 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |browser_view_| can be NULL during tests. 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_view_) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_->ToolbarSizeChanged(true); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1009d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void BookmarkBarView::AnimationEnded(const gfx::Animation* animation) { 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |browser_view_| can be NULL during tests. 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_view_) { 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_view_->ToolbarSizeChanged(false); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1017424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void BookmarkBarView::BookmarkMenuControllerDeleted( 1018424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BookmarkMenuController* controller) { 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller == bookmark_menu_) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_ = NULL; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (controller == bookmark_drop_menu_) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_ = NULL; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowImportDialog() { 1026116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64 install_time = g_browser_process->metrics_service()->GetInstallDate(); 1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 time_from_install = base::Time::Now().ToTimeT() - install_time; 1028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bookmark_bar_state_ == BookmarkBar::SHOW) { 102990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("Import.ShowDialog.FromBookmarkBarView", 1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_from_install); 1031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("Import.ShowDialog.FromFloatingBookmarkBarView", 1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_from_install); 1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowImportDialog(browser_); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::OnBookmarkBubbleShown(const GURL& url) { 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopThrobbing(true); 104146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const BookmarkNode* node = model_->GetMostRecentlyAddedUserNodeForURL(url); 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!node) 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // Generally shouldn't happen. 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartThrobbing(node, false); 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::OnBookmarkBubbleHidden() { 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopThrobbing(false); 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BookmarkBarView::BookmarkModelLoaded(BookmarkModel* model, 10525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool ids_reassigned) { 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be no buttons. If non-zero it means Load was invoked more than 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // once, or we didn't properly clear things. Either of which shouldn't happen. 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, GetBookmarkButtonCount()); 1056f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const BookmarkNode* node = model->bookmark_bar_node(); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a button for each of the children on the bookmark bar. 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, child_count = node->child_count(); i < child_count; ++i) 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); 1061f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(model->other_node()); 1062f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) other_bookmarked_button_->SetAccessibleName(model->other_node()->GetTitle()); 1063f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) other_bookmarked_button_->SetText(model->other_node()->GetTitle()); 1064f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetAccessibleName( 1065f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_->managed_node()->GetTitle()); 1066f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetText(client_->managed_node()->GetTitle()); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 1068f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UpdateButtonsVisibility(); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetEnabled(true); 1070f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetEnabled(true); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) { 1077effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NOTREACHED(); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do minimal cleanup, presumably we'll be deleted shortly. 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_ = NULL; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeMoved(BookmarkModel* model, 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* old_parent, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* new_parent, 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_index) { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_throbbing = throbbing_view_ && 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ == DetermineViewToThrobFromRemove(old_parent, old_index); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_throbbing) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StopThrobbing(); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeRemovedImpl(model, old_parent, old_index); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeAddedImpl(model, new_parent, new_index); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_throbbing) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(new_parent->GetChild(new_index), false); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model, 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeAddedImpl(model, parent, index); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 1107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const BookmarkNode* node, 1108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<GURL>& removed_urls) { 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close the menu if the menu is showing for the deleted node. 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bookmark_menu_ && bookmark_menu_->node() == node) 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_menu_->Cancel(); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeRemovedImpl(model, parent, old_index); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void BookmarkBarView::BookmarkAllUserNodesRemoved( 1116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BookmarkModel* model, 1117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<GURL>& removed_urls) { 1118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UpdateButtonsVisibility(); 1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StopThrobbing(true); 1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove the existing buttons. 1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (GetBookmarkButtonCount()) { 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete GetBookmarkButton(0); 1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Layout(); 1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SchedulePaint(); 1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model, 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeChangedImpl(model, node); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 1138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (node != model->bookmark_bar_node()) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We only care about reordering of the bookmark bar node. 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the existing buttons. 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (GetBookmarkButtonCount()) { 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* button = child_at(0); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(button); 1145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, button); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the new buttons. 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, child_count = node->child_count(); i < child_count; ++i) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeFaviconChanged(BookmarkModel* model, 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeChangedImpl(model, node); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::WriteDragDataForView(View* sender, 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& press_pt, 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::OSExchangeData* data) { 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordAction(UserMetricsAction("BookmarkBar_DragButton")); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 1169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::LabelButton* button = GetBookmarkButton(i); 1170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); 1171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const gfx::Image& image_from_model = model_->GetFavicon(node); 1173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const gfx::ImageSkia& icon = image_from_model.IsEmpty() ? 1174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (node->is_folder() ? GetFolderIcon() : GetDefaultFavicon()) : 1175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *image_from_model.ToImageSkia(); 1176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button_drag_utils::SetDragImage( 1178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) node->url(), 1179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) node->GetTitle(), 1180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) icon, 1181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &press_pt, 1182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) data, 1183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->GetWidget()); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteBookmarkDragData(model_->bookmark_bar_node()->GetChild(i), data); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetDragOperationsForView(View* sender, 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p) { 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_animation_->is_animating() || 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (size_animation_->GetCurrentValue() == 0 && 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ != BookmarkBar::DETACHED)) { 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't let the user drag while animating open or we're closed (and not 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detached, when detached size_animation_ is always 0). This typically is 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only hit if the user does something to inadvertently trigger DnD such as 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pressing the mouse and hitting control-b. 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::GetBookmarkDragOperation( 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->profile(), model_->bookmark_bar_node()->GetChild(i)); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::CanStartDragForView(views::View* sender, 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& press_pt, 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we have not moved enough horizontally but we have moved downward 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vertically - downward drag. 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Vector2d move_offset = p - press_pt; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Vector2d horizontal_offset(move_offset.x(), 0); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!View::ExceededDragThreshold(horizontal_offset) && move_offset.y() > 0) { 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the folder button was dragged, show the menu instead. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node && node->is_folder()) { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* menu_button = 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<views::MenuButton*>(sender); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_button->Activate(); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnMenuButtonClicked(views::View* view, 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_index = 0; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view == other_bookmarked_button_) { 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 1245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (view == managed_bookmarks_button_) { 1246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) node = client_->managed_node(); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (view == overflow_button_) { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node(); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_index = GetFirstHiddenNodeIndex(); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_index = GetIndexOf(view); 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, button_index); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(button_index); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RecordBookmarkFolderOpen(GetBookmarkLaunchLocation()); 1257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bookmark_menu_ = new BookmarkMenuController( 1258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_, page_navigator_, GetWidget(), node, start_index, false); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->set_observer(this); 1260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bookmark_menu_->RunMenuAt(this); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ButtonPressed(views::Button* sender, 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Event& event) { 12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition disposition_from_event_flags = 12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::DispositionFromEventFlags(event.flags()); 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sender->tag() == kAppsShortcutButtonTag) { 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLParams params(GURL(chrome::kChromeUIAppsURL), 12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Referrer(), 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition_from_event_flags, 12721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_AUTO_BOOKMARK, 12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_navigator_->OpenURL(params); 127568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RecordBookmarkAppsPageOpen(GetBookmarkLaunchLocation()); 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->tag() == kOtherFolderButtonTag) { 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 1282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (sender->tag() == kManagedFolderButtonTag) { 1283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) node = client_->managed_node(); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = GetIndexOf(sender); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, index); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(index); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_navigator_); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunch(browser_->profile(), node->url()); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenURLParams params( 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node->url(), Referrer(), disposition_from_event_flags, 12951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_AUTO_BOOKMARK, false); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_->OpenURL(params); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::OpenAll(GetWidget()->GetNativeWindow(), page_navigator_, node, 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition_from_event_flags, browser_->profile()); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RecordBookmarkLaunch(node, GetBookmarkLaunchLocation()); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowContextMenuForView(views::View* source, 13067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Point& point, 13077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::MenuSourceType source_type) { 1308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_->loaded()) { 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't do anything if the model isn't loaded. 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = NULL; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source == other_bookmarked_button_) { 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->other_node(); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do this so the user can open all bookmarks. BookmarkContextMenu makes 13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sure the user can't edit/delete the node in this case. 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(parent); 1320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (source == managed_bookmarks_button_) { 1321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) parent = client_->managed_node(); 1322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) nodes.push_back(parent); 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (source != this && source != apps_page_shortcut_) { 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // User clicked on one of the bookmark buttons, find which one they 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // clicked on, except for the apps page shortcut, which must behave as if 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the user clicked on the bookmark bar background. 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bookmark_button_index = GetIndexOf(source); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bookmark_button_index != -1 && 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_button_index < GetBookmarkButtonCount()); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->bookmark_bar_node()->GetChild(bookmark_button_index); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(node); 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = node->parent(); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->bookmark_bar_node(); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(parent); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool close_on_remove = 1339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (parent == model_->other_node()) && (parent->child_count() == 1); 1340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_.reset(new BookmarkContextMenu( 1342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetWidget(), browser_, browser_->profile(), 13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->tab_strip_model()->GetActiveWebContents(), 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent, nodes, close_on_remove)); 13457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) context_menu_->RunMenuAt(point, source_type); 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::Init() { 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that at this point we're not in a hierarchy so GetThemeProvider() will 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return NULL. When we're inserted into a hierarchy, we'll call 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UpdateColors(), which will set the appropriate colors for all the objects 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // added in this function. 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Child views are traversed in the order they are added. Make sure the order 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they are added matches the visual order. 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_ = CreateOverflowButton(); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(overflow_button_); 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_ = CreateOtherBookmarkedButton(); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll re-enable when the model is loaded. 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetEnabled(false); 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(other_bookmarked_button_); 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) managed_bookmarks_button_ = CreateManagedBookmarksButton(); 1365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Also re-enabled when the model is loaded. 1366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetEnabled(false); 1367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddChildView(managed_bookmarks_button_); 1368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_ = CreateAppsPageShortcutButton(); 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddChildView(apps_page_shortcut_); 13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); 13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_pref_registrar_.Add( 13731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmarks::prefs::kShowAppsShortcutInBookmarkBar, 1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&BookmarkBarView::OnAppsPageShortcutVisibilityPrefChanged, 1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 1376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) profile_pref_registrar_.Add( 13771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmarks::prefs::kShowManagedBookmarksInBookmarkBar, 1378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&BookmarkBarView::UpdateButtonsVisibility, 1379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_page_shortcut_->SetVisible( 1381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::ShouldShowAppsShortcutInBookmarkBar( 1382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_->profile(), browser_->host_desktop_type())); 13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_ = new ButtonSeparatorView(); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(bookmarks_separator_view_); 13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_ = new BookmarkBarInstructionsView(this); 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(instructions_); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_context_menu_controller(this); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) size_animation_.reset(new gfx::SlideAnimation(this)); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_ = BookmarkModelFactory::GetForProfile(browser_->profile()); 1396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_ = ChromeBookmarkClientFactory::GetForProfile(browser_->profile()); 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) { 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 1399b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (model_->loaded()) 14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BookmarkModelLoaded(model_, false); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // else case: we'll receive notification back from the BookmarkModel when 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // done loading, then we'll populate the bar. 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int BookmarkBarView::GetBookmarkButtonCount() const { 1407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We contain six non-bookmark button views: managed bookmarks, 1408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // other bookmarks, bookmarks separator, chevrons (for overflow), apps page, 1409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // and the instruction label. 1410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return child_count() - 6; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)views::LabelButton* BookmarkBarView::GetBookmarkButton(int index) { 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < GetBookmarkButtonCount()); 1415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return static_cast<views::LabelButton*>(child_at(index)); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 141868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)BookmarkLaunchLocation BookmarkBarView::GetBookmarkLaunchLocation() const { 141968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return IsDetached() ? BOOKMARK_LAUNCH_LOCATION_DETACHED_BAR : 142068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BOOKMARK_LAUNCH_LOCATION_ATTACHED_BAR; 14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetFirstHiddenNodeIndex() { 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int bb_count = GetBookmarkButtonCount(); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bb_count; ++i) { 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetBookmarkButton(i)->visible()) 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bb_count; 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Title is set in Loaded. 1434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MenuButton* button = 1435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new BookmarkFolderButton(this, base::string16(), this, false); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_id(VIEW_ID_OTHER_BOOKMARKS); 1437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, GetFolderIcon()); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_context_menu_controller(this); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_tag(kOtherFolderButtonTag); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1443f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MenuButton* BookmarkBarView::CreateManagedBookmarksButton() { 1444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Title is set in Loaded. 1445f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MenuButton* button = 1446f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new BookmarkFolderButton(this, base::string16(), this, false); 1447f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->set_id(VIEW_ID_MANAGED_BOOKMARKS); 14486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 14496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) gfx::ImageSkia* image = 14506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER_MANAGED); 14516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, *image); 1452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->set_context_menu_controller(this); 1453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->set_tag(kManagedFolderButtonTag); 1454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return button; 1455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 1456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuButton* BookmarkBarView::CreateOverflowButton() { 1458d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuButton* button = new OverFlowButton(this); 1460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, 1461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_CHEVRONS)); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The overflow button's image contains an arrow and therefore it is a 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // direction sensitive image and we need to flip it if the UI layout is 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-to-left. 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // By default, menu buttons are not flipped because they generally contain 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // text and flipping the gfx::Canvas object will break text rendering. Since 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the overflow button does not contain text, we can safely flip it. 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->EnableCanvasFlippingForRTLUI(true); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make visible as necessary. 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetVisible(false); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set accessibility name. 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetAccessibleName( 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS_CHEVRON)); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) { 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkButton* button = new BookmarkButton( 14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, node->url(), node->GetTitle(), browser_->profile()); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* button = new BookmarkFolderButton( 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, node->GetTitle(), this, false); 1489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, GetFolderIcon()); 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)views::LabelButton* BookmarkBarView::CreateAppsPageShortcutButton() { 1496f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::LabelButton* button = new ShortcutButton( 14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME)); 14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->SetTooltipText(l10n_util::GetStringUTF16( 14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_BOOKMARK_BAR_APPS_SHORTCUT_TOOLTIP)); 15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_id(VIEW_ID_BOOKMARK_BAR_ELEMENT); 1501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 1502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, 1503f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *rb->GetImageSkiaNamed(IDR_BOOKMARK_BAR_APPS_SHORTCUT)); 15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_context_menu_controller(this); 15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_tag(kAppsShortcutButtonTag); 15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return button; 15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ConfigureButton(const BookmarkNode* node, 1510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::LabelButton* button) { 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetText(node->GetTitle()); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetAccessibleName(node->GetTitle()); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_id(VIEW_ID_BOOKMARK_BAR_ELEMENT); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't always have a theme provider (ui tests, for example). 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetThemeProvider()) { 1516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetTextColor( 1517f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::Button::STATE_NORMAL, 1518f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) button->SetMinSize(gfx::Size()); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_context_menu_controller(this); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_drag_controller(this); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Image& favicon = model_->GetFavicon(node); 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicon.IsEmpty()) 1527f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, *favicon.ToImageSkia()); 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1529f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) button->SetImage(views::Button::STATE_NORMAL, GetDefaultFavicon()); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) button->SetMaxSize(gfx::Size(kMaxButtonWidth, 0)); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model, 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 1537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UpdateButtonsVisibility(); 1538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (parent != model->bookmark_bar_node()) { 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = parent->GetChild(index); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service(ProfileSyncServiceFactory:: 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInstance()->GetForProfile(browser_->profile())); 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!throbbing_view_ && sync_service && sync_service->FirstSetupInProgress()) 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(node, true); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node), index); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 1557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UpdateButtonsVisibility(); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopThrobbing(true); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to start throbbing again as the bookmark bubble can't be up at 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same time as the user reorders. 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (parent != model->bookmark_bar_node()) { 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < GetBookmarkButtonCount()); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* button = child_at(index); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(button); 1570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, button); 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model, 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 1577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (node == client_->managed_node()) { 1578f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The managed node may have its title updated. 1579f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetAccessibleName( 1580f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_->managed_node()->GetTitle()); 1581f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetText(client_->managed_node()->GetTitle()); 1582f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 1583f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1584f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1585f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (node->parent() != model->bookmark_bar_node()) { 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1589f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int index = model->bookmark_bar_node()->GetIndexOf(node); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, index); 1591f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::LabelButton* button = GetBookmarkButton(index); 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size old_pref = button->GetPreferredSize(); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size new_pref = button->GetPreferredSize(); 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_pref.width() != new_pref.width()) { 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button->visible()) { 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SchedulePaint(); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) { 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_->node() == node) { 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already showing for the specified node. 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* menu_button = GetMenuButtonForNode(node); 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!menu_button) 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_index = 0; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->bookmark_bar_node()) 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_index = GetFirstHiddenNodeIndex(); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->is_menu_showing = true; 1621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bookmark_drop_menu_ = new BookmarkMenuController( 1622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_, page_navigator_, GetWidget(), node, start_index, true); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->set_observer(this); 1624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bookmark_drop_menu_->RunMenuAt(this); 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StopShowFolderDropMenuTimer() { 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.InvalidateWeakPtrs(); 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StartShowFolderDropMenuTimer(const BookmarkNode* node) { 16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So that tests can run as fast as possible disable the delay during 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing. 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowDropFolderForNode(node); 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.InvalidateWeakPtrs(); 1639b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BookmarkBarView::ShowDropFolderForNode, 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.GetWeakPtr(), 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node), 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(views::GetMenuShowDelay())); 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::CalculateDropLocation(const DropTargetEvent& event, 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNodeData& data, 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation* location) { 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(model_); 1651b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(model_->loaded()); 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data.is_valid()); 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *location = DropLocation(); 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The drop event uses the screen coordinates while the child Views are 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // always laid out from left to right (even though they are rendered from 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-to-left on RTL locales). Thus, in order to make sure the drop 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coordinates calculation works, we mirror the event's X coordinate if the 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locale is RTL. 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mirrored_x = GetMirroredXInView(event.x()); 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int other_delta_x = mirrored_x - other_bookmarked_button_->x(); 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser_->profile(); 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible() && other_delta_x >= 0 && 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_delta_x < other_bookmarked_button_->width()) { 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is over 'other' folder. 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->button_type = DROP_OTHER_FOLDER; 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = true; 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!GetBookmarkButtonCount()) { 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No bookmarks, accept the drop. 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = 0; 1675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const BookmarkNode* node = data.GetFirstNode(model_, profile->GetPath()); 1676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int ops = node && client_->CanBeEditedByUser(node) ? 16770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ui::DragDropTypes::DRAG_MOVE : 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK; 16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location->operation = chrome::GetPreferredBookmarkDropOperation( 16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.source_operations(), ops); 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount() && 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarkButton(i)->visible() && !found; i++) { 1686f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) views::LabelButton* button = GetBookmarkButton(i); 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_x = mirrored_x - button->x(); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_w = button->width(); 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button_x < button_w) { 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_folder()) { 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button_x <= views::kDropBetweenPixels) { 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button_x < button_w - views::kDropBetweenPixels) { 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = true; 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i + 1; 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button_x < button_w / 2) { 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i + 1; 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_button_->visible()) { 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Are we over the overflow button? 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int overflow_delta_x = mirrored_x - overflow_button_->x(); 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_delta_x >= 0 && 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_delta_x < overflow_button_->width()) { 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is over overflow button. 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->button_type = DROP_OVERFLOW; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (overflow_delta_x < 0) { 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is after the last visible button but before overflow button; 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use the last visible index. 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!other_bookmarked_button_->visible() || 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mirrored_x < other_bookmarked_button_->x()) { 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is after the last visible button but before more recently 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bookmarked; use the last visible index. 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location->on) { 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = (location->button_type == DROP_OTHER_FOLDER) ? 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->other_node() : 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->bookmark_bar_node()->GetChild(location->index); 17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location->operation = chrome::GetBookmarkDropOperation( 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile, event, data, parent, parent->child_count()); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!location->operation && !data.has_single_url() && 17430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.GetFirstNode(model_, profile->GetPath()) == parent) { 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't open a menu if the node being dragged is the menu to open. 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = false; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch location->operation = chrome::GetBookmarkDropOperation( 17490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch profile, event, data, model_->bookmark_bar_node(), location->index); 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::WriteBookmarkDragData(const BookmarkNode* node, 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::OSExchangeData* data) { 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node && data); 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeData drag_data(node); 17570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch drag_data.Write(browser_->profile()->GetPath(), data); 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StartThrobbing(const BookmarkNode* node, 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool overflow_only) { 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!throbbing_view_); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine which visible button is showing the bookmark (or is an ancestor 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the bookmark). 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model_->bookmark_bar_node(); 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent_on_bb = node; 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (parent_on_bb) { 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = parent_on_bb->parent(); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == bbn) 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_on_bb = parent; 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent_on_bb) { 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = bbn->GetIndexOf(parent_on_bb); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= GetFirstHiddenNodeIndex()) { 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node is hidden, animate the overflow button. 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = overflow_button_; 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!overflow_only) { 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = static_cast<CustomButton*>(child_at(index)); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (client_->IsDescendantOfManagedNode(node)) { 1783f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) throbbing_view_ = managed_bookmarks_button_; 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!overflow_only) { 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = other_bookmarked_button_; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a large number so that the button continues to throb. 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (throbbing_view_) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StartThrobbing(std::numeric_limits<int>::max()); 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::CustomButton* BookmarkBarView::DetermineViewToThrobFromRemove( 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index) { 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model_->bookmark_bar_node(); 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* old_node = parent; 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index_on_bb = old_index; 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (old_node && old_node != bbn) { 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = old_node->parent(); 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == bbn) { 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_index_on_bb = bbn->GetIndexOf(old_node); 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_node = parent; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_node) { 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_index_on_bb >= GetFirstHiddenNodeIndex()) { 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node is hidden, animate the overflow button. 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_button_; 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<CustomButton*>(child_at(old_index_on_bb)); 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1814f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (client_->IsDescendantOfManagedNode(parent)) 1815f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return managed_bookmarks_button_; 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node wasn't on the bookmark bar, use the other bookmark button. 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other_bookmarked_button_; 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::UpdateColors() { 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't always have a theme provider (ui tests, for example). 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::ThemeProvider* theme_provider = GetThemeProvider(); 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!theme_provider) 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1825f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SkColor color = 18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT); 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) 1828f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetBookmarkButton(i)->SetTextColor(views::Button::STATE_NORMAL, color); 1829f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) other_bookmarked_button_->SetTextColor(views::Button::STATE_NORMAL, color); 1830f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetTextColor(views::Button::STATE_NORMAL, color); 18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (apps_page_shortcut_->visible()) 1832f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) apps_page_shortcut_->SetTextColor(views::Button::STATE_NORMAL, color); 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void BookmarkBarView::UpdateButtonsVisibility() { 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_other_children = !model_->other_node()->empty(); 1837f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool update_other = has_other_children != other_bookmarked_button_->visible(); 1838f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (update_other) { 1839f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) other_bookmarked_button_->SetVisible(has_other_children); 1840f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 1841f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1842f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1843f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool show_managed = !client_->managed_node()->empty() && 1844f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_->profile()->GetPrefs()->GetBoolean( 18451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmarks::prefs::kShowManagedBookmarksInBookmarkBar); 1846f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool update_managed = show_managed != managed_bookmarks_button_->visible(); 1847f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (update_managed) 1848f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetVisible(show_managed); 1849f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1850f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (update_other || update_managed) { 1851f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Layout(); 1852f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SchedulePaint(); 1853f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::UpdateBookmarksSeparatorVisibility() { 18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ash does not paint the bookmarks separator line because it looks odd on 18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the flat background. We keep it present for layout, but don't draw it. 18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmarks_separator_view_->SetVisible( 18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH && 1861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) other_bookmarked_button_->visible()); 18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BookmarkBarView::LayoutItems() { 1865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!parent()) 1866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = kLeftMargin; 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top_margin = IsDetached() ? kDetachedTopMargin : 0; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = top_margin; 18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = View::width() - kRightMargin - kLeftMargin; 187258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int height = chrome::kBookmarkBarHeight - kBottomMargin; 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int separator_margin = kSeparatorMargin; 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsDetached()) { 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double current_state = 1 - size_animation_->GetCurrentValue(); 1877eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch x += static_cast<int>(kNewtabHorizontalPadding * current_state); 187858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) y += (View::height() - chrome::kBookmarkBarHeight) / 2; 1879eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch width -= static_cast<int>(kNewtabHorizontalPadding * current_state); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_margin -= static_cast<int>(kSeparatorMargin * current_state); 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For the attached appearance, pin the content to the bottom of the bar 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when animating in/out, as shrinking its height instead looks weird. This 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also matches how we layout infobars. 188558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) y += View::height() - chrome::kBookmarkBarHeight; 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size other_bookmarked_pref = other_bookmarked_button_->visible() ? 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->GetPreferredSize() : gfx::Size(); 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size overflow_pref = overflow_button_->GetPreferredSize(); 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size bookmarks_separator_pref = 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_->GetPreferredSize(); 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size apps_page_shortcut_pref = apps_page_shortcut_->visible() ? 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_->GetPreferredSize() : gfx::Size(); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_x = width - overflow_pref.width() - kButtonPadding - 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_pref.width(); 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible()) 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_x -= other_bookmarked_pref.width() + kButtonPadding; 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next, layout out the buttons. Any buttons that are placed beyond the 1902f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // visible region are made invisible. 1903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start with the apps page shortcut button. 1905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (apps_page_shortcut_->visible()) { 1906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) apps_page_shortcut_->SetBounds(x, y, apps_page_shortcut_pref.width(), 1907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) height); 1908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) x += apps_page_shortcut_pref.width() + kButtonPadding; 1909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1911f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Then comes the managed bookmarks folder, if visible. 1912f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (managed_bookmarks_button_->visible()) { 1913f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Size managed_bookmarks_pref = managed_bookmarks_button_->visible() ? 1914f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->GetPreferredSize() : gfx::Size(); 1915f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) managed_bookmarks_button_->SetBounds(x, y, managed_bookmarks_pref.width(), 1916f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) height); 1917f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) x += managed_bookmarks_pref.width() + kButtonPadding; 1918f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1919f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Then go through the bookmark buttons. 1921b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (GetBookmarkButtonCount() == 0 && model_ && model_->loaded()) { 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pref = instructions_->GetPreferredSize(); 1923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) instructions_->SetBounds( 1924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x + kInstructionsPadding, y, 1925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::min(static_cast<int>(pref.width()), 1926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_x - x), 1927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) height); 1928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) instructions_->SetVisible(true); 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) instructions_->SetVisible(false); 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pref = child->GetPreferredSize(); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_x = x + pref.width() + kButtonPadding; 1936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) child->SetVisible(next_x < max_x); 1937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) child->SetBounds(x, y, pref.width(), height); 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = next_x; 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Layout the right side of the bar. 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool all_visible = (GetBookmarkButtonCount() == 0 || 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_at(GetBookmarkButtonCount() - 1)->visible()); 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Layout the right side buttons. 1947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) x = max_x + kButtonPadding; 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The overflow button. 1950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) overflow_button_->SetBounds(x, y, overflow_pref.width(), height); 1951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) overflow_button_->SetVisible(!all_visible); 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += overflow_pref.width(); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separator. 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmarks_separator_view_->visible()) { 1956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bookmarks_separator_view_->SetBounds(x, 1957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) y - top_margin, 1958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bookmarks_separator_pref.width(), 1959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) height + top_margin + kBottomMargin - 1960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) separator_margin); 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += bookmarks_separator_pref.width(); 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The other bookmarks button. 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible()) { 1967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) other_bookmarked_button_->SetBounds(x, y, other_bookmarked_pref.width(), 1968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) height); 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += other_bookmarked_pref.width() + kButtonPadding; 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BookmarkBarView::OnAppsPageShortcutVisibilityPrefChanged() { 19742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(apps_page_shortcut_); 1975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Only perform layout if required. 1976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool visible = chrome::ShouldShowAppsShortcutInBookmarkBar( 1977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_->profile(), browser_->host_desktop_type()); 1978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (apps_page_shortcut_->visible() == visible) 1979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_page_shortcut_->SetVisible(visible); 19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 19822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Layout(); 19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1984