feat(sdk): add IMenuProvider interface and register_command wrapper (#355) #363

Merged
forbes merged 1 commits from feat/gears-addon into main 2026-03-01 19:39:13 +00:00
Owner

Summary

Implements issue #355 (Menu and Action System) with revised scope:

IMenuProvider — C++ interface for declarative menu placement

  • Pure abstract interface with id(), menu_path(), items(), context_ids()
  • SDKMenuManipulator (shared WorkbenchManipulator) injects menu items on workbench switch
  • Context-aware filtering: when context_ids() is non-empty, items only appear when the editing context matches
  • pybind11 trampoline (PyIMenuProvider) + GIL-safe holder (PyMenuHolder)

register_command() — Python wrapper

  • Thin wrapper around FreeCADGui.addCommand() standardizing the calling convention
  • No C++ interface needed — FreeCAD's command system is already stable

Python wrappers

  • kindred_sdk.register_menu() — kcsdk-first routing with FreeCADGui fallback
  • kindred_sdk.register_command() — builds anonymous command class from callables

Files

  • New: IMenuProvider.h, PyIMenuProvider.h, PyMenuHolder.h, command.py, menu.py
  • Modified: SDKRegistry.h/cpp, both CMakeLists.txt, kcsdk_py.cpp, __init__.py

Verification

  • Build: libKCSDK.so + kcsdk.so compile and link cleanly
  • Import test: IMenuProvider subclassing works, all 4 methods callable, default context_ids() returns []

Closes #355

## Summary Implements issue #355 (Menu and Action System) with revised scope: ### IMenuProvider — C++ interface for declarative menu placement - Pure abstract interface with `id()`, `menu_path()`, `items()`, `context_ids()` - `SDKMenuManipulator` (shared WorkbenchManipulator) injects menu items on workbench switch - Context-aware filtering: when `context_ids()` is non-empty, items only appear when the editing context matches - pybind11 trampoline (`PyIMenuProvider`) + GIL-safe holder (`PyMenuHolder`) ### register_command() — Python wrapper - Thin wrapper around `FreeCADGui.addCommand()` standardizing the calling convention - No C++ interface needed — FreeCAD's command system is already stable ### Python wrappers - `kindred_sdk.register_menu()` — kcsdk-first routing with FreeCADGui fallback - `kindred_sdk.register_command()` — builds anonymous command class from callables ### Files - **New:** `IMenuProvider.h`, `PyIMenuProvider.h`, `PyMenuHolder.h`, `command.py`, `menu.py` - **Modified:** `SDKRegistry.h/cpp`, both `CMakeLists.txt`, `kcsdk_py.cpp`, `__init__.py` ### Verification - Build: `libKCSDK.so` + `kcsdk.so` compile and link cleanly - Import test: IMenuProvider subclassing works, all 4 methods callable, default `context_ids()` returns `[]` Closes #355
forbes added 1 commit 2026-03-01 19:14:28 +00:00
feat(sdk): add IMenuProvider interface and register_command wrapper (#355)
All checks were successful
Build and Test / build (pull_request) Successful in 28m41s
2bf083609d
IMenuProvider: declarative menu placement with optional context awareness.
C++ interface with pybind11 bindings + GIL-safe holder. SDKMenuManipulator
(shared WorkbenchManipulator) injects menu items on workbench switch,
filtered by editing context when context_ids() is non-empty.

register_command(): thin Python wrapper around FreeCADGui.addCommand()
that standardizes the calling convention within the SDK contract.

Python wrappers (kindred_sdk.register_menu, kindred_sdk.register_command)
use kcsdk-first routing with FreeCADGui fallback.
forbes merged commit ec5b3850e9 into main 2026-03-01 19:39:13 +00:00
forbes deleted branch feat/gears-addon 2026-03-01 19:39:14 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#363