diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 21:38:29 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 21:38:29 +0000 |
commit | 8e261756c62de3737c5dc9b9418857e2b58a7618 (patch) | |
tree | 7f531ce7155a09f517c21c7e1f9eb95240465216 | |
parent | 2756834856ac17385e6f690f5c73361a877c668d (diff) | |
download | chromium_src-8e261756c62de3737c5dc9b9418857e2b58a7618.zip chromium_src-8e261756c62de3737c5dc9b9418857e2b58a7618.tar.gz chromium_src-8e261756c62de3737c5dc9b9418857e2b58a7618.tar.bz2 |
Adds a bookmark menu. This is experimental. To turn on you need
--bookmark-menu.
BUG=3206
TEST=Turn on the bookmark menu via --bookmark-menu and make sure it
works. Also make sure I didn't break anything on the bookmark bar.
Review URL: http://codereview.chromium.org/42460
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12217 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/theme/menu_bookmark.png | bin | 0 -> 1121 bytes | |||
-rw-r--r-- | chrome/app/theme/theme_resources.grd | 1 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_menu_controller.cc | 31 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_menu_controller.h | 10 | ||||
-rw-r--r-- | chrome/browser/view_ids.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_menu_button.cc | 145 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_menu_button.h | 79 | ||||
-rw-r--r-- | chrome/browser/views/browser_views.vcproj | 8 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.cc | 21 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.h | 2 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 2 | ||||
-rw-r--r-- | chrome/views/controls/button/menu_button.h | 4 |
14 files changed, 302 insertions, 9 deletions
diff --git a/chrome/app/theme/menu_bookmark.png b/chrome/app/theme/menu_bookmark.png Binary files differnew file mode 100644 index 0000000..04f012a --- /dev/null +++ b/chrome/app/theme/menu_bookmark.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index c8dfa5e..04b51b2 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -308,6 +308,7 @@ <include name="IDR_DOCK_MAX" file="dock_tab_max.png" type="BINDATA" /> <include name="IDR_DOCK_HIGH" file="dock_tab_high.png" type="BINDATA" /> <include name="IDR_DOCK_WIDE" file="dock_tab_wide.png" type="BINDATA" /> + <include name="IDR_MENU_BOOKMARK" file="menu_bookmark.png" type="BINDATA" /> <if expr="pp_ifdef('_google_chrome')"> <include name="IDR_ABOUT_BACKGROUND" file="google_chrome/about_background.png" type="BINDATA" /> diff --git a/chrome/browser/bookmarks/bookmark_menu_controller.cc b/chrome/browser/bookmarks/bookmark_menu_controller.cc index 058a2f5..53f2007 100644 --- a/chrome/browser/bookmarks/bookmark_menu_controller.cc +++ b/chrome/browser/bookmarks/bookmark_menu_controller.cc @@ -11,8 +11,10 @@ #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/views/event_utils.h" #include "chrome/common/os_exchange_data.h" +#include "chrome/common/l10n_util.h" #include "chrome/common/page_transition_types.h" #include "chrome/common/resource_bundle.h" +#include "grit/generated_resources.h" #include "grit/theme_resources.h" BookmarkMenuController::BookmarkMenuController(Browser* browser, @@ -20,19 +22,23 @@ BookmarkMenuController::BookmarkMenuController(Browser* browser, PageNavigator* navigator, HWND hwnd, BookmarkNode* node, - int start_child_index) + int start_child_index, + bool show_other_folder) : browser_(browser), profile_(profile), page_navigator_(navigator), hwnd_(hwnd), node_(node), observer_(NULL), - for_drop_(false) { + for_drop_(false), + show_other_folder_(show_other_folder) { menu_.reset(new views::MenuItemView(this)); int next_menu_id = 1; menu_id_to_node_map_[menu_->GetCommand()] = node; menu_->set_has_icons(true); BuildMenu(node, start_child_index, menu_.get(), &next_menu_id); + if (show_other_folder) + BuildOtherFolderMenu(&next_menu_id); } void BookmarkMenuController::RunMenuAt( @@ -104,6 +110,11 @@ int BookmarkMenuController::GetDropOperation( BookmarkNode* drop_parent = node->GetParent(); int index_to_drop_at = drop_parent->IndexOfChild(node); if (*position == DROP_AFTER) { + if (node == profile_->GetBookmarkModel()->other_node()) { + // The other folder is shown after all bookmarks on the bookmark bar. + // Dropping after the other folder makes no sense. + *position = DROP_NONE; + } index_to_drop_at++; } else if (*position == DROP_ON) { drop_parent = node; @@ -165,7 +176,9 @@ void BookmarkMenuController::DropMenuClosed(views::MenuItemView* menu) { } bool BookmarkMenuController::CanDrag(views::MenuItemView* menu) { - return true; + BookmarkNode* node = menu_id_to_node_map_[menu->GetCommand()]; + // Don't let users drag the other folder. + return node->GetParent() != profile_->GetBookmarkModel()->root_node(); } void BookmarkMenuController::WriteDragData(views::MenuItemView* sender, @@ -193,6 +206,18 @@ void BookmarkMenuController::BookmarkNodeFavIconLoaded(BookmarkModel* model, menu_->SetIcon(node->GetFavIcon(), node_to_menu_id_map_[node]); } +void BookmarkMenuController::BuildOtherFolderMenu(int* next_menu_id) { + BookmarkNode* other_folder = profile_->GetBookmarkModel()->other_node(); + int id = *next_menu_id; + (*next_menu_id)++; + SkBitmap* folder_icon = ResourceBundle::GetSharedInstance(). + GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); + views::MenuItemView* submenu = menu_->AppendSubMenuWithIcon( + id, l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_BOOKMARKED), *folder_icon); + BuildMenu(other_folder, 0, submenu, next_menu_id); + menu_id_to_node_map_[id] = other_folder; +} + void BookmarkMenuController::BuildMenu(BookmarkNode* parent, int start_child_index, views::MenuItemView* menu, diff --git a/chrome/browser/bookmarks/bookmark_menu_controller.h b/chrome/browser/bookmarks/bookmark_menu_controller.h index 71d3a74..96bce0e 100644 --- a/chrome/browser/bookmarks/bookmark_menu_controller.h +++ b/chrome/browser/bookmarks/bookmark_menu_controller.h @@ -39,7 +39,8 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, PageNavigator* page_navigator, HWND hwnd, BookmarkNode* node, - int start_child_index); + int start_child_index, + bool show_other_folder); // Shows the menu. void RunMenuAt(const gfx::Rect& bounds, @@ -90,6 +91,10 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // BookmarkMenuController deletes itself as necessary. ~BookmarkMenuController(); + // Builds the menu for the other bookmarks folder. This is added as the last + // item to menu_. + void BuildOtherFolderMenu(int* next_menu_id); + // Creates an entry in menu for each child node of |parent| starting at // |start_child_index|. void BuildMenu(BookmarkNode* parent, @@ -131,6 +136,9 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // Is the menu being shown for a drop? bool for_drop_; + // Should the other folder be shown? + bool show_other_folder_; + DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController); }; diff --git a/chrome/browser/view_ids.h b/chrome/browser/view_ids.h index c0780ab..f46c559 100644 --- a/chrome/browser/view_ids.h +++ b/chrome/browser/view_ids.h @@ -39,6 +39,7 @@ enum ViewID { VIEW_ID_PAGE_MENU, VIEW_ID_APP_MENU, VIEW_ID_AUTOCOMPLETE, + VIEW_ID_BOOKMARK_MENU, // The Bookmark Bar. VIEW_ID_BOOKMARK_BAR, diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index b18012e..8cdfc26 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -1222,7 +1222,7 @@ void BookmarkBarView::RunMenu(views::View* view, View::ConvertPointToScreen(this, &screen_loc); bookmark_menu_ = new BookmarkMenuController( browser_, profile_, page_navigator_, GetWidget()->GetNativeView(), - node, start_index); + node, start_index, false); bookmark_menu_->set_observer(this); bookmark_menu_->RunMenuAt(gfx::Rect(screen_loc.x(), screen_loc.y(), view->width(), bar_height), @@ -1446,7 +1446,7 @@ void BookmarkBarView::ShowDropFolderForNode(BookmarkNode* node) { drop_info_->is_menu_showing = true; bookmark_drop_menu_ = new BookmarkMenuController( browser_, profile_, page_navigator_, GetWidget()->GetNativeView(), - node, start_index); + node, start_index, false); bookmark_drop_menu_->set_observer(this); gfx::Point screen_loc; View::ConvertPointToScreen(view_to_position_menu_from, &screen_loc); diff --git a/chrome/browser/views/bookmark_menu_button.cc b/chrome/browser/views/bookmark_menu_button.cc new file mode 100644 index 0000000..7ee1d0c --- /dev/null +++ b/chrome/browser/views/bookmark_menu_button.cc @@ -0,0 +1,145 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/bookmark_menu_button.h" + +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/view_ids.h" +#include "chrome/common/os_exchange_data.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/views/widget/widget.h" +#include "grit/theme_resources.h" + +BookmarkMenuButton::BookmarkMenuButton(Browser* browser) + : views::MenuButton(NULL, std::wstring(), NULL, false), + browser_(browser), + bookmark_drop_menu_(NULL), + drop_operation_(0) { + set_menu_delegate(this); + SetID(VIEW_ID_BOOKMARK_MENU); + + ResourceBundle &rb = ResourceBundle::GetSharedInstance(); + // TODO (sky): if we keep this code, we need real icons, a11y support, and a + // tooltip. + SetIcon(*rb.GetBitmapNamed(IDR_MENU_BOOKMARK)); +} + +BookmarkMenuButton::~BookmarkMenuButton() { + if (bookmark_drop_menu_) + bookmark_drop_menu_->set_observer(NULL); +} + +bool BookmarkMenuButton::CanDrop(const OSExchangeData& data) { + BookmarkModel* bookmark_model = GetBookmarkModel(); + if (!bookmark_model || !bookmark_model->IsLoaded()) + return false; + + drag_data_ = BookmarkDragData(); + // Only accept drops of 1 node, which is the case for all data dragged from + // bookmark bar and menus. + return drag_data_.Read(data) && drag_data_.has_single_url(); +} + +int BookmarkMenuButton::OnDragUpdated(const views::DropTargetEvent& event) { + if (!drag_data_.is_valid()) + return 0; + + BookmarkModel* bookmark_model = GetBookmarkModel(); + drop_operation_ = bookmark_utils::BookmarkDropOperation( + browser_->profile(), event, drag_data_, + bookmark_model->GetBookmarkBarNode(), + bookmark_model->GetBookmarkBarNode()->GetChildCount()); + if (drop_operation_ != 0) + StartShowFolderDropMenuTimer(); + else + StopShowFolderDropMenuTimer(); + return drop_operation_; +} + +void BookmarkMenuButton::OnDragExited() { + StopShowFolderDropMenuTimer(); + drag_data_ = BookmarkDragData(); +} + +int BookmarkMenuButton::OnPerformDrop(const views::DropTargetEvent& event) { + StopShowFolderDropMenuTimer(); + + if (bookmark_drop_menu_) + bookmark_drop_menu_->Cancel(); + + // Reset the drag data to take as little memory as needed. + BookmarkDragData data = drag_data_; + drag_data_ = BookmarkDragData(); + + if (!drop_operation_) + return DragDropTypes::DRAG_NONE; + + BookmarkModel* model = GetBookmarkModel(); + if (!model) + return DragDropTypes::DRAG_NONE; + + BookmarkNode* parent = model->GetBookmarkBarNode(); + return bookmark_utils::PerformBookmarkDrop( + browser_->profile(), data, parent, parent->GetChildCount()); +} + +void BookmarkMenuButton::BookmarkMenuDeleted( + BookmarkMenuController* controller) { + bookmark_drop_menu_ = NULL; +} + +void BookmarkMenuButton::RunMenu(views::View* source, + const CPoint& pt, + gfx::NativeView hwnd) { + RunMenu(source, pt, hwnd, false); +} + +void BookmarkMenuButton::RunMenu(views::View* source, + const CPoint& pt, + gfx::NativeView hwnd, + bool for_drop) { + Profile* profile = browser_->profile(); + BookmarkMenuController* menu = new BookmarkMenuController( + browser_, profile, browser_->GetSelectedTabContents(), hwnd, + GetBookmarkModel()->GetBookmarkBarNode(), 0, true); + + views::MenuItemView::AnchorPosition anchor = views::MenuItemView::TOPRIGHT; + if (UILayoutIsRightToLeft()) + anchor = views::MenuItemView::TOPLEFT; + gfx::Point button_origin; + ConvertPointToScreen(this, &button_origin); + gfx::Rect menu_bounds(button_origin.x(), button_origin.y(), width(), + height()); + if (for_drop) { + bookmark_drop_menu_ = menu; + bookmark_drop_menu_->set_observer(this); + } + menu->RunMenuAt(menu_bounds, views::MenuItemView::TOPRIGHT, for_drop); +} + +BookmarkModel* BookmarkMenuButton::GetBookmarkModel() { + return browser_->profile()->GetBookmarkModel(); +} + +void BookmarkMenuButton::StartShowFolderDropMenuTimer() { + if (show_drop_menu_timer_.IsRunning()) + return; + + static DWORD delay = 0; + if (!delay && !SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0)) + delay = 400; + show_drop_menu_timer_.Start(base::TimeDelta::FromMilliseconds(delay), + this, &BookmarkMenuButton::ShowDropMenu); +} + +void BookmarkMenuButton::StopShowFolderDropMenuTimer() { + show_drop_menu_timer_.Stop(); +} + +void BookmarkMenuButton::ShowDropMenu() { + RunMenu(NULL, CPoint(), GetWidget()->GetNativeView(), true); +} diff --git a/chrome/browser/views/bookmark_menu_button.h b/chrome/browser/views/bookmark_menu_button.h new file mode 100644 index 0000000..e9da8d0 --- /dev/null +++ b/chrome/browser/views/bookmark_menu_button.h @@ -0,0 +1,79 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_BOOKMARK_MENU_BUTTON_H_ +#define CHROME_BROWSER_VIEWS_BOOKMARK_MENU_BUTTON_H_ + +#include "base/timer.h" +#include "chrome/browser/bookmarks/bookmark_drag_data.h" +#include "chrome/browser/bookmarks/bookmark_menu_controller.h" +#include "chrome/views/controls/button/menu_button.h" +#include "chrome/views/controls/menu/view_menu_delegate.h" + +class BookmarkModel; +class Browser; + +// BookmarkMenuButton is the button on the toolbar that when clicked shows +// all bookmarks in a menu. Additionally users can drag bookmarks over the +// button to have the menu appear. + +class BookmarkMenuButton : public views::MenuButton, + public BookmarkMenuController::Observer, + public views::ViewMenuDelegate { + public: + explicit BookmarkMenuButton(Browser* browser); + virtual ~BookmarkMenuButton(); + + // View drop methods. + virtual bool CanDrop(const OSExchangeData& data); + virtual int OnDragUpdated(const views::DropTargetEvent& event); + virtual void OnDragExited(); + virtual int OnPerformDrop(const views::DropTargetEvent& event); + + // BookmarkMenuController::Observer. + virtual void BookmarkMenuDeleted(BookmarkMenuController* controller); + + // ViewMenuDelegate. + virtual void RunMenu(views::View* source, + const CPoint& pt, + gfx::NativeView hwnd); + + private: + // Shows the menu. + void RunMenu(views::View* source, + const CPoint& pt, + gfx::NativeView hwnd, + bool for_drop); + + // Returns the bookmark model. + BookmarkModel* GetBookmarkModel(); + + // Starts the timer for showing the drop menu if it isn't running. + void StartShowFolderDropMenuTimer(); + + // Stops the timer for showing the drop menu. + void StopShowFolderDropMenuTimer(); + + // Shows the drop menu. + void ShowDropMenu(); + + // Browser used to determine profile for showing bookmarks from. + Browser* browser_; + + // Contents of current drag. + BookmarkDragData drag_data_; + + // Menu shown during drag and drop. + BookmarkMenuController* bookmark_drop_menu_; + + // Drop operation for current drop. + int drop_operation_; + + // Timer used for showing the drop menu. + base::OneShotTimer<BookmarkMenuButton> show_drop_menu_timer_; + + DISALLOW_COPY_AND_ASSIGN(BookmarkMenuButton); +}; + +#endif // CHROME_BROWSER_VIEWS_BOOKMARK_MENU_BUTTON_H_ diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj index 7e14a55..9cde61c 100644 --- a/chrome/browser/views/browser_views.vcproj +++ b/chrome/browser/views/browser_views.vcproj @@ -426,6 +426,14 @@ > </File> <File + RelativePath=".\bookmark_menu_button.cc" + > + </File> + <File + RelativePath=".\bookmark_menu_button.h" + > + </File> + <File RelativePath=".\bookmark_table_view.cc" > </File> diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index f676bb7..5695eac 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/path_service.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/bookmarks/bookmark_drag_data.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" @@ -21,6 +20,7 @@ #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/user_data_manager.h" +#include "chrome/browser/views/bookmark_menu_button.h" #include "chrome/browser/views/dom_view.h" #include "chrome/browser/views/go_button.h" #include "chrome/browser/views/location_bar_view.h" @@ -277,6 +277,13 @@ void BrowserToolbarView::CreateRightSideControls(Profile* profile) { l10n_util::GetString(IDS_PRODUCT_NAME))); app_menu_->SetID(VIEW_ID_APP_MENU); AddChildView(app_menu_); + + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kBookmarkMenu)) { + bookmark_menu_ = new BookmarkMenuButton(browser_); + AddChildView(bookmark_menu_); + } else { + bookmark_menu_ = NULL; + } } void BrowserToolbarView::Layout() { @@ -332,9 +339,12 @@ void BrowserToolbarView::Layout() { int go_button_width = go_->GetPreferredSize().width(); int page_menu_width = page_menu_->GetPreferredSize().width(); int app_menu_width = app_menu_->GetPreferredSize().width(); + int bookmark_menu_width = bookmark_menu_ ? + bookmark_menu_->GetPreferredSize().width() : 0; int location_x = star_->x() + star_->width(); - int available_width = width() - kPaddingRight - app_menu_width - - page_menu_width - kMenuButtonOffset - go_button_width - location_x; + int available_width = width() - kPaddingRight - bookmark_menu_width - + app_menu_width - page_menu_width - kMenuButtonOffset - go_button_width - + location_x; location_bar_->SetBounds(location_x, child_y, std::max(available_width, 0), child_height); @@ -346,6 +356,11 @@ void BrowserToolbarView::Layout() { app_menu_->SetBounds(page_menu_->x() + page_menu_->width(), child_y, app_menu_width, child_height); + + if (bookmark_menu_) { + bookmark_menu_->SetBounds(app_menu_->x() + app_menu_->width(), child_y, + bookmark_menu_width, child_height); + } } void BrowserToolbarView::Paint(ChromeCanvas* canvas) { diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h index 10c5506..2b25bbc 100644 --- a/chrome/browser/views/toolbar_view.h +++ b/chrome/browser/views/toolbar_view.h @@ -192,6 +192,8 @@ class BrowserToolbarView : public views::View, GoButton* go_; views::MenuButton* page_menu_; views::MenuButton* app_menu_; + // The bookmark menu button. This may be null. + views::MenuButton* bookmark_menu_; Profile* profile_; Browser* browser_; diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index b24076f..d3b5a1a 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -409,4 +409,7 @@ const wchar_t kEnableWebWorkers[] = L"enable-web-workers"; // Enables experimental views under gtk. const wchar_t kViewsGtk[] = L"views-gtk"; +// Enables the bookmark menu. +const wchar_t kBookmarkMenu[] = L"bookmark-menu"; + } // namespace switches diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index a958bc9..c8105e2 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -159,6 +159,8 @@ extern const wchar_t kEnableWebWorkers[]; extern const wchar_t kViewsGtk[]; +extern const wchar_t kBookmarkMenu[]; + } // namespace switches #endif // CHROME_COMMON_CHROME_SWITCHES_H__ diff --git a/chrome/views/controls/button/menu_button.h b/chrome/views/controls/button/menu_button.h index 458853e..438d191 100644 --- a/chrome/views/controls/button/menu_button.h +++ b/chrome/views/controls/button/menu_button.h @@ -35,6 +35,10 @@ class MenuButton : public TextButton { bool show_menu_marker); virtual ~MenuButton(); + void set_menu_delegate(ViewMenuDelegate* delegate) { + menu_delegate_ = delegate; + } + // Activate the button (called when the button is pressed). virtual bool Activate(); |