Context Menu
About 1 min
Context Menu
WebCAD provides a flexible context menu system that supports custom menu items, adjusting menus based on command state, fully replacing the default menu, and more.
Event System
The context menu is customized through the event system, mainly using the ContextMenuOpening event.
import { CadEventManager, CadEvents } from 'webcad-lib-ts';
const events = CadEventManager.getInstance();
events.on(CadEvents.ContextMenuOpening, (args) => {
// Customize context menu
});Basic Usage
Add Custom Menu Items
Add custom items before or after the default menu items:
events.on(CadEvents.ContextMenuOpening, (args) => {
// Add before the default menu
args.prependItems.push({
label: "My Tools",
icon: "tool",
submenu: [
{
label: "Draw Circle",
callback: () => {
const c = new CircleEnt([50, 50], 15);
c.setDefaults();
Engine.addEntities(c);
}
},
{
label: "Draw Line",
callback: () => {
const l = new LineEnt([0, 0], [100, 100]);
l.setDefaults();
Engine.addEntities(l);
}
}
]
});
// Separator
args.prependItems.push({ isSeparator: true });
// Add after the default menu
args.appendItems.push({ isSeparator: true });
args.appendItems.push({
label: "Zoom Extents",
shortcut: "Z+E",
callback: () => Engine.zoomExtents()
});
});Disable System Context Menu
events.on(CadEvents.ContextMenuOpening, (args) => {
args.cancel = true; // Completely disable the menu
});Customize Menu Based on Command State
events.on(CadEvents.ContextMenuOpening, (args) => {
if (args.isCommandActive) {
// A command is currently running
console.log('Current command:', args.activeCommandName);
// Add options for specific commands
if (args.activeCommandName === 'LINE') {
args.appendItems.push({
label: "Close",
callback: () => { /* close logic */ }
});
}
} else {
// Idle state
args.prependItems.push({
label: "Quick Commands",
submenu: [
{ label: "Draw Line", command: "LINE" },
{ label: "Draw Circle", command: "CIRCLE" }
]
});
}
});Fully Custom Menu
Disable default menu items and show only custom items:
events.on(CadEvents.ContextMenuOpening, (args) => {
args.useDefaultItems = false; // Do not show default menu items
args.prependItems.push({ label: "Custom Item 1", callback: () => {} });
args.prependItems.push({ label: "Custom Item 2", callback: () => {} });
args.prependItems.push({ isSeparator: true });
args.prependItems.push({ label: "Zoom Extents", callback: () => Engine.zoomExtents() });
});Event Parameters
ContextMenuOpeningEventArgs
| Property | Type | Description |
|---|---|---|
document | CadDocument | Current document |
screenX | number | Screen coordinate X |
screenY | number | Screen coordinate Y |
canvasX | number | Canvas coordinate X |
canvasY | number | Canvas coordinate Y |
isCommandActive | boolean | Whether a command is currently running |
activeCommandName | string | undefined | Current command name |
menuItems | ContextMenuItemInfo[] | Default menu items (modifiable) |
prependItems | ContextMenuItemInfo[] | Prepended custom items |
appendItems | ContextMenuItemInfo[] | Appended custom items |
useDefaultItems | boolean | Whether to show default items |
cancel | boolean | Whether to cancel menu display |
Menu Item Configuration
ContextMenuItemInfo
| Property | Type | Description |
|---|---|---|
label | string? | Menu text (optional for separators) |
icon | string | Icon name |
shortcut | string | Shortcut text |
command | string | System command name |
callback | () => void | Click callback |
submenu | ContextMenuItemInfo[] | Submenu array |
disabled | boolean | Whether disabled |
checked | boolean | Whether checked |
isSeparator | boolean | Whether it is a separator (label can be omitted when true) |
Related Events
| Event | Description |
|---|---|
ContextMenuOpening | Before the context menu opens (cancelable and customizable) |
ContextMenuOpened | After the context menu opens |
ContextMenuItemClicked | Menu item clicked |
Example Files
For complete examples, see:
06contextmenu.js- add custom items06contextmenu_disable.js- disable the menu06contextmenu_command.js- customize by command state06contextmenu_custom.js- fully custom menu