diff --git a/atom.gyp b/atom.gyp index 60d91c3cb45e..41e26f815bdd 100644 --- a/atom.gyp +++ b/atom.gyp @@ -15,6 +15,7 @@ 'browser/api/lib/dialog.coffee', 'browser/api/lib/ipc.coffee', 'browser/api/lib/menu.coffee', + 'browser/api/lib/menu_item.coffee', 'browser/atom/atom.coffee', 'browser/atom/objects_registry.coffee', 'browser/atom/rpc_server.coffee', diff --git a/browser/api/atom_api_menu.cc b/browser/api/atom_api_menu.cc index 627d1f30a421..544ad4339cec 100644 --- a/browser/api/atom_api_menu.cc +++ b/browser/api/atom_api_menu.cc @@ -208,7 +208,7 @@ v8::Handle Menu::InsertRadioItem(const v8::Arguments &args) { v8::Handle Menu::InsertSeparator(const v8::Arguments &args) { UNWRAP_MEMNU_AND_CHECK; - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString()) + if (!args[0]->IsNumber()) return node::ThrowTypeError("Bad argument"); int index = args[0]->IntegerValue(); diff --git a/browser/api/lib/menu.coffee b/browser/api/lib/menu.coffee index f2d27a72f915..132ad8faaa4c 100644 --- a/browser/api/lib/menu.coffee +++ b/browser/api/lib/menu.coffee @@ -1,7 +1,9 @@ EventEmitter = require('events').EventEmitter BrowserWindow = require 'browser_window' +MenuItem = require 'menu_item' bindings = process.atomBinding 'menu' + Menu = bindings.Menu Menu::__proto__ = EventEmitter.prototype @@ -11,23 +13,28 @@ Menu::popup = (window) -> popup.call this, window -insertSubMenu = Menu::insertSubMenu -Menu::insertSubMenu = (index, command_id, label, submenu) -> - throw new TypeError('Invalid menu') unless submenu?.constructor is Menu +Menu::insert = (pos, item) -> + throw new TypeError('Invalid item') unless item?.constructor is MenuItem - @menus = [] unless Array.isArray @menus - @menus.push submenu # prevent submenu from getting destroyed - insertSubMenu.apply this, arguments + switch item.type + when 'normal' then @insertItem pos, item.commandId, item.label + when 'checkbox' then @insertCheckItem pos, item.commandId, item.label + when 'radio' then @insertRadioItem pos, item.commandId, item.label, item.groupId + when 'separator' then @insertSeparator pos + when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu -Menu::appendItem = (args...) -> @insertItem -1, args... -Menu::appendCheckItem = (args...) -> @insertCheckItem -1, args... -Menu::appendRadioItem = (args...) -> @insertRadioItem -1, args... -Menu::appendSeparator = (args...) -> @insertSeparator -1, args... -Menu::appendSubMenu = (args...) -> @insertSubMenu -1, args... + @setSublabel pos, item.sublabel if item.sublabel? + + @items = {} unless @items? + @items[item.commandId] = item + +Menu::append = (item) -> + @insert @getItemCount(), item Menu.setApplicationMenu = (menu) -> throw new TypeError('Invalid menu') unless menu?.constructor is Menu bindings.setApplicationMenu menu + Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder module.exports = Menu diff --git a/browser/api/lib/menu_item.coffee b/browser/api/lib/menu_item.coffee new file mode 100644 index 000000000000..d9d801dabcdb --- /dev/null +++ b/browser/api/lib/menu_item.coffee @@ -0,0 +1,18 @@ +nextCommandId = 0 + +class MenuItem + @types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'] + + constructor: (options) -> + {@type, @label, @sublabel, @click, @checked, @groupId, @submenu} = options + + @type = @type ? 'normal' + @label = @label ? '' + @sublabel = @sublabel ? '' + + throw new Error('Unknown menu type') if MenuItem.types.indexOf(@type) is -1 + throw new Error('Invalid menu') if @type is 'submenu' and @submenu?.constructor.name isnt 'Menu' + + @commandId = ++nextCommandId + +module.exports = MenuItem