summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc148
-rw-r--r--chrome/browser/views/bookmark_bar_view.h39
-rw-r--r--chrome/browser/views/bookmark_bar_view_test.cc3
-rw-r--r--chrome/browser/views/bookmark_context_menu.cc2
-rw-r--r--chrome/browser/views/bookmark_manager_view.cc4
-rw-r--r--chrome/browser/views/bookmark_menu_button.cc6
-rw-r--r--chrome/browser/views/bookmark_menu_controller_views.cc117
-rw-r--r--chrome/browser/views/bookmark_menu_controller_views.h41
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);
};