diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 18:07:17 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 18:07:17 +0000 |
commit | 6777a5795196c21e69169695685191e2df0eb5dd (patch) | |
tree | 866e21158cba150ef6d010ec7dc557ed14451bf9 | |
parent | 81f85b378c9d8c7c3e23233a78d28da785c97a9a (diff) | |
download | chromium_src-6777a5795196c21e69169695685191e2df0eb5dd.zip chromium_src-6777a5795196c21e69169695685191e2df0eb5dd.tar.gz chromium_src-6777a5795196c21e69169695685191e2df0eb5dd.tar.bz2 |
Refactor domui menu to make extending easier
* Moved the code to build JS model to MenuUI.
* Added ModelUpdated/CreateMenuItem/AddCustomConfigValues for subclass to extends behavior.
* Uses the actual icon size to compute left padding
* Adjusted css padding parameters to match the mock (http://www.corp.google.com/~roma/design/chrome/native-widgets/menus/menus-spec.png)
wrech_menu.{cc,h} not used yet, but added for Steven to look at it.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3613015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61981 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/dom_ui/menu_ui.cc | 146 | ||||
-rw-r--r-- | chrome/browser/chromeos/dom_ui/menu_ui.h | 23 | ||||
-rw-r--r-- | chrome/browser/chromeos/dom_ui/wrench_menu_ui.cc | 32 | ||||
-rw-r--r-- | chrome/browser/chromeos/dom_ui/wrench_menu_ui.h | 30 | ||||
-rw-r--r-- | chrome/browser/chromeos/views/domui_menu_widget.cc | 2 | ||||
-rw-r--r-- | chrome/browser/chromeos/views/native_menu_domui.cc | 122 | ||||
-rw-r--r-- | chrome/browser/chromeos/views/native_menu_domui.h | 19 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_factory.cc | 5 | ||||
-rw-r--r-- | chrome/browser/resources/menu.css | 10 | ||||
-rw-r--r-- | chrome/browser/resources/menu.js | 24 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/url_constants.cc | 3 | ||||
-rw-r--r-- | chrome/common/url_constants.h | 3 |
13 files changed, 291 insertions, 130 deletions
diff --git a/chrome/browser/chromeos/dom_ui/menu_ui.cc b/chrome/browser/chromeos/dom_ui/menu_ui.cc index 89361b9..24fc964 100644 --- a/chrome/browser/chromeos/dom_ui/menu_ui.cc +++ b/chrome/browser/chromeos/dom_ui/menu_ui.cc @@ -13,6 +13,7 @@ #include "base/singleton.h" #include "base/string_number_conversions.h" #include "base/string_piece.h" +#include "base/utf_string_conversions.h" #include "base/values.h" #include "base/weak_ptr.h" #include "chrome/browser/chrome_thread.h" @@ -27,6 +28,8 @@ #include "chrome/common/jstemplate_builder.h" #include "chrome/common/net/url_fetcher.h" #include "gfx/canvas_skia.h" +#include "gfx/favicon_size.h" +#include "gfx/font.h" #include "grit/app_resources.h" #include "grit/browser_resources.h" #include "views/controls/menu/menu_config.h" @@ -35,6 +38,34 @@ namespace { +// A utility function that generates css font property from gfx::Font. +std::wstring GetFontShorthand(const gfx::Font* font) { + std::wstring out; + if (font == NULL) { + font = &(views::MenuConfig::instance().font); + } + if (font->GetStyle() & gfx::Font::BOLD) { + out.append(L"bold "); + } + if (font->GetStyle() & gfx::Font::ITALIC) { + out.append(L"italic "); + } + if (font->GetStyle() & gfx::Font::UNDERLINED) { + out.append(L"underline "); + } + + // TODO(oshima): The font size from gfx::Font is too small when + // used in webkit. Figure out the reason. + out.append(ASCIIToWide(base::IntToString(font->GetFontSize() + 4))); + out.append(L"px/"); + out.append(ASCIIToWide(base::IntToString( + std::max(kFavIconSize, font->GetHeight())))); + out.append(L"px \""); + out.append(font->GetFontName()); + out.append(L"\",sans-serif"); + return out; +} + // Creates scroll button's up image when |up| is true or // down image if |up| is false. SkBitmap CreateMenuScrollArrowImage(bool up) { @@ -87,6 +118,7 @@ const std::string& GetImageDataUrlForRadio(bool on) { * |menu_class|, or empty string to use plain "Menu". */ std::string GetMenuUIHTMLSourceFromString( + const chromeos::MenuUI& menu_ui, const base::StringPiece& menu_template, const std::string& menu_class, const std::string& menu_source) { @@ -130,6 +162,8 @@ std::string GetMenuUIHTMLSourceFromString( SET_INTEGER_PROPERTY(scroll_arrow_height); SET_INTEGER_PROPERTY(label_to_accelerator_padding); + menu_ui.AddCustomConfigValues(&value_config); + std::string json_config; base::JSONWriter::Write(&value_config, false, &json_config); @@ -146,7 +180,8 @@ std::string GetMenuUIHTMLSourceFromString( class MenuUIHTMLSource : public ChromeURLDataManager::DataSource, public URLFetcher::Delegate { public: - MenuUIHTMLSource(Profile* profile, + MenuUIHTMLSource(const chromeos::MenuUI& menu_ui, + Profile* profile, const std::string& menu_class, const std::string& menu_source); @@ -170,8 +205,12 @@ class MenuUIHTMLSource : public ChromeURLDataManager::DataSource, private: virtual ~MenuUIHTMLSource() {} + // The menu ui the source is created for. + const chromeos::MenuUI& menu_ui_; + // The name of JS Menu class to use. const std::string menu_class_; + // The source file of the menu subclass. const std::string menu_source_; #ifndef NDEBUG @@ -200,6 +239,7 @@ class MenuHandler : public chromeos::MenuHandlerBase, void HandleMoveInputToSubmenu(const ListValue* values); void HandleMoveInputToParent(const ListValue* values); void HandleCloseAll(const ListValue* values); + void HandleModelUpdated(const ListValue* values); // This is a utility DOMUI message to print debug message. // Menu can't use dev tool as it lives outside of browser. // TODO(oshima): This is inconvenient and figure out how we can use @@ -248,10 +288,12 @@ class MenuHandler : public chromeos::MenuHandlerBase, // //////////////////////////////////////////////////////////////////////////////// -MenuUIHTMLSource::MenuUIHTMLSource(Profile* profile, +MenuUIHTMLSource::MenuUIHTMLSource(const chromeos::MenuUI& menu_ui, + Profile* profile, const std::string& menu_class, const std::string& menu_source) : DataSource(chrome::kChromeUIMenu, MessageLoop::current()), + menu_ui_(menu_ui), menu_class_(menu_class), menu_source_(menu_source) #ifndef NDEBUG @@ -280,8 +322,8 @@ void MenuUIHTMLSource::StartDataRequest(const std::string& path, // The resource string should be pure code and should not contain // i18n string. - const std::string menu_html = - GetMenuUIHTMLSourceFromString(menu_template, menu_class_, menu_source_); + const std::string menu_html = GetMenuUIHTMLSourceFromString( + menu_ui_, menu_template, menu_class_, menu_source_); scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); @@ -301,7 +343,7 @@ void MenuUIHTMLSource::OnURLFetchComplete(const URLFetcher* source, #ifndef NDEBUG // This should not be called in release build. const std::string menu_html = - GetMenuUIHTMLSourceFromString(data, menu_class_, menu_source_); + GetMenuUIHTMLSourceFromString(menu_ui_, data, menu_class_, menu_source_); scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); @@ -359,6 +401,10 @@ void MenuHandler::RegisterMessages() { NewCallback(this, &MenuHandler::HandleCloseAll)); dom_ui_->RegisterMessageCallback( + "model_updated", + NewCallback(this, + &MenuHandler::HandleModelUpdated)); + dom_ui_->RegisterMessageCallback( "log", NewCallback(this, &MenuHandler::HandleLog)); @@ -436,6 +482,12 @@ void MenuHandler::HandleCloseAll(const ListValue* values) { control->CloseAll(); } +void MenuHandler::HandleModelUpdated(const ListValue* values) { + menus::MenuModel* model = GetMenuModel(); + if (model) + static_cast<chromeos::MenuUI*>(dom_ui_)->ModelUpdated(model); +} + void MenuHandler::HandleLog(const ListValue* values) { CHECK_EQ(1U, values->GetSize()); std::string msg; @@ -457,6 +509,7 @@ void MenuHandler::LoadingStateChanged(TabContents* contents) { if (control && !contents->is_loading()) { loaded_ = true; control->OnLoad(); + HandleModelUpdated(NULL); } } @@ -506,8 +559,89 @@ MenuUI::MenuUI(TabContents* contents) : DOMUI(contents) { make_scoped_refptr(CreateDataSource()))); } +void MenuUI::ModelUpdated(const menus::MenuModel* model) { + DictionaryValue json_model; + ListValue* items = new ListValue(); + json_model.Set("items", items); + int max_icon_width = 0; + for (int index = 0; index < model->GetItemCount(); ++index) { + menus::MenuModel::ItemType type = model->GetTypeAt(index); + DictionaryValue* item; + switch (type) { + case menus::MenuModel::TYPE_SEPARATOR: + item = CreateMenuItem(model, index, "separator", &max_icon_width); + break; + case menus::MenuModel::TYPE_RADIO: + max_icon_width = std::max(max_icon_width, 12); + item = CreateMenuItem(model, index, "radio", &max_icon_width); + break; + case menus::MenuModel::TYPE_SUBMENU: + item = CreateMenuItem(model, index, "submenu", &max_icon_width); + break; + case menus::MenuModel::TYPE_COMMAND: + item = CreateMenuItem(model, index, "command", &max_icon_width); + break; + case menus::MenuModel::TYPE_CHECK: + // Add space even when unchecked. + max_icon_width = std::max(max_icon_width, 12); + item = CreateMenuItem(model, index, "check", &max_icon_width); + break; + default: + // TODO(oshima): We don't support BUTTOM_ITEM for now. + // I haven't decided how to implement zoom/cut&paste + // stuff, but may do somethign similar to what linux_views + // does. + NOTREACHED(); + continue; + } + items->Set(index, item); + } + DOMUIMenuWidget* widget = + chromeos::DOMUIMenuWidget::FindDOMUIMenuWidget( + tab_contents()->GetNativeView()); + DCHECK(widget); + json_model.SetInteger("maxIconWidth", max_icon_width); + json_model.SetBoolean("isRoot", widget->is_root()); + CallJavascriptFunction(L"updateModel", json_model); +} + +DictionaryValue* MenuUI::CreateMenuItem(const menus::MenuModel* model, + int index, + const char* type, + int* max_icon_width) const { + // Note: DOM UI uses '&' as mnemonic. + string16 label16 = model->GetLabelAt(index); + DictionaryValue* item = new DictionaryValue(); + + item->SetString("type", type); + item->SetString("label", label16); + item->SetBoolean("enabled", model->IsEnabledAt(index)); + item->SetBoolean("visible", model->IsVisibleAt(index)); + item->SetBoolean("checked", model->IsItemCheckedAt(index)); + item->SetInteger("command_id", model->GetCommandIdAt(index)); + item->SetString( + "font", WideToUTF16(GetFontShorthand(model->GetLabelFontAt(index)))); + SkBitmap icon; + if (model->GetIconAt(index, &icon) && !icon.isNull() && !icon.empty()) { + item->SetString("icon", dom_ui_util::GetImageDataUrl(icon)); + *max_icon_width = std::max(*max_icon_width, icon.width()); + } + return item; +} + ChromeURLDataManager::DataSource* MenuUI::CreateDataSource() { - return new MenuUIHTMLSource(GetProfile(), "Menu", "" /* no extra source */); + return CreateMenuUIHTMLSource(*this, + GetProfile(), + "Menu" /* class name */, + "" /* no extra source */); +} + +ChromeURLDataManager::DataSource* MenuUI::CreateMenuUIHTMLSource( + const MenuUI& menu_ui, + Profile* profile, + const std::string& menu_class, + const std::string& menu_source) { + return new MenuUIHTMLSource(menu_ui, profile, menu_class, menu_source); } } // namespace chromeos diff --git a/chrome/browser/chromeos/dom_ui/menu_ui.h b/chrome/browser/chromeos/dom_ui/menu_ui.h index 1d61b4a..ea505a9f 100644 --- a/chrome/browser/chromeos/dom_ui/menu_ui.h +++ b/chrome/browser/chromeos/dom_ui/menu_ui.h @@ -11,6 +11,8 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/dom_ui.h" +class DictionaryValue; + namespace menus { class MenuModel; } // namespace menus @@ -23,10 +25,31 @@ class MenuUI : public DOMUI { public: explicit MenuUI(TabContents* contents); + // A callback method that is invoked when a menu model associated + // with the DOMUI Menu gets updated. + virtual void ModelUpdated(const menus::MenuModel* new_model); + + // Creates a menu item for the menu item at index in the model. + virtual DictionaryValue* CreateMenuItem(const menus::MenuModel* model, + int index, + const char* type, + int* max_icon_width) const; + + // Subclass can add extra parameters or replaces default configuration. + virtual void AddCustomConfigValues(DictionaryValue* config) const {}; + // Create HTML Data source for the menu. Extended menu // implementation may provide its own menu implmentation. virtual ChromeURLDataManager::DataSource* CreateDataSource(); + // A utility function that create a concrete html file from + // template for given |menu_class|. + static ChromeURLDataManager::DataSource* CreateMenuUIHTMLSource( + const MenuUI& menu_ui, + Profile* profile, + const std::string& menu_class, + const std::string& menu_source); + private: DISALLOW_COPY_AND_ASSIGN(MenuUI); }; diff --git a/chrome/browser/chromeos/dom_ui/wrench_menu_ui.cc b/chrome/browser/chromeos/dom_ui/wrench_menu_ui.cc new file mode 100644 index 0000000..b7a849c --- /dev/null +++ b/chrome/browser/chromeos/dom_ui/wrench_menu_ui.cc @@ -0,0 +1,32 @@ +// 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 "chrome/browser/chromeos/dom_ui/wrench_menu_ui.h" + +#include "base/values.h" +#include "chrome/app/chrome_dll_resource.h" + +namespace chromeos { + +//////////////////////////////////////////////////////////////////////////////// +// +// WrenchMenuUI +// +//////////////////////////////////////////////////////////////////////////////// + +WrenchMenuUI::WrenchMenuUI(TabContents* contents) : chromeos::MenuUI(contents) { +} + +void WrenchMenuUI::AddCustomConfigValues(DictionaryValue* config) const { + // These command ids are to create customized menu items for wrench menu. + config->SetInteger("IDC_CUT", IDC_CUT); + config->SetInteger("IDC_ZOOM_MINUS", IDC_ZOOM_MINUS); +} + +ChromeURLDataManager::DataSource* WrenchMenuUI::CreateDataSource() { + return CreateMenuUIHTMLSource(*this, GetProfile(), + "WrenchMenu", "wrench_menu.js"); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/dom_ui/wrench_menu_ui.h b/chrome/browser/chromeos/dom_ui/wrench_menu_ui.h new file mode 100644 index 0000000..c3f053b --- /dev/null +++ b/chrome/browser/chromeos/dom_ui/wrench_menu_ui.h @@ -0,0 +1,30 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_DOM_UI_WRENCH_MENU_UI_H_ +#define CHROME_BROWSER_CHROMEOS_DOM_UI_WRENCH_MENU_UI_H_ +#pragma once + +#include "chrome/browser/chromeos/dom_ui/menu_ui.h" + +namespace chromeos { + +class WrenchMenuUI : public MenuUI { + public: + explicit WrenchMenuUI(TabContents* contents); + + // MenuUI overrides: + virtual void AddCustomConfigValues(DictionaryValue* config) const; + + // Create HTML Data source for the menu. Extended menu + // implementation may provide its own menu implmentation. + virtual ChromeURLDataManager::DataSource* CreateDataSource(); + + private: + DISALLOW_COPY_AND_ASSIGN(WrenchMenuUI); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_DOM_UI_WRENCH_MENU_UI_H_ diff --git a/chrome/browser/chromeos/views/domui_menu_widget.cc b/chrome/browser/chromeos/views/domui_menu_widget.cc index 50b720c..82a66a6 100644 --- a/chrome/browser/chromeos/views/domui_menu_widget.cc +++ b/chrome/browser/chromeos/views/domui_menu_widget.cc @@ -243,7 +243,7 @@ void DOMUIMenuWidget::ShowAt(chromeos::MenuLocator* locator) { container->set_border(new RoundedBorder(locator)); container->SetLayoutManager(new InsetsLayout()); SetContentsView(container); - dom_view_->LoadURL(GURL("chrome://menu")); + dom_view_->LoadURL(domui_menu_->menu_url()); } else { domui_menu_->UpdateStates(); dom_view_->GetParent()->set_border(new RoundedBorder(locator)); diff --git a/chrome/browser/chromeos/views/native_menu_domui.cc b/chrome/browser/chromeos/views/native_menu_domui.cc index 4477bf6..42c6482 100644 --- a/chrome/browser/chromeos/views/native_menu_domui.cc +++ b/chrome/browser/chromeos/views/native_menu_domui.cc @@ -7,24 +7,16 @@ #include <string> #include "app/menus/menu_model.h" -#include "base/json/json_writer.h" #include "base/message_loop.h" -#include "base/string_number_conversions.h" #include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/chromeos/views/domui_menu_widget.h" #include "chrome/browser/chromeos/views/menu_locator.h" -#include "chrome/browser/dom_ui/dom_ui_util.h" #include "chrome/browser/profile_manager.h" -#include "gfx/favicon_size.h" -#include "gfx/font.h" +#include "chrome/common/url_constants.h" #include "gfx/rect.h" -#include "third_party/skia/include/core/SkBitmap.h" #include "views/controls/menu/menu_2.h" -#include "views/controls/menu/menu_config.h" namespace { @@ -35,34 +27,6 @@ bool MenuTypeCanExecute(menus::MenuModel::ItemType type) { type == menus::MenuModel::TYPE_RADIO; } -// A utility function that generates css font property from gfx::Font. -std::wstring GetFontShorthand(const gfx::Font* font) { - std::wstring out; - if (font == NULL) { - font = &(views::MenuConfig::instance().font); - } - if (font->GetStyle() & gfx::Font::BOLD) { - out.append(L"bold "); - } - if (font->GetStyle() & gfx::Font::ITALIC) { - out.append(L"italic "); - } - if (font->GetStyle() & gfx::Font::UNDERLINED) { - out.append(L"underline "); - } - - // TODO(oshima): The font size from gfx::Font is too small when - // used in webkit. Figure out the reason. - out.append(ASCIIToWide(base::IntToString(font->GetFontSize() + 4))); - out.append(L"px/"); - out.append(ASCIIToWide(base::IntToString( - std::max(kFavIconSize, font->GetHeight())))); - out.append(L"px \""); - out.append(font->GetFontName()); - out.append(L"\",sans-serif"); - return out; -} - // Currently opened menu. See RunMenuAt for reason why we need this. chromeos::NativeMenuDOMUI* current_ = NULL; @@ -70,6 +34,15 @@ chromeos::NativeMenuDOMUI* current_ = NULL; namespace chromeos { +// static +void NativeMenuDOMUI::SetMenuURL(views::Menu2* menu2, const GURL& url) { + gfx::NativeView native = menu2->GetNativeMenu(); + DCHECK(native); + DOMUIMenuWidget* widget = DOMUIMenuWidget::FindDOMUIMenuWidget(native); + DCHECK(widget); + widget->domui_menu()->set_menu_url(url); +} + //////////////////////////////////////////////////////////////////////////////// // NativeMenuDOMUI, public: @@ -81,7 +54,8 @@ NativeMenuDOMUI::NativeMenuDOMUI(menus::MenuModel* menu_model, bool root) menu_shown_(false), activated_menu_(NULL), activated_index_(-1), - menu_action_(MENU_ACTION_NONE) { + menu_action_(MENU_ACTION_NONE), + menu_url_(StringPrintf("chrome://%s", chrome::kChromeUIMenu)) { menu_widget_ = new DOMUIMenuWidget(this, root); // Set the initial location off the screen not to show small // window with dropshadow. @@ -153,47 +127,7 @@ void NativeMenuDOMUI::CancelMenu() { void NativeMenuDOMUI::Rebuild() { activated_menu_ = NULL; - DictionaryValue model; - ListValue* items = new ListValue(); - model.Set("items", items); - bool has_icon = false; - for (int index = 0; index < model_->GetItemCount(); ++index) { - menus::MenuModel::ItemType type = model_->GetTypeAt(index); - DictionaryValue* item; - switch (type) { - case menus::MenuModel::TYPE_SEPARATOR: - item = CreateMenuItem(index, "separator", &has_icon); - break; - case menus::MenuModel::TYPE_RADIO: - has_icon = true; // all radio buttons has indicator icon. - item = CreateMenuItem(index, "radio", &has_icon); - break; - case menus::MenuModel::TYPE_SUBMENU: - item = CreateMenuItem(index, "submenu", &has_icon); - break; - case menus::MenuModel::TYPE_COMMAND: - item = CreateMenuItem(index, "command", &has_icon); - break; - case menus::MenuModel::TYPE_CHECK: - item = CreateMenuItem(index, "check", &has_icon); - break; - default: - // TODO(oshima): We don't support BUTTOM_ITEM for now. - // I haven't decided how to implement zoom/cut&paste - // stuff, but may do somethign similar to what linux_views - // does. - NOTREACHED(); - continue; - } - items->Set(index, item); - } - model.SetBoolean("hasIcon", has_icon); - model.SetBoolean("isRoot", menu_widget_->is_root()); - - std::string json_model; - base::JSONWriter::Write(&model, false, &json_model); - std::wstring script = UTF8ToWide("updateModel(" + json_model + ")"); - menu_widget_->ExecuteJavascript(script); + menu_widget_->ExecuteJavascript(L"modelUpdated()"); } void NativeMenuDOMUI::UpdateStates() { @@ -202,8 +136,7 @@ void NativeMenuDOMUI::UpdateStates() { } gfx::NativeMenu NativeMenuDOMUI::GetNativeMenu() const { - NOTREACHED(); - return NULL; + return menu_widget_->GetNativeView(); } NativeMenuDOMUI::MenuAction NativeMenuDOMUI::GetMenuAction() const { @@ -277,6 +210,7 @@ void NativeMenuDOMUI::OpenSubmenu(int index, int y) { // Returns the model for the submenu at the specified index. menus::MenuModel* submenu = model_->GetSubmenuModelAt(index); submenu_.reset(new chromeos::NativeMenuDOMUI(submenu, false)); + submenu_->set_menu_url(menu_url_); // y in menu_widget_ coordinate. submenu_->set_parent(this); submenu_->ShowAt( @@ -310,7 +244,9 @@ void NativeMenuDOMUI::MoveInputToParent() { } void NativeMenuDOMUI::OnLoad() { - Rebuild(); + // TODO(oshima): OnLoad is no longer used, but kept in case + // we may need it. Delete this if this is not necessary to + // implement wrench/network/bookmark menus. } void NativeMenuDOMUI::SetSize(const gfx::Size& size) { @@ -363,28 +299,6 @@ void NativeMenuDOMUI::ProcessActivate() { } } -DictionaryValue* NativeMenuDOMUI::CreateMenuItem( - int index, const char* type, bool* has_icon_out) { - // Note: DOM UI uses '&' as mnemonic. - string16 label16 = model_->GetLabelAt(index); - DictionaryValue* item = new DictionaryValue(); - - item->SetString("type", type); - item->SetString("label", label16); - item->SetBoolean("enabled", model_->IsEnabledAt(index)); - item->SetBoolean("visible", model_->IsVisibleAt(index)); - item->SetBoolean("checked", model_->IsItemCheckedAt(index)); - item->SetInteger("command_id", model_->GetCommandIdAt(index)); - item->SetString( - "font", WideToUTF16(GetFontShorthand(model_->GetLabelFontAt(index)))); - SkBitmap icon; - if (model_->GetIconAt(index, &icon) && !icon.isNull() && !icon.empty()) { - item->SetString("icon", dom_ui_util::GetImageDataUrl(icon)); - *has_icon_out = true; - } - return item; -} - void NativeMenuDOMUI::ShowAt(MenuLocator* locator) { model_->MenuWillShow(); menu_widget_->ShowAt(locator); diff --git a/chrome/browser/chromeos/views/native_menu_domui.h b/chrome/browser/chromeos/views/native_menu_domui.h index cf4786e..d000985 100644 --- a/chrome/browser/chromeos/views/native_menu_domui.h +++ b/chrome/browser/chromeos/views/native_menu_domui.h @@ -11,6 +11,7 @@ #include "base/message_loop.h" #include "base/observer_list.h" #include "chrome/browser/chromeos/dom_ui/domui_menu_control.h" +#include "googleurl/src/gurl.h" #include "views/controls/menu/menu_wrapper.h" class SkBitmap; @@ -77,16 +78,19 @@ class NativeMenuDOMUI : public views::MenuWrapper, // Returns the profile to create DOMView. Profile* GetProfile(); + // Sets/Gets the url for the domui menu. + void set_menu_url(const GURL& url) { menu_url_ = url; } + const GURL& menu_url() const { return menu_url_; } + + // Sets the menu url of menu2. This has to be called before + // RunMenuAt/RunContextMenuAt is called. + static void SetMenuURL(views::Menu2* menu2, const GURL& url); + private: // Callback that we should really process the menu activation. // See description above class for why we delay processing activation. void ProcessActivate(); - // Creates a menu item for the menu item at index. - DictionaryValue* CreateMenuItem(int index, - const char* type, - bool* has_icon_out); - // Show the menu using given |locator|. void ShowAt(MenuLocator* locator); @@ -124,6 +128,11 @@ class NativeMenuDOMUI : public views::MenuWrapper, // Vector of listeners to receive callbacks when the menu opens. ObserverList<views::MenuListener> listeners_; + // URL to invoke Menu DOMUI. Default menu is chrome://menu, but + // custom menu can use different url using SetMenuURL method + // (e.g. chrome://wrench-menu for wrench menu). + GURL menu_url_; + DISALLOW_COPY_AND_ASSIGN(NativeMenuDOMUI); }; diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc index 1a70756..58f23c9 100644 --- a/chrome/browser/dom_ui/dom_ui_factory.cc +++ b/chrome/browser/dom_ui/dom_ui_factory.cc @@ -38,10 +38,11 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/dom_ui/imageburner_ui.h" +#include "chrome/browser/chromeos/dom_ui/menu_ui.h" #include "chrome/browser/chromeos/dom_ui/mobile_setup_ui.h" #include "chrome/browser/chromeos/dom_ui/register_page_ui.h" #include "chrome/browser/chromeos/dom_ui/system_info_ui.h" -#include "chrome/browser/chromeos/dom_ui/menu_ui.h" +#include "chrome/browser/chromeos/dom_ui/wrench_menu_ui.h" #include "chrome/browser/dom_ui/filebrowse_ui.h" #include "chrome/browser/dom_ui/mediaplayer_ui.h" #endif @@ -166,6 +167,8 @@ static DOMUIFactoryFunction GetDOMUIFactoryFunction(Profile* profile, return &NewDOMUI<SystemInfoUI>; if (url.host() == chrome::kChromeUIMenu) return &NewDOMUI<chromeos::MenuUI>; + if (url.host() == chrome::kChromeUIWrenchMenu) + return &NewDOMUI<chromeos::WrenchMenuUI>; #else if (url.host() == chrome::kChromeUISettingsHost) { if (CommandLine::ForCurrentProcess()->HasSwitch( diff --git a/chrome/browser/resources/menu.css b/chrome/browser/resources/menu.css index 111dc11..1396017 100644 --- a/chrome/browser/resources/menu.css +++ b/chrome/browser/resources/menu.css @@ -10,16 +10,19 @@ body { .menu-item { white-space: nowrap; margin: 0; - padding: 0 20px 0 5px; + padding-top: 0; + padding-right: 19px; + padding-bottom: 0; background-repeat: no-repeat; + -webkit-padding-end: 19px; } .disabled { color: #b7b7b7; } -.noicon { - -webkit-padding-start: 20px; +.no-icon { + -webkit-padding-start: 19px; } .menu-label { @@ -29,7 +32,6 @@ body { .left-icon { background-position: 4px center; - padding-left: 30px; } .right-icon { diff --git a/chrome/browser/resources/menu.js b/chrome/browser/resources/menu.js index 0ad5f47..7cf5f57 100644 --- a/chrome/browser/resources/menu.js +++ b/chrome/browser/resources/menu.js @@ -42,9 +42,9 @@ MenuItem.prototype = { * @param {Object} attrs JSON object that represents this menu items * properties. This is created from menu model in C code. See * chromeos/views/native_menu_domui.cc. - * @param {boolean} hasIcon True if the menu has left icon. + * @param {number} leftIconWidth The left icon's width. 0 if no icon. */ - init: function(menu, attrs, hasIcon) { + init: function(menu, attrs, leftIconWidth) { this.menu_ = menu; this.attrs = attrs; var attrs = this.attrs; @@ -54,12 +54,12 @@ MenuItem.prototype = { attrs.type == 'submenu' || attrs.type == 'check' || attrs.type == 'radio') { - this.initMenuItem_(hasIcon); + this.initMenuItem_(leftIconWidth); } else { this.classList.add('disabled'); this.textContent = 'unknown'; } - this.classList.add(hasIcon ? 'has-icon' : 'noicon'); + this.classList.add(leftIconWidth ? 'has-icon' : 'no-icon'); if (attrs.visible) { menu.appendChild(this); @@ -104,7 +104,7 @@ MenuItem.prototype = { * Internal method to initiailze the MenuItem. * @private */ - initMenuItem_: function(hasIcon) { + initMenuItem_: function(leftIconWidth) { var attrs = this.attrs; this.className = 'menu-item ' + attrs.type; this.menu_.addHandlers(this); @@ -113,7 +113,7 @@ MenuItem.prototype = { var c = mnemonic[2]; this.menu_.registerMnemonicKey(c, this); } - if (hasIcon) { + if (leftIconWidth > 0) { this.classList.add('left-icon'); var url; @@ -129,8 +129,14 @@ MenuItem.prototype = { if (url) { this.style.backgroundImage = "url(" + url + ")"; } + // TODO(oshima): figure out how to update left padding in rule. + // 4 is the padding on left side of icon. + var padding = + 4 + leftIconWidth + this.menu_.config_.icon_to_label_padding; + this.style.paddingLeft = padding + 'px'; } var label = document.createElement('div'); + label.className = 'menu-label'; if (!mnemonic) { @@ -289,7 +295,7 @@ Menu.prototype = { for (var i = 0; i < model.items.length; i++) { var attrs = model.items[i]; var item = this.createMenuItem(attrs); - item.init(this, attrs, model.hasIcon); + item.init(this, attrs, model.maxIconWidth); this.items_.push(item); } this.onResize_(); @@ -614,3 +620,7 @@ function selectItem() { function updateModel(model) { document.getElementById('viewport').updateModel(model); } + +function modelUpdated() { + chrome.send('model_updated', []); +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index af0e3ed..ece8f98 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -477,6 +477,8 @@ 'browser/chromeos/dom_ui/system_options_handler.h', 'browser/chromeos/dom_ui/system_settings_provider.cc', 'browser/chromeos/dom_ui/system_settings_provider.h', + 'browser/chromeos/dom_ui/wrench_menu_ui.cc', + 'browser/chromeos/dom_ui/wrench_menu_ui.h', 'browser/chromeos/drop_shadow_label.cc', 'browser/chromeos/external_cookie_handler.cc', 'browser/chromeos/external_cookie_handler.h', diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index d92f236..4d505b2 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc @@ -119,7 +119,6 @@ const char kChromeUISettingsHost[] = "settings"; const char kChromeUISyncResourcesHost[] = "syncresources"; const char kChromeUIThemePath[] = "theme"; const char kChromeUIThumbnailPath[] = "thumb"; -const char kChromeUIMenu[] = "menu"; #if defined(OS_CHROMEOS) const char kChromeUIFileBrowseHost[] = "filebrowse"; @@ -129,6 +128,8 @@ const char kChromeUIMobileSetupHost[] = "mobilesetup"; const char kChromeUIRegisterPageHost[] = "register"; const char kChromeUISlideshowHost[] = "slideshow"; const char kChromeUISystemInfoHost[] = "system"; +const char kChromeUIMenu[] = "menu"; +const char kChromeUIWrenchMenu[] = "wrench-menu"; #endif const char kAppCacheViewInternalsURL[] = "chrome://appcache-internals/"; diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index b7d56b9..a6dd0e3 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h @@ -113,7 +113,6 @@ extern const char kChromeUISettingsHost[]; extern const char kChromeUISyncResourcesHost[]; extern const char kChromeUIThemePath[]; extern const char kChromeUIThumbnailPath[]; -extern const char kChromeUIMenu[]; #if defined(OS_CHROMEOS) extern const char kChromeUIFileBrowseHost[]; @@ -123,6 +122,8 @@ extern const char kChromeUIMobileSetupHost[]; extern const char kChromeUIRegisterPageHost[]; extern const char kChromeUISlideshowHost[]; extern const char kChromeUISystemInfoHost[]; +extern const char kChromeUIMenu[]; +extern const char kChromeUIWrenchMenu[]; #endif // AppCache related URL. |