Permalink
Browse files

Merge pull request #946 from adobe/tvoliter/newmenus-impl-squashed

Menu, Commands, and Shortcuts API and implementation (squashed pull request)
  • Loading branch information...
2 parents c63a829 + 2a0f08e commit 4e8b7402a4e7569eb659f1d0a6487dbc5370544c @peterflynn peterflynn committed May 26, 2012
@@ -173,7 +173,7 @@ define(function main(require, exports, module) {
}
window.setTimeout(init);
- CommandManager.register(Commands.FILE_LIVE_FILE_PREVIEW, _handleGoLiveCommand);
+ CommandManager.register(Strings.CMD_LIVE_FILE_PREVIEW, Commands.FILE_LIVE_FILE_PREVIEW, _handleGoLiveCommand);
// Export public functions
exports.init = init;
View
@@ -162,7 +162,7 @@ define(function (require, exports, module) {
DocumentCommandHandlers.init($("#main-toolbar"));
// About dialog
- CommandManager.register(Commands.HELP_ABOUT, function () {
+ CommandManager.register(Strings.CMD_ABOUT, Commands.HELP_ABOUT, function () {
// If we've successfully determined a "build number" via .git metadata, add it to dialog
var bracketsSHA = BuildInfoUtils.getBracketsSHA(),
bracketsAppSHA = BuildInfoUtils.getBracketsAppSHA(),
@@ -179,65 +179,7 @@ define(function (require, exports, module) {
});
}
- function initKeyBindings() {
- // Register keymaps and install the keyboard handler
- // TODO: (issue #268) show keyboard equivalents in the menus
- var _globalKeymap = KeyMap.create({
- "bindings": [
- // FILE
- {"Ctrl-N": Commands.FILE_NEW},
- {"Ctrl-O": Commands.FILE_OPEN},
- {"Ctrl-S": Commands.FILE_SAVE},
- {"Ctrl-W": Commands.FILE_CLOSE},
- {"Ctrl-Alt-P": Commands.FILE_LIVE_FILE_PREVIEW},
- {"Ctrl-Q": Commands.FILE_QUIT},
-
- // EDIT
- // disabled until the menu items are connected to the commands. Keyboard shortcuts work via CodeMirror
- //{"Ctrl-Z": Commands.EDIT_UNDO},
- //{"Ctrl-Y": Commands.EDIT_REDO},
- //{"Ctrl-X": Commands.EDIT_CUT},
- //{"Ctrl-C": Commands.EDIT_COPY},
- //{"Ctrl-V": Commands.EDIT_PASTE},
-
- {"Ctrl-A": Commands.EDIT_SELECT_ALL},
- {"Ctrl-F": Commands.EDIT_FIND},
- {"Ctrl-Shift-F": Commands.EDIT_FIND_IN_FILES},
- {"Ctrl-G": Commands.EDIT_FIND_NEXT, "platform": "mac"},
- {"F3": Commands.EDIT_FIND_NEXT, "platform": "win"},
- {"Ctrl-Shift-G": Commands.EDIT_FIND_PREVIOUS, "platform": "mac"},
- {"Shift-F3": Commands.EDIT_FIND_PREVIOUS, "platform": "win"},
- {"Ctrl-Alt-F": Commands.EDIT_REPLACE, "platform": "mac"},
- {"Ctrl-H": Commands.EDIT_REPLACE, "platform": "win"},
- {"Ctrl-D": Commands.EDIT_DUPLICATE},
- {"Ctrl-/": Commands.EDIT_LINE_COMMENT},
-
- // VIEW
- {"Ctrl-Shift-H": Commands.VIEW_HIDE_SIDEBAR},
- {"Ctrl-=": Commands.VIEW_INCREASE_FONT_SIZE},
- {"Ctrl--": Commands.VIEW_DECREASE_FONT_SIZE},
-
- // Navigate
- {"Ctrl-Tab": Commands.NAVIGATE_NEXT_DOC}, // note: DocumentCommandHandlers requires modifier to be Ctrl
- {"Ctrl-Shift-Tab": Commands.NAVIGATE_PREV_DOC},
- {"Ctrl-Shift-O": Commands.NAVIGATE_QUICK_OPEN},
- {"Ctrl-T": Commands.NAVIGATE_GOTO_DEFINITION},
- {"Ctrl-L": Commands.NAVIGATE_GOTO_LINE, "platform": "mac"},
- {"Ctrl-G": Commands.NAVIGATE_GOTO_LINE, "platform": "win"},
- {"Ctrl-E": Commands.SHOW_INLINE_EDITOR},
- {"Alt-Up": Commands.QUICK_EDIT_PREV_MATCH},
- {"Alt-Down": Commands.QUICK_EDIT_NEXT_MATCH},
-
- // DEBUG
- {"F5": Commands.DEBUG_REFRESH_WINDOW, "platform": "win"},
- {"Ctrl-R": Commands.DEBUG_REFRESH_WINDOW, "platform": "mac"}
-
-
- ],
- "platform": brackets.platform
- });
- KeyBindingManager.installKeymap(_globalKeymap);
-
+ function initKeyHandler() {
window.document.body.addEventListener(
"keydown",
function (event) {
@@ -278,7 +220,7 @@ define(function (require, exports, module) {
initListeners();
initCommandHandlers();
- initKeyBindings();
+ initKeyHandler();
Menus.init(); // key bindings should be initialized first
initWindowListeners();
@@ -32,42 +32,156 @@
define(function (require, exports, module) {
'use strict';
+ /**
+ * Map of all registered global commands
+ * @type Object.<commandID: string, Command>
+ */
var _commands = {};
/**
- * Registers a global command.
+ * @constructor
+ * @private
+ *
+ * @param {string} name - text that will be displayed in the UI to represent command
+ * @param {string} id
+ * @param {function} commandFn - the function that is called when the command is executed.
+ *
+ * TODO: where should this be triggered, The Command or Exports?
+ * Events:
+ * enabledStateChange
+ * checkedStateChange
+ */
+ function Command(name, id, commandFn) {
+ this._name = name;
+ this._id = id;
+ this._commandFn = commandFn;
+ this._checked = undefined;
+ this._enabled = true;
+ }
+
+ /** @return {Command} */
+ Command.prototype.getID = function () {
+ return this._id;
+ };
+
+ /**
+ * Executes the command. Additional arguments are passed to the executing function
*
- * @param {string} id The ID of the command.
- * @param {function(...)} command The function to call when the command is executed. Any arguments passed to
+ * @return {$.Promise} a jQuery promise that will be resolved when the command completes.
+ */
+ Command.prototype.execute = function () {
+ var result = this._commandFn.apply(this, arguments);
+ if (!result) {
+ return (new $.Deferred()).resolve().promise();
+ } else {
+ return result;
+ }
+ };
+
+ /** @return {boolean} */
+ Command.prototype.getEnabled = function () {
+ return this._enabled;
+ };
+
+ /**
+ * Sets enabled state of Command and dispatches "enabledStateChange"
+ * when the enabled state changes.
+ * @param {boolean} enabled
+ */
+ Command.prototype.setEnabled = function (enabled) {
+ var changed = this._enabled !== enabled;
+ this._enabled = enabled;
+
+ if (changed) {
+ $(this).triggerHandler("enabledStateChange", this);
+ }
+ };
+
+ /**
+ * Sets enabled state of Command and dispatches "checkedStateChange"
+ * when the enabled state changes.
+ * @param {boolean} checked
+ */
+ Command.prototype.setChecked = function (checked) {
+ var changed = this._checked !== checked;
+ this._checked = checked;
+
+ if (changed) {
+ $(this).triggerHandler("checkedStateChange", this);
+ }
+ };
+
+ /** @return {boolean} */
+ Command.prototype.getChecked = function () {
+ return this._checked;
+ };
+
+ /**
+ * Sets the name of the Command and dispatches "nameChange" so that
+ * UI that reflects the command name can update.
+ * @param {string} name
+ */
+ Command.prototype.setName = function (name) {
+ var changed = this._name !== name;
+ this._name = name;
+
+ if (changed) {
+ $(this).triggerHandler("nameChange", this);
+ }
+ };
+
+ /** @return {string} */
+ Command.prototype.getName = function () {
+ return this._name;
+ };
+
+
+
+ /**
+ * Registers a global command.
+ * @param {string} name - text that will be displayed in the UI to represent command
+ * @param {string} id - unique identifier for command.
+ * Core commands in Brackets use a simple command title as an id, for example "open.file".
+ * Extensions should use the following format: "author.myextension.mycommandname".
+ * For example, "lschmitt.csswizard.format.css".
+ * @param {function(...)} commandFn - the function to call when the command is executed. Any arguments passed to
* execute() (after the id) are passed as arguments to the function. If the function is asynchronous,
* it must return a jQuery promise that is resolved when the command completes. Otherwise, the
* CommandManager will assume it is synchronous, and return a promise that is already resolved.
+ * @return {Command}
*/
- function register(id, command) {
+ function register(name, id, commandFn) {
if (_commands[id]) {
throw new Error("Attempting to register an already-registered command: " + id);
}
- if (!id || !command) {
- throw new Error("Attempting to register a command with a bad id or function");
+ if (!name || !id || !commandFn) {
+ throw new Error("Attempting to register a command with a missing name, id, or command function:" + name + " " + id);
}
+
+ var command = new Command(name, id, commandFn);
_commands[id] = command;
+ return command;
+ }
+
+ /**
+ * Retrieves a Command object by id
+ * @param {string} id
+ * @return {Command}
+ */
+ function get(id) {
+ return _commands[id];
}
/**
- * Runs a global command. Additional arguments are passed to the command.
+ * Looks up and runs a global command. Additional arguments are passed to the command.
*
* @param {string} id The ID of the command to run.
* @return {$.Promise} a jQuery promise that will be resolved when the command completes.
*/
function execute(id) {
var command = _commands[id];
if (command) {
- var result = command.apply(null, Array.prototype.slice.call(arguments, 1));
- if (!result) {
- return (new $.Deferred()).resolve().promise();
- } else {
- return result;
- }
+ return command.execute.apply(command, Array.prototype.slice.call(arguments, 1));
} else {
return (new $.Deferred()).reject().promise();
}
@@ -76,4 +190,5 @@ define(function (require, exports, module) {
// Define public API
exports.register = register;
exports.execute = execute;
+ exports.get = get;
});
View
@@ -33,38 +33,38 @@ define(function (require, exports, module) {
*/
// FILE
- exports.FILE_NEW = "file.new";
- exports.FILE_OPEN = "file.open";
- exports.FILE_OPEN_FOLDER = "file.openFolder";
- exports.FILE_SAVE = "file.save";
- exports.FILE_CLOSE = "file.close";
- exports.FILE_CLOSE_ALL = "file.close_all";
- exports.FILE_CLOSE_WINDOW = "file.close_window"; // string must MATCH string in native code (brackets_extensions)
- exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet";
- exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview";
- exports.FILE_QUIT = "file.quit"; // string must MATCH string in native code (brackets_extensions)
+ exports.FILE_NEW = "file.new";
+ exports.FILE_OPEN = "file.open";
+ exports.FILE_OPEN_FOLDER = "file.openFolder";
+ exports.FILE_SAVE = "file.save";
+ exports.FILE_CLOSE = "file.close";
+ exports.FILE_CLOSE_ALL = "file.close_all";
+ exports.FILE_CLOSE_WINDOW = "file.close_window"; // string must MATCH string in native code (brackets_extensions)
+ exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet";
+ exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview";
+ exports.FILE_QUIT = "file.quit"; // string must MATCH string in native code (brackets_extensions)
// EDIT
- exports.EDIT_UNDO = "edit.undo";
- exports.EDIT_REDO = "edit.redo";
- exports.EDIT_CUT = "edit.cut";
- exports.EDIT_COPY = "edit.copy";
- exports.EDIT_PASTE = "edit.paste";
- exports.EDIT_SELECT_ALL = "edit.selectAll";
- exports.EDIT_FIND = "edit.find";
- exports.EDIT_FIND_IN_FILES = "edit.findInFiles";
- exports.EDIT_FIND_NEXT = "edit.findNext";
- exports.EDIT_FIND_PREVIOUS = "edit.findPrevious";
- exports.EDIT_REPLACE = "edit.replace";
- exports.EDIT_INDENT = "edit.indent";
- exports.EDIT_UNINDENT = "edit.unindent";
- exports.EDIT_DUPLICATE = "edit.duplicate";
- exports.EDIT_LINE_COMMENT = "edit.lineComment";
+ exports.EDIT_UNDO = "edit.undo";
+ exports.EDIT_REDO = "edit.redo";
+ exports.EDIT_CUT = "edit.cut";
+ exports.EDIT_COPY = "edit.copy";
+ exports.EDIT_PASTE = "edit.paste";
+ exports.EDIT_SELECT_ALL = "edit.selectAll";
+ exports.EDIT_FIND = "edit.find";
+ exports.EDIT_FIND_IN_FILES = "edit.findInFiles";
+ exports.EDIT_FIND_NEXT = "edit.findNext";
+ exports.EDIT_FIND_PREVIOUS = "edit.findPrevious";
+ exports.EDIT_REPLACE = "edit.replace";
+ exports.EDIT_INDENT = "edit.indent";
+ exports.EDIT_UNINDENT = "edit.unindent";
+ exports.EDIT_DUPLICATE = "edit.duplicate";
+ exports.EDIT_LINE_COMMENT = "edit.lineComment";
// VIEW
- exports.VIEW_HIDE_SIDEBAR = "view.hideSidebar";
- exports.VIEW_INCREASE_FONT_SIZE = "view.increaseFontSize";
- exports.VIEW_DECREASE_FONT_SIZE = "view.decreaseFontSize";
+ exports.VIEW_HIDE_SIDEBAR = "view.hideSidebar";
+ exports.VIEW_INCREASE_FONT_SIZE = "view.increaseFontSize";
+ exports.VIEW_DECREASE_FONT_SIZE = "view.decreaseFontSize";
// Navigate
exports.NAVIGATE_NEXT_DOC = "navigate.nextDoc";
@@ -76,15 +76,19 @@ define(function (require, exports, module) {
exports.QUICK_EDIT_NEXT_MATCH = "navigate.nextMatch";
exports.QUICK_EDIT_PREV_MATCH = "navigate.previousMatch";
- exports.DEBUG_REFRESH_WINDOW = "debug.refreshWindow"; // string must MATCH string in native code (brackets_extensions)
- exports.DEBUG_SHOW_DEVELOPER_TOOLS = "debug.showDeveloperTools";
- exports.DEBUG_RUN_UNIT_TESTS = "debug.runUnitTests";
- exports.DEBUG_JSLINT = "debug.jslint";
- exports.DEBUG_SHOW_PERF_DATA = "debug.showPerfData";
- exports.DEBUG_NEW_BRACKETS_WINDOW = "debug.newBracketsWindow";
- exports.DEBUG_CLOSE_ALL_LIVE_BROWSERS = "debug.closeAllLiveBrowsers";
- exports.DEBUG_USE_TAB_CHARS = "debug.useTabChars";
+ // Debug
+ exports.DEBUG_EXPERIMENTAL = "debug.experimental";
+ exports.DEBUG_REFRESH_WINDOW = "debug.refreshWindow"; // string must MATCH string in native code (brackets_extensions)
+ exports.DEBUG_SHOW_DEVELOPER_TOOLS = "debug.showDeveloperTools";
+ exports.DEBUG_RUN_UNIT_TESTS = "debug.runUnitTests";
+ exports.DEBUG_JSLINT = "debug.jslint";
+ exports.DEBUG_SHOW_PERF_DATA = "debug.showPerfData";
+ exports.DEBUG_NEW_BRACKETS_WINDOW = "debug.newBracketsWindow";
+ exports.DEBUG_CLOSE_ALL_LIVE_BROWSERS = "debug.closeAllLiveBrowsers";
+ exports.DEBUG_USE_TAB_CHARS = "debug.useTabChars";
- exports.HELP_ABOUT = "help.about";
+ // Command that does nothing. Can be used for place holder menuItems
+
+ exports.HELP_ABOUT = "help.about";
});
Oops, something went wrong.

0 comments on commit 4e8b740

Please sign in to comment.