feat(sdk): menu and action system #355
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Addons can register menu items and keyboard-shortcut actions.
New files
src/Gui/SDK/IMenuProvider.h— Abstract interface:id(),menu_path(),items(),on_triggered(item_id)src/Gui/SDK/IActionProvider.h— Abstract interface:id(),command_name(),shortcut(),on_triggered()Modified files
src/Gui/SDK/SDKRegistry.h/.cpp— Menu/action registrationsrc/Gui/SDK/bindings/kcsdk_py.cpp— Bind both interfaces with trampolinesDepends on #350. Part of the KCSDK epic (#346). Phase 6 of 8.
Scope revision
After reviewing the SDK's goals (stable API contract, GIL safety, lifecycle management) against FreeCAD's existing command and menu systems, we're re-scoping this issue:
Kept: IMenuProvider (full C++ interface)
Declarative menu placement with optional context awareness via context_ids(). Real value over raw WorkbenchManipulator: eliminates boilerplate, ties menus into the editing context system (same pattern as IToolbarProvider), and gives the SDK lifecycle oversight.
Changed: IActionProvider → kindred_sdk.register_command() (Python wrapper only)
FreeCAD's addCommand() is already stable, well-documented, and widely understood. Wrapping it in a C++ interface adds indirection without solving a real problem. Instead, a thin Python wrapper standardizes the calling convention within the SDK contract without a C++ abstraction layer.
Rationale
The C++ interface layer adds value when it provides GIL safety, type checking, or lifecycle management that Python alone can't easily achieve (e.g., IPanelProvider's QWidget bridging, IToolbarProvider's context auto-injection, IMenuProvider's WorkbenchManipulator management). Command registration has none of these concerns — it's a one-shot Python call with no ongoing lifecycle.