| Index: views/controls/menu/native_menu_x.cc
|
| diff --git a/views/controls/menu/native_menu_x.cc b/views/controls/menu/native_menu_x.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5653def584102b086314c7df1dfe0b1a4432cc21
|
| --- /dev/null
|
| +++ b/views/controls/menu/native_menu_x.cc
|
| @@ -0,0 +1,162 @@
|
| +// Copyright (c) 2010 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/native_menu_x.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "gfx/canvas_skia.h"
|
| +#include "gfx/skia_util.h"
|
| +#include "views/controls/menu/menu_2.h"
|
| +#include "views/controls/menu/submenu_view.h"
|
| +
|
| +namespace views {
|
| +
|
| +NativeMenuX::NativeMenuX(Menu2* menu)
|
| + : model_(menu->model()),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(root_(new MenuItemView(this))) {
|
| +}
|
| +
|
| +NativeMenuX::~NativeMenuX() {
|
| +}
|
| +
|
| +// MenuWrapper implementation:
|
| +void NativeMenuX::RunMenuAt(const gfx::Point& point, int alignment) {
|
| + UpdateStates();
|
| + root_->RunMenuAt(NULL, NULL, gfx::Rect(point, gfx::Size()),
|
| + alignment == Menu2::ALIGN_TOPLEFT ? MenuItemView::TOPLEFT :
|
| + MenuItemView::TOPRIGHT, true);
|
| +}
|
| +
|
| +void NativeMenuX::CancelMenu() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void NativeMenuX::Rebuild() {
|
| + if (SubmenuView* submenu = root_->GetSubmenu()) {
|
| + submenu->RemoveAllChildViews(true);
|
| + }
|
| + AddMenuItemsFromModel(root_.get(), model_);
|
| +}
|
| +
|
| +void NativeMenuX::UpdateStates() {
|
| + SubmenuView* submenu = root_->CreateSubmenu();
|
| + UpdateMenuFromModel(submenu, model_);
|
| +}
|
| +
|
| +gfx::NativeMenu NativeMenuX::GetNativeMenu() const {
|
| + NOTIMPLEMENTED();
|
| + return NULL;
|
| +}
|
| +
|
| +MenuWrapper::MenuAction NativeMenuX::GetMenuAction() const {
|
| + NOTIMPLEMENTED();
|
| + return MENU_ACTION_NONE;
|
| +}
|
| +
|
| +void NativeMenuX::AddMenuListener(MenuListener* listener) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void NativeMenuX::RemoveMenuListener(MenuListener* listener) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void NativeMenuX::SetMinimumWidth(int width) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +// MenuDelegate implementation
|
| +
|
| +bool NativeMenuX::IsItemChecked(int cmd) const {
|
| + int index;
|
| + menus::MenuModel* model = model_;
|
| + if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index))
|
| + return false;
|
| + return model->IsItemCheckedAt(index);
|
| +}
|
| +
|
| +bool NativeMenuX::IsCommandEnabled(int cmd) const {
|
| + int index;
|
| + menus::MenuModel* model = model_;
|
| + if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index))
|
| + return false;
|
| + return model->IsEnabledAt(index);
|
| +}
|
| +
|
| +void NativeMenuX::ExecuteCommand(int cmd) {
|
| + int index;
|
| + menus::MenuModel* model = model_;
|
| + if (!menus::MenuModel::GetModelAndIndexForCommandId(cmd, &model, &index))
|
| + return;
|
| + model->ActivatedAt(index);
|
| +}
|
| +
|
| +bool NativeMenuX::GetAccelerator(int id, views::Accelerator* accelerator) {
|
| + int index;
|
| + menus::MenuModel* model = model_;
|
| + if (!menus::MenuModel::GetModelAndIndexForCommandId(id, &model, &index))
|
| + return false;
|
| +
|
| + menus::Accelerator menu_accelerator;
|
| + if (!model->GetAcceleratorAt(index, &menu_accelerator))
|
| + return false;
|
| +
|
| + *accelerator = views::Accelerator(menu_accelerator.GetKeyCode(),
|
| + menu_accelerator.modifiers());
|
| + return true;
|
| +}
|
| +
|
| +// private
|
| +void NativeMenuX::AddMenuItemsFromModel(MenuItemView* parent,
|
| + menus::MenuModel* model) {
|
| + for (int i = 0; i < model->GetItemCount(); ++i) {
|
| + int index = i + model->GetFirstItemIndex(NULL);
|
| + MenuItemView* child = parent->AppendMenuItemFromModel(model, index,
|
| + model->GetCommandIdAt(index));
|
| +
|
| + if (child && child->GetType() == MenuItemView::SUBMENU) {
|
| + AddMenuItemsFromModel(child, model->GetSubmenuModelAt(index));
|
| + }
|
| + }
|
| +}
|
| +
|
| +void NativeMenuX::UpdateMenuFromModel(SubmenuView* menu,
|
| + menus::MenuModel* model) {
|
| + for (int i = 0, sep = 0; i < model->GetItemCount(); ++i) {
|
| + int index = i + model->GetFirstItemIndex(NULL);
|
| + if (model->GetTypeAt(index) == menus::MenuModel::TYPE_SEPARATOR) {
|
| + ++sep;
|
| + continue;
|
| + }
|
| +
|
| + // The submenu excludes the separators when counting the menu-items
|
| + // in it. So exclude the number of separators to get the correct index.
|
| + MenuItemView* mitem = menu->GetMenuItemAt(index - sep);
|
| + mitem->SetVisible(model->IsVisibleAt(index));
|
| + mitem->SetEnabled(model->IsEnabledAt(index));
|
| + if (model->IsLabelDynamicAt(index)) {
|
| + mitem->SetTitle(UTF16ToWide(model->GetLabelAt(index)));
|
| + }
|
| +
|
| + SkBitmap icon;
|
| + if (model->GetIconAt(index, &icon)) {
|
| + mitem->SetIcon(icon);
|
| + }
|
| +
|
| + if (model->GetTypeAt(index) == menus::MenuModel::TYPE_SUBMENU) {
|
| + DCHECK(mitem->HasSubmenu());
|
| + UpdateMenuFromModel(mitem->GetSubmenu(), model->GetSubmenuModelAt(index));
|
| + }
|
| + }
|
| +}
|
| +
|
| +// MenuWrapper, public:
|
| +
|
| +// static
|
| +MenuWrapper* MenuWrapper::CreateWrapper(Menu2* menu) {
|
| + return new NativeMenuX(menu);
|
| +}
|
| +
|
| +} // namespace views
|
|
|