bookmark_bar_view.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "apps/app_launcher.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_utils.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/defaults.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/view_ids.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_bar_instructions_view.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/event_utils.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/page_navigator.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/page_transition_types.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/animation/slide_animation.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_utils.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/os_exchange_data.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/text/text_elider.h" 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/theme_provider.h" 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/button_drag_utils.h" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h" 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_item_view.h" 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/drag_utils.h" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/metrics.h" 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_constants.h" 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/tooltip_manager.h" 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::PageNavigator; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::Referrer; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::DropTargetEvent; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using views::CustomButton; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::MenuButton; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::MenuItemView; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::View; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How much we want the bookmark bar to overlap the toolbar when in its 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'always shown' mode. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kToolbarOverlap = 3; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Margins around the content. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDetachedTopMargin = 1; // When attached, we use 0 and let the 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toolbar above serve as the margin. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBottomMargin = 2; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kLeftMargin = 1; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kRightMargin = 1; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char BookmarkBarView::kViewClassName[] = "BookmarkBarView"; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding between buttons. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kButtonPadding = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Icon to display when one isn't found for the page. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static gfx::ImageSkia* kDefaultFavicon = NULL; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Icon used for folders. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static gfx::ImageSkia* kFolderIcon = NULL; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Offset for where the menu is shown relative to the bottom of the 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkBarView. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMenuOffset = 3; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Color of the drop indicator. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const SkColor kDropIndicatorColor = SK_ColorBLACK; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Width of the drop indicator. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDropIndicatorWidth = 2; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Distance between the bottom of the bar and the separator. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorMargin = 1; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Width of the separator between the recently bookmarked button and the 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// overflow indicator. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorWidth = 4; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starting x-coordinate of the separator line within a separator. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSeparatorStartX = 2; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Left-padding for the instructional text. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kInstructionsPadding = 6; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tag for the 'Other bookmarks' button. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kOtherFolderButtonTag = 1; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kuan): change chrome::kNTPBookmarkBarHeight to this new height when 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// search_ntp replaces ntp4; for now, while both versions exist, this new height 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is only needed locally. 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kSearchNewTabBookmarkBarHeight = 40; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(kuan): change BookmarkBarView::kNewtabHorizontalPadding and 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BookmarkBarView::kNewtabVerticalPadding to these new values when search_ntp 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// replaces ntp4; for now, while both versions exist, these new values are only 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// needed locally. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kSearchNewTabHorizontalPadding = 2; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kSearchNewTabVerticalPadding = 5; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tag for the 'Apps Shortcut' button. 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kAppsShortcutButtonTag = 2; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To enable/disable BookmarkBar animations during testing. In production 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animations are enabled by default. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool animations_enabled = true; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BookmarkButtonBase ----------------------------------------------- 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Base class for text buttons used on the bookmark bar. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BookmarkButtonBase : public views::TextButton { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkButtonBase(views::ButtonListener* listener, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string16& title) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : TextButton(listener, title) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show_animation_.reset(new ui::SlideAnimation(this)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For some reason during testing the events generated by animating 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // throw off the test. So, don't animate while testing. 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show_animation_->Reset(1); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) show_animation_->Show(); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return e.type() == ui::ET_GESTURE_TAP || 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.type() == ui::ET_GESTURE_TAP_DOWN || 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_utils::IsPossibleDispositionEvent(e); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::SlideAnimation> show_animation_; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkButtonBase); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkButton ------------------------------------------------------------- 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Buttons used for the bookmarks on the bookmark bar. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BookmarkButton : public BookmarkButtonBase { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The internal view class name. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kViewClassName[]; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkButton(views::ButtonListener* listener, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkButtonBase(listener, title), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_(url), 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_(profile) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetTooltipText(const gfx::Point& p, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* tooltip) const OVERRIDE { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point location(p); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertPointToScreen(this, &location); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tooltip = BookmarkBarView::CreateToolTipForURLAndTitle( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location, url_, text(), profile_, GetWidget()->GetNativeView()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !tooltip->empty(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual const char* GetClassName() const OVERRIDE { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url_; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkButton); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char BookmarkButton::kViewClassName[] = "BookmarkButton"; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShortcutButton ------------------------------------------------------------- 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Buttons used for the shortcuts on the bookmark bar. 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShortcutButton : public BookmarkButtonBase { 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The internal view class name. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kViewClassName[]; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShortcutButton(views::ButtonListener* listener, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string16& title) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkButtonBase(listener, title) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual const char* GetClassName() const OVERRIDE { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kViewClassName; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ShortcutButton); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 257b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static 258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char ShortcutButton::kViewClassName[] = "ShortcutButton"; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkFolderButton ------------------------------------------------------- 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Buttons used for folders on the bookmark bar, including the 'other folders' 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// button. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkFolderButton : public views::MenuButton { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkFolderButton(views::ButtonListener* listener, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButtonListener* menu_button_listener, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool show_menu_marker) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : MenuButton(listener, title, menu_button_listener, show_menu_marker) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_animation_.reset(new ui::SlideAnimation(this)); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For some reason during testing the events generated by animating 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // throw off the test. So, don't animate while testing. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_animation_->Reset(1); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_animation_->Show(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetTooltipText(const gfx::Point& p, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* tooltip) const OVERRIDE { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text_size_.width() > GetTextBounds().width()) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tooltip = text_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !tooltip->empty(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Left clicks and taps should show the menu contents and right clicks 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should show the context menu. They should not trigger the opening of 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underlying urls. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (e.type() == ui::ET_GESTURE_TAP || 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (e.IsMouseEvent() && (e.flags() & 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)))) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (e.IsMouseEvent()) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ui::DispositionFromEventFlags(e.flags()) != CURRENT_TAB; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton::PaintButton(canvas, views::MenuButton::PB_NORMAL); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::SlideAnimation> show_animation_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkFolderButton); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OverFlowButton (chevron) -------------------------------------------------- 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OverFlowButton : public views::MenuButton { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit OverFlowButton(BookmarkBarView* owner) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MenuButton(NULL, string16(), owner, false), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_(owner) {} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMousePressed(const ui::MouseEvent& e) OVERRIDE { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_->StopThrobbing(true); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return views::MenuButton::OnMousePressed(e); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBarView* owner_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OverFlowButton); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RecordAppLaunch(Profile* profile, GURL url) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile->GetExtensionService()); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const extensions::Extension* extension = 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile->GetExtensionService()->GetInstalledApp(url); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!extension) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppLauncherHandler::RecordAppLaunchType( 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::APP_LAUNCH_BOOKMARK_BAR, 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension->GetType()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetNewtabHorizontalPadding() { 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return chrome::IsInstantExtendedAPIEnabled() 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ? kSearchNewTabHorizontalPadding 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkBarView::kNewtabHorizontalPadding; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetNewtabVerticalPadding() { 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return chrome::IsInstantExtendedAPIEnabled() 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ? kSearchNewTabVerticalPadding 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BookmarkBarView::kNewtabVerticalPadding; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DropLocation --------------------------------------------------------------- 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct BookmarkBarView::DropLocation { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation() 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : index(-1), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation(ui::DragDropTypes::DRAG_NONE), 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on(false), 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_type(DROP_BOOKMARK) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Equals(const DropLocation& other) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((other.index == index) && (other.on == on) && 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (other.button_type == button_type)); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Index into the model the drop is over. This is relative to the root node. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drop constants. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int operation; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, the user is dropping on a folder. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool on; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Type of button. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropButtonType button_type; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DropInfo ------------------------------------------------------------------- 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks drops on the BookmarkBarView. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct BookmarkBarView::DropInfo { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropInfo() 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : valid(false), 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_menu_showing(false), 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x(0), 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y(0) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the data is valid. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool valid; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, the menu is being shown. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_menu_showing; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Coordinates of the drag (in terms of the BookmarkBarView). 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DropData for the drop. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeData data; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation location; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ButtonSeparatorView -------------------------------------------------------- 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkBarView::ButtonSeparatorView : public views::View { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ButtonSeparatorView() {} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ButtonSeparatorView() {} 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::PaintVerticalDivider( 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas, kSeparatorStartX, height(), 1, 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::kEdgeDividerColor, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView::kMiddleDividerColor, 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR)); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Size GetPreferredSize() OVERRIDE { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We get the full height of the bookmark bar, so that the height returned 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here doesn't matter. 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(kSeparatorWidth, 1); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_SEPARATOR); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_SEPARATOR; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ButtonSeparatorView); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkBarView ------------------------------------------------------------ 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int BookmarkBarView::kMaxButtonWidth = 150; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int BookmarkBarView::kNewtabHorizontalPadding = 8; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int BookmarkBarView::kNewtabVerticalPadding = 12; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const gfx::ImageSkia& GetDefaultFavicon() { 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!kDefaultFavicon) { 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDefaultFavicon = rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *kDefaultFavicon; 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const gfx::ImageSkia& GetFolderIcon() { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!kFolderIcon) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kFolderIcon = rb.GetImageSkiaNamed(IDR_BOOKMARK_BAR_FOLDER); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *kFolderIcon; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarView::BookmarkBarView(Browser* browser, BrowserView* browser_view) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : page_navigator_(NULL), 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_(NULL), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_(NULL), 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_(NULL), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_(NULL), 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_(NULL), 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) show_folder_method_factory_(this), 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_(NULL), 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_(NULL), 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_(NULL), 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_(browser_view), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobar_visible_(false), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_(NULL), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_(BookmarkBar::SHOW), 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animating_detached_(false) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_id(VIEW_ID_BOOKMARK_BAR); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Reset(1); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkBarView::~BookmarkBarView() { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible for the menu to outlive us, reset the observer to make sure 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it doesn't have a reference to us. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_menu_) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->set_observer(NULL); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->SetPageNavigator(NULL); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_menu_.get()) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_->SetPageNavigator(NULL); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::DisableAnimationsForTesting(bool disabled) { 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animations_enabled = !disabled; 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_ = navigator; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_menu_) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->SetPageNavigator(navigator); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_menu_.get()) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_->SetPageNavigator(navigator); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::SetBookmarkBarState( 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::State state, 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkBar::AnimateChangeType animate_type) { 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE && 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) animations_enabled) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animating_detached_ = (state == BookmarkBar::DETACHED || 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ == BookmarkBar::DETACHED); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == BookmarkBar::SHOW) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Show(); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Hide(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->Reset(state == BookmarkBar::SHOW ? 1 : 0); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ = state; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetToolbarOverlap(bool return_max) const { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When not detached, always overlap by the full amount. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (return_max || bookmark_bar_state_ != BookmarkBar::DETACHED) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kToolbarOverlap; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When detached with an infobar, overlap by 0 whenever the infobar 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is above us (i.e. when we're detached), since drawing over the infobar 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // looks weird. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsDetached() && infobar_visible_) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When detached with no infobar, animate the overlap between the attached and 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detached states. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(kToolbarOverlap * size_animation_->GetCurrentValue()); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::is_animating() { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_animation_->is_animating(); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BookmarkNode* BookmarkBarView::GetNodeForButtonAtModelIndex( 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& loc, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* model_start_index) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *model_start_index = 0; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point adjusted_loc(GetMirroredXInView(loc.x()), loc.y()); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the buttons first. 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!child->visible()) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child->bounds().Contains(adjusted_loc)) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node()->GetChild(i); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then the overflow button. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_button_->visible() && 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->bounds().Contains(adjusted_loc)) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *model_start_index = GetFirstHiddenNodeIndex(); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->bookmark_bar_node(); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And finally the other folder. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible() && 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->bounds().Contains(adjusted_loc)) { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->other_node(); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuButton* BookmarkBarView::GetMenuButtonForNode( 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->other_node()) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other_bookmarked_button_; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->bookmark_bar_node()) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_button_; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->bookmark_bar_node()->GetIndexOf(node); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == -1 || !node->is_folder()) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<views::MenuButton*>(child_at(index)); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::GetAnchorPositionForButton( 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* button, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuItemView::AnchorPosition* anchor) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button == other_bookmarked_button_ || button == overflow_button_) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *anchor = MenuItemView::TOPRIGHT; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *anchor = MenuItemView::TOPLEFT; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetMenu() { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_menu_ ? bookmark_menu_->menu() : NULL; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetContextMenu() { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_menu_ ? bookmark_menu_->context_menu() : NULL; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::MenuItemView* BookmarkBarView::GetDropMenu() { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StopThrobbing(bool immediate) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!throbbing_view_) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If not immediate, cycle through 2 more complete cycles. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StartThrobbing(immediate ? 0 : 4); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = NULL; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 BookmarkBarView::CreateToolTipForURLAndTitle( 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& screen_loc, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeView context) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_width = views::TooltipManager::GetMaxWidth(screen_loc.x(), 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) screen_loc.y(), 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Font tt_font = views::TooltipManager::GetDefaultFont(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 result; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First the title. 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title.empty()) { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 localized_title = title; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::AdjustStringForLocaleDirection(&localized_title); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(ui::ElideText(localized_title, tt_font, max_width, 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ELIDE_AT_END)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only show the URL if the url and title differ. 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (title != UTF8ToUTF16(url.spec())) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.empty()) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back('\n'); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to explicitly specify the directionality of the URL's text to 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure it is treated as an LTR string when the context is RTL. For 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // example, the URL "http://www.yahoo.com/" appears as 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "/http://www.yahoo.com" when rendered, as is, in an RTL context since 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Unicode BiDi algorithm puts certain characters on the left by 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default. 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string languages = profile->GetPrefs()->GetString( 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs::kAcceptLanguages); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 elided_url(ui::ElideUrl(url, tt_font, max_width, languages)); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(elided_url); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::IsDetached() const { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (bookmark_bar_state_ == BookmarkBar::DETACHED) || 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (animating_detached_ && size_animation_->is_animating()); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double BookmarkBarView::GetAnimationValue() const { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_animation_->GetCurrentValue(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetToolbarOverlap() const { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetToolbarOverlap(false); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size BookmarkBarView::GetPreferredSize() { 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LayoutItems(true); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size BookmarkBarView::GetMinimumSize() { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The minimum width of the bookmark bar should at least contain the overflow 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // button, by which one can access all the Bookmark Bar items, and the "Other 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bookmarks" folder, along with appropriate margins and button padding. 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = kLeftMargin; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double current_state = 1 - size_animation_->GetCurrentValue(); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width += 2 * static_cast<int>(GetNewtabHorizontalPadding() * current_state); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size other_bookmarked_pref; 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (other_bookmarked_button_->visible()) 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other_bookmarked_pref = other_bookmarked_button_->GetPreferredSize(); 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size overflow_pref; 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overflow_button_->visible()) 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overflow_pref = overflow_button_->GetPreferredSize(); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size bookmarks_separator_pref; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bookmarks_separator_view_->visible()) 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmarks_separator_pref = bookmarks_separator_view_->GetPreferredSize(); 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size apps_page_shortcut_pref; 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (apps_page_shortcut_->visible()) 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_pref = apps_page_shortcut_->GetPreferredSize(); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width += other_bookmarked_pref.width() + kButtonPadding + 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_pref.width() + kButtonPadding + 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_pref.width() + kButtonPadding + 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_pref.width(); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(width, browser_defaults::kBookmarkBarHeight); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::Layout() { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutItems(false); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ViewHierarchyChanged(bool is_add, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* parent, 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_add && child == this) { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may get inserted into a hierarchy with a profile - this typically 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs when the bar's contents get populated fast enough that the 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buttons are created before the bar is attached to a frame. 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (height() > 0) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only layout while parented. When we become parented, if our bounds 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // haven't changed, OnBoundsChanged() won't get invoked and we won't 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layout. Therefore we always force a layout when added. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::PaintChildren(gfx::Canvas* canvas) { 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View::PaintChildren(canvas); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_.get() && drop_info_->valid && 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.operation != 0 && drop_info_->location.index != -1 && 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.button_type != DROP_OVERFLOW && 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !drop_info_->location.on) { 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = drop_info_->location.index; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index <= GetBookmarkButtonCount()); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = 0; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = 0; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h = height(); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == GetBookmarkButtonCount()) { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index == 0) { 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x = kLeftMargin; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = GetBookmarkButton(index - 1)->x() + 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarkButton(index - 1)->width(); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = GetBookmarkButton(index)->x(); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetBookmarkButtonCount() > 0 && GetBookmarkButton(0)->visible()) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = GetBookmarkButton(0)->y(); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = GetBookmarkButton(0)->height(); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the drop indicator is painted directly onto the canvas, we must 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure it is painted in the right location if the locale is RTL. 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kDropIndicatorWidth, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indicator_bounds.set_x(GetMirroredXForRect(indicator_bounds)); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky/glen): make me pretty! 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->FillRect(indicator_bounds, kDropIndicatorColor); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::GetDropFormats( 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* formats, 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { 785b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_ || !model_->loaded()) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *formats = ui::OSExchangeData::URL; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) custom_formats->insert(BookmarkNodeData::GetBookmarkCustomFormat()); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::AreDropTypesRequired() { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::CanDrop(const ui::OSExchangeData& data) { 797b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_ || !model_->loaded() || 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !browser_->profile()->GetPrefs()->GetBoolean( 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs::kEditBookmarksEnabled)) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get()) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(new DropInfo()); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only accept drops of 1 node, which is the case for all data dragged from 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bookmark bar and menus. 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->data.Read(data) && drop_info_->data.size() == 1; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnDragEntered(const DropTargetEvent& event) { 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::OnDragUpdated(const DropTargetEvent& event) { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get()) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->valid && 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (drop_info_->x == event.x() && drop_info_->y == event.y())) { 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The location of the mouse didn't change, return the last operation. 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->x = event.x(); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->y = event.y(); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation location; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateDropLocation(event, drop_info_->data, &location); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->valid && drop_info_->location.Equals(location)) { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The position we're going to drop didn't change, return the last drag 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation we calculated. Copy of the operation in case it changed. 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location.operation = location.operation; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): Optimize paint region. 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->location = location; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->valid = true; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->is_menu_showing) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->is_menu_showing = false; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location.on || location.button_type == DROP_OVERFLOW || 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location.button_type == DROP_OTHER_FOLDER) { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location.button_type == DROP_OTHER_FOLDER) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (location.button_type == DROP_OVERFLOW) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node(); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(location.index); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartShowFolderDropMenuTimer(node); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return drop_info_->location.operation; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnDragExited() { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: we don't hide the menu on exit as it's possible the user moved the 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mouse over the menu, which triggers an exit on us. 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->valid = false; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->location.index != -1) { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): optimize the paint region. 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::OnPerformDrop(const DropTargetEvent& event) { 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopShowFolderDropMenuTimer(); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!drop_info_.get() || !drop_info_->location.operation) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* root = 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (drop_info_->location.button_type == DROP_OTHER_FOLDER) ? 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->other_node() : model_->bookmark_bar_node(); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = drop_info_->location.index; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): optimize the SchedulePaint region. 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent_node; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (drop_info_->location.button_type == DROP_OTHER_FOLDER) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = parent_node->child_count(); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (drop_info_->location.on) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root->GetChild(index); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = parent_node->child_count(); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_node = root; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNodeData data = drop_info_->data; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data.is_valid()); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_.reset(); 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::DropBookmarks(browser_->profile(), data, parent_node, index); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowContextMenu(const gfx::Point& p, 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_mouse_gesture) { 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowContextMenuForView(this, p); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnThemeChanged() { 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 923b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* BookmarkBarView::GetClassName() const { 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::GetAccessibleState(ui::AccessibleViewState* state) { 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_TOOLBAR; 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::AnimationProgressed(const ui::Animation* animation) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |browser_view_| can be NULL during tests. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_view_) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_->ToolbarSizeChanged(true); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::AnimationEnded(const ui::Animation* animation) { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |browser_view_| can be NULL during tests. 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_view_) { 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_view_->ToolbarSizeChanged(false); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkMenuDeleted(BookmarkMenuController* controller) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller == bookmark_menu_) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_ = NULL; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (controller == bookmark_drop_menu_) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_ = NULL; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowImportDialog() { 954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 install_time = 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_browser_process->local_state()->GetInt64(prefs::kInstallDate); 956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 time_from_install = base::Time::Now().ToTimeT() - install_time; 957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (bookmark_bar_state_ == BookmarkBar::SHOW) 958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("Import_ShowDlg.FromBookmarkBarView", 959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_from_install); 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (bookmark_bar_state_ == BookmarkBar::DETACHED) { 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("Import_ShowDlg.FromFloatingBookmarkBarView", 962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_from_install); 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowImportDialog(browser_); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::OnBookmarkBubbleShown(const GURL& url) { 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopThrobbing(true); 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* node = model_->GetMostRecentlyAddedNodeForURL(url); 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!node) 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // Generally shouldn't happen. 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartThrobbing(node, false); 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::OnBookmarkBubbleHidden() { 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopThrobbing(false); 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::Loaded(BookmarkModel* model, bool ids_reassigned) { 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be no buttons. If non-zero it means Load was invoked more than 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // once, or we didn't properly clear things. Either of which shouldn't happen. 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, GetBookmarkButtonCount()); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node(); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a button for each of the children on the bookmark bar. 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, child_count = node->child_count(); i < child_count; ++i) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(model_->other_node()); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetAccessibleName(model_->other_node()->GetTitle()); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetText(model_->other_node()->GetTitle()); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetEnabled(true); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) { 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In normal shutdown The bookmark model should never be deleted before us. 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When X exits suddenly though, it can happen, This code exists 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to check for regressions in shutdown code and not crash. 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do minimal cleanup, presumably we'll be deleted shortly. 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_ = NULL; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeMoved(BookmarkModel* model, 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* old_parent, 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* new_parent, 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_index) { 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_throbbing = throbbing_view_ && 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ == DetermineViewToThrobFromRemove(old_parent, old_index); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_throbbing) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StopThrobbing(); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeRemovedImpl(model, old_parent, old_index); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeAddedImpl(model, new_parent, new_index); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (was_throbbing) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(new_parent->GetChild(new_index), false); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model, 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeAddedImpl(model, parent, index); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model, 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index, 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close the menu if the menu is showing for the deleted node. 10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bookmark_menu_ && bookmark_menu_->node() == node) 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_menu_->Cancel(); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeRemovedImpl(model, parent, old_index); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BookmarkBarView::BookmarkAllNodesRemoved(BookmarkModel* model) { 1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UpdateOtherBookmarksVisibility(); 1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StopThrobbing(true); 1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove the existing buttons. 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (GetBookmarkButtonCount()) { 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete GetBookmarkButton(0); 1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Layout(); 1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SchedulePaint(); 1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model, 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeChangedImpl(model, node); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChildrenReordered(BookmarkModel* model, 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node != model_->bookmark_bar_node()) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We only care about reordering of the bookmark bar node. 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the existing buttons. 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (GetBookmarkButtonCount()) { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* button = child_at(0); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(button); 1071b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, button); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the new buttons. 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0, child_count = node->child_count(); i < child_count; ++i) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeFaviconChanged(BookmarkModel* model, 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeChangedImpl(model, node); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::WriteDragDataForView(View* sender, 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& press_pt, 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::OSExchangeData* data) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordAction(UserMetricsAction("BookmarkBar_DragButton")); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::TextButton* button = GetBookmarkButton(i); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<gfx::Canvas> canvas( 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GetCanvasForDragImage(button->GetWidget(), button->size())); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->PaintButton(canvas.get(), views::TextButton::PB_FOR_DRAG); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_utils::SetDragImageOnDataObject(*canvas, button->size(), 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) press_pt.OffsetFromOrigin(), 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteBookmarkDragData(model_->bookmark_bar_node()->GetChild(i), data); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetDragOperationsForView(View* sender, 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p) { 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_animation_->is_animating() || 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (size_animation_->GetCurrentValue() == 0 && 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar_state_ != BookmarkBar::DETACHED)) { 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't let the user drag while animating open or we're closed (and not 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detached, when detached size_animation_ is always 0). This typically is 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only hit if the user does something to inadvertently trigger DnD such as 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pressing the mouse and hitting control-b. 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::GetBookmarkDragOperation( 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->profile(), model_->bookmark_bar_node()->GetChild(i)); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::DragDropTypes::DRAG_NONE; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarkBarView::CanStartDragForView(views::View* sender, 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& press_pt, 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& p) { 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we have not moved enough horizontally but we have moved downward 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vertically - downward drag. 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Vector2d move_offset = p - press_pt; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Vector2d horizontal_offset(move_offset.x(), 0); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!View::ExceededDragThreshold(horizontal_offset) && move_offset.y() > 0) { 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender == GetBookmarkButton(i)) { 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the folder button was dragged, show the menu instead. 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node && node->is_folder()) { 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* menu_button = 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<views::MenuButton*>(sender); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_button->Activate(); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::OnMenuButtonClicked(views::View* view, 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_index = 0; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view == other_bookmarked_button_) { 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (view == overflow_button_) { 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node(); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_index = GetFirstHiddenNodeIndex(); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_index = GetIndexOf(view); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, button_index); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(button_index); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::RecordBookmarkFolderOpen(GetBookmarkLaunchLocation()); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_ = new BookmarkMenuController(browser_, 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_, GetWidget(), node, start_index); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->set_observer(this); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_menu_->RunMenuAt(this, false); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ButtonPressed(views::Button* sender, 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Event& event) { 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition disposition_from_event_flags = 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::DispositionFromEventFlags(event.flags()); 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sender->tag() == kAppsShortcutButtonTag) { 11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OpenURLParams params(GURL(chrome::kChromeUIAppsURL), 11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Referrer(), 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition_from_event_flags, 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PAGE_TRANSITION_AUTO_BOOKMARK, 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) page_navigator_->OpenURL(params); 11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::RecordAppsPageOpen(GetBookmarkLaunchLocation()); 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node; 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->tag() == kOtherFolderButtonTag) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->other_node(); 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = GetIndexOf(sender); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, index); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = model_->bookmark_bar_node()->GetChild(index); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_navigator_); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunch(browser_->profile(), node->url()); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenURLParams params( 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node->url(), Referrer(), disposition_from_event_flags, 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_AUTO_BOOKMARK, false); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_->OpenURL(params); 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::OpenAll(GetWidget()->GetNativeWindow(), page_navigator_, node, 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition_from_event_flags, browser_->profile()); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::RecordBookmarkLaunch(GetBookmarkLaunchLocation()); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowContextMenuForView(views::View* source, 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) { 1221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model_->loaded()) { 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't do anything if the model isn't loaded. 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = NULL; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source == other_bookmarked_button_) { 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->other_node(); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do this so the user can open all bookmarks. BookmarkContextMenu makes 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sure the user can't edit/delete the node in this case. 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(parent); 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (source != this && source != apps_page_shortcut_) { 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // User clicked on one of the bookmark buttons, find which one they 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // clicked on, except for the apps page shortcut, which must behave as if 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the user clicked on the bookmark bar background. 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bookmark_button_index = GetIndexOf(source); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bookmark_button_index != -1 && 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_button_index < GetBookmarkButtonCount()); 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->bookmark_bar_node()->GetChild(bookmark_button_index); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(node); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = node->parent(); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = model_->bookmark_bar_node(); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodes.push_back(parent); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser_->profile(); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool close_on_remove = 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent == BookmarkModelFactory::GetForProfile(profile)->other_node()) && 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent->child_count() == 1); 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_.reset(new BookmarkContextMenu( 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetWidget(), browser_, profile, 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->tab_strip_model()->GetActiveWebContents(), 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent, nodes, close_on_remove)); 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_->RunMenuAt(point); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::Init() { 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that at this point we're not in a hierarchy so GetThemeProvider() will 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return NULL. When we're inserted into a hierarchy, we'll call 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UpdateColors(), which will set the appropriate colors for all the objects 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // added in this function. 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Child views are traversed in the order they are added. Make sure the order 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they are added matches the visual order. 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_ = CreateOverflowButton(); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(overflow_button_); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_ = CreateOtherBookmarkedButton(); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll re-enable when the model is loaded. 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetEnabled(false); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(other_bookmarked_button_); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_ = CreateAppsPageShortcutButton(); 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddChildView(apps_page_shortcut_); 12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); 12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_pref_registrar_.Add( 12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs::kShowAppsShortcutInBookmarkBar, 1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&BookmarkBarView::OnAppsPageShortcutVisibilityPrefChanged, 1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_page_shortcut_->SetVisible( 1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::ShouldShowAppsShortcutInBookmarkBar(browser_->profile())); 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_ = new ButtonSeparatorView(); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(bookmarks_separator_view_); 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_ = new BookmarkBarInstructionsView(this); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(instructions_); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_context_menu_controller(this); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_.reset(new ui::SlideAnimation(this)); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model_ = BookmarkModelFactory::GetForProfile(browser_->profile()); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) { 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 1299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (model_->loaded()) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Loaded(model_, false); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // else case: we'll receive notification back from the BookmarkModel when 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // done loading, then we'll populate the bar. 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The first check for the app launcher is asynchronous, run it now. 1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps::GetIsAppLauncherEnabled( 1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&BookmarkBarView::OnAppLauncherEnabledCompleted, 1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetBookmarkButtonCount() { 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We contain four non-bookmark button views: other bookmarks, bookmarks 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // separator, chevrons (for overflow), apps page, and the instruction label. 13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return child_count() - 5; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::TextButton* BookmarkBarView::GetBookmarkButton(int index) { 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < GetBookmarkButtonCount()); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<views::TextButton*>(child_at(index)); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bookmark_utils::BookmarkLaunchLocation 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkBarView::GetBookmarkLaunchLocation() const { 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IsDetached() ? bookmark_utils::LAUNCH_DETACHED_BAR : 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_utils::LAUNCH_ATTACHED_BAR; 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BookmarkBarView::GetFirstHiddenNodeIndex() { 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int bb_count = GetBookmarkButtonCount(); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bb_count; ++i) { 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetBookmarkButton(i)->visible()) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bb_count; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Title is set in Loaded. 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MenuButton* button = new BookmarkFolderButton(this, string16(), this, false); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_id(VIEW_ID_OTHER_BOOKMARKS); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetIcon(GetFolderIcon()); 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_context_menu_controller(this); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_tag(kOtherFolderButtonTag); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MenuButton* BookmarkBarView::CreateOverflowButton() { 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuButton* button = new OverFlowButton(this); 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetIcon(*rb.GetImageSkiaNamed(IDR_BOOKMARK_BAR_CHEVRONS)); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The overflow button's image contains an arrow and therefore it is a 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // direction sensitive image and we need to flip it if the UI layout is 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-to-left. 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // By default, menu buttons are not flipped because they generally contain 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // text and flipping the gfx::Canvas object will break text rendering. Since 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the overflow button does not contain text, we can safely flip it. 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->EnableCanvasFlippingForRTLUI(true); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make visible as necessary. 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetVisible(false); 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set accessibility name. 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetAccessibleName( 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS_CHEVRON)); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkButton* button = new BookmarkButton( 13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, node->url(), node->GetTitle(), browser_->profile()); 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* button = new BookmarkFolderButton( 13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, node->GetTitle(), this, false); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetIcon(GetFolderIcon()); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button; 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)views::TextButton* BookmarkBarView::CreateAppsPageShortcutButton() { 13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::TextButton* button = new ShortcutButton( 13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME)); 13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->SetTooltipText(l10n_util::GetStringUTF16( 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_BOOKMARK_BAR_APPS_SHORTCUT_TOOLTIP)); 13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_id(VIEW_ID_BOOKMARK_BAR_ELEMENT); 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) button->SetIcon(*rb.GetImageSkiaNamed(IDR_BOOKMARK_BAR_APPS_SHORTCUT)); 13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_context_menu_controller(this); 13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button->set_tag(kAppsShortcutButtonTag); 13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return button; 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ConfigureButton(const BookmarkNode* node, 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::TextButton* button) { 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetText(node->GetTitle()); 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetAccessibleName(node->GetTitle()); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_id(VIEW_ID_BOOKMARK_BAR_ELEMENT); 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't always have a theme provider (ui tests, for example). 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetThemeProvider()) { 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetEnabledColor(GetThemeProvider()->GetColor( 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThemeProperties::COLOR_BOOKMARK_TEXT)); 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->ClearMaxTextSize(); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_context_menu_controller(this); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_drag_controller(this); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_url()) { 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Image& favicon = model_->GetFavicon(node); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicon.IsEmpty()) 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SetIcon(*favicon.ToImageSkia()); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) button->SetIcon(GetDefaultFavicon()); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->set_max_width(kMaxButtonWidth); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent != model_->bookmark_bar_node()) { 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index <= GetBookmarkButtonCount()); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = parent->GetChild(index); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service(ProfileSyncServiceFactory:: 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInstance()->GetForProfile(browser_->profile())); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!throbbing_view_ && sync_service && sync_service->FirstSetupInProgress()) 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartThrobbing(node, true); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(CreateBookmarkButton(node), index); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateColors(); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateOtherBookmarksVisibility(); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopThrobbing(true); 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to start throbbing again as the bookmark bubble can't be up at 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same time as the user reorders. 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent != model_->bookmark_bar_node()) { 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index >= 0 && index < GetBookmarkButtonCount()); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* button = child_at(index); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(button); 1457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, button); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model, 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node) { 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->parent() != model_->bookmark_bar_node()) { 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about nodes on the bookmark bar. 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = model_->bookmark_bar_node()->GetIndexOf(node); 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, index); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::TextButton* button = GetBookmarkButton(index); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size old_pref = button->GetPreferredSize(); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConfigureButton(node, button); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size new_pref = button->GetPreferredSize(); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_pref.width() != new_pref.width()) { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button->visible()) { 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button->SchedulePaint(); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_) { 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_drop_menu_->node() == node) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already showing for the specified node. 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->Cancel(); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* menu_button = GetMenuButtonForNode(node); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!menu_button) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_index = 0; 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == model_->bookmark_bar_node()) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_index = GetFirstHiddenNodeIndex(); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drop_info_->is_menu_showing = true; 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_ = new BookmarkMenuController(browser_, 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_navigator_, GetWidget(), node, start_index); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->set_observer(this); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_drop_menu_->RunMenuAt(this, true); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StopShowFolderDropMenuTimer() { 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.InvalidateWeakPtrs(); 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StartShowFolderDropMenuTimer(const BookmarkNode* node) { 15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!animations_enabled) { 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So that tests can run as fast as possible disable the delay during 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing. 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowDropFolderForNode(node); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.InvalidateWeakPtrs(); 1518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BookmarkBarView::ShowDropFolderForNode, 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_folder_method_factory_.GetWeakPtr(), 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node), 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(views::GetMenuShowDelay())); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::CalculateDropLocation(const DropTargetEvent& event, 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNodeData& data, 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropLocation* location) { 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(model_); 1530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(model_->loaded()); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data.is_valid()); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *location = DropLocation(); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The drop event uses the screen coordinates while the child Views are 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // always laid out from left to right (even though they are rendered from 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-to-left on RTL locales). Thus, in order to make sure the drop 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coordinates calculation works, we mirror the event's X coordinate if the 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locale is RTL. 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mirrored_x = GetMirroredXInView(event.x()); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int other_delta_x = mirrored_x - other_bookmarked_button_->x(); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser_->profile(); 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible() && other_delta_x >= 0 && 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_delta_x < other_bookmarked_button_->width()) { 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is over 'other' folder. 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->button_type = DROP_OTHER_FOLDER; 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = true; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!GetBookmarkButtonCount()) { 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No bookmarks, accept the drop. 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = 0; 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ops = data.GetFirstNode(profile) ? ui::DragDropTypes::DRAG_MOVE : 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK; 15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location->operation = chrome::GetPreferredBookmarkDropOperation( 15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.source_operations(), ops); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount() && 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarkButton(i)->visible() && !found; i++) { 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::TextButton* button = GetBookmarkButton(i); 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_x = mirrored_x - button->x(); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int button_w = button->width(); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button_x < button_w) { 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->is_folder()) { 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (button_x <= views::kDropBetweenPixels) { 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button_x < button_w - views::kDropBetweenPixels) { 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = true; 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i + 1; 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (button_x < button_w / 2) { 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i; 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = i + 1; 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_button_->visible()) { 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Are we over the overflow button? 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int overflow_delta_x = mirrored_x - overflow_button_->x(); 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (overflow_delta_x >= 0 && 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_delta_x < overflow_button_->width()) { 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is over overflow button. 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->button_type = DROP_OVERFLOW; 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (overflow_delta_x < 0) { 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is after the last visible button but before overflow button; 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use the last visible index. 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!other_bookmarked_button_->visible() || 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mirrored_x < other_bookmarked_button_->x()) { 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mouse is after the last visible button but before more recently 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bookmarked; use the last visible index. 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->index = GetFirstHiddenNodeIndex(); 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location->on) { 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = (location->button_type == DROP_OTHER_FOLDER) ? 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->other_node() : 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->bookmark_bar_node()->GetChild(location->index); 16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location->operation = chrome::GetBookmarkDropOperation( 16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile, event, data, parent, parent->child_count()); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!location->operation && !data.has_single_url() && 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.GetFirstNode(profile) == parent) { 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't open a menu if the node being dragged is the menu to open. 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) location->on = false; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location->operation = chrome::GetBookmarkDropOperation(profile, event, 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, model_->bookmark_bar_node(), location->index); 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::WriteBookmarkDragData(const BookmarkNode* node, 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::OSExchangeData* data) { 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node && data); 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkNodeData drag_data(node); 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drag_data.Write(browser_->profile(), data); 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::StartThrobbing(const BookmarkNode* node, 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool overflow_only) { 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!throbbing_view_); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine which visible button is showing the bookmark (or is an ancestor 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the bookmark). 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model_->bookmark_bar_node(); 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent_on_bb = node; 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (parent_on_bb) { 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = parent_on_bb->parent(); 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == bbn) 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_on_bb = parent; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent_on_bb) { 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = bbn->GetIndexOf(parent_on_bb); 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= GetFirstHiddenNodeIndex()) { 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node is hidden, animate the overflow button. 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = overflow_button_; 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!overflow_only) { 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = static_cast<CustomButton*>(child_at(index)); 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!overflow_only) { 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_ = other_bookmarked_button_; 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a large number so that the button continues to throb. 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (throbbing_view_) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throbbing_view_->StartThrobbing(std::numeric_limits<int>::max()); 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::CustomButton* BookmarkBarView::DetermineViewToThrobFromRemove( 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent, 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index) { 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model_->bookmark_bar_node(); 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* old_node = parent; 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_index_on_bb = old_index; 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (old_node && old_node != bbn) { 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = old_node->parent(); 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == bbn) { 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_index_on_bb = bbn->GetIndexOf(old_node); 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_node = parent; 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_node) { 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_index_on_bb >= GetFirstHiddenNodeIndex()) { 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node is hidden, animate the overflow button. 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overflow_button_; 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<CustomButton*>(child_at(old_index_on_bb)); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Node wasn't on the bookmark bar, use the other bookmark button. 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return other_bookmarked_button_; 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::UpdateColors() { 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't always have a theme provider (ui tests, for example). 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::ThemeProvider* theme_provider = GetThemeProvider(); 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!theme_provider) 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor text_color = 16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT); 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarkButton(i)->SetEnabledColor(text_color); 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button()->SetEnabledColor(text_color); 17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (apps_page_shortcut_->visible()) 17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_->SetEnabledColor(text_color); 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkBarView::UpdateOtherBookmarksVisibility() { 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_other_children = !model_->other_node()->empty(); 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_other_children == other_bookmarked_button_->visible()) 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetVisible(has_other_children); 17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkBarView::UpdateBookmarksSeparatorVisibility() { 17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ash does not paint the bookmarks separator line because it looks odd on 17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the flat background. We keep it present for layout, but don't draw it. 17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmarks_separator_view_->SetVisible( 17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH && 1722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) other_bookmarked_button_->visible()); 17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) { 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size prefsize; 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parent() && !compute_bounds_only) 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefsize; 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = kLeftMargin; 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top_margin = IsDetached() ? kDetachedTopMargin : 0; 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y = top_margin; 17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = View::width() - kRightMargin - kLeftMargin; 17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int height = browser_defaults::kBookmarkBarHeight - kBottomMargin; 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int separator_margin = kSeparatorMargin; 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsDetached()) { 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double current_state = 1 - size_animation_->GetCurrentValue(); 17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x += static_cast<int>(GetNewtabHorizontalPadding() * current_state); 17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y += (View::height() - browser_defaults::kBookmarkBarHeight) / 2; 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width -= static_cast<int>(GetNewtabHorizontalPadding() * current_state); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_margin -= static_cast<int>(kSeparatorMargin * current_state); 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For the attached appearance, pin the content to the bottom of the bar 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when animating in/out, as shrinking its height instead looks weird. This 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also matches how we layout infobars. 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y += View::height() - browser_defaults::kBookmarkBarHeight; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size other_bookmarked_pref = other_bookmarked_button_->visible() ? 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->GetPreferredSize() : gfx::Size(); 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size overflow_pref = overflow_button_->GetPreferredSize(); 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size bookmarks_separator_pref = 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_->GetPreferredSize(); 17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size apps_page_shortcut_pref = apps_page_shortcut_->visible() ? 17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps_page_shortcut_->GetPreferredSize() : gfx::Size(); 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_x = width - overflow_pref.width() - kButtonPadding - 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_pref.width(); 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible()) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_x -= other_bookmarked_pref.width() + kButtonPadding; 17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (apps_page_shortcut_->visible()) 17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_x -= apps_page_shortcut_pref.width() + kButtonPadding; 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next, layout out the buttons. Any buttons that are placed beyond the 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visible region and made invisible. 1767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start with the apps page shortcut button. 1769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (apps_page_shortcut_->visible()) { 1770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!compute_bounds_only) { 1771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_page_shortcut_->SetBounds(x, y, apps_page_shortcut_pref.width(), 1772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) height); 1773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) x += apps_page_shortcut_pref.width() + kButtonPadding; 1775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Then go through the bookmark buttons. 1778b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (GetBookmarkButtonCount() == 0 && model_ && model_->loaded()) { 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pref = instructions_->GetPreferredSize(); 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) { 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_->SetBounds( 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x + kInstructionsPadding, y, 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(static_cast<int>(pref.width()), 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_x - x), 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height); 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_->SetVisible(true); 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instructions_->SetVisible(false); 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < GetBookmarkButtonCount(); ++i) { 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size pref = child->GetPreferredSize(); 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int next_x = x + pref.width() + kButtonPadding; 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) { 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetVisible(next_x < max_x); 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child->SetBounds(x, y, pref.width(), height); 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = next_x; 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Layout the right side of the bar. 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool all_visible = (GetBookmarkButtonCount() == 0 || 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_at(GetBookmarkButtonCount() - 1)->visible()); 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Layout the right side buttons. 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = max_x + kButtonPadding; 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += kButtonPadding; 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The overflow button. 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) { 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetBounds(x, y, overflow_pref.width(), height); 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overflow_button_->SetVisible(!all_visible); 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += overflow_pref.width(); 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separator. 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmarks_separator_view_->visible()) { 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) { 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_view_->SetBounds(x, 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y - top_margin, 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks_separator_pref.width(), 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height + top_margin + kBottomMargin - 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) separator_margin); 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += bookmarks_separator_pref.width(); 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The other bookmarks button. 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_bookmarked_button_->visible()) { 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compute_bounds_only) { 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_bookmarked_button_->SetBounds(x, y, other_bookmarked_pref.width(), 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height); 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x += other_bookmarked_pref.width() + kButtonPadding; 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the preferred size computed so far. 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (compute_bounds_only) { 18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x += kRightMargin; 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_width(x); 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsDetached()) { 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x += static_cast<int>(GetNewtabHorizontalPadding() * 18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (1 - size_animation_->GetCurrentValue())); 18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int ntp_bookmark_bar_height = 1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::IsInstantExtendedAPIEnabled() 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ? kSearchNewTabBookmarkBarHeight : chrome::kNTPBookmarkBarHeight; 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height( 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_defaults::kBookmarkBarHeight + 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>( 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ntp_bookmark_bar_height - 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_defaults::kBookmarkBarHeight) * 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (1 - size_animation_->GetCurrentValue()))); 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height( 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>( 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_defaults::kBookmarkBarHeight * 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_->GetCurrentValue())); 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefsize; 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BookmarkBarView::OnAppsPageShortcutVisibilityPrefChanged() { 18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(apps_page_shortcut_); 1871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Only perform layout if required. 1872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool visible = chrome::ShouldShowAppsShortcutInBookmarkBar( 1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_->profile()); 1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (apps_page_shortcut_->visible() == visible) 1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) apps_page_shortcut_->SetVisible(visible); 18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateBookmarksSeparatorVisibility(); 18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Layout(); 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BookmarkBarView::OnAppLauncherEnabledCompleted(bool app_launcher_enabled) { 1882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Disregard |app_launcher_enabled|, use apps::WasAppLauncherEnable instead. 1883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnAppsPageShortcutVisibilityPrefChanged(); 1884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1885