From 63940f56581a1c3dd813bd4b2622123d2b558080 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Sun, 8 May 2016 20:52:37 -0400 Subject: [PATCH] refactor menu creation to accommodate OSX app menu and its default "Edit" menu --- pd/nw/pd_menus.js | 284 ++++++++++++++++++++++++---------------------- 1 file changed, 146 insertions(+), 138 deletions(-) diff --git a/pd/nw/pd_menus.js b/pd/nw/pd_menus.js index 2924f5ada..bf03cb8fc 100644 --- a/pd/nw/pd_menus.js +++ b/pd/nw/pd_menus.js @@ -13,60 +13,61 @@ function create_menu(gui, type) { // nw.js won't create an event listener unless you make the // shortcut immediately when creating the menu item. (It also // won't let you update the keyboard shortcut binding later.) - var m = {}; - - var osx = process.platform === "darwin", - cmd_or_ctrl = osx ? "cmd" : "ctrl"; // for keybindings + var m = {}, + osx = process.platform === "darwin", + cmd_or_ctrl = osx ? "cmd" : "ctrl", // for keybindings + canvas_menu, // menu for canvas = true, menu for Pd console = false + window_menu, // window menu bar, or-- for OSX-- app menu bar + file_menu, // submenus for window menubar... + edit_menu, + view_menu, + put_menu, + winman_menu, + media_menu, + help_menu; // OSX just spawns a single canvas menu and then enables/disables // the various menu items as needed. - var canvas_menu = osx || (type !== "console"); + canvas_menu = osx || (type !== "console"); if (osx_menu) { return osx_menu; // don't spawn multiple menus on OSX } // Window menu - var windowMenu = new gui.Menu({ type: "menubar" }); + window_menu = new gui.Menu({ type: "menubar" }); // File menu - var fileMenu = new gui.Menu(); - - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.file"), - submenu: fileMenu - })); + file_menu = new gui.Menu(); // File sub-entries m.file = {}; - fileMenu.append(m.file.new_file = new gui.MenuItem({ + file_menu.append(m.file.new_file = new gui.MenuItem({ label: l("menu.new"), key: "n", modifiers: cmd_or_ctrl, tooltip: l("menu.new_tt") })); - fileMenu.append(m.file.open = new gui.MenuItem({ + file_menu.append(m.file.open = new gui.MenuItem({ label: l("menu.open"), key: "o", modifiers: cmd_or_ctrl, tooltip: l("menu.open_tt") })); if (pdgui.k12_mode == 1) { - fileMenu.append(m.file.k12 = new gui.MenuItem({ + file_menu.append(m.file.k12 = new gui.MenuItem({ label: l("menu.k12_demos"), tooltip: l("menu.k12_demos_tt") })); } - fileMenu.append(new gui.MenuItem({ type: "separator" })); - + file_menu.append(new gui.MenuItem({ type: "separator" })); if (canvas_menu) { - fileMenu.append(m.file.save = new gui.MenuItem({ + file_menu.append(m.file.save = new gui.MenuItem({ label: l("menu.save"), key: "s", modifiers: cmd_or_ctrl, tooltip: l("menu.save_tt") })); - fileMenu.append(m.file.saveas = new gui.MenuItem({ + file_menu.append(m.file.saveas = new gui.MenuItem({ label: l("menu.saveas"), key: "s", modifiers: cmd_or_ctrl + "+shift", @@ -74,60 +75,54 @@ function create_menu(gui, type) { })); } if (pdgui.k12_mode == 0) { - fileMenu.append(new gui.MenuItem({ type: "separator" })); + file_menu.append(new gui.MenuItem({ type: "separator" })); } - fileMenu.append(m.file.message = new gui.MenuItem({ + file_menu.append(m.file.message = new gui.MenuItem({ label: l("menu.message"), key: "m", modifiers: cmd_or_ctrl, tooltip: l("menu.message_tt") })); if (pdgui.k12_mode == 0) { - fileMenu.append(new gui.MenuItem({ type: "separator" })); + file_menu.append(new gui.MenuItem({ type: "separator" })); } if (canvas_menu) { - fileMenu.append(m.file.close = new gui.MenuItem({ + file_menu.append(m.file.close = new gui.MenuItem({ label: l("menu.close"), key: "w", modifiers: cmd_or_ctrl, tooltip: l("menu.close_tt") })); } - fileMenu.append(m.file.quit = new gui.MenuItem({ + file_menu.append(m.file.quit = new gui.MenuItem({ label: l("menu.quit"), key: "q", modifiers: cmd_or_ctrl })); // Edit menu - var editMenu = new gui.Menu(); - - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.edit"), - submenu: editMenu - })); + edit_menu = new gui.Menu(); // Edit sub-entries m.edit = {}; if (canvas_menu) { - editMenu.append(m.edit.undo = new gui.MenuItem({ + edit_menu.append(m.edit.undo = new gui.MenuItem({ label: l("menu.undo"), tooltip: l("menu.undo_tt") })); - editMenu.append(m.edit.redo = new gui.MenuItem({ + edit_menu.append(m.edit.redo = new gui.MenuItem({ label: l("menu.redo"), tooltip: l("menu.redo_tt") })); - editMenu.append(new gui.MenuItem({ type: "separator" })); - editMenu.append(m.edit.cut = new gui.MenuItem({ + edit_menu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(m.edit.cut = new gui.MenuItem({ label: l("menu.cut"), key: "x", modifiers: cmd_or_ctrl, tooltip: l("menu.cut_tt") })); } - editMenu.append(m.edit.copy = new gui.MenuItem({ + edit_menu.append(m.edit.copy = new gui.MenuItem({ label: l("menu.copy"), key: "c", modifiers: cmd_or_ctrl, @@ -140,20 +135,20 @@ function create_menu(gui, type) { // from an external buffer. So unfortunately we can't // do the keybindings here. The side-effect is that // "Ctrl-V" isn't displayed in the menu item. - editMenu.append(m.edit.paste = new gui.MenuItem({ + edit_menu.append(m.edit.paste = new gui.MenuItem({ label: l("menu.paste"), //key: "v", //modifiers: cmd_or_ctrl, tooltip: l("menu.paste_tt") })); - editMenu.append(m.edit.duplicate = new gui.MenuItem({ + edit_menu.append(m.edit.duplicate = new gui.MenuItem({ label: l("menu.duplicate"), key: "d", modifiers: cmd_or_ctrl, tooltip: l("menu.duplicate_tt") })); } - editMenu.append(m.edit.selectall = new gui.MenuItem({ + edit_menu.append(m.edit.selectall = new gui.MenuItem({ label: l("menu.selectall"), key: "a", modifiers: cmd_or_ctrl, @@ -164,82 +159,82 @@ function create_menu(gui, type) { // key: "Return" or key: "Enter", so we // can't bind to ctrl-Enter here. (Even // tried fromCharCode...) - editMenu.append(m.edit.reselect = new gui.MenuItem({ + edit_menu.append(m.edit.reselect = new gui.MenuItem({ label: l("menu.reselect"), key: String.fromCharCode(10), modifiers: cmd_or_ctrl, tooltip: l("menu.reselect_tt") })); } - editMenu.append(new gui.MenuItem({ type: "separator" })); - editMenu.append(m.edit.clear_console = new gui.MenuItem({ + edit_menu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(m.edit.clear_console = new gui.MenuItem({ label: l("menu.clear_console"), tooltip: l("menu.clear_console"), key: "l", modifiers: "shift+" + cmd_or_ctrl })); - editMenu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(new gui.MenuItem({ type: "separator" })); if (canvas_menu) { - editMenu.append(m.edit.tidyup = new gui.MenuItem({ + edit_menu.append(m.edit.tidyup = new gui.MenuItem({ label: l("menu.tidyup"), key: "y", modifiers: cmd_or_ctrl, tooltip: l("menu.tidyup_tt") })); - editMenu.append(m.edit.tofront = new gui.MenuItem({ + edit_menu.append(m.edit.tofront = new gui.MenuItem({ label: l("menu.tofront"), tooltip: l("menu.tofront_tt") })); - editMenu.append(m.edit.toback = new gui.MenuItem({ + edit_menu.append(m.edit.toback = new gui.MenuItem({ label: l("menu.toback"), tooltip: l("menu.toback_tt") })); - editMenu.append(new gui.MenuItem({ type: "separator" })); - editMenu.append(m.edit.font = new gui.MenuItem({ + edit_menu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(m.edit.font = new gui.MenuItem({ label: l("menu.font"), tooltip: l("menu.font_tt") })); - editMenu.append(m.edit.cordinspector = new gui.MenuItem({ + edit_menu.append(m.edit.cordinspector = new gui.MenuItem({ type: "checkbox", label: l("menu.cordinspector"), key: "r", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.cordinspector_tt") })); - editMenu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(new gui.MenuItem({ type: "separator" })); } - editMenu.append(m.edit.find = new gui.MenuItem({ + edit_menu.append(m.edit.find = new gui.MenuItem({ label: l("menu.find"), key: "f", modifiers: cmd_or_ctrl, tooltip: l("menu.find_tt") })); if (canvas_menu) { - editMenu.append(m.edit.findagain = new gui.MenuItem({ + edit_menu.append(m.edit.findagain = new gui.MenuItem({ label: l("menu.findagain"), key: "g", modifiers: cmd_or_ctrl, tooltip: l("menu.findagain") })); - editMenu.append(m.edit.finderror = new gui.MenuItem({ + edit_menu.append(m.edit.finderror = new gui.MenuItem({ label: l("menu.finderror"), tooltip: l("menu.finderror_tt") })); - editMenu.append(new gui.MenuItem({ type: "separator" })); - editMenu.append(m.edit.autotips = new gui.MenuItem({ + edit_menu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(m.edit.autotips = new gui.MenuItem({ label: l("menu.autotips"), tooltip: l("menu.autotips_tt") })); - editMenu.append(m.edit.editmode = new gui.MenuItem({ + edit_menu.append(m.edit.editmode = new gui.MenuItem({ type: "checkbox", label: l("menu.editmode"), key: "e", modifiers: cmd_or_ctrl, tooltip: l("menu.editmode_tt") })); - editMenu.append(new gui.MenuItem({ type: "separator" })); + edit_menu.append(new gui.MenuItem({ type: "separator" })); } - editMenu.append(m.edit.preferences = new gui.MenuItem({ + edit_menu.append(m.edit.preferences = new gui.MenuItem({ label: l("menu.preferences"), key: osx ? "," : "p", modifiers: cmd_or_ctrl, @@ -247,37 +242,31 @@ function create_menu(gui, type) { })); // View menu - var viewMenu = new gui.Menu(); - - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.view"), - submenu: viewMenu - })); + view_menu = new gui.Menu(); // View sub-entries m.view = {}; - viewMenu.append(m.view.zoomin = new gui.MenuItem({ + view_menu.append(m.view.zoomin = new gui.MenuItem({ label: l("menu.zoomin"), key: "=", modifiers: cmd_or_ctrl, tooltip: l("menu.zoomin_tt") })); - viewMenu.append(m.view.zoomout = new gui.MenuItem({ + view_menu.append(m.view.zoomout = new gui.MenuItem({ label: l("menu.zoomout"), key: "-", modifiers: cmd_or_ctrl, tooltip: l("menu.zoomout_tt") })); - viewMenu.append(new gui.MenuItem({ type: "separator" })); - viewMenu.append(m.view.zoomreset = new gui.MenuItem({ + view_menu.append(new gui.MenuItem({ type: "separator" })); + view_menu.append(m.view.zoomreset = new gui.MenuItem({ label: l("menu.zoomreset"), key: "0", modifiers: cmd_or_ctrl, tooltip: l("menu.zoomreset_tt") })); - viewMenu.append(new gui.MenuItem({ type: "separator" })); - viewMenu.append(m.view.fullscreen = new gui.MenuItem({ + view_menu.append(new gui.MenuItem({ type: "separator" })); + view_menu.append(m.view.fullscreen = new gui.MenuItem({ label: l("menu.fullscreen"), key: process.platform === "darwin" ? "f" : "F11", modifiers: process.platform === "darwin" ? "cmd+ctrl" : null, @@ -286,104 +275,98 @@ function create_menu(gui, type) { if (canvas_menu) { // Put menu - var putMenu = new gui.Menu(); - - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.put"), - submenu: putMenu - })); + put_menu = new gui.Menu(); // Put menu sub-entries m.put = {}; - putMenu.append(m.put.object = new gui.MenuItem({ + put_menu.append(m.put.object = new gui.MenuItem({ label: l("menu.object"), key: "1", modifiers: cmd_or_ctrl, tooltip: l("menu.object_tt") })); - putMenu.append(m.put.message = new gui.MenuItem({ + put_menu.append(m.put.message = new gui.MenuItem({ label: l("menu.msgbox"), key: "2", modifiers: cmd_or_ctrl, tooltip: l("menu.msgbox_tt") })); - putMenu.append(m.put.number = new gui.MenuItem({ + put_menu.append(m.put.number = new gui.MenuItem({ label: l("menu.number"), key: "3", modifiers: cmd_or_ctrl, tooltip: l("menu.number_tt") })); - putMenu.append(m.put.symbol = new gui.MenuItem({ + put_menu.append(m.put.symbol = new gui.MenuItem({ label: l("menu.symbol"), key: "4", modifiers: cmd_or_ctrl, tooltip: l("menu.symbol_tt") })); - putMenu.append(m.put.comment = new gui.MenuItem({ + put_menu.append(m.put.comment = new gui.MenuItem({ label: l("menu.comment"), key: "5", modifiers: cmd_or_ctrl, tooltip: l("menu.comment_tt") })); - putMenu.append(new gui.MenuItem({ type: "separator" })); - putMenu.append(m.put.bang = new gui.MenuItem({ + put_menu.append(new gui.MenuItem({ type: "separator" })); + put_menu.append(m.put.bang = new gui.MenuItem({ label: l("menu.bang"), key: "b", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.bang_tt") })); - putMenu.append(m.put.toggle = new gui.MenuItem({ + put_menu.append(m.put.toggle = new gui.MenuItem({ label: l("menu.toggle"), key: "t", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.toggle_tt") })); - putMenu.append(m.put.number2 = new gui.MenuItem({ + put_menu.append(m.put.number2 = new gui.MenuItem({ label: l("menu.number2"), key: "n", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.number2") })); - putMenu.append(m.put.vslider = new gui.MenuItem({ + put_menu.append(m.put.vslider = new gui.MenuItem({ label: l("menu.vslider"), key: "v", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.vslider_tt") })); - putMenu.append(m.put.hslider = new gui.MenuItem({ + put_menu.append(m.put.hslider = new gui.MenuItem({ label: l("menu.hslider"), key: "h", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.hslider_tt") })); - putMenu.append(m.put.vradio = new gui.MenuItem({ + put_menu.append(m.put.vradio = new gui.MenuItem({ label: l("menu.vradio"), key: "d", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.vradio_tt") })); - putMenu.append(m.put.hradio = new gui.MenuItem({ + put_menu.append(m.put.hradio = new gui.MenuItem({ label: l("menu.hradio"), key: "i", modifiers: cmd_or_ctrl, tooltip: l("menu.hradio_tt") })); - putMenu.append(m.put.vu = new gui.MenuItem({ + put_menu.append(m.put.vu = new gui.MenuItem({ label: l("menu.vu"), key: "u", modifiers: cmd_or_ctrl, tooltip: l("menu.vu_tt") })); - putMenu.append(m.put.cnv = new gui.MenuItem({ + put_menu.append(m.put.cnv = new gui.MenuItem({ label: l("menu.cnv"), key: "c", modifiers: cmd_or_ctrl + "+shift", tooltip: l("menu.cnv_tt") })); - putMenu.append(new gui.MenuItem({ type: "separator" })); + put_menu.append(new gui.MenuItem({ type: "separator" })); //putMenu.append(m.put.graph = new gui.MenuItem()); - putMenu.append(m.put.array = new gui.MenuItem({ + put_menu.append(m.put.array = new gui.MenuItem({ label: l("menu.array"), tooltip: l("menu.array_tt") })); @@ -391,24 +374,18 @@ function create_menu(gui, type) { // Windows menu... call it "winman" (i.e., window management) // to avoid confusion - var winmanMenu = new gui.Menu(); - - // Add to windows menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.windows"), - submenu: winmanMenu - })); + winman_menu = new gui.Menu(); // Win sub-entries m.win = {}; - winmanMenu.append(m.win.nextwin = new gui.MenuItem({ + winman_menu.append(m.win.nextwin = new gui.MenuItem({ label: l("menu.nextwin"), key: "PageDown", //key: String.fromCharCode(12), // Page down modifiers: cmd_or_ctrl, tooltip: l("menu.nextwin_tt") })); - winmanMenu.append(m.win.prevwin = new gui.MenuItem({ + winman_menu.append(m.win.prevwin = new gui.MenuItem({ label: l("menu.prevwin"), key: "PageUp", //key: String.fromCharCode(11), // Page up @@ -416,104 +393,135 @@ function create_menu(gui, type) { tooltip: l("menu.prevwin_tt") })); if (canvas_menu) { - winmanMenu.append(new gui.MenuItem({ type: "separator" })); - winmanMenu.append(m.win.parentwin = new gui.MenuItem({ + winman_menu.append(new gui.MenuItem({ type: "separator" })); + winman_menu.append(m.win.parentwin = new gui.MenuItem({ label: l("menu.parentwin"), tooltip: l("menu.parentwin_tt") })); - winmanMenu.append(m.win.visible_ancestor = new gui.MenuItem({ + winman_menu.append(m.win.visible_ancestor = new gui.MenuItem({ label: l("menu.visible_ancestor"), tooltip: l("menu.visible_ancestor_tt") })); - winmanMenu.append(m.win.pdwin = new gui.MenuItem({ + winman_menu.append(m.win.pdwin = new gui.MenuItem({ label: l("menu.pdwin"), tooltip: l("menu.pdwin_tt"), key: "r", modifiers: cmd_or_ctrl })); } - // Media menu - var mediaMenu = new gui.Menu(); - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.media"), - submenu: mediaMenu - })); + // Media menu + media_menu = new gui.Menu(); // Media sub-entries m.media = {}; - mediaMenu.append(m.media.audio_on = new gui.MenuItem({ + media_menu.append(m.media.audio_on = new gui.MenuItem({ label: l("menu.audio_on"), key: "/", modifiers: cmd_or_ctrl, tooltip: l("menu.audio_on_tt") })); - mediaMenu.append(m.media.audio_off = new gui.MenuItem({ + media_menu.append(m.media.audio_off = new gui.MenuItem({ label: l("menu.audio_off"), key: ".", modifiers: cmd_or_ctrl, tooltip: l("menu.audio_off_tt") })); - mediaMenu.append(new gui.MenuItem({ type: "separator" })); - mediaMenu.append(m.media.test = new gui.MenuItem({ + media_menu.append(new gui.MenuItem({ type: "separator" })); + media_menu.append(m.media.test = new gui.MenuItem({ label: l("menu.test"), tooltip: l("menu.test_tt") })); - mediaMenu.append(m.media.loadmeter = new gui.MenuItem({ + media_menu.append(m.media.loadmeter = new gui.MenuItem({ label: l("menu.loadmeter"), tooltip: l("menu.loadmeter_tt") })); // Help menu - var helpMenu = new gui.Menu(); - - // Add to window menu - windowMenu.append(new gui.MenuItem({ - label: l("menu.help"), - submenu: helpMenu - })); + help_menu = new gui.Menu(); // Help sub-entries m.help = {}; - helpMenu.append(m.help.about = new gui.MenuItem({ + help_menu.append(m.help.about = new gui.MenuItem({ label: l("menu.about"), tooltip: l("menu.about_tt") })); - helpMenu.append(m.help.manual = new gui.MenuItem({ + help_menu.append(m.help.manual = new gui.MenuItem({ label: l("menu.manual"), tooltip: l("menu.manual") })); - helpMenu.append(m.help.browser = new gui.MenuItem({ + help_menu.append(m.help.browser = new gui.MenuItem({ label: l("menu.browser"), key: "b", modifiers: cmd_or_ctrl, tooltip: l("menu.browser_tt") })); - helpMenu.append(new gui.MenuItem({ type: "separator" })); - helpMenu.append(m.help.l2ork_list = new gui.MenuItem({ + help_menu.append(new gui.MenuItem({ type: "separator" })); + help_menu.append(m.help.l2ork_list = new gui.MenuItem({ label: l("menu.l2ork_list"), tooltip: l("menu.l2ork_list_tt") })); - helpMenu.append(m.help.pd_list = new gui.MenuItem({ + help_menu.append(m.help.pd_list = new gui.MenuItem({ label: l("menu.pd_list"), tooltip: l("menu.pd_list_tt") })); - helpMenu.append(m.help.forums = new gui.MenuItem({ + help_menu.append(m.help.forums = new gui.MenuItem({ label: l("menu.forums"), tooltip: l("menu.forums_tt") })); - helpMenu.append(m.help.irc = new gui.MenuItem({ + help_menu.append(m.help.irc = new gui.MenuItem({ label: l("menu.irc"), tooltip: l("menu.irc_tt") })); - helpMenu.append(m.help.devtools = new gui.MenuItem({ + help_menu.append(m.help.devtools = new gui.MenuItem({ label: l("menu.devtools"), tooltip: l("menu.devtools_tt") })); + // Add submenus to window menu + + // On OSX, we need to start with the built-in mac menu in order to + // get the application menu to show up correctly. Unfortunately, this + // will also spawn a built-in "Edit" and "Window" menu. Even more + // unfortunately, we must use the built-in "Edit" menu-- without it + // there is no way to get <command-v> shortcut to trigger the + // DOM "paste" event. + if (osx) { + window_menu.createMacBuiltin("purr-data"); + } + window_menu.append(new gui.MenuItem({ + label: l("menu.file"), + submenu: file_menu + })); + window_menu.append(new gui.MenuItem({ + label: l("menu.edit"), + submenu: edit_menu + })); + window_menu.append(new gui.MenuItem({ + label: l("menu.view"), + submenu: view_menu + })); + if (canvas_menu) { + window_menu.append(new gui.MenuItem({ + label: l("menu.put"), + submenu: put_menu + })); + } + window_menu.append(new gui.MenuItem({ + label: l("menu.windows"), + submenu: winman_menu + })); + window_menu.append(new gui.MenuItem({ + label: l("menu.media"), + submenu: media_menu + })); + window_menu.append(new gui.MenuItem({ + label: l("menu.help"), + submenu: help_menu + })); + // Assign to window - gui.Window.get().menu = windowMenu; + gui.Window.get().menu = window_menu; // If we're on OSX, store the object if (process.platform === "darwin") { -- GitLab