1 /** 2 * Create an Action instance. 3 * @class 4 * An action encapsulates the functionality of a menu item, by making it 5 * possible to register an event listener on the <code>action</code> event 6 * which is triggered when the menu item is clicked. 7 * Actions are typically created by invoking <code>actions.createAction()</code>- 8 * @constructor 9 * @param {String} name name of the action. 10 * @param {String} accelerator the keyboard shortcut of the action. 11 * @example 12 * var hello = actions.createAction('Hello World', 'shortcut shift F5'); 13 * actions.addAction(hello,'file'); 14 * hello.once('action', function() { 15 * actions.removeAction(hello, 'file'); 16 * }); 17 */ 18 19 function Action(name, accelerator) { 20 // invoke the superclass constructor 21 EventEmitter.call(this); 22 /** 23 * Name of the action. 24 * @ignore 25 * @type String 26 */ 27 this.name = name; 28 29 this.emitterAction = new com.escenic.studio.core.script.EmitterAction(this); 30 31 /** 32 * Holds the action instance of <code>com.escenic.studio.core.script.ScriptAction</code>. 33 * @ignore 34 */ 35 var action = new com.escenic.studio.core.script.ScriptAction(this.emitterAction); 36 37 /** 38 * Sets the name of the action. 39 * @param {String} name name of the action. 40 * @ignore 41 */ 42 action.setName(this.name); 43 if (accelerator != undefined) { 44 action.setAccelerator(accelerator); 45 } 46 47 var instance = this; 48 49 /** 50 * Returns the <code>com.escenic.studio.core.script.ScriptAction</code> instance. 51 * @returns the swing <code>com.escenic.studio.core.script.ScriptAction<code>. 52 * @ignore 53 */ 54 this.getSwingAction = function() { 55 return action; 56 // todo: get rid of this method in the public facing API! 57 }; 58 59 /** 60 * Returns the name of the action. 61 */ 62 this.getName = function() { 63 return action.getName(); 64 }; 65 66 /** 67 * Changes the name of the action. This will result in the UI changing 68 * to reflect the new name of the action. 69 */ 70 this.setName = function(newName) { 71 action.setName(newName); 72 } 73 74 /** 75 * Returns the desired accelerator for the action, or 76 * <code>undefined</code> if none has been defined. 77 * Please note that if the existing accelerator is invalid 78 * this method will still return the "invalid" accelerator 79 * even though it's not used in the actual user interface. 80 */ 81 this.getAccelerator = function() { 82 return accelerator; 83 } 84 85 /** 86 * Changes the accelerator for an action. If an invalid (or empty) 87 * accelerator is specified, the action will have no accelerator. 88 * @param {String} accelerator the new accelerator, e.g. "shortcut F11" 89 */ 90 this.setAccelerator = function(accelerator) { 91 if (accelerator != undefined) { 92 action.setAccelerator(accelerator); 93 this.accelerator = accelerator; 94 } 95 } 96 97 98 /** 99 * Sets or retrieves the enabled state of the action. When an action is enabled 100 * any menu item associated with the action are possible to click on. 101 * When an action is disabled, the menu items can not be clicked on and will appear 102 * disabled to the user. 103 * <p> 104 * This method can also be used to see the current enable/disable state. When called 105 * with no parameters it will just return the current enable/disable state. 106 * 107 * @param {Boolean} value true to enable this <code>Action</code>, false to disable it 108 * @return true or false when called without any parameters, and <code>undefined</code> if called with any parameters. 109 * @type Boolean 110 * @example 111 * // toggle an enabled action 112 * if (hello.enabled()) { 113 * hello.enabled(false); 114 * } 115 * else { 116 * hello.enabled(true) 117 * } 118 */ 119 this.enabled = function(value) { 120 if(value === undefined) { 121 return action.isEnabled(); 122 } else { 123 action.setEnabled(value); 124 instance.emit('enabled'); 125 } 126 }; 127 } 128 129 //todo this is a util method ... should be moved some other place 130 /** 131 * Creates a prototype for the subclass to inherits the prototype of the super class. 132 * @ignore 133 * @class This is used to inherit property from the parent class. 134 * @constructor 135 * @param p prototype of the parent class 136 * @returns an instance of the parent class prototype. 137 */ 138 function heir(p) { 139 /** @ignore */ 140 function F() { 141 } 142 143 F.prototype = p; 144 return new F(); 145 } 146 147 Action.prototype = heir(EventEmitter.prototype); 148 149 // set the constructor to the subclass prototype 150 Action.prototype.constructor = Action; 151 152 /** 153 * Provides access to menu items. 154 * @namespace 155 * Provides access to menu items. 156 * To access the namespace, use <code>require('actions')</code>. 157 * The <code>actions</code> namespace provides methods to work with <code>Action</code>s. 158 * Actions can be added to Content Studio's menus, and can also be assigned a shortcut 159 * key combination. 160 * <p> 161 * When actions are invoked by the user, an event is emitted; 162 * actions are also event emitters, and emit the <code>action</code> event when invoked 163 * by the user. 164 * @name actions 165 * @example 166 * var actions = require('actions'); 167 * var hello = actions.createAction('Hello'); 168 * hello.on('action', function() { 169 * console.log('Hello there'); 170 * }); 171 * actions.add(hello, 'help'); 172 */ 173 174 (function() { 175 176 function Actions() { 177 178 /** 179 * Returns an {@link Action} instance with the given name and accelerator. 180 * @param name the name of the action. 181 * @param accelerator the keyboard shortcut of the action. 182 * @memberOf actions 183 * @function 184 * @name createAction 185 * @example 186 * var doit = actions.createAction('Do it!', 'alt F2'); 187 */ 188 this.createAction = function(name, accelerator) { 189 return new Action(name, accelerator); 190 }; 191 192 var studioContext = jsStudioContext; 193 194 /** 195 * Removes the menu item associated with the {@link Action} from the given Content Studio menu. If no name is provided, the action will be removed from all menus. 196 * @param {Action} action the Action used when creating the menu item 197 * @param {String} menuName optionally, the name of the menu from which to remove the action. 198 * @memberOf actions 199 * @function 200 * @name removeAction 201 * @example 202 * actions.removeAction(doit, 'file'); 203 */ 204 this.removeAction = function(action, menuName) { 205 if (typeof(menuName) == 'undefined') { 206 studioContext.removeMenuItem(null, action.getSwingAction()); 207 } 208 else { 209 studioContext.removeMenuItem(menuName, action.getSwingAction()); 210 } 211 }; 212 213 /** 214 * Adds an menuItem to the given menu with the {@link Action}. 215 * @param {Action} action the action created earlier to add to the menu 216 * @param {String} where The name of the menu to which the action should be added. One of <code>file</code>, <code>edit</code>, <code>view</code>, <code>tools</code>, <code>plugins</code> or <code>help</code> 217 * @memberOf actions 218 * @function 219 * @name addAction 220 * @example 221 * actions.addAction(doit, 'file'); 222 */ 223 this.addAction = function (action, where) { 224 studioContext.addMenuItem(where, action.getSwingAction()); 225 }; 226 } 227 228 229 Require['actions'] = new Actions(); 230 }()) 231 232 /* 233 * usage 234 * 235 * var actions = require('actions'); 236 * var helloWorld = actions.createAction('Hello World', 'shortcut shift F5'); 237 * 238 * actions.addAction(helloWorld, 'file'); 239 * 240 * helloWorld.on('action', function(){ console.log('I am clicked'); }); 241 * 242 * helloWorld.on('enabled', function(value) { if (helloWorld.isEnabled()) { console.log('enabled'); } else { console.log('disabled'); } }); 243 * helloWorld.enabled(false); 244 * 245 * 246 * for removing action 247 * 248 * actions.removeAction(helloWorld, 'file'); //will remove menu item from file menu. 249 * actions.removeAction(helloWorld); // will remove menu item from all menu. 250 * 251 * */ 252