summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc2
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h4
-rw-r--r--chrome/browser/back_forward_menu_model_win.h2
-rw-r--r--chrome/browser/encoding_menu_controller_delegate.cc6
-rw-r--r--chrome/browser/encoding_menu_controller_delegate.h4
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.cc16
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.h12
-rw-r--r--chrome/browser/task_manager_win.cc9
-rw-r--r--chrome/browser/views/blocked_popup_container.cc9
-rw-r--r--chrome/browser/views/blocked_popup_container.h4
-rw-r--r--chrome/browser/views/bookmark_bar_view.h2
-rw-r--r--chrome/browser/views/bookmark_editor_view.cc4
-rw-r--r--chrome/browser/views/bookmark_editor_view.h4
-rw-r--r--chrome/browser/views/download_item_view.cc34
-rw-r--r--chrome/browser/views/frame/browser_view.cc12
-rw-r--r--chrome/browser/views/frame/browser_view.h9
-rw-r--r--chrome/browser/views/toolbar_view.cc128
-rw-r--r--chrome/browser/views/toolbar_view.h2
-rw-r--r--chrome/common/temp_scaffolding_stubs.h4
-rw-r--r--views/controls/button/button_dropdown.cc10
-rw-r--r--views/controls/menu/menu.cc547
-rw-r--r--views/controls/menu/menu.h134
-rw-r--r--views/controls/menu/menu_win.cc565
-rw-r--r--views/controls/menu/menu_win.h129
-rw-r--r--views/controls/scrollbar/bitmap_scroll_bar.cc25
-rw-r--r--views/controls/text_field.cc4
-rw-r--r--views/views.vcproj8
27 files changed, 910 insertions, 779 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index be81645..35bd86b 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -469,7 +469,7 @@ AutocompleteEditViewWin::AutocompleteEditViewWin(
SetDefaultCharFormat(cf);
// Set up context menu.
- context_menu_.reset(new Menu(this, Menu::TOPLEFT, m_hWnd));
+ context_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT, m_hWnd));
if (popup_window_mode_) {
context_menu_->AppendMenuItemWithLabel(IDS_COPY,
l10n_util::GetString(IDS_COPY));
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
index 6c74cc9..7b00044 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
@@ -44,7 +44,7 @@ class AutocompleteEditViewWin
CWinTraits<WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL |
ES_NOHIDESEL> >,
public CRichEditCommands<AutocompleteEditViewWin>,
- public Menu::Delegate,
+ public views::Menu::Delegate,
public AutocompleteEditView {
public:
struct State {
@@ -424,7 +424,7 @@ class AutocompleteEditViewWin
CHARRANGE saved_selection_for_focus_change_;
// The context menu for the edit.
- scoped_ptr<Menu> context_menu_;
+ scoped_ptr<views::Menu> context_menu_;
// Font we're using. We keep a reference to make sure the font supplied to
// the constructor doesn't go away before we do.
diff --git a/chrome/browser/back_forward_menu_model_win.h b/chrome/browser/back_forward_menu_model_win.h
index e1805cb..ed308df 100644
--- a/chrome/browser/back_forward_menu_model_win.h
+++ b/chrome/browser/back_forward_menu_model_win.h
@@ -13,7 +13,7 @@
class SkBitmap;
class BackForwardMenuModelWin : public BackForwardMenuModel,
- public Menu::Delegate {
+ public views::Menu::Delegate {
public:
BackForwardMenuModelWin(Browser* browser, ModelType model_type);
diff --git a/chrome/browser/encoding_menu_controller_delegate.cc b/chrome/browser/encoding_menu_controller_delegate.cc
index 6faac2d..6e45ec8 100644
--- a/chrome/browser/encoding_menu_controller_delegate.cc
+++ b/chrome/browser/encoding_menu_controller_delegate.cc
@@ -53,7 +53,7 @@ void EncodingMenuControllerDelegate::ExecuteCommand(int id) {
}
void EncodingMenuControllerDelegate::BuildEncodingMenu(
- Profile* profile, Menu* encoding_menu) {
+ Profile* profile, views::Menu* encoding_menu) {
typedef EncodingMenuController::EncodingMenuItemList EncodingMenuItemList;
EncodingMenuItemList menuItems;
EncodingMenuController controller;
@@ -62,7 +62,7 @@ void EncodingMenuControllerDelegate::BuildEncodingMenu(
for (EncodingMenuItemList::iterator it = menuItems.begin();
it != menuItems.end();
++it) {
- Menu::MenuItemType type = Menu::RADIO;
+ views::Menu::MenuItemType type = views::Menu::RADIO;
int id = it->first;
std::wstring &localized_title = it->second;
@@ -70,7 +70,7 @@ void EncodingMenuControllerDelegate::BuildEncodingMenu(
encoding_menu->AppendSeparator();
} else {
if (id == IDC_ENCODING_AUTO_DETECT) {
- type = Menu::CHECKBOX;
+ type = views::Menu::CHECKBOX;
}
encoding_menu->AppendMenuItem(id, localized_title, type);
diff --git a/chrome/browser/encoding_menu_controller_delegate.h b/chrome/browser/encoding_menu_controller_delegate.h
index f35a5e4..b052fc8a 100644
--- a/chrome/browser/encoding_menu_controller_delegate.h
+++ b/chrome/browser/encoding_menu_controller_delegate.h
@@ -14,7 +14,7 @@ class Profile;
// Encapsulates logic about populating the encoding menu and making
// sure the correct items are checked.
-class EncodingMenuControllerDelegate : public Menu::Delegate {
+class EncodingMenuControllerDelegate : public views::Menu::Delegate {
public:
explicit EncodingMenuControllerDelegate(Browser* browser);
@@ -29,7 +29,7 @@ class EncodingMenuControllerDelegate : public Menu::Delegate {
// is used in both the simple frame menu and in the page menu in the
// toolbar. (And probably elsewhere in the future, hence the
// dedicated delegate).
- static void BuildEncodingMenu(Profile* profile, Menu* encoding_menu);
+ static void BuildEncodingMenu(Profile* profile, views::Menu* encoding_menu);
private:
Browser* browser_;
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.cc b/chrome/browser/tab_contents/render_view_context_menu_win.cc
index 87dce53..dbb1ead 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.cc
@@ -14,7 +14,7 @@ RenderViewContextMenuWin::RenderViewContextMenuWin(
const ContextMenuParams& params,
HWND owner)
: RenderViewContextMenu(tab_contents, params),
- ALLOW_THIS_IN_INITIALIZER_LIST(menu_(this, Menu::TOPLEFT, owner)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(menu_(this, views::Menu::TOPLEFT, owner)),
sub_menu_(NULL) {
InitMenu(params.node);
}
@@ -27,26 +27,26 @@ void RenderViewContextMenuWin::RunMenuAt(int x, int y) {
}
void RenderViewContextMenuWin::AppendMenuItem(int id) {
- AppendItem(id, l10n_util::GetString(id), Menu::NORMAL);
+ AppendItem(id, l10n_util::GetString(id), views::Menu::NORMAL);
}
void RenderViewContextMenuWin::AppendMenuItem(int id,
const std::wstring& label) {
- AppendItem(id, label, Menu::NORMAL);
+ AppendItem(id, label, views::Menu::NORMAL);
}
void RenderViewContextMenuWin::AppendRadioMenuItem(int id,
const std::wstring& label) {
- AppendItem(id, label, Menu::RADIO);
+ AppendItem(id, label, views::Menu::RADIO);
}
void RenderViewContextMenuWin::AppendCheckboxMenuItem(int id,
const std::wstring& label) {
- AppendItem(id, label, Menu::CHECKBOX);
+ AppendItem(id, label, views::Menu::CHECKBOX);
}
void RenderViewContextMenuWin::AppendSeparator() {
- Menu* menu = sub_menu_ ? sub_menu_ : &menu_;
+ views::Menu* menu = sub_menu_ ? sub_menu_ : &menu_;
menu->AppendSeparator();
}
@@ -66,8 +66,8 @@ void RenderViewContextMenuWin::FinishSubMenu() {
void RenderViewContextMenuWin::AppendItem(
int id,
const std::wstring& label,
- Menu::MenuItemType type) {
- Menu* menu = sub_menu_ ? sub_menu_ : &menu_;
+ views::Menu::MenuItemType type) {
+ views::Menu* menu = sub_menu_ ? sub_menu_ : &menu_;
menu->AppendMenuItem(id, label, type);
}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.h b/chrome/browser/tab_contents/render_view_context_menu_win.h
index bc9578e..5d64342 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.h
@@ -7,10 +7,10 @@
#include "chrome/browser/tab_contents/render_view_context_menu.h"
#include "views/accelerator.h"
-#include "views/controls/menu/menu.h"
+#include "views/controls/menu/menu_win.h"
class RenderViewContextMenuWin : public RenderViewContextMenu,
- public Menu::Delegate{
+ public views::Menu::Delegate {
public:
RenderViewContextMenuWin(TabContents* tab_contents,
const ContextMenuParams& params,
@@ -39,10 +39,12 @@ class RenderViewContextMenuWin : public RenderViewContextMenu,
private:
// Append the item to |sub_menu_| if it exists, or |menu_| otherwise.
- void AppendItem(int id, const std::wstring& label, Menu::MenuItemType type);
+ void AppendItem(int id,
+ const std::wstring& label,
+ views::Menu::MenuItemType type);
- Menu menu_;
- Menu* sub_menu_;
+ views::MenuWin menu_;
+ views::Menu* sub_menu_;
};
#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_WIN_H_
diff --git a/chrome/browser/task_manager_win.cc b/chrome/browser/task_manager_win.cc
index 9fa0eba..d20d5a2 100644
--- a/chrome/browser/task_manager_win.cc
+++ b/chrome/browser/task_manager_win.cc
@@ -167,7 +167,7 @@ class TaskManagerViewImpl : public TaskManagerView,
public views::TableViewObserver,
public views::LinkController,
public views::ContextMenuController,
- public Menu::Delegate {
+ public views::Menu::Delegate {
public:
TaskManagerViewImpl(TaskManager* task_manager,
TaskManagerModel* model);
@@ -498,12 +498,13 @@ void TaskManagerViewImpl::ShowContextMenu(views::View* source,
int y,
bool is_mouse_gesture) {
UpdateStatsCounters();
- Menu menu(this, Menu::TOPLEFT, source->GetWidget()->GetNativeView());
+ scoped_ptr<views::Menu> menu(views::Menu::Create(
+ this, views::Menu::TOPLEFT, source->GetWidget()->GetNativeView()));
for (std::vector<views::TableColumn>::iterator i =
columns_.begin(); i != columns_.end(); ++i) {
- menu.AppendMenuItem(i->id, i->title, Menu::CHECKBOX);
+ menu->AppendMenuItem(i->id, i->title, views::Menu::CHECKBOX);
}
- menu.RunMenuAt(x, y);
+ menu->RunMenuAt(x, y);
}
bool TaskManagerViewImpl::IsItemChecked(int id) const {
diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc
index 47e5f8e..b94adb1 100644
--- a/chrome/browser/views/blocked_popup_container.cc
+++ b/chrome/browser/views/blocked_popup_container.cc
@@ -179,8 +179,8 @@ gfx::Size BlockedPopupContainerView::GetPreferredSize() {
void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
if (sender == popup_count_label_) {
- launch_menu_.reset(new Menu(this, Menu::TOPLEFT,
- container_->GetNativeView()));
+ launch_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT,
+ container_->GetNativeView()));
// Set items 1 .. popup_count as individual popups.
size_t popup_count = container_->GetBlockedPopupCount();
@@ -191,7 +191,7 @@ void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
// the value 0 as the nop command.
launch_menu_->AppendMenuItem(i + 1,
l10n_util::GetStringF(IDS_POPUP_TITLE_FORMAT, url, title),
- Menu::NORMAL);
+ views::Menu::NORMAL);
}
// Set items (kImpossibleNumberOfPopups + 1) ..
@@ -201,7 +201,8 @@ void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
launch_menu_->AppendSeparator();
for (size_t i = 0; i < hosts.size(); ++i) {
launch_menu_->AppendMenuItem(kImpossibleNumberOfPopups + i + 1,
- l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]), Menu::NORMAL);
+ l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]),
+ views::Menu::NORMAL);
}
CPoint cursor_position;
diff --git a/chrome/browser/views/blocked_popup_container.h b/chrome/browser/views/blocked_popup_container.h
index 640bdd0..dcf7d8f 100644
--- a/chrome/browser/views/blocked_popup_container.h
+++ b/chrome/browser/views/blocked_popup_container.h
@@ -39,7 +39,7 @@ class ImageButton;
// blocked. This view should only be used inside of BlockedPopupContainer.
class BlockedPopupContainerView : public views::View,
public views::ButtonListener,
- public Menu::Delegate {
+ public views::Menu::Delegate {
public:
explicit BlockedPopupContainerView(BlockedPopupContainer* container);
~BlockedPopupContainerView();
@@ -79,7 +79,7 @@ class BlockedPopupContainerView : public views::View,
views::ImageButton* close_button_;
// Popup menu shown to user.
- scoped_ptr<Menu> launch_menu_;
+ scoped_ptr<views::Menu> launch_menu_;
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainerView);
};
diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h
index ccf787e..1986d2f 100644
--- a/chrome/browser/views/bookmark_bar_view.h
+++ b/chrome/browser/views/bookmark_bar_view.h
@@ -42,7 +42,7 @@ class BookmarkBarView : public views::View,
public BookmarkModelObserver,
public views::ViewMenuDelegate,
public views::ButtonListener,
- public Menu::Delegate,
+ public views::Menu::Delegate,
public NotificationObserver,
public views::ContextMenuController,
public views::DragController,
diff --git a/chrome/browser/views/bookmark_editor_view.cc b/chrome/browser/views/bookmark_editor_view.cc
index 0aee8bc..835ba59 100644
--- a/chrome/browser/views/bookmark_editor_view.cc
+++ b/chrome/browser/views/bookmark_editor_view.cc
@@ -225,8 +225,8 @@ void BookmarkEditorView::ShowContextMenu(View* source,
running_menu_for_root_ =
(tree_model_->GetParent(tree_view_->GetSelectedNode()) ==
tree_model_->GetRoot());
- context_menu_.reset(new Menu(this, Menu::TOPLEFT,
- GetWidget()->GetNativeView()));
+ context_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT,
+ GetWidget()->GetNativeView()));
context_menu_->AppendMenuItemWithLabel(IDS_EDIT,
l10n_util::GetString(IDS_EDIT));
context_menu_->AppendMenuItemWithLabel(
diff --git a/chrome/browser/views/bookmark_editor_view.h b/chrome/browser/views/bookmark_editor_view.h
index 4ca3fde..754e5f8 100644
--- a/chrome/browser/views/bookmark_editor_view.h
+++ b/chrome/browser/views/bookmark_editor_view.h
@@ -40,7 +40,7 @@ class BookmarkEditorView : public BookmarkEditor,
public views::DialogDelegate,
public views::TextField::Controller,
public views::ContextMenuController,
- public Menu::Delegate,
+ public views::Menu::Delegate,
public BookmarkModelObserver {
FRIEND_TEST(BookmarkEditorViewTest, ChangeParent);
FRIEND_TEST(BookmarkEditorViewTest, ChangeParentAndURL);
@@ -243,7 +243,7 @@ class BookmarkEditorView : public BookmarkEditor,
BookmarkNode* node_;
// The context menu.
- scoped_ptr<Menu> context_menu_;
+ scoped_ptr<views::Menu> context_menu_;
// Mode used to create nodes from.
BookmarkModel* bb_model_;
diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc
index 7aa2a37..1e9554f 100644
--- a/chrome/browser/views/download_item_view.cc
+++ b/chrome/browser/views/download_item_view.cc
@@ -65,7 +65,7 @@ static const int kDisabledOnOpenDuration = 3000;
// DownloadShelfContextMenuWin -------------------------------------------------
class DownloadShelfContextMenuWin : public DownloadShelfContextMenu,
- public Menu::Delegate {
+ public views::Menu::Delegate {
public:
DownloadShelfContextMenuWin::DownloadShelfContextMenuWin(
BaseDownloadItemModel* model,
@@ -75,23 +75,27 @@ class DownloadShelfContextMenuWin : public DownloadShelfContextMenu,
DCHECK(model);
// The menu's anchor point is determined based on the UI layout.
- Menu::AnchorPoint anchor_point;
+ views::Menu::AnchorPoint anchor_point;
if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
- anchor_point = Menu::TOPRIGHT;
+ anchor_point = views::Menu::TOPRIGHT;
else
- anchor_point = Menu::TOPLEFT;
+ anchor_point = views::Menu::TOPLEFT;
- Menu context_menu(this, anchor_point, window);
- if (download_->state() == DownloadItem::COMPLETE)
- context_menu.AppendMenuItem(OPEN_WHEN_COMPLETE, L"", Menu::NORMAL);
- else
- context_menu.AppendMenuItem(OPEN_WHEN_COMPLETE, L"", Menu::CHECKBOX);
- context_menu.AppendMenuItem(ALWAYS_OPEN_TYPE, L"", Menu::CHECKBOX);
- context_menu.AppendSeparator();
- context_menu.AppendMenuItem(SHOW_IN_FOLDER, L"", Menu::NORMAL);
- context_menu.AppendSeparator();
- context_menu.AppendMenuItem(CANCEL, L"", Menu::NORMAL);
- context_menu.RunMenuAt(point.x(), point.y());
+ scoped_ptr<views::Menu> context_menu(
+ views::Menu::Create(this, anchor_point, window));
+ if (download_->state() == DownloadItem::COMPLETE) {
+ context_menu->AppendMenuItem(OPEN_WHEN_COMPLETE, L"",
+ views::Menu::NORMAL);
+ } else {
+ context_menu->AppendMenuItem(OPEN_WHEN_COMPLETE, L"",
+ views::Menu::CHECKBOX);
+ }
+ context_menu->AppendMenuItem(ALWAYS_OPEN_TYPE, L"", views::Menu::CHECKBOX);
+ context_menu->AppendSeparator();
+ context_menu->AppendMenuItem(SHOW_IN_FOLDER, L"", views::Menu::NORMAL);
+ context_menu->AppendSeparator();
+ context_menu->AppendMenuItem(CANCEL, L"", views::Menu::NORMAL);
+ context_menu->RunMenuAt(point.x(), point.y());
}
// Menu::Delegate implementation ---------------------------------------------
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index b3aa486..a438cdf 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -60,6 +60,7 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/webkit_resources.h"
+#include "views/controls/menu/menu_win.h"
#include "views/controls/scrollbar/native_scroll_bar.h"
#include "views/fill_layout.h"
#include "views/view.h"
@@ -1298,7 +1299,7 @@ void BrowserView::Init() {
void BrowserView::InitSystemMenu() {
HMENU system_menu = GetSystemMenu(frame_->GetNativeView(), FALSE);
- system_menu_.reset(new Menu(system_menu));
+ system_menu_.reset(new views::MenuWin(system_menu));
int insertion_index = std::max(0, system_menu_->ItemCount() - 1);
// We add the menu items in reverse order so that insertion_index never needs
// to change.
@@ -1549,7 +1550,7 @@ void BrowserView::LoadAccelerators() {
free(accelerators);
}
-void BrowserView::BuildMenuForTabStriplessWindow(Menu* menu,
+void BrowserView::BuildMenuForTabStriplessWindow(views::Menu* menu,
int insertion_index) {
encoding_menu_delegate_.reset(new EncodingMenuControllerDelegate(
browser_.get()));
@@ -1560,7 +1561,7 @@ void BrowserView::BuildMenuForTabStriplessWindow(Menu* menu,
} else {
int command = kMenuLayout[i].command;
if (command == IDC_ENCODING_MENU) {
- Menu* encoding_menu = menu->AddSubMenu(
+ views::Menu* encoding_menu = menu->AddSubMenu(
insertion_index,
IDC_ENCODING_MENU,
l10n_util::GetString(IDS_ENCODING_MENU));
@@ -1568,8 +1569,9 @@ void BrowserView::BuildMenuForTabStriplessWindow(Menu* menu,
EncodingMenuControllerDelegate::BuildEncodingMenu(browser_->profile(),
encoding_menu);
} else if (command == IDC_ZOOM_MENU) {
- Menu* zoom_menu = menu->AddSubMenu(insertion_index, IDC_ZOOM_MENU,
- l10n_util::GetString(IDS_ZOOM_MENU));
+ views::Menu* zoom_menu =
+ menu->AddSubMenu(insertion_index, IDC_ZOOM_MENU,
+ l10n_util::GetString(IDS_ZOOM_MENU));
zoom_menu->AppendMenuItemWithLabel(
IDC_ZOOM_PLUS,
l10n_util::GetString(IDS_ZOOM_PLUS));
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 40afbc5..c3e0734 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -25,10 +25,13 @@ class ExtensionShelf;
class FullscreenExitBubble;
class HtmlDialogUIDelegate;
class InfoBarContainer;
-class Menu;
class StatusBubbleViews;
class TabContentsContainerView;
+namespace views {
+class Menu;
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView
//
@@ -316,7 +319,7 @@ class BrowserView : public BrowserWindow,
void LoadAccelerators();
// Builds the correct menu for when we have minimal chrome.
- void BuildMenuForTabStriplessWindow(Menu* menu, int insertion_index);
+ void BuildMenuForTabStriplessWindow(views::Menu* menu, int insertion_index);
// Retrieves the command id for the specified Windows app command.
int GetCommandIDForAppCommandID(int app_command_id) const;
@@ -376,7 +379,7 @@ class BrowserView : public BrowserWindow,
scoped_ptr<FullscreenExitBubble> fullscreen_bubble_;
// Lazily created representation of the system menu.
- scoped_ptr<Menu> system_menu_;
+ scoped_ptr<views::Menu> system_menu_;
// The default favicon image.
static SkBitmap default_favicon_;
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc
index 104cb34..5162b98 100644
--- a/chrome/browser/views/toolbar_view.cc
+++ b/chrome/browser/views/toolbar_view.cc
@@ -583,28 +583,28 @@ gfx::Size BrowserToolbarView::GetPreferredSize() {
}
void BrowserToolbarView::RunPageMenu(const gfx::Point& pt, HWND hwnd) {
- Menu::AnchorPoint anchor = Menu::TOPRIGHT;
+ views::Menu::AnchorPoint anchor = views::Menu::TOPRIGHT;
if (UILayoutIsRightToLeft())
- anchor = Menu::TOPLEFT;
+ anchor = views::Menu::TOPLEFT;
- Menu menu(this, anchor, hwnd);
- menu.AppendMenuItemWithLabel(IDC_CREATE_SHORTCUTS,
+ scoped_ptr<views::Menu> menu(views::Menu::Create(this, anchor, hwnd));
+ menu->AppendMenuItemWithLabel(IDC_CREATE_SHORTCUTS,
l10n_util::GetString(IDS_CREATE_SHORTCUTS));
- menu.AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_CUT, l10n_util::GetString(IDS_CUT));
- menu.AppendMenuItemWithLabel(IDC_COPY, l10n_util::GetString(IDS_COPY));
- menu.AppendMenuItemWithLabel(IDC_PASTE, l10n_util::GetString(IDS_PASTE));
- menu.AppendSeparator();
-
- menu.AppendMenuItemWithLabel(IDC_FIND,
- l10n_util::GetString(IDS_FIND));
- menu.AppendMenuItemWithLabel(IDC_SAVE_PAGE,
- l10n_util::GetString(IDS_SAVE_PAGE));
- menu.AppendMenuItemWithLabel(IDC_PRINT, l10n_util::GetString(IDS_PRINT));
- menu.AppendSeparator();
-
- Menu* zoom_menu = menu.AppendSubMenu(IDC_ZOOM_MENU,
- l10n_util::GetString(IDS_ZOOM_MENU));
+ menu->AppendSeparator();
+ menu->AppendMenuItemWithLabel(IDC_CUT, l10n_util::GetString(IDS_CUT));
+ menu->AppendMenuItemWithLabel(IDC_COPY, l10n_util::GetString(IDS_COPY));
+ menu->AppendMenuItemWithLabel(IDC_PASTE, l10n_util::GetString(IDS_PASTE));
+ menu->AppendSeparator();
+
+ menu->AppendMenuItemWithLabel(IDC_FIND,
+ l10n_util::GetString(IDS_FIND));
+ menu->AppendMenuItemWithLabel(IDC_SAVE_PAGE,
+ l10n_util::GetString(IDS_SAVE_PAGE));
+ menu->AppendMenuItemWithLabel(IDC_PRINT, l10n_util::GetString(IDS_PRINT));
+ menu->AppendSeparator();
+
+ views::Menu* zoom_menu = menu->AppendSubMenu(
+ IDC_ZOOM_MENU, l10n_util::GetString(IDS_ZOOM_MENU));
zoom_menu->AppendMenuItemWithLabel(IDC_ZOOM_PLUS,
l10n_util::GetString(IDS_ZOOM_PLUS));
zoom_menu->AppendMenuItemWithLabel(IDC_ZOOM_NORMAL,
@@ -613,7 +613,7 @@ void BrowserToolbarView::RunPageMenu(const gfx::Point& pt, HWND hwnd) {
l10n_util::GetString(IDS_ZOOM_MINUS));
// Create encoding menu.
- Menu* encoding_menu = menu.AppendSubMenu(
+ views::Menu* encoding_menu = menu->AppendSubMenu(
IDC_ENCODING_MENU, l10n_util::GetString(IDS_ENCODING_MENU));
EncodingMenuControllerDelegate::BuildEncodingMenu(profile_, encoding_menu);
@@ -629,8 +629,8 @@ void BrowserToolbarView::RunPageMenu(const gfx::Point& pt, HWND hwnd) {
{ IDC_TASK_MANAGER, IDS_TASK_MANAGER }
};
// Append developer menu.
- menu.AppendSeparator();
- Menu* developer_menu = menu.AppendSubMenu(IDC_DEVELOPER_MENU,
+ menu->AppendSeparator();
+ views::Menu* developer_menu = menu->AppendSubMenu(IDC_DEVELOPER_MENU,
l10n_util::GetString(IDS_DEVELOPER_MENU));
for (int i = 0; i < arraysize(developer_menu_materials); ++i) {
if (developer_menu_materials[i].menu_id) {
@@ -642,24 +642,24 @@ void BrowserToolbarView::RunPageMenu(const gfx::Point& pt, HWND hwnd) {
}
}
- menu.AppendSeparator();
+ menu->AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_REPORT_BUG,
+ menu->AppendMenuItemWithLabel(IDC_REPORT_BUG,
l10n_util::GetString(IDS_REPORT_BUG));
- menu.RunMenuAt(pt.x(), pt.y());
+ menu->RunMenuAt(pt.x(), pt.y());
}
void BrowserToolbarView::RunAppMenu(const gfx::Point& pt, HWND hwnd) {
- Menu::AnchorPoint anchor = Menu::TOPRIGHT;
+ views::Menu::AnchorPoint anchor = views::Menu::TOPRIGHT;
if (UILayoutIsRightToLeft())
- anchor = Menu::TOPLEFT;
+ anchor = views::Menu::TOPLEFT;
- Menu menu(this, anchor, hwnd);
- menu.AppendMenuItemWithLabel(IDC_NEW_TAB, l10n_util::GetString(IDS_NEW_TAB));
- menu.AppendMenuItemWithLabel(IDC_NEW_WINDOW,
- l10n_util::GetString(IDS_NEW_WINDOW));
- menu.AppendMenuItemWithLabel(IDC_NEW_INCOGNITO_WINDOW,
- l10n_util::GetString(IDS_NEW_INCOGNITO_WINDOW));
+ scoped_ptr<views::Menu> menu(views::Menu::Create(this, anchor, hwnd));
+ menu->AppendMenuItemWithLabel(IDC_NEW_TAB, l10n_util::GetString(IDS_NEW_TAB));
+ menu->AppendMenuItemWithLabel(IDC_NEW_WINDOW,
+ l10n_util::GetString(IDS_NEW_WINDOW));
+ menu->AppendMenuItemWithLabel(IDC_NEW_INCOGNITO_WINDOW,
+ l10n_util::GetString(IDS_NEW_INCOGNITO_WINDOW));
// Enumerate profiles asynchronously and then create the parent menu item.
// We will create the child menu items for this once the asynchronous call is
@@ -667,44 +667,44 @@ void BrowserToolbarView::RunAppMenu(const gfx::Point& pt, HWND hwnd) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kEnableUserDataDirProfiles)) {
profiles_helper_->GetProfiles(NULL);
- profiles_menu_ = menu.AppendSubMenu(IDC_PROFILE_MENU,
- l10n_util::GetString(IDS_PROFILE_MENU));
+ profiles_menu_ = menu->AppendSubMenu(
+ IDC_PROFILE_MENU, l10n_util::GetString(IDS_PROFILE_MENU));
}
- menu.AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_SHOW_BOOKMARK_BAR,
- l10n_util::GetString(IDS_SHOW_BOOKMARK_BAR));
- menu.AppendMenuItemWithLabel(IDC_FULLSCREEN,
- l10n_util::GetString(IDS_FULLSCREEN));
- menu.AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_SHOW_HISTORY,
- l10n_util::GetString(IDS_SHOW_HISTORY));
- menu.AppendMenuItemWithLabel(IDC_SHOW_BOOKMARK_MANAGER,
- l10n_util::GetString(IDS_BOOKMARK_MANAGER));
- menu.AppendMenuItemWithLabel(IDC_SHOW_DOWNLOADS,
- l10n_util::GetString(IDS_SHOW_DOWNLOADS));
- menu.AppendSeparator();
+ menu->AppendSeparator();
+ menu->AppendMenuItemWithLabel(IDC_SHOW_BOOKMARK_BAR,
+ l10n_util::GetString(IDS_SHOW_BOOKMARK_BAR));
+ menu->AppendMenuItemWithLabel(IDC_FULLSCREEN,
+ l10n_util::GetString(IDS_FULLSCREEN));
+ menu->AppendSeparator();
+ menu->AppendMenuItemWithLabel(IDC_SHOW_HISTORY,
+ l10n_util::GetString(IDS_SHOW_HISTORY));
+ menu->AppendMenuItemWithLabel(IDC_SHOW_BOOKMARK_MANAGER,
+ l10n_util::GetString(IDS_BOOKMARK_MANAGER));
+ menu->AppendMenuItemWithLabel(IDC_SHOW_DOWNLOADS,
+ l10n_util::GetString(IDS_SHOW_DOWNLOADS));
+ menu->AppendSeparator();
#ifdef CHROME_PERSONALIZATION
if (!Personalization::IsP13NDisabled()) {
- menu.AppendMenuItemWithLabel(IDC_P13N_INFO,
+ menu->AppendMenuItemWithLabel(IDC_P13N_INFO,
Personalization::GetMenuItemInfoText(browser()));
}
#endif
- menu.AppendMenuItemWithLabel(IDC_CLEAR_BROWSING_DATA,
- l10n_util::GetString(IDS_CLEAR_BROWSING_DATA));
- menu.AppendMenuItemWithLabel(IDC_IMPORT_SETTINGS,
- l10n_util::GetString(IDS_IMPORT_SETTINGS));
- menu.AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_OPTIONS, l10n_util::GetStringF(IDS_OPTIONS,
- l10n_util::GetString(IDS_PRODUCT_NAME)));
- menu.AppendMenuItemWithLabel(IDC_ABOUT, l10n_util::GetStringF(IDS_ABOUT,
- l10n_util::GetString(IDS_PRODUCT_NAME)));
- menu.AppendMenuItemWithLabel(IDC_HELP_PAGE,
- l10n_util::GetString(IDS_HELP_PAGE));
- menu.AppendSeparator();
- menu.AppendMenuItemWithLabel(IDC_EXIT, l10n_util::GetString(IDS_EXIT));
-
- menu.RunMenuAt(pt.x(), pt.y());
+ menu->AppendMenuItemWithLabel(IDC_CLEAR_BROWSING_DATA,
+ l10n_util::GetString(IDS_CLEAR_BROWSING_DATA));
+ menu->AppendMenuItemWithLabel(IDC_IMPORT_SETTINGS,
+ l10n_util::GetString(IDS_IMPORT_SETTINGS));
+ menu->AppendSeparator();
+ menu->AppendMenuItemWithLabel(IDC_OPTIONS, l10n_util::GetStringF(IDS_OPTIONS,
+ l10n_util::GetString(IDS_PRODUCT_NAME)));
+ menu->AppendMenuItemWithLabel(IDC_ABOUT, l10n_util::GetStringF(IDS_ABOUT,
+ l10n_util::GetString(IDS_PRODUCT_NAME)));
+ menu->AppendMenuItemWithLabel(IDC_HELP_PAGE,
+ l10n_util::GetString(IDS_HELP_PAGE));
+ menu->AppendSeparator();
+ menu->AppendMenuItemWithLabel(IDC_EXIT, l10n_util::GetString(IDS_EXIT));
+
+ menu->RunMenuAt(pt.x(), pt.y());
// Menu is going away, so set the profiles menu pointer to NULL.
profiles_menu_ = NULL;
diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h
index ad373d4..64feb34 100644
--- a/chrome/browser/views/toolbar_view.h
+++ b/chrome/browser/views/toolbar_view.h
@@ -202,7 +202,7 @@ class BrowserToolbarView : public views::View,
TabContents* tab_;
// Profiles menu to populate with profile names.
- Menu* profiles_menu_;
+ views::Menu* profiles_menu_;
// Helper class to enumerate profiles information on the file thread.
scoped_refptr<GetProfilesHelper> profiles_helper_;
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index fe22906..eda42e8 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -247,6 +247,8 @@ class Window {
class InputWindowDelegate {
};
+namespace views {
+
class Menu {
public:
enum AnchorPoint {
@@ -279,6 +281,8 @@ class Menu {
void AppendDelegateMenuItem(int item_id) { NOTIMPLEMENTED(); }
};
+} // namespace view
+
class BookmarkManagerView {
public:
static BookmarkManagerView* current() {
diff --git a/views/controls/button/button_dropdown.cc b/views/controls/button/button_dropdown.cc
index 157caf0..6c81c24 100644
--- a/views/controls/button/button_dropdown.cc
+++ b/views/controls/button/button_dropdown.cc
@@ -137,7 +137,7 @@ void ButtonDropDown::ShowDropDownMenu(HWND window) {
if (menu_position.x() < left_bound)
menu_position.set_x(left_bound);
- Menu menu(menu_delegate_, anchor, window);
+ scoped_ptr<Menu> menu(Menu::Create(menu_delegate_, anchor, window));
// ID's for AppendMenu is 1-based because RunMenu will ignore the user
// selection if id=0 is selected (0 = NO-OP) so we add 1 here and subtract 1
@@ -145,16 +145,16 @@ void ButtonDropDown::ShowDropDownMenu(HWND window) {
int item_count = menu_delegate_->GetItemCount();
for (int i = 0; i < item_count; i++) {
if (menu_delegate_->IsItemSeparator(i + 1)) {
- menu.AppendSeparator();
+ menu->AppendSeparator();
} else {
if (menu_delegate_->HasIcon(i + 1))
- menu.AppendMenuItemWithIcon(i + 1, L"", SkBitmap());
+ menu->AppendMenuItemWithIcon(i + 1, L"", SkBitmap());
else
- menu.AppendMenuItem(i+1, L"", Menu::NORMAL);
+ menu->AppendMenuItem(i+1, L"", Menu::NORMAL);
}
}
- menu.RunMenuAt(menu_position.x(), menu_position.y());
+ menu->RunMenuAt(menu_position.x(), menu_position.y());
// Need to explicitly clear mouse handler so that events get sent
// properly after the menu finishes running. If we don't do this, then
diff --git a/views/controls/menu/menu.cc b/views/controls/menu/menu.cc
index 1597da5..6a81d9c 100644
--- a/views/controls/menu/menu.cc
+++ b/views/controls/menu/menu.cc
@@ -4,353 +4,31 @@
#include "views/controls/menu/menu.h"
-#include <atlbase.h>
-#include <atlapp.h>
-#include <atlwin.h>
-#include <atlcrack.h>
-#include <atlframe.h>
-#include <atlmisc.h>
-#include <string>
-
-#include "app/gfx/chrome_canvas.h"
-#include "app/gfx/chrome_font.h"
#include "app/l10n_util.h"
-#include "app/l10n_util_win.h"
-#include "base/gfx/rect.h"
-#include "base/logging.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "views/accelerator.h"
-
-const SkBitmap* Menu::Delegate::kEmptyIcon = 0;
-
-// The width of an icon, including the pixels between the icon and
-// the item label.
-static const int kIconWidth = 23;
-// Margins between the top of the item and the label.
-static const int kItemTopMargin = 3;
-// Margins between the bottom of the item and the label.
-static const int kItemBottomMargin = 4;
-// Margins between the left of the item and the icon.
-static const int kItemLeftMargin = 4;
-// Margins between the right of the item and the label.
-static const int kItemRightMargin = 10;
-// The width for displaying the sub-menu arrow.
-static const int kArrowWidth = 10;
-
-// Current active MenuHostWindow. If NULL, no menu is active.
-static MenuHostWindow* active_host_window = NULL;
-
-// The data of menu items needed to display.
-struct Menu::ItemData {
- std::wstring label;
- SkBitmap icon;
- bool submenu;
-};
-
-namespace {
-
-static int ChromeGetMenuItemID(HMENU hMenu, int pos) {
- // The built-in Windows ::GetMenuItemID doesn't work for submenus,
- // so here's our own implementation.
- MENUITEMINFO mii = {0};
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_ID;
- GetMenuItemInfo(hMenu, pos, TRUE, &mii);
- return mii.wID;
-}
-
-// MenuHostWindow -------------------------------------------------------------
-
-// MenuHostWindow is the HWND the HMENU is parented to. MenuHostWindow is used
-// to intercept right clicks on the HMENU and notify the delegate as well as
-// for drawing icons.
-//
-class MenuHostWindow : public CWindowImpl<MenuHostWindow, CWindow,
- CWinTraits<WS_CHILD>> {
- public:
- MenuHostWindow(Menu* menu, HWND parent_window) : menu_(menu) {
- int extended_style = 0;
- // If the menu needs to be created with a right-to-left UI layout, we must
- // set the appropriate RTL flags (such as WS_EX_LAYOUTRTL) property for the
- // underlying HWND.
- if (menu_->delegate_->IsRightToLeftUILayout())
- extended_style |= l10n_util::GetExtendedStyles();
- Create(parent_window, gfx::Rect().ToRECT(), 0, 0, extended_style);
- }
-
- ~MenuHostWindow() {
- DestroyWindow();
- }
-
- DECLARE_FRAME_WND_CLASS(L"MenuHostWindow", NULL);
- BEGIN_MSG_MAP(MenuHostWindow);
- MSG_WM_RBUTTONUP(OnRButtonUp)
- MSG_WM_MEASUREITEM(OnMeasureItem)
- MSG_WM_DRAWITEM(OnDrawItem)
- END_MSG_MAP();
-
- private:
- // NOTE: I really REALLY tried to use WM_MENURBUTTONUP, but I ran into
- // two problems in using it:
- // 1. It doesn't contain the coordinates of the mouse.
- // 2. It isn't invoked for menuitems representing a submenu that have children
- // menu items (not empty).
-
- void OnRButtonUp(UINT w_param, const CPoint& loc) {
- int id;
- if (menu_->delegate_ && FindMenuIDByLocation(menu_, loc, &id))
- menu_->delegate_->ShowContextMenu(menu_, id, loc.x, loc.y, true);
- }
-
- void OnMeasureItem(WPARAM w_param, MEASUREITEMSTRUCT* lpmis) {
- Menu::ItemData* data = reinterpret_cast<Menu::ItemData*>(lpmis->itemData);
- if (data != NULL) {
- ChromeFont font;
- lpmis->itemWidth = font.GetStringWidth(data->label) + kIconWidth +
- kItemLeftMargin + kItemRightMargin -
- GetSystemMetrics(SM_CXMENUCHECK);
- if (data->submenu)
- lpmis->itemWidth += kArrowWidth;
- // If the label contains an accelerator, make room for tab.
- if (data->label.find(L'\t') != std::wstring::npos)
- lpmis->itemWidth += font.GetStringWidth(L" ");
- lpmis->itemHeight = font.height() + kItemBottomMargin + kItemTopMargin;
- } else {
- // Measure separator size.
- lpmis->itemHeight = GetSystemMetrics(SM_CYMENU) / 2;
- lpmis->itemWidth = 0;
- }
- }
-
- void OnDrawItem(UINT wParam, DRAWITEMSTRUCT* lpdis) {
- HDC hDC = lpdis->hDC;
- COLORREF prev_bg_color, prev_text_color;
-
- // Set background color and text color
- if (lpdis->itemState & ODS_SELECTED) {
- prev_bg_color = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
- prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
- } else {
- prev_bg_color = SetBkColor(hDC, GetSysColor(COLOR_MENU));
- if (lpdis->itemState & ODS_DISABLED)
- prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
- else
- prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_MENUTEXT));
- }
-
- if (lpdis->itemData) {
- Menu::ItemData* data =
- reinterpret_cast<Menu::ItemData*>(lpdis->itemData);
-
- // Draw the background.
- HBRUSH hbr = CreateSolidBrush(GetBkColor(hDC));
- FillRect(hDC, &lpdis->rcItem, hbr);
- DeleteObject(hbr);
-
- // Draw the label.
- RECT rect = lpdis->rcItem;
- rect.top += kItemTopMargin;
- // Should we add kIconWidth only when icon.width() != 0 ?
- rect.left += kItemLeftMargin + kIconWidth;
- rect.right -= kItemRightMargin;
- UINT format = DT_TOP | DT_SINGLELINE;
- // Check whether the mnemonics should be underlined.
- BOOL underline_mnemonics;
- SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &underline_mnemonics, 0);
- if (!underline_mnemonics)
- format |= DT_HIDEPREFIX;
- ChromeFont font;
- HGDIOBJ old_font = static_cast<HFONT>(SelectObject(hDC, font.hfont()));
- int fontsize = font.FontSize();
-
- // If an accelerator is specified (with a tab delimiting the rest of the
- // label from the accelerator), we have to justify the fist part on the
- // left and the accelerator on the right.
- // TODO(jungshik): This will break in RTL UI. Currently, he/ar use the
- // window system UI font and will not hit here.
- std::wstring label = data->label;
- std::wstring accel;
- std::wstring::size_type tab_pos = label.find(L'\t');
- if (tab_pos != std::wstring::npos) {
- accel = label.substr(tab_pos);
- label = label.substr(0, tab_pos);
- }
- DrawTextEx(hDC, const_cast<wchar_t*>(label.data()),
- static_cast<int>(label.size()), &rect, format | DT_LEFT, NULL);
- if (!accel.empty())
- DrawTextEx(hDC, const_cast<wchar_t*>(accel.data()),
- static_cast<int>(accel.size()), &rect,
- format | DT_RIGHT, NULL);
- SelectObject(hDC, old_font);
+#include "third_party/skia/include/core/SkBitmap.h"
- // Draw the icon after the label, otherwise it would be covered
- // by the label.
- if (data->icon.width() != 0 && data->icon.height() != 0) {
- ChromeCanvas canvas(data->icon.width(), data->icon.height(), false);
- canvas.drawColor(SK_ColorBLACK, SkPorterDuff::kClear_Mode);
- canvas.DrawBitmapInt(data->icon, 0, 0);
- canvas.getTopPlatformDevice().drawToHDC(hDC, lpdis->rcItem.left +
- kItemLeftMargin, lpdis->rcItem.top + (lpdis->rcItem.bottom -
- lpdis->rcItem.top - data->icon.height()) / 2, NULL);
- }
-
- } else {
- // Draw the separator
- lpdis->rcItem.top += (lpdis->rcItem.bottom - lpdis->rcItem.top) / 3;
- DrawEdge(hDC, &lpdis->rcItem, EDGE_ETCHED, BF_TOP);
- }
-
- SetBkColor(hDC, prev_bg_color);
- SetTextColor(hDC, prev_text_color);
- }
-
- bool FindMenuIDByLocation(Menu* menu, const CPoint& loc, int* id) {
- int index = MenuItemFromPoint(NULL, menu->menu_, loc);
- if (index != -1) {
- *id = ChromeGetMenuItemID(menu->menu_, index);
- return true;
- } else {
- for (std::vector<Menu*>::iterator i = menu->submenus_.begin();
- i != menu->submenus_.end(); ++i) {
- if (FindMenuIDByLocation(*i, loc, id))
- return true;
- }
- }
- return false;
- }
-
- // The menu that created us.
- Menu* menu_;
-
- DISALLOW_EVIL_CONSTRUCTORS(MenuHostWindow);
-};
-
-} // namespace
+namespace views {
bool Menu::Delegate::IsRightToLeftUILayout() const {
return l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT;
}
const SkBitmap& Menu::Delegate::GetEmptyIcon() const {
- if (kEmptyIcon == NULL)
- kEmptyIcon = new SkBitmap();
- return *kEmptyIcon;
+ static const SkBitmap* empty_icon = new SkBitmap();
+ return *empty_icon;
}
-Menu::Menu(Delegate* delegate, AnchorPoint anchor, HWND owner)
+Menu::Menu(Delegate* delegate, AnchorPoint anchor)
: delegate_(delegate),
- menu_(CreatePopupMenu()),
- anchor_(anchor),
- owner_(owner),
- is_menu_visible_(false),
- owner_draw_(l10n_util::NeedOverrideDefaultUIFont(NULL, NULL)) {
- DCHECK(delegate_);
+ anchor_(anchor) {
}
Menu::Menu(Menu* parent)
: delegate_(parent->delegate_),
- menu_(CreatePopupMenu()),
- anchor_(parent->anchor_),
- owner_(parent->owner_),
- is_menu_visible_(false),
- owner_draw_(parent->owner_draw_) {
-}
-
-Menu::Menu(HMENU hmenu)
- : delegate_(NULL),
- menu_(hmenu),
- anchor_(TOPLEFT),
- owner_(NULL),
- is_menu_visible_(false),
- owner_draw_(false) {
- DCHECK(menu_);
+ anchor_(parent->anchor_) {
}
Menu::~Menu() {
- STLDeleteContainerPointers(submenus_.begin(), submenus_.end());
- STLDeleteContainerPointers(item_data_.begin(), item_data_.end());
- DestroyMenu(menu_);
-}
-
-UINT Menu::GetStateFlagsForItemID(int item_id) const {
- // Use the delegate to get enabled and checked state.
- UINT flags =
- delegate_->IsCommandEnabled(item_id) ? MFS_ENABLED : MFS_DISABLED;
-
- if (delegate_->IsItemChecked(item_id))
- flags |= MFS_CHECKED;
-
- if (delegate_->IsItemDefault(item_id))
- flags |= MFS_DEFAULT;
-
- return flags;
-}
-
-void Menu::AddMenuItemInternal(int index,
- int item_id,
- const std::wstring& label,
- const SkBitmap& icon,
- HMENU submenu,
- MenuItemType type) {
- DCHECK(type != SEPARATOR) << "Call AddSeparator instead!";
-
- if (label.empty() && !delegate_) {
- // No label and no delegate; don't add an empty menu.
- // It appears under some circumstance we're getting an empty label
- // (l10n_util::GetString(IDS_TASK_MANAGER) returns ""). This shouldn't
- // happen, but I'm working over the crash here.
- NOTREACHED();
- return;
- }
-
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_FTYPE | MIIM_ID;
- if (submenu) {
- mii.fMask |= MIIM_SUBMENU;
- mii.hSubMenu = submenu;
- }
-
- // Set the type and ID.
- if (!owner_draw_) {
- mii.fType = MFT_STRING;
- mii.fMask |= MIIM_STRING;
- } else {
- mii.fType = MFT_OWNERDRAW;
- }
-
- if (type == RADIO)
- mii.fType |= MFT_RADIOCHECK;
-
- mii.wID = item_id;
-
- // Set the item data.
- Menu::ItemData* data = new ItemData;
- item_data_.push_back(data);
- data->submenu = submenu != NULL;
-
- std::wstring actual_label(label.empty() ?
- delegate_->GetLabel(item_id) : label);
-
- // Find out if there is a shortcut we need to append to the label.
- views::Accelerator accelerator(0, false, false, false);
- if (delegate_ && delegate_->GetAcceleratorInfo(item_id, &accelerator)) {
- actual_label += L'\t';
- actual_label += accelerator.GetShortcutText();
- }
- labels_.push_back(actual_label);
-
- if (owner_draw_) {
- if (icon.width() != 0 && icon.height() != 0)
- data->icon = icon;
- else
- data->icon = delegate_->GetIcon(item_id);
- } else {
- mii.dwTypeData = const_cast<wchar_t*>(labels_.back().c_str());
- }
-
- InsertMenuItem(menu_, index, TRUE, &mii);
}
void Menu::AppendMenuItem(int item_id,
@@ -366,7 +44,7 @@ void Menu::AddMenuItem(int index,
if (type == SEPARATOR)
AddSeparator(index);
else
- AddMenuItemInternal(index, item_id, label, SkBitmap(), NULL, type);
+ AddMenuItemInternal(index, item_id, label, SkBitmap(), type);
}
Menu* Menu::AppendSubMenu(int item_id, const std::wstring& label) {
@@ -383,19 +61,6 @@ Menu* Menu::AppendSubMenuWithIcon(int item_id,
return AddSubMenuWithIcon(-1, item_id, label, icon);
}
-Menu* Menu::AddSubMenuWithIcon(int index,
- int item_id,
- const std::wstring& label,
- const SkBitmap& icon) {
- if (!owner_draw_ && icon.width() != 0 && icon.height() != 0)
- owner_draw_ = true;
-
- Menu* submenu = new Menu(this);
- submenus_.push_back(submenu);
- AddMenuItemInternal(index, item_id, label, icon, submenu->menu_, NORMAL);
- return submenu;
-}
-
void Menu::AppendMenuItemWithLabel(int item_id, const std::wstring& label) {
AddMenuItemWithLabel(-1, item_id, label);
}
@@ -417,14 +82,6 @@ void Menu::AppendSeparator() {
AddSeparator(-1);
}
-void Menu::AddSeparator(int index) {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_FTYPE;
- mii.fType = MFT_SEPARATOR;
- InsertMenuItem(menu_, index, TRUE, &mii);
-}
-
void Menu::AppendMenuItemWithIcon(int item_id,
const std::wstring& label,
const SkBitmap& icon) {
@@ -435,192 +92,10 @@ void Menu::AddMenuItemWithIcon(int index,
int item_id,
const std::wstring& label,
const SkBitmap& icon) {
- if (!owner_draw_)
- owner_draw_ = true;
- AddMenuItemInternal(index, item_id, label, icon, NULL, Menu::NORMAL);
-}
-
-void Menu::EnableMenuItemByID(int item_id, bool enabled) {
- UINT enable_flags = enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
- EnableMenuItem(menu_, item_id, MF_BYCOMMAND | enable_flags);
+ AddMenuItemInternal(index, item_id, label, icon, Menu::NORMAL);
}
-void Menu::EnableMenuItemAt(int index, bool enabled) {
- UINT enable_flags = enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
- EnableMenuItem(menu_, index, MF_BYPOSITION | enable_flags);
+Menu::Menu() : delegate_(NULL), anchor_(TOPLEFT) {
}
-void Menu::SetMenuLabel(int item_id, const std::wstring& label) {
- MENUITEMINFO mii = {0};
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STRING;
- mii.dwTypeData = const_cast<wchar_t*>(label.c_str());
- mii.cch = static_cast<UINT>(label.size());
- SetMenuItemInfo(menu_, item_id, false, &mii);
-}
-
-DWORD Menu::GetTPMAlignFlags() const {
- // The manner in which we handle the menu alignment depends on whether or not
- // the menu is displayed within a mirrored view. If the UI is mirrored, the
- // alignment needs to be fliped so that instead of aligning the menu to the
- // right of the point, we align it to the left and vice versa.
- DWORD align_flags = TPM_TOPALIGN;
- switch (anchor_) {
- case TOPLEFT:
- if (delegate_->IsRightToLeftUILayout()) {
- align_flags |= TPM_RIGHTALIGN;
- } else {
- align_flags |= TPM_LEFTALIGN;
- }
- break;
-
- case TOPRIGHT:
- if (delegate_->IsRightToLeftUILayout()) {
- align_flags |= TPM_LEFTALIGN;
- } else {
- align_flags |= TPM_RIGHTALIGN;
- }
- break;
-
- default:
- NOTREACHED();
- return 0;
- }
- return align_flags;
-}
-
-bool Menu::SetIcon(const SkBitmap& icon, int item_id) {
- if (!owner_draw_)
- owner_draw_ = true;
-
- const int num_items = GetMenuItemCount(menu_);
- int sep_count = 0;
- for (int i = 0; i < num_items; ++i) {
- if (!(GetMenuState(menu_, i, MF_BYPOSITION) & MF_SEPARATOR)) {
- if (ChromeGetMenuItemID(menu_, i) == item_id) {
- item_data_[i - sep_count]->icon = icon;
- // When the menu is running, we use SetMenuItemInfo to let Windows
- // update the item information so that the icon being displayed
- // could change immediately.
- if (active_host_window) {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_FTYPE | MIIM_DATA;
- mii.fType = MFT_OWNERDRAW;
- mii.dwItemData =
- reinterpret_cast<ULONG_PTR>(item_data_[i - sep_count]);
- SetMenuItemInfo(menu_, item_id, false, &mii);
- }
- return true;
- }
- } else {
- ++sep_count;
- }
- }
-
- // Continue searching for the item in submenus.
- for (size_t i = 0; i < submenus_.size(); ++i) {
- if (submenus_[i]->SetIcon(icon, item_id))
- return true;
- }
-
- return false;
-}
-
-void Menu::SetMenuInfo() {
- const int num_items = GetMenuItemCount(menu_);
- int sep_count = 0;
- for (int i = 0; i < num_items; ++i) {
- MENUITEMINFO mii_info;
- mii_info.cbSize = sizeof(mii_info);
- // Get the menu's original type.
- mii_info.fMask = MIIM_FTYPE;
- GetMenuItemInfo(menu_, i, MF_BYPOSITION, &mii_info);
- // Set item states.
- if (!(mii_info.fType & MF_SEPARATOR)) {
- const int id = ChromeGetMenuItemID(menu_, i);
-
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_DATA | MIIM_STRING;
- // We also need MFT_STRING for owner drawn items in order to let Windows
- // handle the accelerators for us.
- mii.fType = MFT_STRING;
- if (owner_draw_)
- mii.fType |= MFT_OWNERDRAW;
- // If the menu originally has radiocheck type, we should follow it.
- if (mii_info.fType & MFT_RADIOCHECK)
- mii.fType |= MFT_RADIOCHECK;
- mii.fState = GetStateFlagsForItemID(id);
-
- // Validate the label. If there is a contextual label, use it, otherwise
- // default to the static label
- std::wstring label;
- if (!delegate_->GetContextualLabel(id, &label))
- label = labels_[i - sep_count];
-
- if (owner_draw_) {
- item_data_[i - sep_count]->label = label;
- mii.dwItemData = reinterpret_cast<ULONG_PTR>(item_data_[i - sep_count]);
- }
- mii.dwTypeData = const_cast<wchar_t*>(label.c_str());
- mii.cch = static_cast<UINT>(label.size());
- SetMenuItemInfo(menu_, i, true, &mii);
- } else {
- // Set data for owner drawn separators. Set dwItemData NULL to indicate
- // a separator.
- if (owner_draw_) {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_FTYPE;
- mii.fType = MFT_SEPARATOR | MFT_OWNERDRAW;
- mii.dwItemData = NULL;
- SetMenuItemInfo(menu_, i, true, &mii);
- }
- ++sep_count;
- }
- }
-
- for (size_t i = 0; i < submenus_.size(); ++i)
- submenus_[i]->SetMenuInfo();
-}
-
-void Menu::RunMenuAt(int x, int y) {
- SetMenuInfo();
-
- delegate_->MenuWillShow();
-
- // NOTE: we don't use TPM_RIGHTBUTTON here as it breaks selecting by way of
- // press, drag, release. See bugs 718 and 8560.
- UINT flags =
- GetTPMAlignFlags() | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE;
- is_menu_visible_ = true;
- DCHECK(owner_);
- // In order for context menus on menus to work, the context menu needs to
- // share the same window as the first menu is parented to.
- bool created_host = false;
- if (!active_host_window) {
- created_host = true;
- active_host_window = new MenuHostWindow(this, owner_);
- }
- UINT selected_id =
- TrackPopupMenuEx(menu_, flags, x, y, active_host_window->m_hWnd, NULL);
- if (created_host) {
- delete active_host_window;
- active_host_window = NULL;
- }
- is_menu_visible_ = false;
-
- // Execute the chosen command
- if (selected_id != 0)
- delegate_->ExecuteCommand(selected_id);
-}
-
-void Menu::Cancel() {
- DCHECK(is_menu_visible_);
- EndMenu();
-}
-
-int Menu::ItemCount() {
- return GetMenuItemCount(menu_);
-}
+} // namespace views
diff --git a/views/controls/menu/menu.h b/views/controls/menu/menu.h
index 0be9126..e07d7e5 100644
--- a/views/controls/menu/menu.h
+++ b/views/controls/menu/menu.h
@@ -5,34 +5,17 @@
#ifndef CONTROLS_MENU_VIEWS_MENU_H_
#define CONTROLS_MENU_VIEWS_MENU_H_
-#include <windows.h>
-
-#include <vector>
-
#include "base/basictypes.h"
+#include "base/gfx/native_widget_types.h"
#include "views/controls/menu/controller.h"
class SkBitmap;
-namespace {
-class MenuHostWindow;
-}
-
namespace views {
+
class Accelerator;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// Menu class
-//
-// A wrapper around a Win32 HMENU handle that provides convenient APIs for
-// menu construction, display and subsequent command execution.
-//
-///////////////////////////////////////////////////////////////////////////////
-class Menu {
- friend class MenuHostWindow;
+class Menu {
public:
/////////////////////////////////////////////////////////////////////////////
//
@@ -131,14 +114,8 @@ class Menu {
}
protected:
- // Returns an empty icon. Will initialize kEmptyIcon if it hasn't been
- // initialized.
+ // Returns an empty icon.
const SkBitmap& GetEmptyIcon() const;
-
- private:
- // Will be initialized to an icon of 0 width and 0 height when first using.
- // An empty icon means we don't need to draw it.
- static const SkBitmap* kEmptyIcon;
};
// This class is a helper that simply wraps a controller and forwards all
@@ -195,15 +172,18 @@ class Menu {
// owner The window that the menu is being brought up relative
// to. Not actually used for anything but must not be
// NULL.
- Menu(Delegate* delegate, AnchorPoint anchor, HWND owner);
- // Alternatively, a Menu object can be constructed wrapping an existing
- // HMENU. This can be used to use the convenience methods to insert
- // menu items and manage label string ownership. However this kind of
- // Menu object cannot use the delegate.
- explicit Menu(HMENU hmenu);
+ Menu(Delegate* delegate, AnchorPoint anchor);
+ Menu();
virtual ~Menu();
+ static Menu* Create(Delegate* delegate,
+ AnchorPoint anchor,
+ gfx::NativeView parent);
+
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
+ Delegate* delegate() const { return delegate_; }
+
+ AnchorPoint anchor() const { return anchor_; }
// Adds an item to this menu.
// item_id The id of the item, used to identify it in delegate callbacks
@@ -234,10 +214,10 @@ class Menu {
Menu* AppendSubMenuWithIcon(int item_id,
const std::wstring& label,
const SkBitmap& icon);
- Menu* AddSubMenuWithIcon(int index,
- int item_id,
- const std::wstring& label,
- const SkBitmap& icon);
+ virtual Menu* AddSubMenuWithIcon(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon) = 0;
// This is a convenience for standard text label menu items where the label
// is provided with this call.
@@ -251,7 +231,7 @@ class Menu {
// Adds a separator to this menu
void AppendSeparator();
- void AddSeparator(int index);
+ virtual void AddSeparator(int index) = 0;
// Appends a menu item with an icon. This is for the menu item which
// needs an icon. Calling this function forces the Menu class to draw
@@ -265,91 +245,47 @@ class Menu {
const SkBitmap& icon);
// Enables or disables the item with the specified id.
- void EnableMenuItemByID(int item_id, bool enabled);
- void EnableMenuItemAt(int index, bool enabled);
+ virtual void EnableMenuItemByID(int item_id, bool enabled) = 0;
+ virtual void EnableMenuItemAt(int index, bool enabled) = 0;
// Sets menu label at specified index.
- void SetMenuLabel(int item_id, const std::wstring& label);
+ virtual void SetMenuLabel(int item_id, const std::wstring& label) = 0;
// Sets an icon for an item with a given item_id. Calling this function
// also forces the Menu class to draw the menu, instead of relying on Windows.
// Returns false if the item with |item_id| is not found.
- bool SetIcon(const SkBitmap& icon, int item_id);
+ virtual bool SetIcon(const SkBitmap& icon, int item_id) = 0;
// Shows the menu, blocks until the user dismisses the menu or selects an
// item, and executes the command for the selected item (if any).
// Warning: Blocking call. Will implicitly run a message loop.
- void RunMenuAt(int x, int y);
+ virtual void RunMenuAt(int x, int y) = 0;
// Cancels the menu.
- virtual void Cancel();
+ virtual void Cancel() = 0;
// Returns the number of menu items.
- int ItemCount();
+ virtual int ItemCount() = 0;
protected:
- // The delegate that is being used to get information about the presentation.
- Delegate* delegate_;
-
- private:
- // The data of menu items needed to display.
- struct ItemData;
-
explicit Menu(Menu* parent);
- void AddMenuItemInternal(int index,
- int item_id,
- const std::wstring& label,
- const SkBitmap& icon,
- HMENU submenu,
- MenuItemType type);
-
- // Sets menu information before displaying, including sub-menus.
- void SetMenuInfo();
-
- // Get all the state flags for the |fState| field of MENUITEMINFO for the
- // item with the specified id. |delegate| is consulted if non-NULL about
- // the state of the item in preference to |controller_|.
- UINT GetStateFlagsForItemID(int item_id) const;
-
- // Gets the Win32 TPM alignment flags for the specified AnchorPoint.
- DWORD GetTPMAlignFlags() const;
-
- // The Win32 Menu Handle we wrap
- HMENU menu_;
-
- // The window that would receive WM_COMMAND messages when the user selects
- // an item from the menu.
- HWND owner_;
+ virtual void AddMenuItemInternal(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon,
+ MenuItemType type) = 0;
- // This list is used to store the default labels for the menu items.
- // We may use contextual labels when RunMenu is called, so we must save
- // a copy of default ones here.
- std::vector<std::wstring> labels_;
-
- // A flag to indicate whether this menu will be drawn by the Menu class.
- // If it's true, all the menu items will be owner drawn. Otherwise,
- // all the drawing will be done by Windows.
- bool owner_draw_;
+ private:
+ // The delegate that is being used to get information about the presentation.
+ Delegate* delegate_;
// How this popup menu should be aligned relative to the point it is run at.
AnchorPoint anchor_;
- // This list is to store the string labels and icons to display. It's used
- // when owner_draw_ is true. We give MENUITEMINFO pointers to these
- // structures to specify what we'd like to draw. If owner_draw_ is false,
- // we only give MENUITEMINFO pointers to the labels_.
- // The label member of the ItemData structure comes from either labels_ or
- // the GetContextualLabel.
- std::vector<ItemData*> item_data_;
-
- // Our sub-menus, if any.
- std::vector<Menu*> submenus_;
-
- // Whether the menu is visible.
- bool is_menu_visible_;
-
DISALLOW_COPY_AND_ASSIGN(Menu);
};
+} // namespace views
+
#endif // CONTROLS_MENU_VIEWS_MENU_H_
diff --git a/views/controls/menu/menu_win.cc b/views/controls/menu/menu_win.cc
new file mode 100644
index 0000000..9c85b54
--- /dev/null
+++ b/views/controls/menu/menu_win.cc
@@ -0,0 +1,565 @@
+// Copyright (c) 2006-2008 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 "views/controls/menu/menu_win.h"
+
+#include <atlbase.h>
+#include <atlapp.h>
+#include <atlwin.h>
+#include <atlcrack.h>
+#include <atlframe.h>
+#include <atlmisc.h>
+#include <string>
+
+#include "app/gfx/chrome_canvas.h"
+#include "app/gfx/chrome_font.h"
+#include "app/l10n_util.h"
+#include "app/l10n_util_win.h"
+#include "base/gfx/rect.h"
+#include "base/logging.h"
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "views/accelerator.h"
+
+namespace views {
+
+// The width of an icon, including the pixels between the icon and
+// the item label.
+static const int kIconWidth = 23;
+// Margins between the top of the item and the label.
+static const int kItemTopMargin = 3;
+// Margins between the bottom of the item and the label.
+static const int kItemBottomMargin = 4;
+// Margins between the left of the item and the icon.
+static const int kItemLeftMargin = 4;
+// Margins between the right of the item and the label.
+static const int kItemRightMargin = 10;
+// The width for displaying the sub-menu arrow.
+static const int kArrowWidth = 10;
+
+// Current active MenuHostWindow. If NULL, no menu is active.
+static MenuHostWindow* active_host_window = NULL;
+
+// The data of menu items needed to display.
+struct MenuWin::ItemData {
+ std::wstring label;
+ SkBitmap icon;
+ bool submenu;
+};
+
+namespace {
+
+static int ChromeGetMenuItemID(HMENU hMenu, int pos) {
+ // The built-in Windows ::GetMenuItemID doesn't work for submenus,
+ // so here's our own implementation.
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID;
+ GetMenuItemInfo(hMenu, pos, TRUE, &mii);
+ return mii.wID;
+}
+
+// MenuHostWindow -------------------------------------------------------------
+
+// MenuHostWindow is the HWND the HMENU is parented to. MenuHostWindow is used
+// to intercept right clicks on the HMENU and notify the delegate as well as
+// for drawing icons.
+//
+class MenuHostWindow : public CWindowImpl<MenuHostWindow, CWindow,
+ CWinTraits<WS_CHILD>> {
+ public:
+ MenuHostWindow(MenuWin* menu, HWND parent_window) : menu_(menu) {
+ int extended_style = 0;
+ // If the menu needs to be created with a right-to-left UI layout, we must
+ // set the appropriate RTL flags (such as WS_EX_LAYOUTRTL) property for the
+ // underlying HWND.
+ if (menu_->delegate()->IsRightToLeftUILayout())
+ extended_style |= l10n_util::GetExtendedStyles();
+ Create(parent_window, gfx::Rect().ToRECT(), 0, 0, extended_style);
+ }
+
+ ~MenuHostWindow() {
+ DestroyWindow();
+ }
+
+ DECLARE_FRAME_WND_CLASS(L"MenuHostWindow", NULL);
+ BEGIN_MSG_MAP(MenuHostWindow);
+ MSG_WM_RBUTTONUP(OnRButtonUp)
+ MSG_WM_MEASUREITEM(OnMeasureItem)
+ MSG_WM_DRAWITEM(OnDrawItem)
+ END_MSG_MAP();
+
+ private:
+ // NOTE: I really REALLY tried to use WM_MENURBUTTONUP, but I ran into
+ // two problems in using it:
+ // 1. It doesn't contain the coordinates of the mouse.
+ // 2. It isn't invoked for menuitems representing a submenu that have children
+ // menu items (not empty).
+
+ void OnRButtonUp(UINT w_param, const CPoint& loc) {
+ int id;
+ if (menu_->delegate() && FindMenuIDByLocation(menu_, loc, &id))
+ menu_->delegate()->ShowContextMenu(menu_, id, loc.x, loc.y, true);
+ }
+
+ void OnMeasureItem(WPARAM w_param, MEASUREITEMSTRUCT* lpmis) {
+ MenuWin::ItemData* data =
+ reinterpret_cast<MenuWin::ItemData*>(lpmis->itemData);
+ if (data != NULL) {
+ ChromeFont font;
+ lpmis->itemWidth = font.GetStringWidth(data->label) + kIconWidth +
+ kItemLeftMargin + kItemRightMargin -
+ GetSystemMetrics(SM_CXMENUCHECK);
+ if (data->submenu)
+ lpmis->itemWidth += kArrowWidth;
+ // If the label contains an accelerator, make room for tab.
+ if (data->label.find(L'\t') != std::wstring::npos)
+ lpmis->itemWidth += font.GetStringWidth(L" ");
+ lpmis->itemHeight = font.height() + kItemBottomMargin + kItemTopMargin;
+ } else {
+ // Measure separator size.
+ lpmis->itemHeight = GetSystemMetrics(SM_CYMENU) / 2;
+ lpmis->itemWidth = 0;
+ }
+ }
+
+ void OnDrawItem(UINT wParam, DRAWITEMSTRUCT* lpdis) {
+ HDC hDC = lpdis->hDC;
+ COLORREF prev_bg_color, prev_text_color;
+
+ // Set background color and text color
+ if (lpdis->itemState & ODS_SELECTED) {
+ prev_bg_color = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
+ prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ } else {
+ prev_bg_color = SetBkColor(hDC, GetSysColor(COLOR_MENU));
+ if (lpdis->itemState & ODS_DISABLED)
+ prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
+ else
+ prev_text_color = SetTextColor(hDC, GetSysColor(COLOR_MENUTEXT));
+ }
+
+ if (lpdis->itemData) {
+ MenuWin::ItemData* data =
+ reinterpret_cast<MenuWin::ItemData*>(lpdis->itemData);
+
+ // Draw the background.
+ HBRUSH hbr = CreateSolidBrush(GetBkColor(hDC));
+ FillRect(hDC, &lpdis->rcItem, hbr);
+ DeleteObject(hbr);
+
+ // Draw the label.
+ RECT rect = lpdis->rcItem;
+ rect.top += kItemTopMargin;
+ // Should we add kIconWidth only when icon.width() != 0 ?
+ rect.left += kItemLeftMargin + kIconWidth;
+ rect.right -= kItemRightMargin;
+ UINT format = DT_TOP | DT_SINGLELINE;
+ // Check whether the mnemonics should be underlined.
+ BOOL underline_mnemonics;
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &underline_mnemonics, 0);
+ if (!underline_mnemonics)
+ format |= DT_HIDEPREFIX;
+ ChromeFont font;
+ HGDIOBJ old_font = static_cast<HFONT>(SelectObject(hDC, font.hfont()));
+ int fontsize = font.FontSize();
+
+ // If an accelerator is specified (with a tab delimiting the rest of the
+ // label from the accelerator), we have to justify the fist part on the
+ // left and the accelerator on the right.
+ // TODO(jungshik): This will break in RTL UI. Currently, he/ar use the
+ // window system UI font and will not hit here.
+ std::wstring label = data->label;
+ std::wstring accel;
+ std::wstring::size_type tab_pos = label.find(L'\t');
+ if (tab_pos != std::wstring::npos) {
+ accel = label.substr(tab_pos);
+ label = label.substr(0, tab_pos);
+ }
+ DrawTextEx(hDC, const_cast<wchar_t*>(label.data()),
+ static_cast<int>(label.size()), &rect, format | DT_LEFT, NULL);
+ if (!accel.empty())
+ DrawTextEx(hDC, const_cast<wchar_t*>(accel.data()),
+ static_cast<int>(accel.size()), &rect,
+ format | DT_RIGHT, NULL);
+ SelectObject(hDC, old_font);
+
+ // Draw the icon after the label, otherwise it would be covered
+ // by the label.
+ if (data->icon.width() != 0 && data->icon.height() != 0) {
+ ChromeCanvas canvas(data->icon.width(), data->icon.height(), false);
+ canvas.drawColor(SK_ColorBLACK, SkPorterDuff::kClear_Mode);
+ canvas.DrawBitmapInt(data->icon, 0, 0);
+ canvas.getTopPlatformDevice().drawToHDC(hDC, lpdis->rcItem.left +
+ kItemLeftMargin, lpdis->rcItem.top + (lpdis->rcItem.bottom -
+ lpdis->rcItem.top - data->icon.height()) / 2, NULL);
+ }
+
+ } else {
+ // Draw the separator
+ lpdis->rcItem.top += (lpdis->rcItem.bottom - lpdis->rcItem.top) / 3;
+ DrawEdge(hDC, &lpdis->rcItem, EDGE_ETCHED, BF_TOP);
+ }
+
+ SetBkColor(hDC, prev_bg_color);
+ SetTextColor(hDC, prev_text_color);
+ }
+
+ bool FindMenuIDByLocation(MenuWin* menu, const CPoint& loc, int* id) {
+ int index = MenuItemFromPoint(NULL, menu->menu_, loc);
+ if (index != -1) {
+ *id = ChromeGetMenuItemID(menu->menu_, index);
+ return true;
+ } else {
+ for (std::vector<MenuWin*>::iterator i = menu->submenus_.begin();
+ i != menu->submenus_.end(); ++i) {
+ if (FindMenuIDByLocation(*i, loc, id))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // The menu that created us.
+ MenuWin* menu_;
+
+ DISALLOW_COPY_AND_ASSIGN(MenuHostWindow);
+};
+
+} // namespace
+
+// static
+Menu* Menu::Create(Delegate* delegate,
+ AnchorPoint anchor,
+ gfx::NativeView parent) {
+ return new MenuWin(delegate, anchor, parent);
+}
+
+MenuWin::MenuWin(Delegate* d, AnchorPoint anchor, HWND owner)
+ : Menu(d, anchor),
+ menu_(CreatePopupMenu()),
+ owner_(owner),
+ is_menu_visible_(false),
+ owner_draw_(l10n_util::NeedOverrideDefaultUIFont(NULL, NULL)) {
+ DCHECK(delegate());
+}
+
+MenuWin::MenuWin(HMENU hmenu)
+ : Menu(NULL, TOPLEFT),
+ menu_(hmenu),
+ owner_(NULL),
+ is_menu_visible_(false),
+ owner_draw_(false) {
+ DCHECK(menu_);
+}
+
+MenuWin::~MenuWin() {
+ STLDeleteContainerPointers(submenus_.begin(), submenus_.end());
+ STLDeleteContainerPointers(item_data_.begin(), item_data_.end());
+ DestroyMenu(menu_);
+}
+
+Menu* MenuWin::AddSubMenuWithIcon(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon) {
+ MenuWin* submenu = new MenuWin(this);
+ submenus_.push_back(submenu);
+ AddMenuItemInternal(index, item_id, label, icon, submenu->menu_, NORMAL);
+ return submenu;
+}
+
+void MenuWin::AddSeparator(int index) {
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_FTYPE;
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(menu_, index, TRUE, &mii);
+}
+
+void MenuWin::EnableMenuItemByID(int item_id, bool enabled) {
+ UINT enable_flags = enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
+ EnableMenuItem(menu_, item_id, MF_BYCOMMAND | enable_flags);
+}
+
+void MenuWin::EnableMenuItemAt(int index, bool enabled) {
+ UINT enable_flags = enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
+ EnableMenuItem(menu_, index, MF_BYPOSITION | enable_flags);
+}
+
+void MenuWin::SetMenuLabel(int item_id, const std::wstring& label) {
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.dwTypeData = const_cast<wchar_t*>(label.c_str());
+ mii.cch = static_cast<UINT>(label.size());
+ SetMenuItemInfo(menu_, item_id, false, &mii);
+}
+
+bool MenuWin::SetIcon(const SkBitmap& icon, int item_id) {
+ if (!owner_draw_)
+ owner_draw_ = true;
+
+ const int num_items = GetMenuItemCount(menu_);
+ int sep_count = 0;
+ for (int i = 0; i < num_items; ++i) {
+ if (!(GetMenuState(menu_, i, MF_BYPOSITION) & MF_SEPARATOR)) {
+ if (ChromeGetMenuItemID(menu_, i) == item_id) {
+ item_data_[i - sep_count]->icon = icon;
+ // When the menu is running, we use SetMenuItemInfo to let Windows
+ // update the item information so that the icon being displayed
+ // could change immediately.
+ if (active_host_window) {
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_FTYPE | MIIM_DATA;
+ mii.fType = MFT_OWNERDRAW;
+ mii.dwItemData =
+ reinterpret_cast<ULONG_PTR>(item_data_[i - sep_count]);
+ SetMenuItemInfo(menu_, item_id, false, &mii);
+ }
+ return true;
+ }
+ } else {
+ ++sep_count;
+ }
+ }
+
+ // Continue searching for the item in submenus.
+ for (size_t i = 0; i < submenus_.size(); ++i) {
+ if (submenus_[i]->SetIcon(icon, item_id))
+ return true;
+ }
+
+ return false;
+}
+
+void MenuWin::RunMenuAt(int x, int y) {
+ SetMenuInfo();
+
+ delegate()->MenuWillShow();
+
+ // NOTE: we don't use TPM_RIGHTBUTTON here as it breaks selecting by way of
+ // press, drag, release. See bugs 718 and 8560.
+ UINT flags =
+ GetTPMAlignFlags() | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE;
+ is_menu_visible_ = true;
+ DCHECK(owner_);
+ // In order for context menus on menus to work, the context menu needs to
+ // share the same window as the first menu is parented to.
+ bool created_host = false;
+ if (!active_host_window) {
+ created_host = true;
+ active_host_window = new MenuHostWindow(this, owner_);
+ }
+ UINT selected_id =
+ TrackPopupMenuEx(menu_, flags, x, y, active_host_window->m_hWnd, NULL);
+ if (created_host) {
+ delete active_host_window;
+ active_host_window = NULL;
+ }
+ is_menu_visible_ = false;
+
+ // Execute the chosen command
+ if (selected_id != 0)
+ delegate()->ExecuteCommand(selected_id);
+}
+
+void MenuWin::Cancel() {
+ DCHECK(is_menu_visible_);
+ EndMenu();
+}
+
+int MenuWin::ItemCount() {
+ return GetMenuItemCount(menu_);
+}
+
+void MenuWin::AddMenuItemInternal(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon,
+ MenuItemType type) {
+ AddMenuItemInternal(index, item_id, label, icon, NULL, type);
+}
+
+void MenuWin::AddMenuItemInternal(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon,
+ HMENU submenu,
+ MenuItemType type) {
+ DCHECK(type != SEPARATOR) << "Call AddSeparator instead!";
+
+ if (!owner_draw_ && !icon.empty())
+ owner_draw_ = true;
+
+ if (label.empty() && !delegate()) {
+ // No label and no delegate; don't add an empty menu.
+ // It appears under some circumstance we're getting an empty label
+ // (l10n_util::GetString(IDS_TASK_MANAGER) returns ""). This shouldn't
+ // happen, but I'm working over the crash here.
+ NOTREACHED();
+ return;
+ }
+
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_FTYPE | MIIM_ID;
+ if (submenu) {
+ mii.fMask |= MIIM_SUBMENU;
+ mii.hSubMenu = submenu;
+ }
+
+ // Set the type and ID.
+ if (!owner_draw_) {
+ mii.fType = MFT_STRING;
+ mii.fMask |= MIIM_STRING;
+ } else {
+ mii.fType = MFT_OWNERDRAW;
+ }
+
+ if (type == RADIO)
+ mii.fType |= MFT_RADIOCHECK;
+
+ mii.wID = item_id;
+
+ // Set the item data.
+ MenuWin::ItemData* data = new ItemData;
+ item_data_.push_back(data);
+ data->submenu = submenu != NULL;
+
+ std::wstring actual_label(label.empty() ?
+ delegate()->GetLabel(item_id) : label);
+
+ // Find out if there is a shortcut we need to append to the label.
+ views::Accelerator accelerator(0, false, false, false);
+ if (delegate() && delegate()->GetAcceleratorInfo(item_id, &accelerator)) {
+ actual_label += L'\t';
+ actual_label += accelerator.GetShortcutText();
+ }
+ labels_.push_back(actual_label);
+
+ if (owner_draw_) {
+ if (icon.width() != 0 && icon.height() != 0)
+ data->icon = icon;
+ else
+ data->icon = delegate()->GetIcon(item_id);
+ } else {
+ mii.dwTypeData = const_cast<wchar_t*>(labels_.back().c_str());
+ }
+
+ InsertMenuItem(menu_, index, TRUE, &mii);
+}
+
+MenuWin::MenuWin(MenuWin* parent)
+ : Menu(parent->delegate(), parent->anchor()),
+ menu_(CreatePopupMenu()),
+ owner_(parent->owner_),
+ is_menu_visible_(false),
+ owner_draw_(parent->owner_draw_) {
+}
+
+void MenuWin::SetMenuInfo() {
+ const int num_items = GetMenuItemCount(menu_);
+ int sep_count = 0;
+ for (int i = 0; i < num_items; ++i) {
+ MENUITEMINFO mii_info;
+ mii_info.cbSize = sizeof(mii_info);
+ // Get the menu's original type.
+ mii_info.fMask = MIIM_FTYPE;
+ GetMenuItemInfo(menu_, i, MF_BYPOSITION, &mii_info);
+ // Set item states.
+ if (!(mii_info.fType & MF_SEPARATOR)) {
+ const int id = ChromeGetMenuItemID(menu_, i);
+
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_DATA | MIIM_STRING;
+ // We also need MFT_STRING for owner drawn items in order to let Windows
+ // handle the accelerators for us.
+ mii.fType = MFT_STRING;
+ if (owner_draw_)
+ mii.fType |= MFT_OWNERDRAW;
+ // If the menu originally has radiocheck type, we should follow it.
+ if (mii_info.fType & MFT_RADIOCHECK)
+ mii.fType |= MFT_RADIOCHECK;
+ mii.fState = GetStateFlagsForItemID(id);
+
+ // Validate the label. If there is a contextual label, use it, otherwise
+ // default to the static label
+ std::wstring label;
+ if (!delegate()->GetContextualLabel(id, &label))
+ label = labels_[i - sep_count];
+
+ if (owner_draw_) {
+ item_data_[i - sep_count]->label = label;
+ mii.dwItemData = reinterpret_cast<ULONG_PTR>(item_data_[i - sep_count]);
+ }
+ mii.dwTypeData = const_cast<wchar_t*>(label.c_str());
+ mii.cch = static_cast<UINT>(label.size());
+ SetMenuItemInfo(menu_, i, true, &mii);
+ } else {
+ // Set data for owner drawn separators. Set dwItemData NULL to indicate
+ // a separator.
+ if (owner_draw_) {
+ MENUITEMINFO mii;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_FTYPE;
+ mii.fType = MFT_SEPARATOR | MFT_OWNERDRAW;
+ mii.dwItemData = NULL;
+ SetMenuItemInfo(menu_, i, true, &mii);
+ }
+ ++sep_count;
+ }
+ }
+
+ for (size_t i = 0; i < submenus_.size(); ++i)
+ submenus_[i]->SetMenuInfo();
+}
+
+UINT MenuWin::GetStateFlagsForItemID(int item_id) const {
+ // Use the delegate to get enabled and checked state.
+ UINT flags =
+ delegate()->IsCommandEnabled(item_id) ? MFS_ENABLED : MFS_DISABLED;
+
+ if (delegate()->IsItemChecked(item_id))
+ flags |= MFS_CHECKED;
+
+ if (delegate()->IsItemDefault(item_id))
+ flags |= MFS_DEFAULT;
+
+ return flags;
+}
+
+DWORD MenuWin::GetTPMAlignFlags() const {
+ // The manner in which we handle the menu alignment depends on whether or not
+ // the menu is displayed within a mirrored view. If the UI is mirrored, the
+ // alignment needs to be fliped so that instead of aligning the menu to the
+ // right of the point, we align it to the left and vice versa.
+ DWORD align_flags = TPM_TOPALIGN;
+ switch (anchor()) {
+ case TOPLEFT:
+ if (delegate()->IsRightToLeftUILayout()) {
+ align_flags |= TPM_RIGHTALIGN;
+ } else {
+ align_flags |= TPM_LEFTALIGN;
+ }
+ break;
+
+ case TOPRIGHT:
+ if (delegate()->IsRightToLeftUILayout()) {
+ align_flags |= TPM_LEFTALIGN;
+ } else {
+ align_flags |= TPM_RIGHTALIGN;
+ }
+ break;
+
+ default:
+ NOTREACHED();
+ return 0;
+ }
+ return align_flags;
+}
+
+} // namespace views
diff --git a/views/controls/menu/menu_win.h b/views/controls/menu/menu_win.h
new file mode 100644
index 0000000..bea4c65
--- /dev/null
+++ b/views/controls/menu/menu_win.h
@@ -0,0 +1,129 @@
+// Copyright (c) 2006-2008 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 CONTROLS_MENU_VIEWS_MENU_WIN_H_
+#define CONTROLS_MENU_VIEWS_MENU_WIN_H_
+
+#include <vector>
+#include <windows.h>
+
+#include "base/basictypes.h"
+#include "views/controls/menu/menu.h"
+
+namespace views {
+
+namespace {
+class MenuHostWindow;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Menu class
+//
+// A wrapper around a Win32 HMENU handle that provides convenient APIs for
+// menu construction, display and subsequent command execution.
+//
+///////////////////////////////////////////////////////////////////////////////
+class MenuWin : public Menu {
+ friend class MenuHostWindow;
+
+ public:
+ // Construct a Menu using the specified controller to determine command
+ // state.
+ // delegate A Menu::Delegate implementation that provides more
+ // information about the Menu presentation.
+ // anchor An alignment hint for the popup menu.
+ // owner The window that the menu is being brought up relative
+ // to. Not actually used for anything but must not be
+ // NULL.
+ MenuWin(Delegate* d, AnchorPoint anchor, HWND owner);
+ // Alternatively, a Menu object can be constructed wrapping an existing
+ // HMENU. This can be used to use the convenience methods to insert
+ // menu items and manage label string ownership. However this kind of
+ // Menu object cannot use the delegate.
+ explicit MenuWin(HMENU hmenu);
+ virtual ~MenuWin();
+
+ // Menu overrides.
+ virtual Menu* AddSubMenuWithIcon(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon);
+ virtual void AddSeparator(int index);
+ virtual void EnableMenuItemByID(int item_id, bool enabled);
+ virtual void EnableMenuItemAt(int index, bool enabled);
+ virtual void SetMenuLabel(int item_id, const std::wstring& label);
+ virtual bool SetIcon(const SkBitmap& icon, int item_id);
+ virtual void RunMenuAt(int x, int y);
+ virtual void Cancel();
+ virtual int ItemCount();
+
+ protected:
+ virtual void AddMenuItemInternal(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon,
+ MenuItemType type);
+
+ private:
+ // The data of menu items needed to display.
+ struct ItemData;
+
+ void AddMenuItemInternal(int index,
+ int item_id,
+ const std::wstring& label,
+ const SkBitmap& icon,
+ HMENU submenu,
+ MenuItemType type);
+
+ explicit MenuWin(MenuWin* parent);
+
+ // Sets menu information before displaying, including sub-menus.
+ void SetMenuInfo();
+
+ // Get all the state flags for the |fState| field of MENUITEMINFO for the
+ // item with the specified id. |delegate| is consulted if non-NULL about
+ // the state of the item in preference to |controller_|.
+ UINT GetStateFlagsForItemID(int item_id) const;
+
+ // Gets the Win32 TPM alignment flags for the specified AnchorPoint.
+ DWORD GetTPMAlignFlags() const;
+
+ // The Win32 Menu Handle we wrap
+ HMENU menu_;
+
+ // The window that would receive WM_COMMAND messages when the user selects
+ // an item from the menu.
+ HWND owner_;
+
+ // This list is used to store the default labels for the menu items.
+ // We may use contextual labels when RunMenu is called, so we must save
+ // a copy of default ones here.
+ std::vector<std::wstring> labels_;
+
+ // A flag to indicate whether this menu will be drawn by the Menu class.
+ // If it's true, all the menu items will be owner drawn. Otherwise,
+ // all the drawing will be done by Windows.
+ bool owner_draw_;
+
+ // This list is to store the string labels and icons to display. It's used
+ // when owner_draw_ is true. We give MENUITEMINFO pointers to these
+ // structures to specify what we'd like to draw. If owner_draw_ is false,
+ // we only give MENUITEMINFO pointers to the labels_.
+ // The label member of the ItemData structure comes from either labels_ or
+ // the GetContextualLabel.
+ std::vector<ItemData*> item_data_;
+
+ // Our sub-menus, if any.
+ std::vector<MenuWin*> submenus_;
+
+ // Whether the menu is visible.
+ bool is_menu_visible_;
+
+ DISALLOW_COPY_AND_ASSIGN(MenuWin);
+};
+
+} // namespace views
+
+#endif // CONTROLS_MENU_VIEWS_MENU_WIN_H_
diff --git a/views/controls/scrollbar/bitmap_scroll_bar.cc b/views/controls/scrollbar/bitmap_scroll_bar.cc
index 18096fb..4fe8934 100644
--- a/views/controls/scrollbar/bitmap_scroll_bar.cc
+++ b/views/controls/scrollbar/bitmap_scroll_bar.cc
@@ -540,18 +540,19 @@ void BitmapScrollBar::ShowContextMenu(View* source,
View::ConvertPointFromWidget(this, &temp_pt);
context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
- Menu menu(this, Menu::TOPLEFT, GetWidget()->GetNativeView());
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
- menu.AppendSeparator();
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
- menu.AppendSeparator();
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
- menu.AppendSeparator();
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
- menu.AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
- menu.RunMenuAt(x, y);
+ scoped_ptr<Menu> menu(
+ Menu::Create(this, Menu::TOPLEFT, GetWidget()->GetNativeView()));
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
+ menu->RunMenuAt(x, y);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/text_field.cc b/views/controls/text_field.cc
index 08f982a..62762f4 100644
--- a/views/controls/text_field.cc
+++ b/views/controls/text_field.cc
@@ -24,7 +24,7 @@
#include "grit/generated_resources.h"
#include "skia/ext/skia_utils_win.h"
#include "views/controls/hwnd_view.h"
-#include "views/controls/menu/menu.h"
+#include "views/controls/menu/menu_win.h"
#include "views/focus/focus_util_win.h"
#include "views/views_delegate.h"
#include "views/widget/widget.h"
@@ -289,7 +289,7 @@ TextField::Edit::Edit(TextField* parent, bool draw_border)
ole_interface.Attach(GetOleInterface());
text_object_model_ = ole_interface;
- context_menu_.reset(new Menu(this, Menu::TOPLEFT, m_hWnd));
+ context_menu_.reset(new MenuWin(this, Menu::TOPLEFT, m_hWnd));
context_menu_->AppendMenuItemWithLabel(IDS_UNDO,
l10n_util::GetString(IDS_UNDO));
context_menu_->AppendSeparator();
diff --git a/views/views.vcproj b/views/views.vcproj
index 0c336a6..bdc83a5 100644
--- a/views/views.vcproj
+++ b/views/views.vcproj
@@ -768,6 +768,14 @@
>
</File>
<File
+ RelativePath=".\controls\menu\menu_win.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\controls\menu\menu_win.h"
+ >
+ </File>
+ <File
RelativePath=".\controls\menu\view_menu_delegate.h"
>
</File>