Onion Skin View Widget Roadmap
OnionSkinViewWidget Development Roadmap
This document tracks remaining development tasks for the Onion Skin View Widget. For documentation of completed features and current architecture, see the main developer documentation.
Completed Work Summary
The following features are complete and documented in index.qmd:
- Widget skeleton: EditorState pattern, registration, state/view/properties factories
- State management:
OnionSkinViewStatewithHorizontalAxisState,VerticalAxisStatecomposition;OnionSkinViewStateDataserializable struct withrfl::json - Three data type support: Add/remove multiple
PointData,LineData, andMaskDatakeys via properties panel - Temporal window: Configurable
window_behind/window_ahead(frames before/after current time) - Alpha curve: Linear, Exponential, Gaussian curves with configurable min/max alpha
- Rendering pipeline:
SceneRendererfor points (glyphs), lines (polylines), and mask contours (polylines), all with per-element temporal alpha - Spatial mapping:
SpatialMapper::mapPointsInWindow(),mapLinesInWindow(),mapMaskContoursInWindow()for windowed data retrieval - Back-to-front rendering: Depth-sorted by temporal distance for correct alpha blending
- Current-frame highlight: Distinct colors for current-frame elements (orange-red vs blue/green/orange)
- Auto-fit bounds: Bounding box computation from all windowed point, line, and mask contour data
- Axis system:
HorizontalAxisWidget(X) andVerticalAxisWidget(Y) with bidirectional sync, including the “silent update” pattern - Interaction: Separated X/Y zoom, pan via shared
PlotInteractionHelpers - Entity selection: Click-to-select point at current frame (15px tolerance), double-click for navigation
- Properties panel: Data key tables + combo boxes for all 3 types, temporal window controls, alpha curve controls, rendering controls (point size, line width, highlight current), axis range controls in collapsible sections
- DataManager observer: Combo box population (point, line, mask), cleanup in destructor, and stale key purging when data keys are deleted from DataManager; tested in
OnionSkinViewPropertiesWidget.test.cpp - State serialization: Full round-trip JSON via
rfl::json - Registration wiring:
timeChanged→_onTimeChanged(),timePositionSelected→EditorRegistry::setCurrentTime() - Per-key line style: Each
LineDatakey has its ownCorePlotting::LineStyleData(color, thickness, alpha) stored inOnionSkinViewStateData::line_key_line_styles; managed at runtime viaLineStyleStateQObject wrappers; editable in a collapsible “Line Style Options” section in the properties panel viaLineStyleControls; `alpha` field sets the maximum alpha before temporal decay; serialized/deserialized as part of the JSON state - Per-key mask contour style: Each
MaskDatakey has its ownCorePlotting::LineStyleData(color, thickness, alpha) stored inOnionSkinViewStateData::mask_key_line_styles; managed at runtime viaLineStyleStateQObject wrappers; editable in a collapsible “Mask Style Options” section in the properties panel viaLineStyleControls;alphafield sets the maximum alpha before temporal decay; serialized/deserialized as part of the JSON state
Not yet implemented: SVG export.
Phase 4: SVG Export
Status: Not started. No export infrastructure exists in the current widget.
Goal: Allow the user to export the current onion skin view as an SVG file, preserving vector quality for publication.
4.1 Export Approach
SVG export requires converting the OpenGL scene to vector graphics. Two approaches:
Option A — Scene-to-SVG serialization (recommended): Walk the RenderableScene primitives (glyphs, polylines) and emit SVG <circle>, <polygon>, and <polyline> elements with the same colors and alpha values computed during rebuildScene(). This avoids OpenGL framebuffer capture and produces clean, resolution-independent output.
Option B — QPainter-based rendering: Use QSvgGenerator + QPainter to re-render the scene data using Qt’s 2D drawing API. This provides more mature vector rendering but requires duplicating the rendering logic outside OpenGL.
4.2 SVG Export Infrastructure
Because SVG export will be needed by multiple widgets (see cross-widget export below), the export logic should be implemented as a shared utility rather than per-widget code:
| Component | Location | Purpose |
|---|---|---|
SvgExporter |
CorePlotting/Export/ |
Scene-to-SVG conversion |
ExportButton |
Plots/Common/ |
Shared “Export SVG” button + file dialog |
SVG export is also a planned feature for:
| Widget | Export Complexity | Notes |
|---|---|---|
| LinePlotWidget | Medium | Trial-aligned lines + axes |
| TemporalProjectionViewWidget | Medium | Full spatial overlay |
| OnionSkinViewWidget | Medium | Windowed spatial + alpha fading |
4.3 Export Flow
User clicks "Export SVG" button in properties panel
↓
File dialog → choose output path
↓
SvgExporter reads current RenderableScene (or re-gathers data from state)
↓
For each glyph: emit SVG element with position, size, fill color + opacity
For each polyline: emit SVG <polyline> with stroke color + opacity + width
↓
Add axis labels, tick marks, bounds metadata
↓
Write SVG file
4.4 Properties Panel Controls
Add an “Export” section to the properties panel:
- Export SVG button — opens file dialog and triggers export
- Include axes checkbox — whether to render axis labels and ticks in the SVG
- Background color — whether to include the dark background or use transparent
Priority Order
| Priority | Phase | Status | Dependency |
|---|---|---|---|
| 1 | Phase 4 — SVG Export | Not started | Phases 2–3 (export should capture per-key styles) |