Skip to content

Commit ffbcb56

Browse files
committed
feat: add menus quick start docs
1 parent 1b64a5a commit ffbcb56

File tree

8 files changed

+388
-0
lines changed

8 files changed

+388
-0
lines changed

api/Extension-quick-start/Menus.md

Lines changed: 388 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,388 @@
1+
---
2+
title: Menus
3+
---
4+
5+
This document outlines the basic features of working with Menus, including:
6+
7+
[How to add a Menu](#adding-a-menu)
8+
[How to add a SubMenu](#adding-a-sub-menu)
9+
[How to add a Menu item](#adding-a-menu-item)
10+
[How to position a Menu item](#position-the-menu-item)
11+
[How to add a keyboard shortcut to a Menu item](#attach-a-keyboard-shortcut-to-a-menu-item)
12+
13+
---
14+
15+
16+
## Adding a Menu
17+
18+
To add a custom menu, follow these steps :-
19+
20+
1. **Import the `Menus` module.**
21+
To use the menu functionality, import the `Menus` module:
22+
23+
```jsx
24+
const Menus = brackets.getModule("command/Menus");
25+
```
26+
27+
2. **Create the menu.**
28+
29+
Use `Menus.addMenu()` to add a menu to the menu bar. Provide the display name and the identifier. *The identifier must be written in* `snake_case`.
30+
<br>
31+
> Providing the identifier is necessary to display the menu on the menu bar. This identifier may later be used to add menu items inside it or even remove the menu if needed.
32+
33+
```jsx
34+
// Add a menu to the menu bar
35+
const menu = Menus.addMenu('Test', 'Test_Extension_Docs');
36+
```
37+
38+
39+
> For a detailed description, refer to [this link](https://docs.phcode.dev/api/API-Reference/command/Menus#addMenu).
40+
41+
Full Code Example :-
42+
43+
```jsx
44+
define(function (require, exports, module) {
45+
"use strict";
46+
47+
// Brackets modules
48+
const AppInit = brackets.getModule("utils/AppInit"),
49+
Menus = brackets.getModule("command/Menus");
50+
51+
// Add a menu to the menu bar
52+
const menu = Menus.addMenu('Test', 'Test_Extension_Docs');
53+
54+
// Initialize extension once shell is finished initializing.
55+
AppInit.appReady(function () {
56+
console.log("hello world");
57+
});
58+
});
59+
```
60+
61+
Expected Output :-
62+
63+
![Adding a menu](./images/add-menu.png)
64+
65+
66+
## Adding a Menu Item
67+
68+
To add a menu item, follow these steps :-
69+
70+
1. **Import the `Menus` and `CommandManager` module.**
71+
72+
These modules allow you to register commands and add items to menus:
73+
74+
```jsx
75+
const CommandManager = brackets.getModule("command/CommandManager");
76+
const Menus = brackets.getModule("command/Menus");
77+
```
78+
79+
80+
2. **Register the Command**
81+
82+
Use `CommandManager.register()` to associate an ID with a function:
83+
84+
```jsx
85+
function handleTestExtension() {
86+
alert("Test menu item");
87+
}
88+
89+
// The `CommandID` must be written in snake_case
90+
const MY_COMMAND_ID = "test_menuitem";
91+
CommandManager.register("Test", MY_COMMAND_ID, handleTestExtension);
92+
```
93+
94+
- The first argument is the label for the menu item.
95+
- The second argument is a unique command ID.
96+
- The third argument is the handler function to execute when the item is clicked.
97+
98+
3. **Add the Menu Item**
99+
To add the menu item, use `menu.addMenuItem()`. For instance, if you wish to add an item to the **File menu**, you can write:
100+
101+
102+
```jsx
103+
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
104+
menu.addMenuItem(MY_COMMAND_ID);
105+
```
106+
107+
108+
> These are some of the menus available by default :-
109+
110+
- FILE_MENU : ‘file-menu’
111+
- EDIT_MENU : ‘edit-menu’
112+
- FIND_MENU : ‘find-menu’
113+
- VIEW_MENU : ‘view-menu’
114+
- NAVIGATE_MENU : ‘navigate-menu’
115+
116+
You can also add menu items to any custom menus you create.
117+
118+
> For a detailed description, refer to [this link](https://docs.phcode.dev/api/API-Reference/command/Menus#addMenuItem).
119+
120+
Full Code Example :-
121+
122+
```jsx
123+
define(function (require, exports, module) {
124+
"use strict";
125+
126+
// Brackets modules
127+
const AppInit = brackets.getModule("utils/AppInit"),
128+
CommandManager = brackets.getModule("command/CommandManager"),
129+
Menus = brackets.getModule("command/Menus");
130+
131+
// Function to run when the menu item is clicked
132+
function handleTestExtension() {
133+
alert("Test menu item");
134+
}
135+
136+
// The `CommandID` must be written in snake_case
137+
const MY_COMMAND_ID = "test_menuitem";
138+
CommandManager.register("Test", MY_COMMAND_ID, handleTestExtension);
139+
140+
// Add Menu item
141+
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
142+
menu.addMenuItem(MY_COMMAND_ID);
143+
144+
// Initialize extension once shell is finished initializing.
145+
AppInit.appReady(function () {
146+
console.log("hello world");
147+
});
148+
});
149+
```
150+
151+
Expected Output :-
152+
153+
![Menu Item Example](./images/menu-item-example.png)
154+
155+
![Menu Item Dialog](./images/menu-item-dialog.png)
156+
157+
The alert box that appears when the `Test` menu item is clicked!
158+
159+
160+
## Position the Menu Item
161+
162+
You can position the menu item to make it appear at the first, last or before/after a given item.
163+
164+
To position the menu item at the top, use
165+
166+
```jsx
167+
// second parameter is for keyboard shortcut. Empty string means no shortcut.
168+
menu.addMenuItem(MY_COMMAND_ID, "", Menus.FIRST);
169+
```
170+
171+
![Menu Item at first](./images/menu-item-first.png)
172+
173+
`Menus.FIRST` is used to position it before every other item. *Note: It is recommended to avoid using this and prefer relative menu IDs for better positioning.**
174+
175+
`Menus.LAST` is used to position it at the end. It is the Default value.
176+
177+
To position the menu item before or after any item, use
178+
179+
```jsx
180+
// second parameter is for keyboard shortcut. Empty string means no shortcut.
181+
menu.addMenuItem(MY_COMMAND_ID, "", "before", "file.saveAs");
182+
```
183+
184+
- Third parameter must specify “before” or “after” the item should be set.
185+
- Fourth parameter must specify the “relativeID” of the menu item to set the position.
186+
187+
![Menu Item before/after](./images/menu-item-before-after.png)
188+
189+
Here, the menu item is set before the `Save As...` option.
190+
191+
To get the list of all the `RelativeIDs` available by default, refer to [this link](https://docs.phcode.dev/api/API-Reference/command/Commands).
192+
193+
194+
## Attach a keyboard shortcut to a Menu Item
195+
196+
You can assign a keyboard shortcut to your menu item.
197+
198+
*Note: Only add shortcuts if they're essential and frequently used, ensuring compatibility across platforms. Users can set custom shortcuts, so default shortcuts should be reserved only for high-use actions.*
199+
200+
To add the keyboard shortcut, use :-
201+
202+
1. Import the `KeyBindingManager` module.
203+
204+
```jsx
205+
const KeyBindingManager = brackets.getModule("command/KeyBindingManager");
206+
```
207+
208+
209+
2. Add the keyboard shortcut to `addMenuItem`. The keyboard shortcut will be displayed next to the menu item in the UI.
210+
211+
> Ensure that the keyboard shortcut you choose doesn't conflict with any existing shortcuts already in use.
212+
213+
```jsx
214+
menu.addMenuItem(MY_COMMAND_ID, "Ctrl-Alt-T", Menus.FIRST);
215+
```
216+
217+
![Menu Item keyboard shortcut](./images/menu-item-keyboard-shortcut.png)
218+
219+
3. Register the keyboard shortcut. To register use `addBinding()`. The first parameter will be the `CommandID` of the menu item and the second parameter will be the keyboard shortcut.
220+
221+
```jsx
222+
KeyBindingManager.addBinding(MY_COMMAND_ID, "Ctrl-Alt-T");
223+
```
224+
225+
226+
That's it! Now, pressing the assigned keyboard shortcut will trigger the corresponding menu item.
227+
228+
> For a detailed description, refer to [this link](https://docs.phcode.dev/api/API-Reference/command/KeyBindingManager).
229+
230+
Full Code Example :-
231+
232+
```jsx
233+
define(function (require, exports, module) {
234+
"use strict";
235+
236+
// Brackets modules
237+
const AppInit = brackets.getModule("utils/AppInit"),
238+
CommandManager = brackets.getModule("command/CommandManager"),
239+
Menus = brackets.getModule("command/Menus"),
240+
KeyBindingManager = brackets.getModule("command/KeyBindingManager");
241+
242+
// Function to run when the menu item is clicked
243+
function handleTestExtension() {
244+
alert("Test menu item");
245+
}
246+
247+
const MY_COMMAND_ID = "test_menuitem";
248+
CommandManager.register("Test", MY_COMMAND_ID, handleTestExtension);
249+
250+
// Add Menu item
251+
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
252+
253+
menu.addMenuItem(MY_COMMAND_ID, "Ctrl-Alt-T", Menus.FIRST);
254+
255+
// Register the keyboard shortcut
256+
KeyBindingManager.addBinding(MY_COMMAND_ID, "Ctrl-Alt-T");
257+
258+
// Initialize extension once shell is finished initializing.
259+
AppInit.appReady(function () {
260+
console.log("hello world");
261+
});
262+
});
263+
```
264+
265+
## Adding a Sub Menu
266+
267+
To add a submenu to an existing menu item, follow these steps:
268+
269+
1. **Import the `Menus` and `CommandManager` modules**
270+
271+
```jsx
272+
const CommandManager = brackets.getModule("command/CommandManager");
273+
const Menus = brackets.getModule("command/Menus");
274+
```
275+
276+
2. **Create and register the main command**
277+
First, create a command that will serve as the parent menu item:
278+
279+
```jsx
280+
function handleTestExtension() {
281+
alert("Test menu item");
282+
}
283+
284+
const MY_COMMAND_ID = "Test";
285+
CommandManager.register("Test", MY_COMMAND_ID, handleTestExtension);
286+
```
287+
288+
3. **Get the parent menu and create the submenu**
289+
Use `menu.addSubMenu()` to create a submenu under an existing menu:
290+
291+
```jsx
292+
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
293+
const subMenu = menu.addSubMenu(MY_COMMAND_ID, "Test_Sub_Menu");
294+
```
295+
296+
- First parameter is the command ID of the parent menu item
297+
- Second parameter is the identifier for the submenu (must be in `snake_case`)
298+
299+
4. **Create and register submenu commands**
300+
Register commands for each submenu item:
301+
302+
```jsx
303+
const SUB_COMMAND_1 = "Test_SubCommand1";
304+
const SUB_COMMAND_2 = "Test_SubCommand2";
305+
306+
CommandManager.register("Sub Item 1", SUB_COMMAND_1, function() {
307+
alert("Sub Item 1 clicked");
308+
});
309+
CommandManager.register("Sub Item 2", SUB_COMMAND_2, function() {
310+
alert("Sub Item 2 clicked");
311+
});
312+
```
313+
314+
5. **Add items to the submenu**
315+
Use `addMenuItem()` to add the registered commands to your submenu:
316+
317+
```jsx
318+
subMenu.addMenuItem(SUB_COMMAND_1);
319+
subMenu.addMenuDivider(); // Add a separator line
320+
subMenu.addMenuItem(SUB_COMMAND_2);
321+
```
322+
323+
> For visual separation between menu items, you can add a divider using `addMenuDivider()`.
324+
325+
→ For a detailed description, refer to [this link](https://docs.phcode.dev/api/API-Reference/command/Menus#addSubMenu).
326+
327+
Full Code Example:
328+
329+
```jsx
330+
define(function (require, exports, module) {
331+
"use strict";
332+
333+
// Brackets modules
334+
const AppInit = brackets.getModule("utils/AppInit"),
335+
CommandManager = brackets.getModule("command/CommandManager"),
336+
Menus = brackets.getModule("command/Menus");
337+
338+
// Function to run when the menu item is clicked
339+
function handleTestExtension() {
340+
alert("Test menu item");
341+
}
342+
343+
// Main command
344+
const MY_COMMAND_ID = "Test";
345+
CommandManager.register("Test", MY_COMMAND_ID, handleTestExtension);
346+
347+
// Add menu item
348+
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
349+
350+
// Add sub menu
351+
const subMenu = menu.addSubMenu(MY_COMMAND_ID, "Test_Sub_Menu");
352+
353+
// Additional submenu commands
354+
const SUB_COMMAND_1 = "Test_SubCommand1";
355+
const SUB_COMMAND_2 = "Test_SubCommand2";
356+
357+
// Register new commands
358+
CommandManager.register("Sub Item 1", SUB_COMMAND_1, function() {
359+
alert("Sub Item 1 clicked");
360+
});
361+
CommandManager.register("Sub Item 2", SUB_COMMAND_2, function() {
362+
alert("Sub Item 2 clicked");
363+
});
364+
365+
// Add items inside sub menu
366+
subMenu.addMenuItem(SUB_COMMAND_1);
367+
subMenu.addMenuDivider(); // Add separator
368+
subMenu.addMenuItem(SUB_COMMAND_2);
369+
370+
// Initialize extension once shell is finished initializing.
371+
AppInit.appReady(function () {
372+
console.log("hello world");
373+
});
374+
});
375+
376+
```
377+
378+
Expected Output:
379+
380+
![Sub Menu](./images/submenu.png)
381+
382+
When a submenu item is clicked, it will show an alert box with the corresponding message.
383+
384+
> Note: Make sure all command IDs are unique throughout your extension to avoid conflicts.
385+
386+
> You can add as many submenu items as needed by repeating steps 4 and 5 for each new item. You can even create nested submenu items.
387+
388+
> Submenu items can have their own keyboard shortcuts using the same method described in the "Attach a keyboard shortcut to a menu item" section.
9.65 KB
Loading
36 KB
Loading
5.72 KB
Loading
50.5 KB
Loading
21.9 KB
Loading
9.35 KB
Loading
22.9 KB
Loading

0 commit comments

Comments
 (0)