Previously launch_svg_viewer() (eco.utilities.svg_interactor) only ever
opened as a separate top-level Qt window or an inline notebook-cell
IFrame -- no way to tile it into eco desktop's own dock layout or a
JupyterLab Sidecar panel like every other eco Qt/notebook widget can.
Added dock_in (an EcoDesktopApp instance) to embed the viewer as a tiled
QDockWidget via the same _dock_widget_object mechanism the Namespace
launcher already uses for every other widget -- _build_qt_window now
optionally hands off a new _SvgViewerHandle (.window/.stop(), matching
the DisplayQt/AxisPTZStreamQt/CamServerStreamQt convention) instead of
self-showing as a standalone window. Added sidecar_anchor to open the
notebook-side Dash+IFrame viewer inside a JupyterLab Sidecar panel
instead of the current cell's output, reusing the same same-origin Dash
server (verified live: serves the real Bernina beamline SVG with its
click-extraction JS and namespace_prefix wired correctly). Both wired
through to Assembly.show(), so e.g. `namespace.show(sidecar_anchor=
"split-right")` or `namespace.show(in_window=True, dock_in=app)` works
for any Assembly with an SVG panel.
Found and documented (not fixed -- outside repo scope, needs an
environment change) a real gap while testing this: the deployed bpy312
env's qtpy picks PyQt5 as its default binding, which has no
QtWebEngineWidgets installed there, even though PySide6 (also installed)
does -- so in_window=True's native Qt viewer currently can't actually
open in that environment at all. Only one Qt binding can be active per
process, so this needs PyQtWebEngine added to bpy312 (or QT_API pinned
to pyside6), not an eco-side code fix. See
test_launch_svg_viewer_in_window_reports_missing_webengine_clearly.
Added tests/test_svg_interactor.py (previously zero coverage for this
module) covering _SvgViewerHandle, the dock_in wiring in both
launch_svg_viewer and _build_qt_window, and the sidecar_anchor path
(including its RuntimeError message when 'sidecar' isn't installed and
that omitting sidecar_anchor keeps today's plain inline behaviour for
Voila/classic Notebook compatibility).