Load core menus from a file

This commit is contained in:
Matt Colyer 2013-10-04 12:28:19 -07:00
parent b63a33c7bb
commit 32101c57bf
7 changed files with 108 additions and 80 deletions

63
menus/base.cson Normal file
View File

@ -0,0 +1,63 @@
'menu': [
{
label: 'Atom'
submenu: [
{ label: 'About Atom', command: 'application:about' }
{ label: "Version #{@version}", enabled: false }
{ label: "Install update", command: 'application:install-update', visible: false }
{ type: 'separator' }
{ label: 'Preferences...', command: 'application:show-settings' }
{ label: 'Hide Atom', command: 'application:hide' }
{ label: 'Hide Others', command: 'application:hide-other-applications' }
{ label: 'Show All', command: 'application:unhide-all-applications' }
{ type: 'separator' }
{ label: 'Run Atom Specs', command: 'application:run-all-specs' }
{ type: 'separator' }
{ label: 'Quit', command: 'application:quit' }
]
}
{
label: 'File'
submenu: [
{ label: 'New Window', command: 'application:new-window' }
{ label: 'New File', command: 'application:new-file' }
{ type: 'separator' }
{ label: 'Open...', command: 'application:open' }
{ label: 'Open In Dev Mode...', command: 'application:open-dev' }
{ type: 'separator' }
{ label: 'Close Window', command: 'window:close' }
]
}
{
label: 'Edit'
submenu: [
{ label: 'Undo', command: 'core:undo' }
{ label: 'Redo', command: 'core:redo' }
{ type: 'separator' }
{ label: 'Cut', command: 'core:cut' }
{ label: 'Copy', command: 'core:copy' }
{ label: 'Paste', command: 'core:paste' }
{ label: 'Select All', command: 'core:select-all' }
]
}
{
label: 'View'
submenu: [
{ label: 'Reload', command: 'window:reload' }
{ label: 'Toggle Full Screen', command: 'window:toggle-full-screen' }
{ label: 'Toggle Developer Tools', command: 'window:toggle-dev-tools' }
]
}
{
label: 'Window'
submenu: [
{ label: 'Minimize', command: 'application:minimize' }
{ label: 'Zoom', command: 'application:zoom' }
{ type: 'separator' }
{ label: 'Bring All to Front', command: 'application:bring-all-windows-to-front' }
]
}
]

View File

@ -18,11 +18,13 @@ class ApplicationMenu
# Public: Updates the entire menu with the given keybindings.
#
# * template:
# The Object which describes the menu to display.
# * keystrokesByCommand:
# An Object where the keys are commands and the values are Arrays containing
# the keystrokes.
update: (keystrokesByCommand) ->
template = @getTemplate(keystrokesByCommand)
update: (template, keystrokesByCommand) ->
@translateTemplate template, keystrokesByCommand
@menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(@menu)
@ -77,77 +79,6 @@ class ApplicationMenu
]
]
# Private: The complete list of menu items.
#
# * keystrokesByCommand:
# An Object where the keys are commands and the values are Arrays containing
# the keystrokes.
#
# Returns a complete menu configuration Object for use with atom-shell's
# native menu API.
getTemplate: (keystrokesByCommand) ->
atomMenu =
label: 'Atom'
submenu: [
{ label: 'About Atom', command: 'application:about' }
{ label: "Version #{@version}", enabled: false }
{ label: "Install update", command: 'application:install-update', visible: false }
{ type: 'separator' }
{ label: 'Preferences...', command: 'application:show-settings' }
{ label: 'Hide Atom', command: 'application:hide' }
{ label: 'Hide Others', command: 'application:hide-other-applications' }
{ label: 'Show All', command: 'application:unhide-all-applications' }
{ type: 'separator' }
{ label: 'Run Atom Specs', command: 'application:run-all-specs' }
{ type: 'separator' }
{ label: 'Quit', command: 'application:quit' }
]
fileMenu =
label: 'File'
submenu: [
{ label: 'New Window', command: 'application:new-window' }
{ label: 'New File', command: 'application:new-file' }
{ type: 'separator' }
{ label: 'Open...', command: 'application:open' }
{ label: 'Open In Dev Mode...', command: 'application:open-dev' }
{ type: 'separator' }
{ label: 'Close Window', command: 'window:close' }
]
editMenu =
label: 'Edit'
submenu: [
{ label: 'Undo', command: 'core:undo' }
{ label: 'Redo', command: 'core:redo' }
{ type: 'separator' }
{ label: 'Cut', command: 'core:cut' }
{ label: 'Copy', command: 'core:copy' }
{ label: 'Paste', command: 'core:paste' }
{ label: 'Select All', command: 'core:select-all' }
]
viewMenu =
label: 'View'
submenu: [
{ label: 'Reload', command: 'window:reload' }
{ label: 'Toggle Full Screen', command: 'window:toggle-full-screen' }
{ label: 'Toggle Developer Tools', command: 'window:toggle-dev-tools' }
]
windowMenu =
label: 'Window'
submenu: [
{ label: 'Minimize', command: 'application:minimize' }
{ label: 'Zoom', command: 'application:zoom' }
{ type: 'separator' }
{ label: 'Bring All to Front', command: 'application:bring-all-windows-to-front' }
]
template = [atomMenu, fileMenu, editMenu, viewMenu, windowMenu]
@translateTemplate template, keystrokesByCommand
# Private: Combines a menu template with the appropriate keystrokes.
#
# * template:

View File

@ -165,8 +165,8 @@ class AtomApplication
else
@promptForPath()
ipc.once 'update-application-menu', (processId, routingId, keystrokesByCommand) =>
@applicationMenu.update(keystrokesByCommand)
ipc.once 'update-application-menu', (processId, routingId, template, keystrokesByCommand) =>
@applicationMenu.update(template, keystrokesByCommand)
ipc.on 'run-package-specs', (processId, routingId, specDirectory) =>
@runSpecs({resourcePath: global.devResourcePath, specDirectory: specDirectory, exitWhenDone: false})

View File

@ -43,10 +43,10 @@ class Atom
@__defineSetter__ 'packageStates', (packageStates) => @packages.packageStates = packageStates
@subscribe @packages, 'loaded', => @watchThemes()
@config = new Config()
@themes = new ThemeManager()
@contextMenu = new ContextMenuManager(@getLoadSettings().devMode)
@menu = new MenuManager()
@config = new Config()
@pasteboard = new Pasteboard()
@keymap = new Keymap()
@syntax = deserialize(@getWindowState('syntax')) ? new Syntax()

View File

@ -38,6 +38,7 @@ class Config
constructor: ->
@configDirPath = configDirPath
@bundledKeymapsDirPath = path.join(resourcePath, "keymaps")
@bundledMenusDirPath = path.join(resourcePath, "menus")
@nodeModulesDirPath = path.join(resourcePath, "node_modules")
@bundledPackageDirPaths = [@nodeModulesDirPath]
@lessSearchPaths = [

View File

@ -1,4 +1,10 @@
path = require 'path'
_ = require 'underscore'
ipc = require 'ipc'
CSON = require 'season'
fsUtils = require './fs-utils'
# Public: Provides a registry for menu items that you'd like to appear in the
# application menu.
@ -8,13 +14,39 @@ module.exports =
class MenuManager
# Private:
constructor: ->
@template = {}
@template = []
@loadCoreItems()
# Public: Adds the given item definition to the existing template.
#
# * item:
# An object which describes a menu item as defined by
# https://github.com/atom/atom-shell/blob/master/docs/api/browser/menu.md
#
# Returns nothing.
add: (item) ->
@merge(@template, item)
# Public: Refreshes the currently visible menu.
update: ->
@sendToBrowserProcess()
# Private: Request a context menu to be displayed.
sendToBrowserProcess: ->
ipc.sendChannel 'update-application-menu', atom.keymap.keystrokesByCommandForSelector('body')
# Private
loadCoreItems: ->
menuPaths = fsUtils.listSync(atom.config.bundledMenusDirPath, ['cson', 'json'])
for menuPath in menuPaths
data = CSON.readFileSync(menuPath)
@add(item) for item in data.menu
# Private: Merges an item in a menu aware way such that new items are always
# appended to the bottom.
merge: (template, item) ->
if match = _.find(template, (t) -> t.label == item.label)
match.submenu = match.submenu.concat(item.submenu)
else
template.push(item)
# Private
sendToBrowserProcess: ->
ipc.sendChannel 'update-application-menu', @template, atom.keymap.keystrokesByCommandForSelector('body')

View File

@ -50,6 +50,7 @@ module.exports = (grunt) ->
for directory in packageDirectories
cp directory, path.join(appDir, directory), filter: /.+\.(cson|coffee)$/
cp 'menus', path.join(appDir, 'menus')
cp 'spec', path.join(appDir, 'spec')
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
cp 'static', path.join(appDir, 'static')