Files
create/mods/sdk/kindred_sdk/dock.py
forbes 99a08e4e99
All checks were successful
Build and Test / build (pull_request) Successful in 30m5s
feat(sdk): remove fallbacks, add deprecation warnings, bump v1.0.0 (#357)
- Bump SDK_VERSION to 1.0.0 in version.py and package.xml
- Remove <pure_python> tag from package.xml (kcsdk is C++)
- Remove all FreeCADGui.* fallback paths in context.py, dock.py,
  toolbar.py, menu.py; require kcsdk module
- Remove query fallbacks in origin.py (keep register/unregister
  which still need FreeCADGui.addOrigin/removeOrigin)
- Add deprecation warnings to 11 superseded FreeCADGui methods
  in ApplicationPy.cpp (not addOrigin/removeOrigin)
- All 39 Tier 1 tests pass
2026-03-01 14:32:08 -06:00

102 lines
2.9 KiB
Python

"""Dock panel registration helper.
Routes through the ``kcsdk`` C++ module (IPanelProvider / DockWindowManager).
The kcsdk module is required — legacy PySide fallback has been removed.
"""
import FreeCAD
try:
import kcsdk as _kcsdk
except ImportError:
_kcsdk = None
_DOCK_AREA_MAP = None # lazily populated from kcsdk
def _require_kcsdk():
if _kcsdk is None:
raise RuntimeError(
"kcsdk module not available. "
"The kindred_sdk requires the kcsdk C++ module (libKCSDK)."
)
def _get_dock_area(area_str):
"""Convert area string to kcsdk.DockArea enum value."""
global _DOCK_AREA_MAP
if _DOCK_AREA_MAP is None:
_DOCK_AREA_MAP = {
"left": _kcsdk.DockArea.Left,
"right": _kcsdk.DockArea.Right,
"top": _kcsdk.DockArea.Top,
"bottom": _kcsdk.DockArea.Bottom,
}
return _DOCK_AREA_MAP.get(area_str)
_AREA_NAMES = ("left", "right", "top", "bottom")
def register_dock_panel(object_name, title, widget_factory, area="right", delay_ms=0):
"""Register a dock panel, optionally deferred.
Parameters
----------
object_name : str
Qt object name for duplicate prevention.
title : str
Dock widget title bar text.
widget_factory : callable
Zero-argument callable returning a ``QWidget``. Called only
when the panel is actually created (after *delay_ms*).
area : str, optional
Dock area: ``"left"``, ``"right"``, ``"top"``, or ``"bottom"``.
Default ``"right"``.
delay_ms : int, optional
Milliseconds to wait before creating the panel. Default 0
(immediate, but still posted to the event loop).
"""
if not isinstance(object_name, str):
raise TypeError(f"object_name must be str, got {type(object_name).__name__}")
if not callable(widget_factory):
raise TypeError("widget_factory must be callable")
if area not in _AREA_NAMES:
raise ValueError(f"area must be one of {list(_AREA_NAMES)}, got {area!r}")
_require_kcsdk()
dock_area = _get_dock_area(area)
class _AnonymousProvider(_kcsdk.IPanelProvider):
def id(self):
return object_name
def title(self):
return title
def create_widget(self):
return widget_factory()
def preferred_area(self):
return dock_area
try:
_kcsdk.register_panel(_AnonymousProvider())
def _create():
try:
_kcsdk.create_panel(object_name)
except Exception as e:
FreeCAD.Console.PrintLog(
f"kindred_sdk: Panel '{object_name}' creation failed: {e}\n"
)
from PySide.QtCore import QTimer
QTimer.singleShot(max(0, delay_ms), _create)
except Exception as e:
FreeCAD.Console.PrintWarning(
f"kindred_sdk: Panel registration failed for '{object_name}': {e}\n"
)