diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 148 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.h | 39 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view_test.cc | 3 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_context_menu.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_manager_view.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_menu_button.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_menu_controller_views.cc | 117 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_menu_controller_views.h | 41 |
8 files changed, 235 insertions, 125 deletions
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 5eba994..1eb8d63 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -38,6 +38,8 @@ #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "views/controls/button/menu_button.h" +#include "views/controls/label.h" +#include "views/controls/button/menu_button.h" #include "views/controls/menu/menu_item_view.h" #include "views/drag_utils.h" #include "views/view_constants.h" @@ -797,6 +799,71 @@ views::MenuItemView* BookmarkBarView::GetDropMenu() { return bookmark_drop_menu_ ? bookmark_drop_menu_->menu() : NULL; } +const BookmarkNode* BookmarkBarView::GetNodeForButtonAt(const gfx::Point& loc, + int* start_index) { + *start_index = 0; + + if (loc.x() < 0 || loc.x() >= width() || loc.y() < 0 || loc.y() >= height()) + return NULL; + + // Check the buttons first. + for (int i = 0; i < GetBookmarkButtonCount(); ++i) { + views::View* child = GetChildViewAt(i); + if (!child->IsVisible()) + break; + if (child->bounds().Contains(loc)) + return model_->GetBookmarkBarNode()->GetChild(i); + } + + // Then the overflow button. + if (overflow_button_->IsVisible() && + overflow_button_->bounds().Contains(loc)) { + *start_index = GetFirstHiddenNodeIndex(); + return model_->GetBookmarkBarNode(); + } + + // And finally the other folder. + if (other_bookmarked_button_->bounds().Contains(loc)) + return model_->other_node(); + + return NULL; +} + +views::MenuButton* BookmarkBarView::GetMenuButtonForNode( + const BookmarkNode* node) { + if (node == model_->other_node()) + return other_bookmarked_button_; + if (node == model_->GetBookmarkBarNode()) + return overflow_button_; + int index = model_->GetBookmarkBarNode()->IndexOfChild(node); + if (index == -1 || !node->is_folder()) + return NULL; + return static_cast<views::MenuButton*>(GetChildViewAt(index)); +} + +void BookmarkBarView::GetAnchorPositionAndStartIndexForButton( + views::MenuButton* button, + MenuItemView::AnchorPosition* anchor, + int* start_index) { + if (button == other_bookmarked_button_ || button == overflow_button_) + *anchor = MenuItemView::TOPRIGHT; + else + *anchor = MenuItemView::TOPLEFT; + + // Invert orientation if right to left. + if (UILayoutIsRightToLeft()) { + if (*anchor == MenuItemView::TOPRIGHT) + *anchor = MenuItemView::TOPLEFT; + else + *anchor = MenuItemView::TOPRIGHT; + } + + if (button == overflow_button_) + *start_index = GetFirstHiddenNodeIndex(); + else + *start_index = 0; +} + void BookmarkBarView::Init() { // Note that at this point we're not in a hierarchy so GetThemeProvider() will // return NULL. When we're inserted into a hierarchy, we'll call @@ -1072,55 +1139,24 @@ int BookmarkBarView::GetDragOperations(View* sender, int x, int y) { void BookmarkBarView::RunMenu(views::View* view, const gfx::Point& pt) { const BookmarkNode* node; - MenuItemView::AnchorPosition anchor_point = MenuItemView::TOPLEFT; - - // When we set the menu's position, we must take into account the mirrored - // position of the View relative to its parent. This can be easily done by - // passing the right flag to View::x(). - int x = view->GetX(APPLY_MIRRORING_TRANSFORMATION); - int bar_height = height() - kMenuOffset; - - if (IsDetached()) - bar_height -= kNewtabVerticalPadding; int start_index = 0; if (view == other_bookmarked_button_) { - UserMetrics::RecordAction(L"BookmarkBar_ShowOtherBookmarks", profile_); - node = model_->other_node(); - if (UILayoutIsRightToLeft()) - anchor_point = MenuItemView::TOPLEFT; - else - anchor_point = MenuItemView::TOPRIGHT; } else if (view == overflow_button_) { node = model_->GetBookmarkBarNode(); start_index = GetFirstHiddenNodeIndex(); - if (UILayoutIsRightToLeft()) - anchor_point = MenuItemView::TOPLEFT; - else - anchor_point = MenuItemView::TOPRIGHT; } else { int button_index = GetChildIndex(view); DCHECK_NE(-1, button_index); node = model_->GetBookmarkBarNode()->GetChild(button_index); - - // When the UI layout is RTL, the bookmarks are laid out from right to left - // and therefore when we display the menu we want it to be aligned with the - // bottom right corner of the bookmark item. - if (UILayoutIsRightToLeft()) - anchor_point = MenuItemView::TOPRIGHT; - else - anchor_point = MenuItemView::TOPLEFT; } - gfx::Point screen_loc(x, 0); - View::ConvertPointToScreen(this, &screen_loc); + bookmark_menu_ = new BookmarkMenuController( browser_, profile_, page_navigator_, GetWindow()->GetNativeWindow(), node, start_index, false); bookmark_menu_->set_observer(this); - bookmark_menu_->RunMenuAt(gfx::Rect(screen_loc.x(), screen_loc.y(), - view->width(), bar_height), - anchor_point, false); + bookmark_menu_->RunMenuAt(this, false); } void BookmarkBarView::ButtonPressed(views::Button* sender, @@ -1298,54 +1334,20 @@ void BookmarkBarView::ShowDropFolderForNode(const BookmarkNode* node) { bookmark_drop_menu_->Cancel(); } + views::MenuButton* menu_button = GetMenuButtonForNode(node); + if (!menu_button) + return; + int start_index = 0; - View* view_to_position_menu_from; - - // Note that both the anchor position and the position of the menu itself - // change depending on the locale. Also note that we must apply the - // mirroring transformation when querying for the child View bounds - // (View::x(), specifically) so that we end up with the correct screen - // coordinates if the View in question is mirrored. - MenuItemView::AnchorPosition anchor = MenuItemView::TOPLEFT; - if (node == model_->other_node()) { - view_to_position_menu_from = other_bookmarked_button_; - if (!UILayoutIsRightToLeft()) - anchor = MenuItemView::TOPRIGHT; - } else if (node == model_->GetBookmarkBarNode()) { - DCHECK(overflow_button_->IsVisible()); - view_to_position_menu_from = overflow_button_; + if (node == model_->GetBookmarkBarNode()) start_index = GetFirstHiddenNodeIndex(); - if (!UILayoutIsRightToLeft()) - anchor = MenuItemView::TOPRIGHT; - } else { - // Make sure node is still valid. - int index = -1; - const BookmarkNode* bb_node = model_->GetBookmarkBarNode(); - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (bb_node->GetChild(i) == node) { - index = i; - break; - } - } - if (index == -1) - return; - view_to_position_menu_from = GetBookmarkButton(index); - if (UILayoutIsRightToLeft()) - anchor = MenuItemView::TOPRIGHT; - } drop_info_->is_menu_showing = true; bookmark_drop_menu_ = new BookmarkMenuController( browser_, profile_, page_navigator_, GetWindow()->GetNativeWindow(), node, start_index, false); bookmark_drop_menu_->set_observer(this); - gfx::Point screen_loc; - View::ConvertPointToScreen(view_to_position_menu_from, &screen_loc); - bookmark_drop_menu_->RunMenuAt( - gfx::Rect(screen_loc.x(), screen_loc.y(), - view_to_position_menu_from->width(), - view_to_position_menu_from->height()), - anchor, true); + bookmark_drop_menu_->RunMenuAt(this, true); } void BookmarkBarView::StopShowFolderDropMenuTimer() { diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index c7008fb7..0d79cc6 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -13,18 +13,19 @@ #include "chrome/browser/views/bookmark_menu_controller_views.h" #include "chrome/browser/views/detachable_toolbar_view.h" #include "chrome/common/notification_registrar.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/label.h" +#include "views/controls/button/button.h" #include "views/controls/menu/view_menu_delegate.h" -#include "views/view.h" -#include "third_party/skia/include/core/SkRect.h" class Browser; class PageNavigator; class PrefService; namespace views { +class CustomButton; +class Label; +class MenuButton; class MenuItemView; +class TextButton; } // BookmarkBarView renders the BookmarkModel. Each starred entry on the @@ -173,7 +174,7 @@ class BookmarkBarView : public DetachableToolbarView, // Returns the button responsible for showing bookmarks in the other bookmark // folder. - views::TextButton* other_bookmarked_button() const { + views::MenuButton* other_bookmarked_button() const { return other_bookmarked_button_; } @@ -187,7 +188,25 @@ class BookmarkBarView : public DetachableToolbarView, views::MenuItemView* GetContextMenu(); // Returns the button used when not all the items on the bookmark bar fit. - views::TextButton* overflow_button() const { return overflow_button_; } + views::MenuButton* overflow_button() const { return overflow_button_; } + + // If |loc| is over a bookmark button the node is returned corresponding + // to the button and |start_index| is set to 0. If a overflow button is + // showing and |loc| is over the overflow button, the bookmark bar node is + // returned and |start_index| is set to the index of the first node + // contained in the overflow menu. + const BookmarkNode* GetNodeForButtonAt(const gfx::Point& loc, + int* start_index); + + // Returns the MenuButton for node. + views::MenuButton* GetMenuButtonForNode(const BookmarkNode* node); + + // Returns the position to anchor the menu for |button| at, the index of the + // first child of the node to build the menu from. + void GetAnchorPositionAndStartIndexForButton( + views::MenuButton* button, + views::MenuItemView::AnchorPosition* anchor, + int* start_index); // Maximum size of buttons on the bookmark bar. static const int kMaxButtonWidth; @@ -317,12 +336,8 @@ class BookmarkBarView : public DetachableToolbarView, // Returns the drag operations for the specified button. virtual int GetDragOperations(views::View* sender, int x, int y); - // ViewMenuDelegate method. 3 types of menus may be shown: - // . the menu allowing the user to choose when the bookmark bar is visible. - // . most recently bookmarked menu - // . menu for star groups. - // The latter two are handled by a MenuRunner, which builds the appropriate - // menu. + // ViewMenuDelegate method. Ends up creating a BookmarkMenuController to + // show the menu. virtual void RunMenu(views::View* view, const gfx::Point& pt); // Invoked when a star entry corresponding to a URL on the bookmark bar is diff --git a/chrome/browser/views/bookmark_bar_view_test.cc b/chrome/browser/views/bookmark_bar_view_test.cc index 751a1ec..cedfd19 100644 --- a/chrome/browser/views/bookmark_bar_view_test.cc +++ b/chrome/browser/views/bookmark_bar_view_test.cc @@ -14,6 +14,7 @@ #include "chrome/common/pref_service.h" #include "chrome/test/testing_profile.h" #include "chrome/test/interactive_ui/view_event_test_base.h" +#include "views/controls/button/menu_button.h" #include "views/controls/button/text_button.h" #include "views/controls/menu/menu_controller.h" #include "views/controls/menu/menu_item_view.h" @@ -279,7 +280,7 @@ class BookmarkBarViewTest3 : public BookmarkBarViewEventTestBase { virtual void DoTestOnMessageLoop() { // Move the mouse to the first folder on the bookmark bar and press the // mouse. - views::TextButton* button = bb_view_->other_bookmarked_button(); + views::MenuButton* button = bb_view_->other_bookmarked_button(); ui_controls::MoveMouseToCenterAndPress(button, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP, CreateEventTask(this, &BookmarkBarViewTest3::Step2)); diff --git a/chrome/browser/views/bookmark_context_menu.cc b/chrome/browser/views/bookmark_context_menu.cc index ddb0d5b..a3f3a15 100644 --- a/chrome/browser/views/bookmark_context_menu.cc +++ b/chrome/browser/views/bookmark_context_menu.cc @@ -37,7 +37,7 @@ void BookmarkContextMenu::RunMenuAt(const gfx::Point& point) { views::MenuItemView::AnchorPosition anchor = (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ? views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT; - menu_->RunMenuAt(parent_window_, gfx::Rect(point.x(), point.y(), 0, 0), + menu_->RunMenuAt(parent_window_, NULL, gfx::Rect(point.x(), point.y(), 0, 0), anchor, true); } diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc index fafa228..ce40b28 100644 --- a/chrome/browser/views/bookmark_manager_view.cc +++ b/chrome/browser/views/bookmark_manager_view.cc @@ -795,8 +795,8 @@ void BookmarkManagerView::ShowToolsMenu(int x, int y) { views::MenuItemView::AnchorPosition anchor = UILayoutIsRightToLeft() ? views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT; - menu.RunMenuAt(GetWidget()->GetNativeView(), gfx::Rect(x, y, 0, 0), anchor, - true); + menu.RunMenuAt(GetWidget()->GetNativeView(), NULL, gfx::Rect(x, y, 0, 0), + anchor, true); } void BookmarkManagerView::ShowImportBookmarksFileChooser() { diff --git a/chrome/browser/views/bookmark_menu_button.cc b/chrome/browser/views/bookmark_menu_button.cc index 4255ffd..988f1f0 100644 --- a/chrome/browser/views/bookmark_menu_button.cc +++ b/chrome/browser/views/bookmark_menu_button.cc @@ -133,15 +133,11 @@ void BookmarkMenuButton::RunMenu(views::View* source, 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); + menu->RunMenuAt(this, views::MenuItemView::TOPRIGHT, for_drop); } BookmarkModel* BookmarkMenuButton::GetBookmarkModel() { diff --git a/chrome/browser/views/bookmark_menu_controller_views.cc b/chrome/browser/views/bookmark_menu_controller_views.cc index 58ff604..80bf767 100644 --- a/chrome/browser/views/bookmark_menu_controller_views.cc +++ b/chrome/browser/views/bookmark_menu_controller_views.cc @@ -7,16 +7,21 @@ #include "app/l10n_util.h" #include "app/os_exchange_data.h" #include "app/resource_bundle.h" +#include "base/stl_util-inl.h" #include "chrome/browser/bookmarks/bookmark_drag_data.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/page_navigator.h" +#include "chrome/browser/views/bookmark_bar_view.h" #include "chrome/browser/views/event_utils.h" #include "chrome/common/page_transition_types.h" #include "grit/app_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "views/controls/button/menu_button.h" + +using views::MenuItemView; BookmarkMenuController::BookmarkMenuController(Browser* browser, Profile* profile, @@ -30,28 +35,45 @@ BookmarkMenuController::BookmarkMenuController(Browser* browser, page_navigator_(navigator), parent_(parent), node_(node), + menu_(NULL), observer_(NULL), 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); + show_other_folder_(show_other_folder), + bookmark_bar_(NULL), + next_menu_id_(1) { + menu_ = CreateMenu(node, start_child_index); +} + +void BookmarkMenuController::RunMenuAt(BookmarkBarView* bookmark_bar, + bool for_drop) { + bookmark_bar_ = bookmark_bar; + views::MenuButton* menu_button = bookmark_bar_->GetMenuButtonForNode(node_); + DCHECK(menu_button); + MenuItemView::AnchorPosition anchor; + int start_index; + bookmark_bar_->GetAnchorPositionAndStartIndexForButton( + menu_button, &anchor, &start_index); + RunMenuAt(menu_button, anchor, for_drop); } void BookmarkMenuController::RunMenuAt( - const gfx::Rect& bounds, - views::MenuItemView::AnchorPosition position, + views::MenuButton* button, + MenuItemView::AnchorPosition position, bool for_drop) { + gfx::Point screen_loc; + views::View::ConvertPointToScreen(button, &screen_loc); + // Subtract 1 from the height to make the popup flush with the button border. + gfx::Rect bounds(screen_loc.x(), screen_loc.y(), button->width(), + button->height() - 1); for_drop_ = for_drop; profile_->GetBookmarkModel()->AddObserver(this); + // The constructor creates the initial menu and that is all we should have + // at this point. + DCHECK(node_to_menu_map_.size() == 1); if (for_drop) { menu_->RunMenuForDropAt(parent_, bounds, position); } else { - menu_->RunMenuAt(parent_, bounds, position, false); + menu_->RunMenuAt(parent_, button, bounds, position, false); delete this; } } @@ -74,7 +96,7 @@ void BookmarkMenuController::ExecuteCommand(int id, int mouse_event_flags) { } bool BookmarkMenuController::GetDropFormats( - views::MenuItemView* menu, + MenuItemView* menu, int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) { *formats = OSExchangeData::URL; @@ -82,11 +104,11 @@ bool BookmarkMenuController::GetDropFormats( return true; } -bool BookmarkMenuController::AreDropTypesRequired(views::MenuItemView* menu) { +bool BookmarkMenuController::AreDropTypesRequired(MenuItemView* menu) { return true; } -bool BookmarkMenuController::CanDrop(views::MenuItemView* menu, +bool BookmarkMenuController::CanDrop(MenuItemView* menu, const OSExchangeData& data) { // Only accept drops of 1 node, which is the case for all data dragged from // bookmark bar and menus. @@ -113,7 +135,7 @@ bool BookmarkMenuController::CanDrop(views::MenuItemView* menu, } int BookmarkMenuController::GetDropOperation( - views::MenuItemView* item, + MenuItemView* item, const views::DropTargetEvent& event, DropPosition* position) { // Should only get here if we have drop data. @@ -138,7 +160,7 @@ int BookmarkMenuController::GetDropOperation( profile_, event, drop_data_, drop_parent, index_to_drop_at); } -int BookmarkMenuController::OnPerformDrop(views::MenuItemView* menu, +int BookmarkMenuController::OnPerformDrop(MenuItemView* menu, DropPosition position, const views::DropTargetEvent& event) { const BookmarkNode* drop_node = menu_id_to_node_map_[menu->GetCommand()]; @@ -163,7 +185,7 @@ int BookmarkMenuController::OnPerformDrop(views::MenuItemView* menu, return result; } -bool BookmarkMenuController::ShowContextMenu(views::MenuItemView* source, +bool BookmarkMenuController::ShowContextMenu(MenuItemView* source, int id, int x, int y, @@ -183,17 +205,17 @@ bool BookmarkMenuController::ShowContextMenu(views::MenuItemView* source, return true; } -void BookmarkMenuController::DropMenuClosed(views::MenuItemView* menu) { +void BookmarkMenuController::DropMenuClosed(MenuItemView* menu) { delete this; } -bool BookmarkMenuController::CanDrag(views::MenuItemView* menu) { +bool BookmarkMenuController::CanDrag(MenuItemView* menu) { const 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, +void BookmarkMenuController::WriteDragData(MenuItemView* sender, OSExchangeData* data) { DCHECK(sender && data); @@ -203,11 +225,41 @@ void BookmarkMenuController::WriteDragData(views::MenuItemView* sender, drag_data.Write(profile_, data); } -int BookmarkMenuController::GetDragOperations(views::MenuItemView* sender) { +int BookmarkMenuController::GetDragOperations(MenuItemView* sender) { return bookmark_utils::BookmarkDragOperation( menu_id_to_node_map_[sender->GetCommand()]); } +views::MenuItemView* BookmarkMenuController::GetSiblingMenu( + views::MenuItemView* menu, + const gfx::Point& screen_point, + views::MenuItemView::AnchorPosition* anchor, + bool* has_mnemonics, + views::MenuButton** button) { + if (show_other_folder_ || !bookmark_bar_ || for_drop_) + return NULL; + gfx::Point bookmark_bar_loc(screen_point); + views::View::ConvertPointToView(NULL, bookmark_bar_, &bookmark_bar_loc); + int start_index; + const BookmarkNode* node = + bookmark_bar_->GetNodeForButtonAt(bookmark_bar_loc, &start_index); + if (!node || !node->is_folder()) + return NULL; + + MenuItemView* alt_menu = node_to_menu_map_[node]; + if (!alt_menu) + alt_menu = CreateMenu(node, start_index); + + if (alt_menu) + menu_ = alt_menu; + + *button = bookmark_bar_->GetMenuButtonForNode(node); + bookmark_bar_->GetAnchorPositionAndStartIndexForButton( + *button, anchor, &start_index); + *has_mnemonics = false; + return alt_menu; +} + void BookmarkMenuController::BookmarkModelChanged() { menu_->Cancel(); } @@ -218,13 +270,27 @@ void BookmarkMenuController::BookmarkNodeFavIconLoaded( menu_->SetIcon(model->GetFavIcon(node), node_to_menu_id_map_[node]); } -void BookmarkMenuController::BuildOtherFolderMenu(int* next_menu_id) { +MenuItemView* BookmarkMenuController::CreateMenu(const BookmarkNode* parent, + int start_child_index) { + MenuItemView* menu = new MenuItemView(this); + menu->SetCommand(next_menu_id_++); + menu_id_to_node_map_[menu->GetCommand()] = parent; + menu->set_has_icons(true); + BuildMenu(parent, start_child_index, menu, &next_menu_id_); + if (show_other_folder_) + BuildOtherFolderMenu(menu, &next_menu_id_); + node_to_menu_map_[parent] = menu; + return menu; +} + +void BookmarkMenuController::BuildOtherFolderMenu( + MenuItemView* menu, int* next_menu_id) { const 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( + 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; @@ -232,7 +298,7 @@ void BookmarkMenuController::BuildOtherFolderMenu(int* next_menu_id) { void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, int start_child_index, - views::MenuItemView* menu, + MenuItemView* menu, int* next_menu_id) { DCHECK(!parent->GetChildCount() || start_child_index < parent->GetChildCount()); @@ -252,7 +318,7 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, } else if (node->is_folder()) { SkBitmap* folder_icon = ResourceBundle::GetSharedInstance(). GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER); - views::MenuItemView* submenu = + MenuItemView* submenu = menu->AppendSubMenuWithIcon(id, node->GetTitle(), *folder_icon); BuildMenu(node, 0, submenu, next_menu_id); } else { @@ -266,4 +332,5 @@ BookmarkMenuController::~BookmarkMenuController() { profile_->GetBookmarkModel()->RemoveObserver(this); if (observer_) observer_->BookmarkMenuDeleted(this); + STLDeleteValues(&node_to_menu_map_); } diff --git a/chrome/browser/views/bookmark_menu_controller_views.h b/chrome/browser/views/bookmark_menu_controller_views.h index fa6462f..f19c3cc 100644 --- a/chrome/browser/views/bookmark_menu_controller_views.h +++ b/chrome/browser/views/bookmark_menu_controller_views.h @@ -16,8 +16,13 @@ namespace gfx { class Rect; -} +} // namespace gfx +namespace views { +class MenuButton; +} // namespace views + +class BookmarkBarView; class BookmarkContextMenu; class BookmarkNode; class Browser; @@ -48,8 +53,10 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, int start_child_index, bool show_other_folder); + void RunMenuAt(BookmarkBarView* bookmark_bar, bool for_drop); + // Shows the menu. - void RunMenuAt(const gfx::Rect& bounds, + void RunMenuAt(views::MenuButton* button, views::MenuItemView::AnchorPosition position, bool for_drop); @@ -60,7 +67,7 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, const BookmarkNode* node() const { return node_; } // Returns the menu. - views::MenuItemView* menu() const { return menu_.get(); } + views::MenuItemView* menu() const { return menu_; } // Returns the context menu, or NULL if the context menu isn't showing. views::MenuItemView* context_menu() const { @@ -93,7 +100,14 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, virtual bool CanDrag(views::MenuItemView* menu); virtual void WriteDragData(views::MenuItemView* sender, OSExchangeData* data); virtual int GetDragOperations(views::MenuItemView* sender); + virtual views::MenuItemView* GetSiblingMenu( + views::MenuItemView* menu, + const gfx::Point& screen_point, + views::MenuItemView::AnchorPosition* anchor, + bool* has_mnemonics, + views::MenuButton** button); + // BookmarkModelObserver methods. virtual void BookmarkModelChanged(); virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, const BookmarkNode* node); @@ -102,9 +116,14 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // BookmarkMenuController deletes itself as necessary. ~BookmarkMenuController(); + // Creates a menu and adds it to node_to_menu_id_map_. This uses + // BuildMenu to recursively populate the menu. + views::MenuItemView* CreateMenu(const BookmarkNode* parent, + int start_child_index); + // Builds the menu for the other bookmarks folder. This is added as the last // item to menu_. - void BuildOtherFolderMenu(int* next_menu_id); + void BuildOtherFolderMenu(views::MenuItemView* menu, int* next_menu_id); // Creates an entry in menu for each child node of |parent| starting at // |start_child_index|. @@ -132,8 +151,8 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // URL. std::map<const BookmarkNode*, int> node_to_menu_id_map_; - // The menu. - scoped_ptr<views::MenuItemView> menu_; + // Current menu. + views::MenuItemView* menu_; // Data for the drop. BookmarkDragData drop_data_; @@ -150,6 +169,16 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // Should the other folder be shown? bool show_other_folder_; + // The bookmark bar. This is only non-null if we're showing a menu item + // for a folder on the bookmark bar and not for drop. + BookmarkBarView* bookmark_bar_; + + typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap; + NodeToMenuMap node_to_menu_map_; + + // ID of the next menu item. + int next_menu_id_; + DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController); }; |