Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::view Namespace Reference

Hover-cursor tracking for platform window hosts. More...

Namespaces

namespace  detail
namespace  easing
namespace  painters
namespace  motion
namespace  atspi
namespace  uia
namespace  win_input
namespace  rmlui
namespace  script_events
namespace  web

Classes

class  ABCompare
class  AccessibilityValueInterface
 Interface for accessible values (sliders, knobs, progress bars). More...
class  AccessibilityTextInterface
 Interface for accessible text content (text editors, labels). More...
class  AccessibilityTableInterface
 Interface for accessible tables and lists. More...
class  AccessibilityCellInterface
 Interface for individual table cells. More...
struct  AccessibilityInterfaceSet
 The accessibility interfaces a View can actually serve. More...
struct  AccessibilityNodeSnapshot
struct  AnchorDisambiguation
 One derived anchor a collision pass replaced. More...
struct  StaticAnimationLimits
 Compile-time animation limits for optimization. More...
class  Tween
class  AnimationManager
class  ValueAnimation
 Lightweight, embeddable value animator for widget members. More...
struct  Keyframe
 A single keyframe: offset (0-1) and value. More...
class  KeyframeAnimation
 Multi-step keyframe animation with iteration, direction, fill mode. More...
class  AnimationStep
 A step in an animation sequence — either a tween or a parallel group. More...
class  TweenStep
 Single tween step. More...
class  ParallelStep
 Parallel group — all steps run simultaneously. More...
class  AnimatorSetBuilder
 Builder for composing animation sequences and parallel groups. More...
struct  Vector3D
struct  Quaternion
class  Draggable3DOrientation
 Draggable 3D orientation — arcball rotation from mouse drag. More...
struct  KeyShortcut
 A keyboard shortcut (key + modifiers). More...
struct  Command
 A named command with optional shortcut and callback. More...
class  KeyMapping
 Manages keyboard shortcuts with configurable bindings. More...
class  MenuBar
 Cross-platform menu bar descriptor. More...
class  NativeToolbar
 Native-toolbar descriptor — a lightweight config struct for host-level toolbars. More...
class  AppSettings
 Persistent application settings (window size, device selection, preferences). More...
struct  TextRun
 One piece of painted text, resolved to screen space. More...
struct  AppearanceCoverage
 N of M evaluated, K skipped and why. Printed on every run. More...
struct  AppearanceFinding
struct  AppearanceReport
struct  AppearanceOptions
class  AppearanceTracker
 Tracks OS-level appearance (light/dark mode) and auto-switches themes. More...
class  ThemeManager
 Manages the connection between AppearanceTracker and Theme switching. More...
struct  ImageData
 Raw pixel data (RGBA 8-bit per channel). More...
struct  FontData
 Font data loaded from TTF/OTF. More...
struct  ShaderData
 Shader source with optional compilation error. More...
struct  BlobData
 Raw binary data for any resource. More...
class  AssetManager
class  AutoUi
struct  BindingAttempt
 One recorded attempt, successful or not. More...
struct  BorderShades
 The two shades a 3D border style paints a side colour in, as Chromium resolves them. More...
struct  BorderBands
 How a side of width CSS px splits into bands for style: an outer band, a transparent gap, and an inner band, summing to width. More...
struct  CornerRadii
 A box's corner radii, each corner with a horizontal and a vertical radius. More...
struct  BandedBorder
 A banded border in its own border box, origin at the top-left corner. More...
class  Breadcrumb
class  BubbleMessageComponent
class  TextButton
class  HyperlinkButton
class  ArrowButton
class  ShapeButton
class  ImageButton
class  ResizableCorner
struct  CalloutStyle
 Tunables for the callout geometry. All lengths in the window coordinate space. More...
struct  CalloutPlacement
 Resolved placement in the window coordinate space. More...
class  AnchoredCallout
 A view-tree callout: hosts one content child, anchored to a target rect with a pointer triangle, auto-flipping + edge-clamping against a window rect. More...
struct  NativeCanvasPaintContext
 Per-paint metadata for native, retained CanvasWidget content. More...
class  NativeCanvasPainter
 Retained native painter installed on a CanvasWidget. More...
struct  CanvasDrawCmd
 A draw command recorded from JS for replay in paint(). More...
class  CanvasWidget
 A View whose paint() replays a list of recorded draw commands. More...
struct  CaretBlinkConfig
 Blink timing. The defaults are the values Pulp has always used. More...
 The "solid while moving, blinking while still" state machine. More...
struct  CaretMetrics
 Where a caret goes, in the coordinate space the widget paints text in. More...
class  ChannelStripView
struct  ChartShaderPresetOptions
struct  ChartShaderPreset
struct  CodeEditorConfig
 Configuration for the code editor. More...
class  CodeEditor
 Native code editor widget with gutter, language mode, and lightweight token coloring. More...
class  SystemTrayIcon
 System tray icon (macOS NSStatusItem, Windows Shell_NotifyIcon). More...
class  FileBasedDocument
 FileBasedDocument — document model with save/load/dirty tracking. More...
class  RecentlyOpenedFilesList
 RecentlyOpenedFilesList — persistent MRU list. More...
struct  Token
 One token span — half-open [start, start+length) into the line. More...
class  ColorPicker
struct  CommandInfo
 Metadata for one command. More...
class  CommandHandler
 Interface implemented by any object that can perform commands. More...
class  ShortcutMap
 (KeyCode, modifiers) → CommandID lookup table. More...
class  CommandRegistry
 Central command dispatcher. More...
class  ComponentDragger
class  ConcertinaPanel
class  ContextMenu
 Floating, view-tree-drawn context / popup menu. More...
struct  CssEasing
 CSS easing function — maps a normalized progress t ∈ [0,1] to an eased progress p ∈ [0,1]. More...
struct  TransitionSpec
 One transition spec — one CSS property with its own duration / delay / easing. More...
struct  CssAnimation
 One running animation. More...
struct  CssKeyframe
 One @keyframe stop. More...
struct  CssKeyframesBlock
 One @keyframes block: name + ordered stops. More...
struct  CssKeyframesRegistry
 Application-wide registry for @keyframes blocks. More...
class  CustomShaderHost
 Mixin for widgets whose body can be painted by a custom SkSL shader. More...
class  LevelDisplay
 Generic level, series and bin display seams owned by view-core. More...
class  SeriesDisplay
class  BinDisplay
struct  DataDisplayCatalogRow
struct  DataDisplayRegistration
struct  CodeGenOptions
 Options for code generation. More...
struct  CppExportOptions
struct  CppExportResult
struct  SwiftExportOptions
struct  SwiftExportResult
class  DesignExport
 Export a Theme's design tokens to various output formats. More...
struct  DesignMdProseHints
struct  FidelityIssue
 A single import-fidelity self-check finding. More...
struct  FidelityContext
 Everything a check needs: the node, its sanitized bridge id, the dimensions codegen emitted for it, and which branch produced them. More...
struct  FidelityKindInfo
 One entry in the named fidelity taxonomy: the stable kind slug the checks emit, its typical severity, and what it means. More...
struct  FidelityLedgerMeta
 Provenance recorded in the ledger header. More...
class  DesignFitView
 Uniformly scales one fixed-size subtree to fit this view's bounds — the SUB-VIEW analogue of WindowHost::set_design_viewport. More...
struct  DesignFrameElement
struct  DesignControlContext
class  DesignControl
struct  UnregisteredCustomControl
struct  ParamScaleMismatch
class  DesignFrameView
class  DesignTabGroup
class  DesignStepper
struct  ImportReportEntry
struct  ImportReport
struct  UnrenderableFrameSet
struct  DuplicateAnchor
struct  NativeMaterializeOptions
struct  NativeImportBindingOptions
struct  NativeImportBindingDescriptor
struct  NativeImportSegmentedBindingDescriptor
struct  NativeImportStepperBindingDescriptor
struct  NativeImportXYPadBindingDescriptor
struct  NativeImportMeterBindingDescriptor
 A level display's binding. More...
struct  NativeImportChoiceBindingDescriptor
struct  NativeImportWaveformBindingDescriptor
struct  NativeImportTextBindingDescriptor
struct  NativeImportHostActionDescriptor
class  NativeImportBindingContext
class  NativeImportComboBoxBindingContext
 Optional capability for binding a collapsed selector. More...
struct  IRBoxShadow
 A single CSS box-shadow layer. More...
struct  IRStyle
 Style properties for an IR node. More...
struct  IRLayout
 Layout properties for an IR container node. More...
struct  IRProvenance
 Adapter-side provenance: who lowered this node, from what source. More...
struct  IRTextLineBox
 One styled character range inside a text node. More...
struct  IRTextLayoutBasis
 What the cached line boxes above were laid out AGAINST. More...
struct  IRTextRun
struct  IRInteractiveElement
struct  IRNode
struct  ImportDiagnostic
struct  IRAssetRef
struct  IRAssetManifest
struct  IRFontAsset
 A bundled (non-system) font shipped with the design (figma-plugin #43a: envelope font_family_assets[]). More...
struct  IRTokenIdentity
struct  IRTokens
 Design token collection (W3C-compatible). More...
struct  DesignIR
 Complete design IR document. More...
struct  DesignIrJsonOptions
struct  DesignIrAssetOptions
struct  DesignIrParseError
 Thrown by parse_design_ir_json for input that is not well-formed JSON: truncated documents, unterminated strings or escapes, unbalanced or over-deep nesting, embedded NUL bytes, and anything the JSON parser itself refuses. More...
struct  LineMetrics
 A text run's primary-font ascent and descent in CSS px, as the browser rounded and adjusted them when it built the run's content area. More...
class  DesignParamBinding
struct  DetectedShortcut
struct  DefaultShortcutCandidate
 One default-binding emission produced by the source heuristic. More...
struct  DefaultShortcutCollision
 One unresolved candidate set — emitted when multiple components match the same pattern with comparable confidence. More...
struct  DefaultShortcutScan
 Result of running detect_default_shortcuts. More...
struct  SnapshotDynamicApiScan
struct  DesignMdDiagnostic
struct  DesignMdOmittedSection
struct  DesignMdParseResult
struct  DesignMdTokenDiff
struct  DesignMdDiffResult
struct  ClaudeBundleAsset
 One asset entry from a Claude Design bundle. More...
struct  ClaudeBundleFontBinding
 One captured @font-face rule joined to a content-addressed bundle asset. More...
struct  ClaudeBundleMaterializedBinding
 One id-addressed binding from a v2 materialized browser document. More...
struct  ClaudeBundle
 Result of unpacking a Claude Design bundle's <script type="__bundler/manifest">. More...
struct  MaterializedDocumentCacheStats
struct  ClaudeRuntimeOptions
 Options for the --execute-bundle import lane. More...
struct  DesignSlot
struct  DesignChildUpdate
struct  DesignKeyDiagnostic
struct  DesignUpdateBlock
struct  DesignUpdateWorkCounters
struct  DesignChildUpdatePlan
struct  DesignedControlSkin
 Colours and geometry for the value layer, taken from the design's own tokens so the ring belongs to the palette that asked for it. More...
struct  DropData
class  DropReceiver
class  DropTarget
struct  DragSource
struct  FileDragRequest
struct  DragSession
struct  ActiveDrag
class  EditorBridge
 Renderer-agnostic dispatcher for editor↔processor JSON messages. More...
class  FileBrowser
 File browser component with directory navigation, file list, and preview panel. More...
class  FileTree
 File tree component — tree-structured directory view. More...
class  ContentSharer
 Content opener for files and text. More...
class  MultiDocumentPanel
 Multi-document panel — tabbed container for multiple document views. More...
class  FileChooser
 Builder-style file chooser. More...
class  FileDropZone
class  FrameClock
class  FrameCostProbe
class  Badge
class  InlineBanner
class  Toast
class  EmptyState
class  Stepper
class  PanControl
class  Popover
class  InCanvasDialog
class  ChannelStrip
class  Spinner
class  NumberBox
struct  Point
struct  Size
struct  Rect
 Axis-aligned rectangle in continuous (float) coordinates. More...
struct  IntRect
 Axis-aligned rectangle in DISCRETE (integer) coordinates. More...
struct  Dimension
struct  FlexStyle
struct  GridTrack
 Grid track size: fixed px, fractional (fr), or auto. More...
struct  GridStyle
 Grid layout properties (CSS Grid Level 1 subset). More...
struct  GestureContext
class  GestureRecognizer
class  TapRecognizer
class  LongPressRecognizer
class  PanRecognizer
class  SwipeRecognizer
class  FlingRecognizer
class  PinchRecognizer
class  RotateRecognizer
class  GestureArbiter
struct  GpuAcquireDiagnostics
struct  LogFrequencyScale
 Maps frequency (Hz) to a horizontal pixel position on a logarithmic axis. More...
struct  DecibelScale
 Maps decibels to a vertical pixel position on a linear axis (dB is already logarithmic in amplitude, so the axis itself is linear in dB). More...
class  GroupBoxView
struct  HitMetrics
 Minimum hit-target sizing for one pointer type. More...
class  HostDragCoalescer
 Owns a PointerCoalescer plus the host-side policy around it: the frame-driver opt-in, the idle->pending dirty edge, and the counters. More...
class  HostFramePump
 Converts a host's monotonic presentation timestamps into per-frame deltas. More...
struct  HostFrameTick
 Result of begin_host_frame. More...
class  HostFrameTimeRecorder
 Keeps the first kMaxSamples frame durations. More...
class  HotReloader
class  HoverCursorTracker
 Remembers the pointer position and the style last handed to the platform. More...
struct  DecodedImage
struct  ImageCacheStats
class  ImageCache
class  InlineValueEditorView
struct  MouseEvent
 Rich mouse/pointer event with position, modifiers, button state, pointer ID, and stylus properties. More...
struct  GestureEvent
 High-level gesture event for pinch (scale) and rotate. More...
struct  KeyEvent
 Rich key event with key code, modifiers, and repeat state. More...
struct  TextInputEvent
 Text input from IME or keyboard composition (separate from KeyEvent). More...
class  ViewInspector
class  InspectorFacts
 Lets a widget describe itself to the component inspector (ViewInspector) and to view-core's layout and appearance diagnostics without either naming its class. More...
class  InspectorHighlight
 Highlight overlay added to the target root to visualize the selected view bounds. More...
class  InspectorWindow
 Floating inspector window that displays the view hierarchy and properties of a target view tree in a separate OS window. More...
struct  HostObjectProperty
struct  HostObjectMethod
struct  HostObjectDescriptor
struct  JsEngineCreationStats
class  JsEngine
struct  ScriptBytecodeCacheStats
 Process-wide reuse of compiled script bytecode (QuickJS backend). More...
struct  EngineRecommendation
struct  JsxLockTweak
 A single tweak to promote into authored JSX/TSX source. More...
struct  JsxLockResult
 Result of locking one tweak into an authored JSX/TSX source string. More...
class  KeyMappingEditor
class  KnobModulationView
struct  SelectionRect
 Rectangle in parent coordinates. More...
class  LassoComponent
 Lasso (rubber-band) selection overlay. More...
struct  LayoutTreeSnapshotOptions
struct  LayoutTreeTolerance
struct  LayoutTreeDiff
struct  LiveConstant
 A single live-editable constant. More...
class  LiveConstantRegistry
 Registry of live constants — thread-safe singleton. More...
class  LiveConstantEditor
 Debug overlay that shows sliders for all live constants. More...
struct  LockToSourceTweak
 A single tweak to promote into source. More...
struct  LockResult
 Result of locking one tweak into a generated source string. More...
struct  ReparentToSourceEdit
 A single structural reparent to promote into source: move the element anchored by child_anchor_id to become a child of the element anchored by new_parent_anchor_id. More...
class  LottieView
class  ModalOverlay
 A modal overlay that captures focus and dims the background. More...
class  ModelManagerView
struct  ModRoute
class  ModulationMatrix
class  ModulationMatrixWidget
class  MotionPreferences
 Process-wide reduced-motion preference tracker. More...
class  NativeViewHost
 A Yoga-laid-out widget that embeds a single platform-native child view (a system WebView, a native text field with IME + OS accessibility, a video / camera layer, an OS picker) inside Pulp's GPU-painted view tree. More...
class  NumberBoxStatesView
struct  OverlayPressTarget
struct  OverlayDismissalPolicy
 Tunable defaults for the dismissal policy. More...
struct  PassivePointerRoute
 Where a PASSIVE pointer input — a wheel / two-finger scroll, a trackpad magnify or rotate — at root_pt goes while overlays may be open. More...
struct  ContextPressResult
 What a context (right-button) press resolved to. More...
struct  ParamSubscription
 A live onParamChanged registration. More...
class  ParameterBinding
 RAII owner of a widget↔parameter binding's store listener. More...
class  PendingDamage
 Accumulated repaint damage for one frame, in root/window coordinates. More...
struct  FrameGeometry
 The size/scale/viewport a frame is painted against, in one value. More...
struct  PluginKeyOffer
 Platform-supplied facts about the key that core/view cannot derive from a KeyEvent alone. More...
class  PluginViewHost
struct  PointerSample
 One pointer sample as the host received it, before any coalescing. More...
class  PointerCoalescer
 Collapses runs of motion into one sample per presented frame while leaving button transitions untouched and in order. More...
struct  PointerAttributes
 Device identity of the pointer a delivery verb is dispatching, stamped onto every MouseEvent the verb builds (including the ancestor-bubble copies). More...
struct  WheelHost
 Host hooks the portable wheel router calls back into. More...
struct  MouseDownHost
 Optional host-owned continuation check for re-entrant press delivery. More...
struct  MouseUpHost
 Host hooks the portable mouse-up router calls back into. More...
class  PreferencesPanel
class  PresetBrowser
 Preset browser widget with list display, search filtering, category grouping, and prev/next navigation. More...
struct  PressReach
 What a press at a point resolves to, WITHOUT delivering it. More...
struct  UnreachablePressTarget
 One control that advertises a press target but cannot be reached by a press at the rect it paints. More...
struct  PressReachAudit
 What an audit examined, so a caller can tell a clean tree from a blind one. More...
struct  PressReachOptions
 Tuning for audit_press_reach. More...
class  PropertyList
class  PropertyPanel
class  PropertyPanelView
struct  QueryOptions
class  QueryService
class  RangeSliderView
struct  RecognitionEntry
 One recognition source: a flat map of a designer's component identity to the Pulp control it materializes. More...
struct  RecognitionSource
 A named bundle of recognition entries from one origin (built-in library, user manifest, or — later — an installed package). More...
struct  ResolvedControl
 The result of resolving one node's identity against the merged table. More...
class  RecognitionResolver
 The single merge layer. More...
struct  UnmatchedComponent
 Apply the resolver to a parsed figma-plugin IR tree IN PLACE: for every node that carries a Figma component identity (attributes figmaComponentKey / figmaMainComponentName, stamped by parse_ir_node) but is NOT already a recognized audio widget, resolve it against the merged table and stamp audio_widget (built-in kinds) on a match. More...
struct  PackageDesignControlSources
class  RelativeExpression
class  RelativePoint
class  CapabilitySet
 A granted-capability set. More...
class  ReorderList
 Single-axis drag-to-reorder container. More...
struct  DamageDecision
 The result of the damage decision. More...
struct  ResizableShellConfig
class  ResizableShell
struct  CaptureRequirements
struct  CaptureResult
struct  CompareResult
 Result of comparing two screenshots. More...
struct  DiffBounds
 Bounding box of changed pixels between two screenshots. More...
struct  ScreenshotContentStats
 Basic content statistics for a decoded PNG. More...
 Decoder-independent PNG structure and dimensions. More...
class  ScriptEngine
class  ScriptInspectorBridge
class  ScriptInspectorPort
 The engine-thread half of a runtime inspector, as ScriptedUiSession drives it. More...
class  ScriptedEditorSession
 The part of a scripted editor session that editor hosts drive: the frame pump, the content-first open, GPU-surface handoff, and teardown. More...
struct  ScriptedUiOptions
class  ScopedDeferredDocumentLoad
 View-first editor opening. More...
class  ScriptedUiSession
struct  ScriptedUiPrewarmRequest
struct  ScriptedUiPrewarmStats
class  ScrollBar
 Standalone, parameter-style scrollbar. More...
class  SdlWindowHost
struct  SelectableLine
 One painted line of selectable text, in the widget's LOCAL coordinates. More...
struct  SelectableLayout
 The painted line geometry of one widget. More...
class  SelectableText
 A widget whose painted text can join a document-level selection. More...
class  SidePanel
class  SliderCore
class  SplashScreen
class  SplitView
class  SpriteStrip
 A filmstrip image containing N frames of a control at different values. More...
struct  FragmentTransform
struct  SvgPathSegment
 Parsed path segment — flat, allocation-light, ready to replay onto a Canvas in a single pass during paint(). More...
class  SvgPathWidget
 Renders an inline SVG <path d="..."> icon. More...
struct  TableColumn
 Column definition for TableListBox. More...
class  TableModel
 Data model for TableListBox — implement this to provide row data. More...
class  SimpleTableModel
 Simple in-memory table model backed by a vector of string vectors. More...
class  TableListBox
 Scrollable table with sortable columns. More...
struct  TableCell
struct  TextAccessibilityNode
 A single accessible text node — the minimum a screen reader needs to describe a piece of painted text. More...
class  TextEditor
 Text editing widget with comprehensive keyboard/mouse interaction. More...
struct  Theme
struct  ContrastIssue
class  ThemeEditor
 Interactive theme editor widget — displays all color tokens as editable swatches. More...
struct  SemanticColors
 Semantic color tokens from tweakcn/shadcn-ui (the base 11 + 5 chart colors). More...
struct  ThemePreset
 A theme preset with light and dark variants. More...
struct  TokenTarget
 A tweak classified as targeting a design token. More...
struct  TokenLockResult
 Outcome of a lock_token_in_designmd call. More...
struct  ToolbarItem
 Single toolbar item. More...
class  Toolbar
 Toolbar container. More...
class  TooltipWindow
struct  TracingBadgePlacement
struct  TracingBadgeLayout
struct  TreeNode
 A node in the tree hierarchy. More...
class  TreeView
 Hierarchical tree view widget. More...
class  ComboBox
 Drop-down selector for enumerated parameters. More...
class  Tooltip
 Hover tooltip that displays text near a target view. More...
class  ThemeModeControl
 Compact 3-segment control to pick the theme mode: system / light / dark. More...
class  ProgressBar
 Visual progress indicator for long-running operations. More...
class  CallOutBox
 Floating alert/notification box. More...
class  TabPanel
 Tabbed container that shows one child at a time. More...
class  SegmentedControl
 Horizontal segmented selector — a row of mutually-exclusive labeled segments sharing one inset track, with the selected segment raised as an "elevated" pill (the Ink & Signal navigation treatment, Figma 227:1763). More...
class  ScrollView
 Scrollable container that clips and scrolls its content. More...
class  ListBox
 Scrollable list of selectable items. More...
class  FrameClockBinding
 Subscription lifecycle for a view that pulls a value once per frame. More...
class  MeterSourceBinding
 Binds a MeterSource channel and caches the latest frame for paint. More...
class  ScalarSourceBinding
 Binds a ScalarSource and caches the latest value for paint. More...
class  ViewCapture
 Identity-safe reference to a View captured across native event boundaries. More...
class  View
class  DispatchLease
 RAII gate held across any call into overridable View code. More...
class  ViewPool
 Per-class recycling pool for View objects. More...
class  VirtualGrid
 Recycling virtualized 2D grid for large, scrolling, rich cell views. More...
class  VirtualListDirtyTracker
class  VirtualList
 Recycling virtualized list for large, scrolling, rich row views. More...
struct  WaveformRegion
 A region (selection or marker) within the waveform. More...
class  WaveformEditor
 Interactive waveform editor for audio file editing and sample selection. More...
struct  WaveformSampleRange
 Sample range in source-frame coordinates. End is exclusive by convention. More...
struct  WaveformViewport
 Immutable-for-paint viewport state and sample/pixel conversion rules. More...
struct  WaveformRenderSpan
 One pixel/column span for waveform min/max reduction or GPU upload planning. More...
struct  WaveformRenderPlan
 Opt-in geometry plan. Callers decide when span allocation is acceptable. More...
struct  WaveformHandle
struct  WaveformHandleModel
 Editor handle state without rendering, input events, or audio ownership. More...
struct  WaveformHitResult
struct  WaveformSnapSettings
struct  WaveformSnapResult
struct  WaveformPlayheadOverlay
struct  WaveformEditorTransactionResult
class  WaveformEditorTransaction
 Semantic edit transaction state. Platform input translation stays in widgets/views. More...
struct  WaveformEditorSurfaceSnapshot
struct  WaveformEditorSurfaceEditResult
class  WaveformEditorSurface
 View-layer editing surface that composes waveform primitives without owning audio or painting. More...
struct  WebViewOptions
struct  WebViewMessage
struct  WebViewEmbeddedAsset
class  WebViewPanel
struct  WidgetReloadSnapshot
class  WidgetBridge
struct  FontSpec
 A font request, as a delegate expresses it. More...
struct  EdgeInsets
 Per-side insets in pixels. More...
struct  MenuItemMetricsQuery
 What a menu row is, when the delegate is asked how big it should be. More...
struct  BoxSize
 A control's natural size. More...
class  WidgetMetrics
 Install on a View to supply the SIZES of the controls in its subtree. More...
struct  ControlPaintState
 State every control hands to its painter. More...
struct  RotaryPaintState
 A rotary control. More...
struct  LinearPaintState
 A linear control (fader / slider / scroll thumb). More...
struct  ButtonPaintState
 A push / toggle button. More...
struct  ComboBoxPaintState
 A dropdown field (the closed control, not the open list). More...
struct  MenuBackgroundPaintState
 A menu panel's backing surface. bounds is the whole panel. More...
struct  MenuItemPaintState
 One menu row. bounds is the row rect within the menu panel. More...
struct  MenuHeaderPaintState
 A menu section title row. More...
struct  TextFieldPaintState
 A text field's frame. More...
struct  CaretPaintState
 The text-insertion caret. More...
class  WidgetPainter
 Install on a View to supply the pixels for the controls in its subtree. More...
struct  SkinImage
 Derives native-widget skin styling from a captured design asset (a flat PNG exported by a design tool such as the Figma plugin). More...
struct  FaderSkin
 Derived fader skin. More...
struct  MeterSkin
 Derived meter skin: gradient stops ordered low→high (bottom→top), plus an optional background color. More...
class  Label
class  Knob
class  Fader
class  RangeSlider
class  Toggle
class  Checkbox
class  ButtonSurface
class  ToggleButton
class  Icon
class  ImageView
class  XYPad
class  Panel
class  GroupBox
class  DualRangeSlider
class  InlineValueEditor
class  WaveformRecorder
class  SvgLineWidget
 Renders an inline SVG <line x1 y1 x2 y2 stroke stroke-width />. More...
class  SvgRectWidget
 Renders an inline SVG <rect x y width height fill stroke stroke-width />. More...
class  DocumentWindow
class  DialogWindow
class  AlertWindow
struct  WindowOptions
class  WindowHost
struct  ScreenInfo
struct  WindowState
struct  WindowRecord
struct  WindowMessage
class  WindowManager
class  AudioWaveformView
 Time-domain waveform plot over a copied, fixed-capacity sample buffer. More...
class  AudioInspectorPanel
 Audio Inspector content panel. More...
class  AudioInspectorWindow
 Floating Audio Inspector window. More...
class  Meter
class  WaveformView
class  SpectrumView
class  EqCurveView
class  MidiKeyboard
class  MusicalTypingController
class  MusicalTypingKeyboard
struct  SampleAssetDropPlan
class  SampleAssetDropTarget
 DropTarget adapter for sampler/import UIs. More...
class  StepGridViewBase
struct  DefaultCellPolicy
 Primary template is deliberately undefined-usable: a custom cell type must supply its own CellPolicy (visual + make_set_cell), else it is a compile error rather than a silent blank / uneditable grid. More...
struct  DefaultCellPolicy< state::StepCell >
class  StepGridViewT
class  SpectrogramView
class  MultiMeter
class  CorrelationMeter
struct  WaveformPeakVertex
struct  WaveformGpuUploadKey
struct  WaveformGpuLayerConfig
struct  WaveformGpuStaticLayerPlan
struct  WaveformGpuLayerPlan
struct  WaveformGpuResourceRecord
struct  WaveformGpuResourceCacheStats
struct  WaveformGpuResourcePutResult
class  WaveformGpuResourceCache
 Metadata-only LRU for backend-owned waveform resources. More...
struct  WaveformGpuRenderContext
struct  WaveformGpuRenderDecision
class  WaveformGpuRenderController
 Stateful policy helper for backend-owned waveform resources. More...
struct  WaveformHeadlessRenderConfig
struct  WaveformHeadlessRenderFrame
class  WaveformHeadlessRenderBackend
 Headless backend adapter over WaveformGpuRenderController. More...
class  WaveformOverviewView
 A View that renders a pre-decoded min/max peak overview as vertical columns. More...
class  WaveformRecorderView
struct  EventFrame
 A bounded list of occurrences from one audio block. More...
class  EventSource
 Lock-free event channel: the writer publishes the occurrences from one audio block and the view reads the latest completed block. More...
class  HostActionSurface
 A framework-agnostic host command channel. More...
class  HostParamSurface
 A framework-agnostic, native-view-facing runtime parameter accessor. More...
struct  MeterFrame
 A single multi-channel meter reading. More...
class  MeterSource
 Lock-free meter channel: the host publishes a MeterFrame from the audio/host thread; the view reads the latest frame paint-safe. More...
class  ScalarSource
 Lock-free scalar channel: a single paint-safe cached number (a readout value, a modulation ring's base→modulated position). More...
class  StateStoreHostParamSurface
 The native (Pulp Processor::create_view()) backing for HostParamSurface, implemented over a StateStore. More...
class  ValueChannelSet
 A processor's declared channels. More...
class  ValueChannelTelemetryAttachment
 Exclusive reader attachment for every telemetry sidecar in one channel set. More...
struct  VectorFrame
 A block of samples for a scope-style display — an envelope curve, a detector's output, a window of the signal a processor is actually working on. More...
class  VectorSource
 Lock-free vector channel: the writer publishes a block of samples, the view reads the latest block paint-safe. More...
struct  ValueChannelInfo
 What a channel is, for discovery and for a UI lint to check names against. More...
struct  ValueChannelTelemetryDescriptor
 Stable metadata for a channel held by a telemetry attachment. More...
struct  ValueChannelTelemetryEventBatch
 One producer event batch retained by the ordered telemetry tap. More...
struct  ValueChannelTelemetryEventStats
 Current producer-tap state. Overflow is cumulative for the source lifetime. More...
struct  ValueChannelTelemetrySnapshot
 A coherent continuous payload copied by the existing UI reader path. More...
class  PublishCounter
 Monotonic publish counter, shared by every value source. More...
struct  ValueEvent
 One occurrence inside an audio block. More...
class  AudioBridge
struct  MeterBallistics
struct  MeterData
struct  SpectrumData
 Published one-sided amplitude spectrum (lock-free via TripleBuffer). More...
struct  VisualizationBenchSink
 Where the bridge reports its benchmark timings. More...
class  VisualizationBridge
 Central visualization bridge: a fixed multichannel audio tap plus a caller-driven, non-RT analyzer and lock-free latest-value publication. More...
struct  VisualizationConfig
 Configuration for the visualization bridge. More...
struct  WaveformData
 Published waveform capture (latest buffer snapshot). More...

Typedefs

using AnnouncementSink
 Install a platform-specific announcement sink when a live-region backend is available.
using EasingFunction = float(*)(float)
using CommandID = uint32_t
 A unique command identifier.
using PopupMenu = ContextMenu
 Design-system alias.
using ContinuousFramePredicate = bool (*)(const View*)
using CssColorParser = std::function<canvas::Color(const std::string&)>
 Color parser callback: maps a single CSS color token (hex / rgb() / rgba()) to a canvas::Color.
using DataDisplayFactory = std::unique_ptr<View> (*)()
using DesignControlFactory
using LegacyImportBinder
using ClaudeClassNameRules = std::map<std::string, std::map<std::string, std::string>>
using FileDragBackend = std::function<bool(const FileDragRequest&)>
using AffineTransform = pulp::canvas::AffineTransform
 The 2D affine transform value type.
using HostClock = std::chrono::steady_clock
using ReloadCallback = std::function<void(const std::string& code)>
using ImageDecodeFn = std::function<std::optional<DecodedImage>(const std::string& uri)>
 Pluggable decode callback.
using ImageReleaseFn = std::function<void(DecodedImage&)>
 Release the platform handle when an entry is evicted.
using ModuleResolver = std::function<std::optional<std::string>(std::string_view path)>
using ModuleCompletionHandler = std::function<void(const std::string& error, const choc::value::Value& result)>
using LogCallback = std::function<void(std::string_view level, std::string_view message)>
using NativeFunction = std::function<choc::value::Value(const choc::value::Value* args, size_t num_args)>
using NativePromiseFunction = NativeFunction
using ModSourceId = uint32_t
using ModDestinationId = uint32_t
using NativeViewHandle = void*
using ScreenshotProvider
using ScriptInspectorPortFactory = std::unique_ptr<ScriptInspectorPort> (*)()
 Builds the port every ScriptedUiSession constructed afterwards installs.
using ScriptedUiPrewarmRunner = void (*)(ScriptedUiPrewarmRequest)
 prewarm_scripted_ui(), reachable without naming it.
using Sidebar = SidePanel
 Design-system alias.
using Table = TableListBox
 Design-system alias.
using Color = canvas::Color
using HSL = canvas::Color::HSL
using WindowId = uint32_t
using MessageHandler = std::function<void(const WindowMessage&)>
using StepGridView = StepGridViewT<state::ReferenceSequencerConfig>
using ValueChannelAccess
using ValueChannelVisitor
 Runs a value-channel operation while the hosting processor guarantees that the exposed set and all of its sources remain alive.
using ValueChannelContinuousPayload

Enumerations

enum class  AccessToggleState { unset , off , on , mixed }
 Tri-state check/press state, resolved from the ARIA slots a View carries (aria-checked first, then aria-pressed — a checkbox/switch state is more load-bearing than a toggle-button pressed state). More...
enum class  AnnouncementPriority { Polite , Assertive }
 Politeness level for a live-region announcement. More...
enum class  AnchorStrategy { content_hash , path , adapter }
 Strategy for computing stable_anchor_id values. See header comment. More...
enum class  AppearanceDefectKind { text_overlap , painted_wider_than_box , canvas_text_overlap , container_paints_no_text }
 Visual-appearance defect detection over a laid-out View tree. More...
enum class  TextRunSkip {
  none , invisible , empty_text , clipped_away ,
  unmeasurable , degenerate_box
}
 Why a piece of text was not evaluated. More...
enum class  Appearance { light , dark }
 System appearance mode. More...
enum class  ThemeMode { system , light , dark }
 User-facing theme preference. More...
enum class  BindingTarget : std::uint8_t { value , meter , scope , uniform }
 What a binding drives on its widget. More...
enum class  BindingOutcome : std::uint8_t {
  ok , deferred_widget_missing , replaced_prior_binding , empty_widget_id ,
  empty_param_name , null_widget , incompatible_widget , unknown_param ,
  unknown_value_channel , undeclared_uniform
}
 The outcome of one bindWidgetToParam / bindMeter call. More...
enum class  BorderEdge { top , right , bottom , left }
 Which edge of the box a border side is on. More...
enum class  ArrowDirection { up , down , left , right }
enum class  CalloutSide { above , below , left_of , right_of }
 Which side of the anchor the callout BODY sits on. More...
enum class  NativeCanvasBackendRequirement { any , skia_dawn_allow_recording , skia_dawn }
enum class  CaretStyle { ibeam , underline , block }
 Caret shape. All three anchor at the same caret x. More...
enum class  ChartProfile { round , flat , chamfer }
 Cross-section of a tube or light pipe across its band. More...
enum class  CodeLanguage {
  PlainText , Cpp , JavaScript , Lua ,
  Python , JSON , XML , GLSL ,
  Faust , JSFX
}
 Language mode for syntax highlighting. More...
enum class  TokenClass {
  text , keyword , type , identifier ,
  number , string , comment , preprocessor ,
  punctuation , heading , link
}
 Token classification for tokenize_line. More...
enum class  AnimatableProperty {
  opacity , background_color , color , border_color ,
  translate_x , translate_y , rotate_deg , scale ,
  width , height , margin_top , margin_right ,
  margin_bottom , margin_left , padding_top , padding_right ,
  padding_bottom , padding_left , top , right ,
  bottom , left , none
}
 Property whose values can be tweened. More...
enum class  WidgetRenderStyle { standard , minimal , silver }
 Rendering style for widgets. More...
enum class  CodeGenMode { web_compat , bridge_native_js , native = bridge_native_js }
 Code generation output mode. More...
enum class  FidelityElement { image , container , widget , text }
 What codegen branch produced the emitted geometry — lets a check apply only where it is meaningful without re-deriving the element kind. More...
enum class  DesignSource {
  figma , stitch , v0 , pencil ,
  claude , designmd , jsx , figma_plugin ,
  html , preconverted_svg
}
enum class  LayoutDirection { row , column }
 Layout direction for flex containers. More...
enum class  LayoutAlign {
  flex_start , flex_end , center , stretch ,
  space_between , space_around
}
 Alignment values for flex containers. More...
enum class  SizingMode { fixed , hug , fill }
 Sizing mode for an IR node dimension. More...
enum class  AudioWidgetType {
  none , knob , fader , meter ,
  xy_pad , waveform , spectrum , toggle ,
  selector , stepper
}
 Audio widget type detected from naming conventions or annotations. More...
enum class  WidgetPromotionSignal { none , onclick_attribute , aria_role_button , cursor_pointer }
 Heuristic signals that a parsed frame is interactive enough to promote from a static frame to a button widget. More...
enum class  IRConfidence { pass , diverge , not_impl }
 Confidence the adapter has that a node was lowered correctly. More...
enum class  NodeRenderMode { normal , faithful_svg , faithful_capture }
 A single node in the normalized design IR. More...
enum class  InteractiveElementKind {
  knob , fader , toggle , dropdown ,
  text_field , tab_group , stepper , swap ,
  action , xy_pad , value_label , custom
}
enum class  ImportDiagnosticSeverity { info , warning , error }
enum class  ImportDiagnosticKind {
  unknown , unsupported_property , unsupported_node , unresolved_asset ,
  snapshot_semantics_warning , legacy_field_shortcut , capture_partial , fallback_used
}
enum class  DefaultShortcutPattern {
  settings , help , cheatsheet , new_file ,
  open_file , save_file , find
}
 Which platform-convention surface a default binding maps to. More...
enum class  TargetPlatform { macos , win_linux }
 Convert accepted candidates from detect_default_shortcuts into the DetectedShortcut form that V2 codegen expects. More...
enum class  DesignMdSeverity { info , warning , error }
enum class  DesignUpdateKind { retained , moved , inserted , removed }
enum class  DesignSlotKind {
  static_visual , dynamic_scalar , dynamic_vector , dynamic_meter ,
  dynamic_text , dynamic_action
}
enum class  DesignKeyDiagnosticReason { missing , duplicate , mixed }
enum class  Tone {
  neutral , info , success , warning ,
  danger
}
enum class  LayoutMode { flex , grid }
enum class  FlexDirection { row , column , row_reverse , column_reverse }
enum class  FlexWrap { no_wrap , wrap , wrap_reverse }
 Flex-wrap tri-state. More...
enum class  BoxSizing { content_box , border_box }
 CSS box-sizing. More...
enum class  FlexAlign {
  start , center , end , stretch ,
  auto_ , baseline
}
enum class  FlexJustify {
  start , center , end_ , space_between ,
  space_around , space_evenly
}
 Justify content modes (main axis space distribution). More...
enum class  FlexOverflow { visible , hidden , scroll , auto_ }
 Overflow behavior. More...
enum class  DimensionUnit {
  px , percent , vw , vh ,
  vmin , vmax , auto_
}
enum class  GestureState {
  possible , began , changed , ended ,
  cancelled , failed
}
enum  Modifier : uint16_t {
  kModNone = 0 , kModShift = 1 << 0 , kModCtrl = 1 << 1 , kModAlt = 1 << 2 ,
  kModMeta = 1 << 3 , kModCmd = 1 << 4
}
enum class  KeyCode : int {
  unknown = 0 , a = 'a' , b = 'b' , c = 'c' ,
  d = 'd' , e = 'e' , f = 'f' , g = 'g' ,
  h = 'h' , i = 'i' , j = 'j' , k = 'k' ,
  l = 'l' , m = 'm' , n = 'n' , o = 'o' ,
  p = 'p' , q = 'q' , r = 'r' , s = 's' ,
  t = 't' , u = 'u' , v = 'v' , w = 'w' ,
  x = 'x' , y = 'y' , z = 'z' , num0 = '0' ,
  num1 = '1' , num2 = '2' , num3 = '3' , num4 = '4' ,
  num5 = '5' , num6 = '6' , num7 = '7' , num8 = '8' ,
  num9 = '9' , semicolon = ';' , apostrophe = '\'' , left = 256 ,
  right , up , down , home ,
  end_ , page_up , page_down , backspace = 270 ,
  delete_ , tab , enter , escape ,
  space = ' ' , f1 = 290 , f2 , f3 ,
  f4 , f5 , f6 , f7 ,
  f8 , f9 , f10 , f11 ,
  f12
}
enum class  MouseButton : uint8_t { none = 0 , left = 1 , right = 2 , middle = 3 }
 Mouse button identifiers. More...
enum class  PointerType : uint8_t { mouse = 0 , touch = 1 , pen = 2 }
 Pointer device type (W3C PointerEvent.pointerType). More...
enum class  MousePhase : uint8_t {
  automatic = 0 , press , drag , release ,
  hover
}
 Explicit press/drag/release phase for a pointer gesture. More...
enum class  GesturePhase : uint8_t { began = 0 , changed = 1 , ended = 2 , cancelled = 3 }
enum class  JsEngineType { quickjs , jsc , v8 }
enum class  JsxLockStatus {
  patched , already_current , anchor_not_found , anchor_ambiguous ,
  unsupported_property , too_dynamic
}
 Outcome status for a single JSX/TSX lock attempt. More...
enum class  LockStatus {
  rewritten , inserted , already_current , anchor_not_found ,
  unsupported_property
}
 Outcome status for a single lock attempt. More...
enum class  ModCurve : uint8_t {
  Linear = 0 , Exponential = 1 , Logarithmic = 2 , Quadratic = 3 ,
  SCurve = 4
}
enum class  MotionPolicy { Full , Reduced , Off }
 Reduced-motion policy. More...
enum class  OverlayPressRouting { no_overlay , routed , not_hittable , dismissed }
 What consulting the generalized overlay slot decided about a press. More...
enum class  OverlayEscapeResult { none , modal , combo_popup , overlay }
 What an Escape keypress dismissed, in the order the policy tries them. More...
enum class  PluginKeyDisposition : std::uint8_t { forward_to_host , consumed , insert_as_text }
 What an embedded plugin editor should do with a key it has been offered. More...
enum class  PressChannel { click , context_menu }
 Which handler channel a press looks for, and therefore which resolution rule applies. More...
enum class  ReloadCapability : std::uint8_t {
  Exec , Clipboard , Filesystem , Storage ,
  Ai , RuntimeImport , Network
}
 A capability gates one effectful bridge-API group. More...
enum class  ScreenshotBackend {
  default_backend , coregraphics , skia , gpu ,
  auto_select
}
enum class  Notify { none , sync , async }
 Whether a value write notifies listeners, and when. More...
enum class  TableSortOrder : uint8_t { None = 0 , Ascending = 1 , Descending = 2 }
enum class  TextAccessibilityRole : std::uint8_t {
  Label , Button , TextEditor , Heading ,
  Other
}
 Coarse semantic role for a piece of accessible text. More...
enum class  ContrastLevel { aa_normal , aa_large , aaa_normal , aaa_large }
 WCAG AA compliance levels. More...
enum class  TokenGroup { colors , spacing , rounded , typography }
 The four canonical DESIGN.md frontmatter token groups this engine can lock into. More...
enum class  ToolbarItemType {
  Button , Toggle , Separator , Spacer ,
  Custom
}
 Toolbar item types. More...
enum class  RuntimeViewKind : std::uint8_t {
  generic , knob , fader , toggle ,
  scroll , eq_curve , design_frame
}
 Internal concrete-type hint for the two whole-tree hot paths. More...
enum class  WaveformHandleKind {
  none , selection_start , selection_end , trim_start ,
  trim_end , fade_in , fade_out , loop_start ,
  loop_end , slice_marker , playhead
}
enum class  WaveformSnapSource { none , bounds , candidate , grid }
enum class  WaveformEditorOperationKind {
  none , create_selection , extend_selection , drag_selection_start ,
  drag_selection_end , move_playhead
}
enum class  LabelAlign {
  left , center , right , auto_ ,
  justify , match_parent
}
 Text alignment for Label. More...
enum class  UaSkin { platform , chromium_refresh }
 Which skin a form-control widget paints with. More...
enum class  UaColorScheme { light , dark }
 The CSS color-scheme a chromium_refresh palette resolves against. More...
enum class  UaControlState { normal , hovered , pressed , disabled }
 Interaction state a chromium_refresh palette is keyed on. More...
enum class  DialogResult { ok , cancel , closed }
enum class  AlertIcon {
  none , info , warning , error ,
  question
}
enum class  WindowType {
  main , palette , inspector , popup ,
  dialog
}
enum class  AudioInspectorMode { kSignal , kScope }
enum class  WaveformGpuRenderActionKind : std::uint8_t {
  NoOpInvalidPlan , NoOpBackendUnavailable , NoOpCpuFallbackUnavailable , NoOpStagingTooSmall ,
  NoOpVertexFillFailed , CpuFallbackReady , UploadStaticLayerReady , DrawCachedStaticLayer ,
  PlayheadOnlyRedraw
}
enum class  WaveformHeadlessRenderStatus : std::uint8_t {
  NoOp , CpuFallbackReady , UploadedStaticLayer , DrawCachedStaticLayer ,
  PlayheadOnlyRedraw , MissingCachedResource , ResourceAllocationFailed , ResourceCommitRejected
}
enum class  ValueChannelShape
 The shape of a channel's payload. More...
enum class  VisualizationBacklogPolicy
 How poll() treats captured audio it has not analyzed yet. More...

Functions

AccessToggleState accessibility_toggle_state (const View &v)
 The View's check/press state.
std::string accessibility_toggle_state_string (const View &v)
 The state as the word a reader announces: "checked" / "unchecked" / "mixed" (aria-checked) or "pressed" / "not pressed" / "mixed" (aria-pressed).
std::string accessibility_value_string (const View &v)
 What assistive tech reads as the element's VALUE, resolved from the one source that is actually present, in priority order:
bool has_accessibility_value (const View &v)
 True when the view has ANY value source at all (slots 1–4 above).
AccessibilityInterfaceSet accessibility_interfaces (const View &v)
std::string accessibility_text_content (const View &v)
 The string content a text interface exposes: AccessibilityTextInterface's content, else the access_value slot, else "".
bool accessibility_text_editable (const View &v)
 True when the text content is user-editable (an editable AccessibilityTextInterface).
bool is_accessibility_element (const View &v)
 The single gate EVERY accessibility bridge uses to decide whether a View enters the platform accessibility tree (macOS window host + plug-in editor host, iOS, Windows UIA fragments, Linux AT-SPI objects, Android TalkBack nodes) and the cross-platform snapshot's count_announceable().
void announce_accessibility (std::string_view text, AnnouncementPriority priority=AnnouncementPriority::Polite)
 Request the installed accessibility announcement sink speak text.
void set_announcement_sink (AnnouncementSink sink)
void * init_accessibility (View &root, void *native_window)
 Initialize the OS accessibility bridge for this root view.
void shutdown_accessibility (void *handle)
 Release any OS-side resources acquired in init_accessibility.
void accessibility_tree_changed (void *handle)
 Request the provider to re-walk the View tree.
void accessibility_tree_will_change (void *handle)
 Make every cached native node inert before a caller starts destructively editing the View tree.
bool accessibility_tree_retirement_ready (void *handle)
void accessibility_retain_until_retired (void *handle, std::shared_ptr< void > owner) noexcept
void accessibility_tree_changed (View &root)
 Rebuild every native provider currently attached to root.
void accessibility_tree_will_change (View &root)
bool accessibility_tree_retirement_ready (View &root)
void accessibility_retain_until_retired (View &root, std::shared_ptr< void > owner) noexcept
void accessibility_pump (void *handle)
 Service any pending accessibility IPC for this handle.
void notify_accessibility_value_changed (void *handle, View &target)
 Notify the provider that a View's access_value has changed.
void notify_accessibility_focus_changed (void *handle, View &target)
 Notify the provider that focus moved to a different View.
void notify_accessibility_name_changed (void *handle, View &target)
 Notify the provider that a View's accessible name or role changed (e.g.
std::vector< AccessibilityNodeSnapshot > snapshot_accessibility_tree (const View &root)
 Depth-first snapshot of root and every descendant.
std::size_t count_announceable (const View &root)
 Count nodes the platform bridges actually expose (snapshot node exposed — role != none AND named when the role requires a name).
const View * find_by_role_and_label (const View &root, View::AccessRole role, std::string_view label)
 Find the first descendant whose access_label exactly matches label and whose role equals role.
void assign_anchors (IRNode &root, AnchorStrategy strategy, std::string_view adapter_name="")
 Walk root and populate stable_anchor_id on every node according to strategy.
std::vector< AnchorDisambiguation > resolve_anchor_collisions (IRNode &root)
 Makes every derived anchor in root unique, in document order over children.
std::string compute_anchor_id (const IRNode &node, std::string_view parent_anchor, std::size_t sibling_tag_index_for_path, std::size_t depth, std::size_t sig_index_for_content_hash, AnchorStrategy strategy, std::string_view adapter_name="")
 Compute a single anchor without walking.
AnchorStrategy default_anchor_strategy (DesignSource source)
 Map a DesignSource to its default anchor strategy.
EasingFunction easing_by_name (const std::string &name)
 Resolve an easing function by name string. Returns linear for unknown names.
const char * to_string (AppearanceDefectKind kind)
AppearanceReport detect_appearance_defects (const View &root, const AppearanceOptions &options={})
 Walk root (already laid out) and report painted-text defects.
View::AccessRole access_role_from_aria (std::string_view role)
 Map an ARIA role token to a Pulp AccessRole.
constexpr bool is_bound (BindingOutcome o) noexcept
 True for the three outcomes that produced a live binding.
const char * describe (BindingOutcome o) noexcept
 Human-readable reason, for diagnostics and test failure messages.
std::optional< View::BorderStyle > border_style_from_css (std::string_view keyword)
 The View::BorderStyle a CSS border-style / outline-style keyword names, or nullopt for anything that is not one of the ten CSS keywords.
BorderShades border_shades (Color side_color)
BorderBands border_bands (View::BorderStyle style, BorderEdge side, float width)
Color border_band_color (View::BorderStyle style, BorderEdge side, bool outer_band, Color side_color, float width)
 The colour style paints the outer or inner band of side in, for a side whose specified colour is side_color and width width.
bool is_banded_border_style (View::BorderStyle style)
 Whether style is painted in bands of per-side colour (double and the four 3D styles) rather than as one stroke.
CornerRadii fit_corner_radii (float width, float height, CornerRadii radii)
 radii fitted to a width x height box the way CSS fits border radii (CSS Backgrounds 3, "Overlapping Curves"): a negative radius is 0, and when the two radii along any side sum to more than that side, every radius is scaled by f = min over the four sides of (side length / sum of its two radii), so adjacent curves meet instead of crossing.
void paint_banded_border (canvas::Canvas &canvas, const BandedBorder &border)
 Paint border.
CalloutSide opposite_side (CalloutSide s)
 Opposite side, used by the auto-flip.
CalloutPlacement place_callout (const Rect &anchor, float body_w, float body_h, const Rect &window, CalloutSide preferred, const CalloutStyle &style={})
 Place a body_w×body_h callout tethered to anchor, kept inside window.
void warn_capability_fallback_once (canvas::CanvasCapability cap, const char *msg)
 Warn at most once per process, per capability, when a paint path degrades because the active canvas backend does not support the capability it needs.
const char * caret_style_to_string (CaretStyle style) noexcept
 Stable lowercase names, for serialization and the JS bridge.
CaretStyle caret_style_from_string (std::string_view name) noexcept
 Parse a name produced by caret_style_to_string.
CaretStyle default_caret_style () noexcept
 Process-wide caret defaults.
void set_default_caret_style (CaretStyle style) noexcept
const CaretBlinkConfig & default_caret_blink () noexcept
void set_default_caret_blink (const CaretBlinkConfig &config) noexcept
float caret_advance (const CaretMetrics &metrics) noexcept
 The width the underline and block shapes cover: advance when there is a glyph at the caret, else nominal_advance.
Rect caret_rect_for_style (CaretStyle style, const CaretMetrics &metrics) noexcept
 The rect a caret of style occupies.
void paint_caret (canvas::Canvas &canvas, CaretStyle style, const CaretMetrics &metrics, canvas::Color color)
 Fill the caret rect.
void paint_caret_over_text (canvas::Canvas &canvas, CaretStyle style, const CaretMetrics &metrics, canvas::Color color, canvas::Color text_bg, const std::string &text, float text_x)
 Paint the caret, and for block redraw the covered glyph in text_bg so it stays legible against the fill.
const std::vector< std::string > & chart_shader_preset_names ()
 The preset names: bevel, inset-channel, tube, light-pipe, centre-highlight and glow.
ChartShaderPreset make_chart_shader_preset (std::string_view name, const ChartShaderPresetOptions &options={})
 Build the named preset's chart shader with options baked in as constants.
float chart_glow_reach (float sigma, float intensity)
 Distance past which a glow of sigma and intensity is below one 8-bit step (intensity * exp(-r^2 / (2 sigma^2)) < 1/255), and never less than three sigma.
bool parse_chart_profile (std::string_view name, ChartProfile &out)
 Parse a profile name (round, flat, chamfer).
std::vector< Token > tokenize_line (std::string_view line, CodeLanguage language)
 Tokenize a single line of source text for language.
std::vector< Token > tokenize_cpp_line (std::string_view line)
std::vector< Token > tokenize_javascript_line (std::string_view line)
std::vector< Token > tokenize_python_line (std::string_view line)
std::vector< Token > tokenize_json_line (std::string_view line)
std::vector< Token > tokenize_lua_line (std::string_view line)
std::vector< Token > tokenize_markdown_line (std::string_view line)
bool is_keyword (std::string_view name, CodeLanguage language)
 True when name is one of the keywords the tokenizer recognizes for language.
CommandInfo make_open_settings_command_info ()
 CommandInfo for kCommandOpenSettings with the platform-standard chord as its default binding.
void route_global_keys (View &root, CommandRegistry &registry)
 Install registry as the root view's single global-key dispatcher: assigns root.on_global_key to forward every key event into registry.dispatch_key_event().
void register_continuous_frame_predicate (RuntimeViewKind kind, ContinuousFramePredicate predicate)
 Install the allocation-free predicate for a framework-owned runtime kind.
bool needs_continuous_frames (const View *view)
 True if view (or any descendant) needs continuous per-frame repaints.
AnimatableProperty animatable_property_from_css_name (const std::string &name)
 Map CSS property name to AnimatableProperty enum.
float parse_css_time_seconds (const std::string &s)
 Parse a CSS time string (200ms / 0.3s / bare seconds) into seconds.
bool parse_css_float_token (const std::string &token, float &out)
std::vector< TransitionSpec > parse_transition_shorthand (const std::string &css)
 Parse a CSS transition shorthand into a list of TransitionSpecs.
std::vector< TransitionSpec > parse_transition_shorthand_with_provenance (const std::string &css, std::string source_file, int source_line)
 Parse a transition shorthand AND stamp each emitted TransitionSpec with the source attribution (CSS file path + line number, or React/JS component file:line when the CSS came from an inline style="...").
std::optional< float > css_blur_radius (const std::string &filter)
 The blur radius out of a CSS filter list, in px.
std::vector< canvas::Canvas::FilterChainEntry > css_filter_chain (const std::string &filter)
 A whole CSS filter list as the canvas layer verbs consume it, in source order — saturate(0.15), grayscale(1) brightness(1.6), blur(6px).
std::optional< canvas::Canvas::BlendMode > css_blend_mode (const std::string &keyword)
 A CSS mix-blend-mode keyword.
std::optional< float > css_transform_rotation (const std::string &transform)
 The angle out of a rotate(<deg>deg) in a CSS transform, in degrees.
bool css_keyword_is_none (std::string_view value)
 True for an empty value or the CSS keyword none, which keywords match case-insensitively and with surrounding whitespace.
canvas::Color parse_css_color (const std::string &token)
 The built-in CSS color parser: #RGB / #RRGGBB / #RRGGBBAA, rgb(), rgba(), hsl(), hsla(), oklab(), oklch(), and transparent.
bool css_color_syntax_supported (std::string_view token)
 True when token uses one of the CSS color syntaxes understood by parse_css_color().
bool apply_css_background_gradient (View &v, std::string_view css, const CssColorParser &parse_color={})
 Parse a CSS linear-gradient(...), radial-gradient(...), or conic-gradient(...) string and apply it to v's background via the View::set_background_gradient_* API.
void register_data_display (DataDisplayRegistration registration)
bool has_data_display (std::string_view id)
std::unique_ptr< View > make_data_display (std::string_view id)
void clear_data_displays ()
std::size_t data_display_registration_count ()
std::optional< IRNode > lower_faithful_capture_to_image (const IRNode &node)
 Canonical lowering from an authoritative browser-capture node to the ordinary image-node contract shared by JS, baked C++, and native materialization.
void lower_faithful_captures_in_place (IRNode &node)
std::string generate_pulp_js (const DesignIR &ir, const CodeGenOptions &opts={})
 Generate Pulp JS code from a DesignIR.
CppExportResult generate_pulp_cpp (const DesignIR &ir, const IRAssetManifest &manifest, const CppExportOptions &opts={})
 Generate an ownable baked-C++ view artifact from a DesignIR.
SwiftExportResult generate_pulp_swift (const DesignIR &ir, const IRAssetManifest &manifest, const SwiftExportOptions &opts={})
 Generate a baked SwiftUI artifact from a DesignIR.
int key_string_to_keycode (const std::string &key)
 Map a W3C KeyboardEvent.key (or KeyboardEvent.code) string to a Pulp KeyCode integer.
int modifier_strings_to_mask (const std::vector< std::string > &mods)
 Combine modifier strings ("shift", "ctrl", "alt", "meta") into the bitmask registerShortcut consumes.
std::string export_designmd (const Theme &theme, const DesignMdProseHints &hints={})
 Export DESIGN.md text or throw while the DESIGN.md merge path is gated.
bool is_vector_kind (const std::string &type)
 True for every normalized IR type that represents a vector / path-like shape (svg path/rect/line, ellipse/circle, polygon/polyline/star, …), matched on the IR type string only so the classification is identical across figma/pencil/stitch/v0.
std::optional< FidelityIssue > check_image_sizing_fidelity (const FidelityContext &)
 No-skew: a BLEED sprite (render_bounds or asset_bleed) must be emitted at an aspect matching its source PNG; missing PNG dims → aspect-unverified.
std::optional< FidelityIssue > check_gross_size_divergence (const FidelityContext &)
 Gross-size: a node the user pinned on BOTH axes (SizingMode::fixed) must not be emitted >3x its source box; hug/fill/absolute/display:none self-skip.
std::optional< FidelityIssue > check_widget_intrinsic_size (const FidelityContext &)
 Widget-intrinsic-size: a recognized audio widget whose emitted box diverges >1.5x from its source intrinsic size (shape_width/height attrs, else style box).
std::optional< FidelityIssue > check_text_vertical_centering (const FidelityContext &)
 Text-vertical-centering: a SINGLE-LINE text given a reserved vertical slot (emitted box taller than one line, below the multi-line threshold) must be emitted vertically centered.
void run_fidelity_checks (const FidelityContext &ctx, std::vector< FidelityIssue > &sink)
 Run every registered fidelity check against ctx, appending findings to sink.
void check_vector_renderability (const IRNode &root, const std::vector< ImportDiagnostic > &diagnostics, const std::function< std::string(const IRNode &)> &node_id_of, std::vector< FidelityIssue > &sink)
 Vector-renderability: every visible vector/path-like node (svg path/rect/ line, ellipse, polygon, …) above an area threshold must map to a real renderable primitive — a rasterized asset, a native widget, child paint, or a visible fill — OR already carry an explicit unsupported diagnostic.
std::size_t count_strict_fidelity_failures (const std::vector< FidelityIssue > &issues)
 Number of findings that should fail --strict-fidelity.
const std::vector< FidelityKindInfo > & fidelity_taxonomy ()
 Every fidelity kind the checks can emit, in a stable documentation order.
const FidelityKindInfo * fidelity_kind_info (const std::string &kind)
 Look up a kind by slug; nullptr if it is not in the taxonomy.
std::string fidelity_ledger_json (const std::vector< FidelityIssue > &issues, const FidelityLedgerMeta &meta)
 Serialize one import run's findings to a deterministic JSON ledger.
void register_design_control_factory (std::string factory_id, DesignControlFactory factory)
bool has_design_control_factory (const std::string &factory_id)
void clear_design_control_factories ()
bool suppress_svg_rect (std::string &svg, float x, float y, float w, float h, float tol=2.0f)
bool suppress_svg_glow_at (std::string &svg, float x, float y, float w, float h)
bool suppress_svg_glyph_at (std::string &svg, float x, float y, float w, float h)
ImportReport collect_import_report (const IRNode &root, float low_confidence_threshold=0.6f)
std::string import_report_to_json (const ImportReport &report)
std::string import_report_to_text (const ImportReport &report)
int apply_placement_verification (IRNode &root, float frame_w=0.0f, float frame_h=0.0f)
int apply_swap_target_verification (IRNode &root)
std::vector< UnrenderableFrameSet > find_unrenderable_alternate_frames (const IRNode &root)
std::vector< DuplicateAnchor > find_duplicate_anchors (const IRNode &root)
void register_legacy_import_binder (std::string id, LegacyImportBinder binder)
void invoke_legacy_import_binder (std::string_view id, NativeImportBindingContext &, View &, const NativeImportMeterBindingDescriptor *meter, const NativeImportWaveformBindingDescriptor *waveform)
void bind_imported_level_display (NativeImportBindingContext &ctx, View &view, LevelDisplay &display, const NativeImportMeterBindingDescriptor &descriptor)
 Bind an imported level or series display through both binder generations: the provider-neutral virtual, then the deprecated concrete one through the provider's registered legacy binder.
void bind_imported_series_display (NativeImportBindingContext &ctx, View &view, SeriesDisplay &display, const NativeImportWaveformBindingDescriptor &descriptor)
std::unique_ptr< View > build_native_view_tree (const DesignIR &ir, const IRAssetManifest &manifest, const NativeMaterializeOptions &options={})
canvas::TextRasterPolicy design_ir_text_raster_policy (const DesignIR &ir)
 The text raster policy a surface showing ir should be created with: chromium when any captured text node was authored -webkit-font-smoothing: antialiased, otherwise legacy.
void bind_native_view_tree (View &root, const DesignIR &ir, NativeImportBindingContext &ctx, const NativeImportBindingOptions &options={})
 Apply explicit pulp* binding metadata from ir to an already materialized native view tree.
void enrich_imported_image_asset_metadata (DesignIR &ir, const IRAssetManifest &manifest, std::string_view base_directory={})
 Resolve imported image asset_ref nodes against an asset manifest and stamp source-derived metadata onto the nodes: absolute asset_path, PNG natural dimensions, opaque-core bounds for render-bounds sprites, and asset_bleed when the PNG is much larger than the logical box.
void hoist_captured_art_knobs (DesignIR &ir)
 Captured-art knob promotion.
void synthesize_primitive_paths (IRNode &root)
 Source-agnostic IR normalization for vector SHAPE PRIMITIVES.
void normalize_border_shorthand (IRNode &root)
 Split the CSS border shorthand — "1px solid #333" — into the discrete border_color / border_width / border_style fields, for every node in the tree that set the shorthand but not the parts.
void reconnect_slider_fill (IRNode &root)
 Reconnect a slider's progress fill to its thumb.
int apply_param_binding_manifest (IRNode &root, const std::unordered_map< std::string, std::string > &node_id_to_param_key)
 Bind geometry-detected controls to host parameters from an out-of-band manifest that maps a Figma node id (IRInteractiveElement::source_node_id, stamped by the producer) to a host-param key.
std::optional< std::unordered_map< std::string, std::string > > parse_param_binding_manifest_json (const std::string &json, std::string *error)
 Parse a --param-binding-manifest document — a flat JSON object mapping a Figma node id to a host-param key, e.g.
float selector_segment_value (int index, int count)
 The value a segmented selector writes for segment index of count, and the segment a parameter value selects.
float stepper_normalized_value (double plain, double min, double max)
 A stepper's plain value (voices, octaves) against the normalized parameter behind it.
double stepper_plain_value (float normalized, double min, double max, double step)
int selector_segment_index (float value, int count)
bool toggle_on_from_normalized (double value)
 The single threshold used by every toggle import/binding path.
WidgetPromotionSignal classify_interactive_signal (const IRNode &node)
 Inspect one IR node for interactive-frame promotion signals.
std::size_t promote_interactive_frames (IRNode &root)
 Promote parsed frame nodes carrying click/ARIA/cursor signals to button.
std::vector< IRBoxShadow > parse_css_box_shadow (const std::string &css)
 Parse a CSS box-shadow value into ordered layers.
std::string box_shadow_to_css (const std::vector< IRBoxShadow > &shadows)
 Serialize ordered box-shadow layers back to a CSS box-shadow string, preferring each layer's raw text when present (lossless) and otherwise reconstructing from the parsed fields.
std::string serialize_design_ir (const DesignIR &ir, const DesignIrJsonOptions &options={})
 Serialize a DesignIR as a deterministic, versioned canonical JSON envelope.
DesignIR parse_design_ir_json (const std::string &json)
 Parse either the v1 canonical envelope or a legacy bare-node IR JSON document.
IRAssetManifest collect_design_ir_assets (const DesignIR &ir, const DesignIrAssetOptions &options={})
 Collect all external resources referenced by the IR into a manifest.
void refresh_design_ir_asset_manifest (DesignIR &ir, const DesignIrAssetOptions &options={})
 Refresh ir.asset_manifest from the current tree while preserving embedded manifest entries whose stable asset_id may already be referenced by nodes.
std::vector< DetectedShortcut > extract_keyboard_shortcuts (const std::string &source, const std::string &filename="")
 Static-scan a TSX/JS source string for keyboard-shortcut patterns.
std::string serialize_detected_shortcuts (const std::vector< DetectedShortcut > &shortcuts)
 Serialize a list of DetectedShortcuts to JSON in the caller-provided order.
DefaultShortcutScan detect_default_shortcuts (const std::string &source, const std::vector< DetectedShortcut > &existing_extracted)
 Static-scan a TSX/JS source string for components matching the platform-convention defaults table.
std::vector< DetectedShortcut > apply_default_shortcuts (const std::vector< DefaultShortcutCandidate > &accepted, TargetPlatform platform)
std::string serialize_default_shortcut_scan (const DefaultShortcutScan &scan)
 Render the auto-bound defaults + collisions into JSON for emission alongside the extracted-shortcuts manifest.
bool looks_like_bundler_entry (const std::string &html)
 Heuristic: does this HTML look like a JS-bundler entry (React, Vue, Svelte, @pulp/react, generic webpack/vite/bun output) rather than a hand-authored Claude Design page?
AudioWidgetType detect_audio_widget (const std::string &name)
 Detect audio widget type from a node name.
std::optional< DesignSource > parse_design_source (const std::string &name)
 Convert string to DesignSource, returns nullopt for unknown sources.
const char * design_source_name (DesignSource source)
 Convert DesignSource to display name.
SnapshotDynamicApiScan detect_jsx_snapshot_dynamic_apis (std::string_view source)
 Detect dynamic APIs that make a JSX baked snapshot non-deterministic unless the caller explicitly accepts or warns on snapshot semantics.
DesignIR parse_figma_json (const std::string &json)
 Parse a Figma export JSON into a DesignIR.
DesignIR parse_figma_plugin_json (const std::string &json)
 Parse Pulp's "Design for Pulp" Figma-plugin export envelope.
DesignIR parse_stitch_html (const std::string &html)
 Parse Stitch HTML export into a DesignIR.
DesignIR parse_v0_tsx (const std::string &tsx)
 Parse v0-generated TSX/Tailwind into a DesignIR.
DesignIR parse_pencil_json (const std::string &json)
 Parse Pencil node tree JSON into a DesignIR.
DesignIR parse_claude_html (const std::string &html)
 Parse a Claude Design standalone HTML export into a DesignIR.
DesignMdParseResult parse_designmd (const std::string &markdown)
 Parse a DESIGN.md file (YAML frontmatter + Markdown body) into a DesignIR.
DesignIR parse_designmd_yaml (const std::string &markdown)
 Thin wrapper that returns just the IR.
std::vector< DesignMdDiagnostic > lint_designmd (const DesignMdParseResult &parsed)
 Run Pulp's Google design.md compatibility lint against a parsed DESIGN.md.
DesignMdDiffResult diff_designmd (const DesignMdParseResult &before, const DesignMdParseResult &after)
 Compute the token diff between two parsed DESIGN.md files plus a regression flag derived from their respective lint outputs.
std::string export_tailwind_v3_json (const DesignMdParseResult &parsed)
 Emit a Tailwind v3 theme.extend-shaped JSON object from the parsed token tree.
std::string export_tailwind_v4_css (const DesignMdParseResult &parsed)
 Emit a Tailwind v4 @theme { ... } CSS block from the parsed token tree.
std::optional< ClaudeBundle > parse_claude_bundle (const std::string &html)
 Decode the bundler envelope from a Claude Design standalone HTML file.
std::optional< ClaudeBundle > parse_materialized_browser_document (const std::string &json)
 Decode the deterministic pre-mount document emitted by Chromium browser capture.
std::shared_ptr< const ClaudeBundle > parse_materialized_browser_document_shared (const std::string &json)
 parse_materialized_browser_document with process-wide reuse.
MaterializedDocumentCacheStats materialized_document_cache_stats ()
void clear_materialized_document_cache ()
 Drop every kept document (tests; a host that wants the memory back).
std::vector< std::string > runtime_import_whole_scripts (const ClaudeBundle &bundle)
 The whole scripts a live editor evaluates when it imports bundle at run time (__pulpRuntimeImport__): each JavaScript asset payload and each text/javascript inline script, byte-identical to what the payload pipeline hands evaluate_script().
std::optional< ClaudeBundle > parse_v0_dev_react (const std::string &tsx_or_envelope)
 Normalize a constrained v0.dev React TSX export into the runtime-import bundle payload shape.
std::optional< ClaudeBundle > parse_figma_make_react (const std::string &tsx)
 Normalize a constrained Figma Make React TSX export into the runtime-import bundle payload shape.
std::optional< ClaudeBundle > parse_stitch_react (const std::string &tsx)
 Normalize a constrained Google Stitch React export into the runtime-import bundle payload shape.
std::optional< ClaudeBundle > parse_react_native_export (const std::string &tsx)
 Normalize a constrained React Native single-file component export into the runtime-import bundle payload shape.
std::optional< ClaudeBundle > parse_pencil_react (const std::string &tsx)
 Normalize a constrained Pencil/OpenPencil sanitized Tailwind-JSX export into the runtime-import bundle payload shape.
std::optional< ClaudeBundle > parse_jsx_react (const std::string &bundle_js, const std::string &component_name="JsxComponent")
 Wrap a pre-compiled JSX runtime bundle (esbuild IIFE of React plus either ReactDOM or the @pulp/react native bridge and the user's JSX component, produced by tools/import-design/jsx-runtime/ jsx-transform.mjs) as a synthetic ClaudeBundle so the existing runtime-import harness (parse_claude_html_with_runtime) can materialize it.
std::string synthesize_runtime_envelope (const ClaudeBundle &bundle)
 Synthesize a Claude-style HTML envelope around an arbitrary ClaudeBundle so the existing parse_claude_html_with_runtime harness can consume it without a real Claude Design HTML wrapper on input.
DesignIR parse_claude_html_with_runtime (const std::string &html, ClaudeRuntimeOptions opts={})
 Run the Claude Design bundle in a headless JS engine and harvest the materialized DOM into a DesignIR.
ClaudeClassNameRules extract_claude_classnames (const std::string &html)
 Extract classname → declaration map from a Claude Design HTML export.
std::string serialize_claude_classnames (const ClaudeClassNameRules &rules)
 Serialize a ClaudeClassNameRules map to the JSON shape Spectr's extract.mjs produces.
std::string export_css_variables (const Theme &theme)
 Export a Pulp Theme to CSS custom properties (variables).
std::string token_css_var (const std::string &token_name)
 The CSS custom-property id a token binds through: -- + the token name with its trailing .dark mode suffix stripped and every .
Theme ir_tokens_to_theme (const IRTokens &tokens, std::vector< std::string > *unresolved_widget_tokens=nullptr)
 Convert IR tokens to a Pulp Theme.
std::optional< ImportDiagnostic > unmapped_widget_token_diagnostic (const std::vector< std::string > &unresolved)
 The diagnostic naming the widget keys a design supplied no colour for, or nothing when it supplied them all.
IRTokens theme_to_ir_tokens (const Theme &theme)
 Convert a Pulp Theme to W3C-compatible IR tokens.
Theme parse_figma_variables (const std::string &json)
 Parse Figma Variables JSON (from MCP get_variable_defs) into a Pulp Theme.
std::string export_figma_variables (const Theme &theme)
 Export a Pulp Theme as Figma Variables-compatible JSON.
Theme parse_stitch_design_system (const std::string &json)
 Parse a Stitch Design System JSON (from MCP list_design_systems/get_screen) into a Pulp Theme.
std::string export_stitch_design_system (const Theme &theme)
 Export a Pulp Theme as Stitch Design System-compatible JSON.
std::string to_w3c_tokens_json (const IRTokens &tokens, bool pretty=true)
 Serialize design-import tokens to a W3C Design Tokens (DTCG) JSON document.
std::vector< std::string > validate_dtcg (const std::string &json)
 Validate a JSON document against the DTCG invariants the emitter targets.
std::vector< DesignSlot > classify_design_slots (const IRNode &node)
std::string_view to_string (DesignKeyDiagnosticReason reason) noexcept
DesignChildUpdatePlan plan_design_child_updates (std::span< const IRNode > old_children, std::span< const IRNode > new_children)
void apply_designed_control_skin (View &control, const DesignedControlSkin &skin)
 Install the value-only painter on control.
bool begin_file_drag (void *native_view, const FileDragRequest &request)
FileDragBackend set_file_drag_backend (FileDragBackend backend)
bool invoke_file_drag_backend (const FileDragRequest &request)
bool register_drop_target (void *native_view, DropTarget &target)
void unregister_drop_target (void *native_view)
bool dispatch_drag_enter (View &root, DragSession &session, const DropData &data, Point root_pos)
void dispatch_drag_move (View &root, DragSession &session, const DropData &data, Point root_pos)
void dispatch_drag_exit (View &root, DragSession &session)
bool dispatch_drop (View &root, DragSession &session, const DropData &data, Point root_pos)
std::string render_claude_bridge_scaffold (const std::string &generated_js_path)
 Build the starter bridge_handlers.cpp text the CLI emits next to the generated JS view when --from claude runs.
GpuAcquireDiagnostics gpu_acquire_diagnostics (double now_s, double vsync_target_s, double refresh_period_s, int frames_in_flight) noexcept
 Build the record for one acquire.
bool gpu_timing_requested (const char *env_value) noexcept
 Whether an environment value asks for GPU timing: "1", "true", "yes" or "on", case-insensitively.
void resample_spectrum_log (std::span< const float > bins_db, float sample_rate, const LogFrequencyScale &scale, std::span< float > out)
 Resample a real-FFT magnitude array (bins spanning DC..Nyquist) onto out.size() log-spaced frequencies across [scale.min_hz, scale.max_hz], linearly interpolating in dB between adjacent bins.
bool should_dispatch_host_frame (HostFramePump &pump, bool needs_repaint, bool continuous, bool has_idle_callback)
 Step 0 of a host tick, on the VSYNC SOURCE'S OWN THREAD: does this vsync need to reach the UI thread at all?
HostFrameTick begin_host_frame (View *root, FrameClock &clock, HostFramePump &pump, double now_seconds, bool needs_repaint)
 Step 1 of a host tick: measure dt, pump the FrameClock's activity probes with it, then decide whether this frame needs compositing.
void advance_host_frame (View *root, FrameClock &clock, float dt)
 Step 2 of a host tick, run only when HostFrameTick::should_render: advance every dt-integrating consumer in the tree by the SAME dt — the render clock (and its subscribers), widget animations, and CSS animation timelines — and pump the gesture recognizers.
bool host_frame_composites (const HostFrameTick &tick, bool damaged) noexcept
 Step 3 of a host tick, after advance_host_frame: does this frame composite?
void advance_widget_animations (View *view, float dt)
 Advance the built-in widget animations and the CSS animation timeline for view and every descendant.
double host_elapsed_ms (HostClock::time_point since) noexcept
 Milliseconds elapsed since since on the monotonic host clock.
View::CursorStyle hover_cursor_at (View &root, Point p)
 The cursor style a pointer at p (root-view coordinates) should show over root: the style of the view hit_test resolves to, or default_ when the point hits nothing.
bool is_main_modifier (uint16_t mods)
 True if the primary action modifier is held (Cmd on macOS, Ctrl on Windows/Linux).
std::string view_type_name (const View &view)
 The type name the inspector and the layout/appearance diagnostics show for view ("Knob", "Fader", "Label", ...): the built-in widget name, else the InspectorFacts name a widget reports, else "View".
constexpr std::string_view engine_type_name (JsEngineType type)
std::unique_ptr< JsEngine > create_js_engine (JsEngineType type)
std::unique_ptr< JsEngine > create_default_js_engine ()
bool is_engine_available (JsEngineType type)
JsEngineCreationStats js_engine_creation_stats ()
void reset_js_engine_creation_stats_for_tests ()
ScriptBytecodeCacheStats script_bytecode_cache_stats ()
void clear_script_bytecode_cache ()
 Drop every stored script (tests; a host that wants the memory back).
std::size_t precompile_scripts (const std::vector< std::string > &sources, const std::atomic< bool > *cancel=nullptr)
 Compile whole scripts into the bytecode cache without running them, on the calling thread, in a private QuickJS runtime.
bool script_bytecode_cached (const std::string &source)
 True when byte-identical source has stored bytecode (tests, diagnostics).
std::vector< std::uint8_t > build_embedded_script_bytecode (const std::string &source)
 Build-time script bytecode (QuickJS backend).
bool register_embedded_script_bytecode (const std::uint8_t *blob, std::size_t size)
 Returns false (and registers nothing) for a malformed blob, or one whose engine fingerprint differs from this process's engine.
std::string script_bytecode_engine_fingerprint ()
 The engine's bytecode fingerprint: the QuickJS version plus a digest of the bytecode this engine emits for a fixed probe script, so any change to the bytecode format or opcode/atom numbering changes it.
EngineRecommendation recommend_engine_for_script (std::string_view js_source, JsEngineType current=JsEngineType::quickjs)
EngineRecommendation recommend_engine_for_workload (std::string_view workload, JsEngineType current=JsEngineType::quickjs)
std::optional< std::string > jsx_lock_property_to_key (const std::string &property_path)
 Map a dotted tweak property_path (paint.backgroundColor, style.width, layout.padding, a bare width, …) to the camelCase JSX style / prop key the engine looks for in style={{…}} or as a bare attribute.
bool is_authored_jsx_source (const std::string &source)
 Heuristic guard: does source look like hand-authored JSX/TSX (as opposed to a Pulp-generated web-compat artifact)?
JsxLockResult jsx_lock_tweak_into_source (const std::string &source, const JsxLockTweak &tweak)
 Locate the JSX element carrying data-pulp-anchor="<tweak.anchor_id>" in an authored JSX/TSX source string and surgically rewrite the literal value of the prop named by tweak.property_path so it carries tweak.value.
std::vector< JsxLockResult > jsx_lock_tweaks_into_source (const std::string &source, const std::vector< JsxLockTweak > &tweaks)
 Lock several tweaks into the same authored source in one pass.
std::string format_chord (KeyCode key, std::uint16_t modifiers)
 Render a (key + modifiers) chord as a user-facing string, e.g.
std::string dump_layout_tree (const View &root, const LayoutTreeSnapshotOptions &options={})
 Dump the current, already-laid-out View tree as deterministic JSON.
bool layout_tree_snapshots_equivalent (std::string_view actual_json, std::string_view expected_json, const LayoutTreeTolerance &tolerance={}, LayoutTreeDiff *diff=nullptr)
 Compare two dump_layout_tree() JSON strings with the layout oracle rules: node kind/id/visibility/z-order/overflow must match exactly, numeric layout bounds must match exactly by default, and text-box dimensions allow a small tolerance for text measurement.
std::optional< std::string > lock_property_to_style_name (const std::string &property_path)
 Map a dotted tweak property_path (paint.backgroundColor, style.width, layout.padding, …) to the camelCase CSS property name the web-compat codegen emits as el.style.
LockResult lock_tweak_into_source (const std::string &source, const LockToSourceTweak &tweak)
 Locate the element anchored by tweak.anchor_id in a generated web-compat JS/TSX source string and rewrite (or insert) the style assignment for tweak.property_path so it carries tweak.value.
std::vector< LockResult > lock_tweaks_into_source (const std::string &source, const std::vector< LockToSourceTweak > &tweaks)
 Lock several tweaks into the same source in one pass.
LockResult reparent_in_source (const std::string &source, const ReparentToSourceEdit &edit)
 Rewrite the dragged element's appendChild receiver so the generated source wires it under the new parent.
bool is_generated_source (const std::string &source)
 Heuristic guard for the generated-file boundary.
float apply_motion_policy_to_duration (float configured_seconds)
 Apply the current MotionPolicy to a configured duration.
bool motion_policy_is_off ()
 Returns true when the current policy says "do not animate" — i.e.
const char * motion_policy_to_string (MotionPolicy p)
 Returns the current policy string for fixture headers.
MotionPolicy motion_policy_from_string (const std::string_view s)
 Parse a policy string (case-sensitive). Returns Full on unknown.
const OverlayDismissalPolicy & overlay_dismissal_policy ()
 The active policy. Reading is cheap and allocation-free.
void set_overlay_dismissal_policy (const OverlayDismissalPolicy &policy)
 Replace the active policy. Call from application setup, not mid-gesture.
OverlayPressTarget route_press_to_active_overlay (View &root, Point root_pt)
 Consult root's generalized overlay slot for a press at root_pt.
View * hover_target_at (View &root, Point root_pt)
 The view a HOVER at root_pt lands on: the deepest hit inside the topmost open overlay that contains the point, otherwise root.hit_test(root_pt).
PassivePointerRoute route_passive_pointer (View &root, Point root_pt)
 Resolve a passive pointer input through the root's open overlays.
ContextPressResult route_context_press (View &root, Point root_pt)
 Route a context (right-button) press at root_pt, consulting the generalized overlay slot first.
OverlayEscapeResult route_escape_to_active_overlay (View &root, std::uint16_t modifiers=0, bool is_repeat=false)
 Dismiss the topmost thing Escape should close under root.
bool root_overlay_owns_keyboard (View &root)
 Whether an overlay under root is the kind that should own the keyboard.
std::pair< std::unique_ptr< Knob >, state::Binding > attach_knob (state::StateStore &store, state::ParamID id, float size=60.0f)
 Attach a Knob widget to a parameter.
std::pair< std::unique_ptr< Fader >, state::Binding > attach_fader (state::StateStore &store, state::ParamID id)
 Attach a Fader widget to a parameter.
std::pair< std::unique_ptr< Toggle >, state::Binding > attach_toggle (state::StateStore &store, state::ParamID id)
 Attach a Toggle widget to a boolean parameter.
std::pair< std::unique_ptr< ComboBox >, state::Binding > attach_combo (state::StateStore &store, state::ParamID id, std::vector< std::string > items)
 Attach a ComboBox to an integer/stepped parameter.
void poll_bindings (std::vector< state::Binding > &bindings)
 Poll all bindings in a vector to sync with host automation.
std::pair< std::unique_ptr< Knob >, state::ExternalBinding > attach_knob (state::ExternalBindingConfig cfg, float size=60.0f)
std::pair< std::unique_ptr< Fader >, state::ExternalBinding > attach_fader (state::ExternalBindingConfig cfg)
std::pair< std::unique_ptr< Toggle >, state::ExternalBinding > attach_toggle (state::ExternalBindingConfig cfg)
ParameterBinding bind_parameter (Knob &knob, state::StateStore &store, state::ParamID id)
 Knob ↔ parameter (normalized).
ParameterBinding bind_parameter (Fader &fader, state::StateStore &store, state::ParamID id)
 Fader ↔ parameter (normalized).
ParameterBinding bind_parameter (XYPad &pad, state::StateStore &store, state::ParamID x_id, state::ParamID y_id)
 XY pad ↔ two parameters (normalized). A single drag drives both.
ParameterBinding bind_parameter (RangeSlider &slider, state::StateStore &store, state::ParamID id)
 Range slider ↔ parameter (normalized).
ParameterBinding bind_parameter (ComboBox &combo, state::StateStore &store, state::ParamID id)
 ComboBox ↔ stepped/index parameter.
ParameterBinding bind_parameter (DesignStepper &stepper, state::StateStore &store, state::ParamID id)
 DesignStepper ↔ stepped/index parameter (same contract as ComboBox): user steps are one-shot gestures; automation playback drives the selection via set_selected_silent (which does not re-fire on_select).
ParameterBinding bind_parameter (Toggle &toggle, state::StateStore &store, state::ParamID id)
 Toggle (switch) ↔ parameter, as a one-shot gesture per flip.
ParameterBinding bind_parameter (Checkbox &box, state::StateStore &store, state::ParamID id)
 Checkbox ↔ parameter, as a one-shot gesture per flip.
ParameterBinding bind_parameter (ToggleButton &button, state::StateStore &store, state::ParamID id)
 Toggle button ↔ parameter.
bool compute_frame_clip (View &root, const PendingDamage::Snapshot &damage, const FrameGeometry &geometry, Rect &out_clip)
 Decide the clip rect for a partial repaint, in SURFACE space.
void paint_plugin_scene (canvas::Canvas &canvas, View &root, const FrameGeometry &geometry, const Rect *clip)
 Paint one editor frame: background fill (geometry.background_rgb), design-viewport transform, view tree, overlays.
PluginKeyDisposition route_plugin_key (View &root, const PluginKeyOffer &offer)
 Resolve who consumes offer under root.
View * plugin_key_focus (View &root)
 The focused view under root, or nullptr.
bool is_plugin_navigation_key (KeyCode key, std::uint16_t modifiers)
 The bounded navigation set a non-text widget may borrow from the host.
void register_platform_plugin_view_host ()
Point point_to_local (Point root_pos, View *target, View *root)
 Convert root_pos (root-local, i.e.
void dispatch_dom_pointer_event (View &root, View *target, const MouseEvent &event, bool moving, bool bubble=true)
 Enter rich + JS pointer delivery from a platform host.
bool dispatch_context_menu (View &root, Point root_pos)
 Route a right-click at root_pos to the view under it.
bool dispatch_context_menu (View &root, View *target, Point root_pos)
 Route a context menu to an already-resolved pointer target.
bool should_yield_to_gesture (View &root, const MouseEvent &event)
 Feed one pointer event to root's gesture arbiter and report whether the host must now YIELD — i.e.
bool yield_to_gesture_with_handoff (View &root, View *&drag_target, const MouseEvent &event, int click_count=1)
 Apply the host-side gesture gate and close an already-delivered press when a recognizer claims after that press.
bool transfer_input_focus (View &root, View *target)
 Move input focus within one hosted root while tolerating callbacks that synchronously unmount either the previous or requested focus target.
View * focused_input_under_root (View &root)
 Return this root's live focused input.
void deliver_mouse_drag (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count=1, PointerType pointer_type=PointerType::mouse, float pressure=0.5f)
 Deliver one drag tick of an in-flight gesture to the captured target.
void deliver_mouse_drag (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, PointerType pointer_type, float pressure, MouseButton button)
 Button-aware overload.
void deliver_mouse_drag (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, MouseButton button, const PointerAttributes &pointer)
 Attribute-carrying overload — the only drag form that also carries pointer_id.
void deliver_hover_move (View &root, Point root_pt, uint16_t modifiers=0)
 Deliver one BUTTONLESS pointer move — a hover — to the view under root_pt, which is in root-view space.
void deliver_hover_move (View &root, Point root_pt, uint16_t modifiers, const PointerAttributes &pointer)
 Attribute-carrying hover overload, for a host that knows the pointer device (a trackpad/stylus hover) or reports movement deltas.
void deliver_mouse_wheel (View &root, Point root_pt, float scroll_delta_x, float scroll_delta_y, const WheelHost &host)
 Route one wheel/scroll tick to the view tree rooted at root.
void deliver_mouse_wheel (View &root, Point root_pt, float scroll_delta_x, float scroll_delta_y, uint16_t modifiers, const WheelHost &host)
 Attribute-carrying wheel delivery.
bool deliver_mouse_down (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count=1, bool bubble=true)
 Deliver a press to an already-resolved target (the host has done the hit_test, any combo/overlay pre-routing, and the focus protocol before calling in — those steps diverge per platform/host and stay host-side).
bool deliver_mouse_down (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, bool bubble, MouseButton button)
 Button-aware overload; the original ABI remains the left-button wrapper.
bool deliver_mouse_down (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, bool bubble, MouseButton button, const MouseDownHost &host)
 Guarded button-aware overload.
bool deliver_mouse_down (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, bool bubble, MouseButton button, const MouseDownHost &host, const PointerAttributes &pointer)
 Attribute-carrying overload.
void deliver_mouse_up (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, const MouseUpHost &host)
 Deliver a release for an in-flight gesture captured on target.
void deliver_mouse_up (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, const MouseUpHost &host, MouseButton button)
 Button-aware overload; the original ABI remains the left-button wrapper.
void deliver_mouse_up (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, const MouseUpHost &host, MouseButton button, const PointerAttributes &pointer)
 Attribute-carrying overload.
void deliver_mouse_cancel (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count, MouseButton button, const PointerAttributes &pointer={})
 Cancel an in-flight gesture through the same identity-safe terminal router as deliver_mouse_up.
void deliver_gesture_handoff (View &root, View *target, Point root_pt, uint16_t modifiers, int click_count)
 Close the press bracket when a recognizer CLAIMS the pointer mid-gesture, after a press was already delivered to target.
const char * press_channel_name (PressChannel channel)
 Human-readable channel name, for reports and test failure messages.
PressReach reach_of_press (View &root, Point root_pt, PressChannel channel=PressChannel::click)
 Resolve — without delivering — what a press at root_pt would reach.
std::optional< Rect > rect_in_root (const View &view, View &root)
 view's painted rect in root-local coordinates, or std::nullopt when that cannot be established exactly.
PressReachAudit audit_press_reach (View &root, const PressReachOptions &options={})
 Walk root and press every control that advertises a press handler, at the centre of the rect it paints.
std::string format_press_reach_audit (const PressReachAudit &audit)
 Format an audit as a report a human reads in CI output.
RecognitionSource pulp_audio_control_library_source ()
 The built-in library as one recognition source named "builtin-library".
RecognitionResolver recognition_resolver_with_builtin_library ()
 A resolver seeded with the built-in library as source 0.
AudioWidgetType audio_widget_kind_from_manifest_id (const std::string &id)
 Map an AudioWidgetType to/from the lowercase id used in manifests and the figma-plugin envelope ("knob"/"fader"/...).
const char * audio_widget_kind_to_manifest_id (AudioWidgetType kind)
int apply_recognition_resolver (IRNode &root, const RecognitionResolver &resolver, std::vector< UnmatchedComponent > *unmatched_out=nullptr)
PackageDesignControlSources gather_package_design_controls (const std::filesystem::path &lockfile_path, const std::filesystem::path &registry_path)
PackageDesignControlSources discover_package_design_controls (const std::filesystem::path &start_dir)
int materialize_recognized_custom_controls (IRNode &root)
const std::vector< std::pair< std::string_view, ReloadCapability > > & autocaps_function_table ()
 Effectful bridge function name → the capability that gates it.
CapabilitySet infer_capabilities_from_js (std::string_view js_source)
 Scan js_source and return the granted set it needs.
std::vector< std::string > infer_capability_names_from_js (std::string_view js_source)
 The capability NAMES a scripted UI needs, sorted + de-duplicated — ready to drop into a manifest's declared_capabilities.
std::string_view capability_name (ReloadCapability c)
 Stable wire name for a capability (used in the SIGNED pack manifest + config).
bool capability_from_name (std::string_view s, ReloadCapability &out)
 Parse a wire name; returns false on an unknown token (caller fails closed — an unrecognized capability must never silently grant nothing-or-everything).
int reorder_target_index (int from, float offset, float pitch, int count)
 Target index for a drag that started on item from, moved offset along the main axis, over a list of count items spaced pitch apart.
DamageDecision compute_effective_damage (const View &root, const Rect &requested_root_rect, float device_scale=1.0f)
 Decide whether requested_root_rect can be repainted as a bounded clip (pixel-identical to a full repaint) or must escalate to a full repaint.
std::vector< uint8_t > render_to_png (View &root, uint32_t width, uint32_t height, float scale=2.0f, ScreenshotBackend backend=ScreenshotBackend::default_backend, canvas::TextRasterPolicy text_raster=canvas::TextRasterPolicy::legacy)
bool render_to_file (View &root, uint32_t width, uint32_t height, const std::string &output_path, float scale=2.0f, ScreenshotBackend backend=ScreenshotBackend::default_backend, canvas::TextRasterPolicy text_raster=canvas::TextRasterPolicy::legacy)
CaptureRequirements inspect_capture_requirements (View &root)
 Inspect the tree once for requirements shared by capture routing and capability admission.
CaptureResult capture_view (View &root, uint32_t width, uint32_t height, float scale=2.0f, ScreenshotBackend backend=ScreenshotBackend::auto_select)
std::vector< uint8_t > render_to_png_gpu (View &root, uint32_t width, uint32_t height, float scale=2.0f, canvas::TextRasterPolicy text_raster=canvas::TextRasterPolicy::legacy)
bool has_gpu_capture ()
bool has_screenshot_backend ()
bool has_screenshot_decoder ()
 True when this build can decode PNG pixels for the mandatory capture content floor.
bool passes_capture_content_floor (const std::vector< uint8_t > &png)
 Apply the same deliberately lenient "did anything paint?" floor used by capture_view().
std::vector< uint8_t > render_to_rgba (View &root, uint32_t width, uint32_t height, float scale, uint32_t *out_width, uint32_t *out_height, canvas::TextRasterPolicy text_raster=canvas::TextRasterPolicy::legacy)
bool raw_rgba_render_available ()
void set_screenshot_provider (ScreenshotProvider provider)
void clear_screenshot_provider ()
bool has_screenshot_provider ()
PngMetadata inspect_png_metadata (const std::vector< uint8_t > &png)
CompareResult compare_screenshots (const std::vector< uint8_t > &reference_png, const std::vector< uint8_t > &rendered_png, uint8_t tolerance=32)
 Compare two PNG images for visual similarity.
CompareResult compare_screenshot_files (const std::string &reference_path, const std::string &rendered_path, uint8_t tolerance=32)
 Compare two PNG files for visual similarity.
std::vector< uint8_t > generate_diff_image (const std::vector< uint8_t > &reference_png, const std::vector< uint8_t > &rendered_png, uint8_t tolerance=32)
 Generate a visual diff image highlighting differences between two PNGs.
std::vector< uint8_t > crop_png (const std::vector< uint8_t > &png, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
 Crop a rectangular region from a PNG image and return it as a new PNG.
DiffBounds diff_bounds (const std::vector< uint8_t > &reference_png, const std::vector< uint8_t > &rendered_png, uint8_t tolerance=32)
 Compute the bounding box of pixels that differ beyond the given tolerance.
ScreenshotContentStats analyze_screenshot_content (const std::vector< uint8_t > &png)
 Decode a PNG and compute content statistics suitable for catching empty or stable single-color captures before any parity claim is accepted.
void install_script_inspector_bridge () noexcept
 Make every ScriptedUiSession constructed afterwards carry a ScriptInspectorBridge as its inspector port.
ScriptInspectorBridge * script_inspector (ScriptedUiSession &session) noexcept
 The session's ScriptInspectorBridge, or nullptr when the session was built without one (install_script_inspector_bridge() had not run).
void set_script_inspector_port_factory (ScriptInspectorPortFactory factory) noexcept
 Process-wide: set before the sessions that should carry an inspector are constructed (sessions built earlier keep what they had).
ScriptInspectorPortFactory script_inspector_port_factory () noexcept
void prewarm_scripted_ui (ScriptedUiPrewarmRequest request)
 Queue request for the process's prewarm worker and return at once.
std::atomic< ScriptedUiPrewarmRunner > & scripted_ui_prewarm_runner () noexcept
ScriptedUiPrewarmStats scripted_ui_prewarm_stats ()
bool wait_for_scripted_ui_prewarm (std::chrono::milliseconds timeout)
 Block until the worker is idle or timeout passes; true when idle.
View * enclosing_text_selection_region (View &from)
 The nearest enclosing text-content region of from (itself included), or null when it is not inside one.
int selectable_index_at_point (const SelectableLayout &layout, Point local)
 Nearest cluster boundary to local within layout.
std::vector< Rect > selectable_rects_for_range (const SelectableLayout &layout, int start_utf8, int end_utf8)
 The painted rects covering [start_utf8, end_utf8), in local coordinates, one per touched line.
int selectable_first_index (const SelectableLayout &layout)
 First / last selectable byte offset in layout.
int selectable_last_index (const SelectableLayout &layout)
void flush_async_notifications ()
 Deferred Notify::async callbacks, oldest first.
void queue_async_notification (std::function< void()> fn)
 Queue a callback for the next flush.
std::string extract_svg_fragment (const std::string &svg, const std::string &marker)
std::string svg_open_tag (const std::string &svg)
std::string recolor_svg_fragment (std::string fragment, const std::string &hex, bool include_stroke=false)
std::string build_svg_fragment_document (const std::string &source_svg, const std::string &fragment, const FragmentTransform &xform, float opacity=1.0f, const std::string &recolor_hex={})
std::string_view accessibility_backend_name () noexcept
 Returns the active accessibility backend identifier.
void register_text_accessibility_node (const TextAccessibilityNode &node)
 Register or replace a text node with the active a11y backend.
void unregister_text_accessibility_node (std::string_view id)
 Drop the node registered under id.
std::vector< TextAccessibilityNode > snapshot_accessibility_nodes ()
 Read back the currently-registered nodes.
float captured_baseline_offset (float line_height, float css_descent, const std::optional< LineMetrics > &measured)
 Where the baseline of a captured line sits below the top of its run rect, for a rect line_height CSS px tall.
float captured_baseline (float line_top, float offset, float root_y)
 The baseline of a captured line whose rect top is at line_top in the label's coordinates and whose baseline sits offset below that top, snapped to a whole CSS px the way Chromium paints it.
std::size_t utf8_advance (std::string_view text, std::size_t count)
 Walk forward over UTF-8 leading bytes.
std::size_t utf8_codepoint_count (std::string_view text)
 Count the number of UTF-8 leading-byte codepoints in text.
std::string truncate_to_width (canvas::Canvas &canvas, std::string_view text, float available_width, bool force_ellipsis=false)
 If text already fits within available_width, return it as-is unless force_ellipsis is true.
Color color_from_hex (uint32_t hex)
Color color_from_hex_alpha (uint32_t hex)
float relative_luminance (Color c)
 Compute relative luminance of a color per WCAG 2.1 definition.
float contrast_ratio (Color a, Color b)
 Compute WCAG contrast ratio between two colors.
float min_contrast_for_level (ContrastLevel level)
 Get the minimum contrast ratio required for a given level.
bool meets_contrast (Color foreground, Color background, ContrastLevel level=ContrastLevel::aa_normal)
 Check if a foreground/background pair meets a given contrast level.
Color auto_contrast_foreground (Color background, ContrastLevel level=ContrastLevel::aa_normal)
 Given a background color, compute an accessible foreground color.
std::optional< Color > adjust_for_contrast (Color foreground, Color background, ContrastLevel level=ContrastLevel::aa_normal)
 Given a background color and a desired foreground, adjust the foreground lightness until it meets the required contrast level.
HSL rgb_to_hsl (Color c)
Color hsl_to_rgb (HSL hsl, float alpha=1.0f)
Color shift_hue (Color c, float degrees)
 Shift hue by degrees (wraps around 360).
Color adjust_lightness (Color c, float delta)
 Adjust lightness by a delta (clamped to [0,1]).
Color blend_colors (Color a, Color b, float t)
 Blend two colors by factor t in [0,1]. t=0 returns a, t=1 returns b.
Color with_alpha (Color c, float alpha)
 Apply alpha to a color [0.0-1.0].
std::vector< ContrastIssue > validate_theme_contrast (const Theme &theme, ContrastLevel level=ContrastLevel::aa_normal)
 Validate a theme for contrast issues.
Theme auto_fix_contrast (const Theme &theme, ContrastLevel level=ContrastLevel::aa_normal)
 Auto-fix contrast issues in a theme by adjusting foreground colors.
const std::vector< ThemePreset > & all_presets ()
 Get all built-in theme presets (37 tweakcn-sourced + "Ink & Signal", Pulp's flagship design language = 38 total).
const ThemePreset * find_preset (const std::string &id)
 Look up a preset by id. Returns nullptr if not found.
std::vector< std::string > preset_ids ()
 Get the list of preset ids.
Theme derive_theme (const SemanticColors &colors)
 Derive a complete Theme from semantic colors.
Theme theme_from_preset (const ThemePreset &preset, bool dark)
 Build a complete Theme from a preset for the given appearance.
std::optional< std::string > threejs_iife_source ()
const char * token_group_key (TokenGroup group)
 Stringify a TokenGroup as its DESIGN.md frontmatter key.
std::optional< TokenTarget > classify_token_tweak (const std::string &anchor_id, const std::string &property_path)
 Classify a tweak as token-typed or not.
TokenLockResult lock_token_in_designmd (const std::string &markdown, const TokenTarget &target, const std::string &new_value)
 Lock a single token tweak back into DESIGN.md text.
TokenLockResult lock_token_in_designmd (const std::string &markdown, const std::string &anchor_id, const std::string &property_path, const std::string &new_value)
 Convenience overload: classify + lock in one call.
bool tracing_badge_should_paint ()
void set_tracing_badge_visible (bool visible)
void set_tracing_badge_placement (const TracingBadgePlacement &placement)
TracingBadgePlacement tracing_badge_placement ()
TracingBadgeLayout tracing_badge_layout (float root_width, float text_width, float ascent, float descent, const TracingBadgePlacement &placement)
float fit_combo_label (std::string &text, float avail, float base, float min, const std::function< float(const std::string &, float)> &width_at)
ScrollView * find_scroll_view_at (View &root, Point root_point)
 Find the deepest ScrollView whose bounds contain root_point (a point in root's local coordinate space).
View * find_wheel_scroll_view_at (View &root, Point root_point)
 Find the deepest view that participates in native wheel scrolling.
void accumulate_overflow_extent (const View *v, float parent_abs_x, float parent_abs_y, float &min_x, float &min_y, float &max_x, float &max_y)
void accumulate_scroll_content_extent (const View &parent, float parent_x, float parent_y, float &right, float &bottom, bool &found)
constexpr bool is_structural_access_role (View::AccessRole role)
 Structural roles: a container announces the children underneath it, so it is meaningful without a name of its own.
void clamp_oversize_absolute_view (pulp::view::View &view, float vw, float vh, std::uint32_t viewport_width, std::uint32_t viewport_height, int depth, const char *parent_label)
void walk_and_clamp (pulp::view::View &view, float vw, float vh, std::uint32_t viewport_width, std::uint32_t viewport_height, int depth, const char *parent_label)
bool reconcile_disabled_by_env (const char *raw)
 Whether a caller has opted out of reconciliation, given the raw value of PULP_SHOT_NO_RECONCILE (nullptr when the variable is unset).
void reconcile_oversize_absolute_subtree (pulp::view::View &root, std::uint32_t viewport_width, std::uint32_t viewport_height)
Theme parse_w3c_tokens (const std::string &json)
 Parse W3C / DTCG Design Tokens JSON into a Pulp Theme.
std::string export_w3c_tokens (const Theme &theme)
 Export a Pulp Theme to W3C Design Tokens JSON.
WaveformRenderPlan build_waveform_render_plan (const WaveformViewport &viewport, int max_spans=0)
WaveformHitResult hit_test_waveform_handles (const WaveformViewport &viewport, const WaveformHandleModel &model, float x, float tolerance_px)
WaveformHitResult hit_test_waveform_handles (const WaveformViewport &viewport, const WaveformHandleModel &model, float x, const HitMetrics &metrics, float pixels_per_point=1.0f)
 Device-aware overload: the same hit test sized for the pointer driving it.
WaveformSnapResult resolve_waveform_snap (int64_t sample, int64_t total_samples, const WaveformSnapSettings &settings)
WaveformPlayheadOverlay build_waveform_playhead_overlay (const WaveformViewport &viewport, int64_t playhead_sample)
std::string encode_webview_message_json (const WebViewMessage &message)
 Encode a structured WebView message to canonical JSON.
bool decode_webview_message_json (const std::string &json, WebViewMessage &message)
 Decode a structured WebView message from JSON.
std::string make_webview_bridge_bootstrap_script ()
 JavaScript helper that installs a small window.pulp bridge on a page.
std::string make_webview_eval_script (const std::string &request_id, const std::string &js_source)
 JavaScript wrapper that evaluates user code asynchronously and reports the result back through the internal __pulpEvalResult bridge.
std::string guess_webview_mime_type (const std::string &path)
 Best-effort MIME type guess for an HTML-linked asset path.
std::string make_webview_data_uri (const std::string &mime_type, const std::vector< uint8_t > &bytes)
 Create a data: URI for an embedded WebView asset.
std::string load_webview_embedded_text (const std::string &embedded_name)
 Load a UTF-8 text asset previously registered with AssetManager.
std::string make_webview_offline_html (const std::string &html, const std::vector< WebViewEmbeddedAsset > &assets)
 Rewrite simple src/href references in HTML to offline data: URIs backed by embedded assets.
std::string make_webview_offline_html_from_embedded (const std::string &html_embedded_name, const std::vector< WebViewEmbeddedAsset > &assets)
 Load embedded HTML and rewrite its referenced assets for offline use.
std::optional< WebViewOptions::Resource > fetch_webview_embedded_resource (const std::string &path, const std::string &html_embedded_name, const std::vector< WebViewEmbeddedAsset > &assets)
 Fetch a single embedded resource for a WebView custom resource server.
WebViewOptions::FetchResource make_webview_embedded_resource_fetcher (std::string html_embedded_name, std::vector< WebViewEmbeddedAsset > assets)
 Create a resource callback that serves embedded HTML/assets through CHOC's fetchResource/customSchemeURI path.
std::optional< WebViewOptions::Resource > fetch_webview_directory_resource (const std::string &path, const std::filesystem::path &root_directory, std::string index_filename="index.html")
 Fetch a single file-system resource for a WebView custom resource server.
WebViewOptions::FetchResource make_webview_directory_resource_fetcher (std::filesystem::path root_directory, std::string index_filename="index.html")
 Create a resource callback that serves files from a directory through CHOC's fetchResource/customSchemeURI path.
std::string detect_webview_backend ()
 Identifies the live WebView backend on this platform / build.
bool webview_backend_available ()
 Returns true if the host process has a usable WebView backend.
std::unique_ptr< View > build_widget_gallery (const Theme &theme)
std::unique_ptr< View > build_scrolling_widget_gallery (const Theme &theme, float viewport_w, float viewport_h)
void render_schema (canvas::Canvas &canvas, const std::string &json, float w, float h, float value, View &view)
FaderSkin derive_fader_skin (const SkinImage &img)
 Sample a captured fader PNG → FaderSkin.
MeterSkin derive_meter_skin (const SkinImage &img, int stop_count=5)
 Sample a captured meter PNG → MeterSkin.
std::optional< canvas::Canvas::SDFShape > widget_chart_shape (const View &view)
 The SDF shape a widget's chart shader is drawn on: flat_arc for a Knob's value arc, stadium for a Fader's track (a vertical Fader turns it a quarter counter-clockwise, so t runs from the bottom up).
float fader_chart_track_thickness (float cross_extent)
 Height of the stadium a Fader's chart is drawn in, given the fader's extent across its track: half of it, kept between 8 and 24 units.
UaColorScheme ua_scheme_for_accent (canvas::Color accent, UaColorScheme scheme, canvas::Color contrast_light, canvas::Color contrast_dark)
 The scheme Chromium actually paints a control in when an author accent is set: it flips scheme to the other one when the accent's WCAG contrast with contrast_light (the part's light-scheme colour adjacent to the accent) is under 3:1 and lower than with contrast_dark; symmetrically from dark.
float dbfs_meter_fill (float linear)
 Map a linear amplitude (1.0 == full scale) to a 0..1 meter fill on the SAME dBFS scale the panel's text labels print, so a bar and its "… dBFS" label agree.
void bind_midi_cc (Knob &knob, midi::MidiControlBus &bus, uint8_t channel, uint8_t cc)
 Knob → MIDI CC.
void bind_midi_cc (Fader &fader, midi::MidiControlBus &bus, uint8_t channel, uint8_t cc)
 Fader → MIDI CC.
void bind_midi_cc (RangeSlider &slider, midi::MidiControlBus &bus, uint8_t channel, uint8_t cc)
 Range slider → MIDI CC.
void bind_midi_cc (ToggleButton &button, midi::MidiControlBus &bus, uint8_t channel, uint8_t cc)
 Toggle button → MIDI CC (0 / 127).
void bind_midi_cc (Toggle &toggle, midi::MidiControlBus &bus, uint8_t channel, uint8_t cc)
 Toggle → MIDI CC (0 / 127).
void bind_midi_note (ToggleButton &button, midi::MidiControlBus &bus, uint8_t channel, uint8_t note, uint8_t velocity=100)
 Toggle button → MIDI note: note-on while on, note-off when off.
void bind_midi_note (Toggle &toggle, midi::MidiControlBus &bus, uint8_t channel, uint8_t note, uint8_t velocity=100)
 Toggle → MIDI note: note-on while on, note-off when off.
void register_audio_widgets ()
 Registers the optional audio display factories.
SampleAssetDropPlan classify_sample_asset_file_drop (const std::vector< std::string > &paths, const audio::SampleAssetPolicy &policy={})
bool operator== (const WaveformGpuUploadKey &a, const WaveformGpuUploadKey &b) noexcept
bool operator!= (const WaveformGpuUploadKey &a, const WaveformGpuUploadKey &b) noexcept
WaveformGpuStaticLayerPlan build_waveform_gpu_static_layer_plan (const pulp::audio::WaveformOverview &thumbnail, const WaveformViewport &viewport, const WaveformGpuLayerConfig &config={})
WaveformGpuLayerPlan build_waveform_gpu_layer_plan (const pulp::audio::WaveformOverview &thumbnail, const WaveformViewport &viewport, int64_t playhead_sample, const WaveformGpuLayerConfig &config={}, const WaveformGpuUploadKey *previous_static_key=nullptr)
std::size_t fill_waveform_peak_vertices (const pulp::audio::WaveformOverview &thumbnail, const WaveformGpuStaticLayerPlan &plan, std::span< WaveformPeakVertex > dst) noexcept
 Fill caller-owned vertices for CPU fallback or GPU upload staging.
double param_index_to_normalized (int index, int step_count)
 Map a discrete parameter's value index to a normalized [0, 1] value.
int param_normalized_to_index (double normalized, int step_count)
 Inverse of param_index_to_normalized: the nearest value index for a normalized [0, 1] value.
const char * value_channel_shape_name (ValueChannelShape shape) noexcept
 Stable wire name for a channel's shape.
choc::value::Value value_channel_to_value (const ValueChannelInfo &info)
 One channel as {name, unit, shape, neutral}.
choc::value::Value value_channels_to_value (const ValueChannelSet *channels)
 Every declared channel, in declaration order.

Variables

constexpr float kChartGlowSigmaMax = 256.0f
 Largest accepted glow_sigma.
constexpr CommandID kInvalidCommandID = 0
constexpr KeyCode kKeyComma = static_cast<KeyCode>(',')
 ASCII comma as a KeyCode.
constexpr CommandID kCommandOpenSettings = 0x504C5354
 Framework-reserved CommandID for "open the app's settings / preferences" (ASCII 'PLST').
constexpr std::uint16_t kOpenSettingsModifiers = kModCmd
 The platform-standard open-settings chord: Cmd+, on macOS, Ctrl+, elsewhere.
constexpr std::string_view kFidelityLedgerVersion = "2026.07-fidelity-ledger-v1"
 Format id stamped into the ledger JSON; bump on a non-additive shape change.
constexpr std::size_t kMaxDesignIrJsonDepth = 512
 Deepest object/array nesting parse_design_ir_json accepts.
constexpr std::string_view kGpuTimingEnvVar = "PULP_GPU_TIMING"
 The environment variable a standalone GPU window reads to enable GPU render timing.
constexpr std::size_t kDefaultJsMemoryLimitBytes = std::size_t{512} * 1024 * 1024
constexpr std::uint32_t kEditorHostClearRgb = 0x1E1E2E
 The background a plug-in editor host paints when the plug-in has not declared its own (Processor::editor_background()): RGB 30,30,46, which is also Theme::dark()'s bg.primary.
constexpr std::uint8_t kEditorHostClearR = (kEditorHostClearRgb >> 16) & 0xff
constexpr std::uint8_t kEditorHostClearG = (kEditorHostClearRgb >> 8) & 0xff
constexpr std::uint8_t kEditorHostClearB = kEditorHostClearRgb & 0xff
constexpr float kDefaultSimilarityThreshold = 0.85f
 The default similarity a render must reach to count as matching its reference, as a fraction (0.0-1.0).
constexpr const char * kEllipsis = "\xe2\x80\xa6"
 UTF-8 horizontal ellipsis character (U+2026, "…").
constexpr const char * kTracingBadgeLabel = "\u25C9 TRACING"
constexpr float GALLERY_WIDTH = 940.0f
constexpr float kInspectorMeterFloorDb = -60.0f
 dBFS floor used by the inspector's meter fill (and the empty-bar anchor).
constexpr int kTypingFrame = 0
constexpr int kPianoFrame = 1

Detailed Description

Hover-cursor tracking for platform window hosts.

StepGridView renders and edits one pattern of a step-sequencer grid backed by a SequencerStateChannel (the audio-safe non-param state transport).

View::simulate_context_click lives in view.hpp beside the rest of the simulate_* family, and is implemented here so the one policy stays in one place.

Platform cursor APIs are EDGE-driven: AppKit (and Win32's WM_SETCURSOR, and X11's window cursor attribute) re-ask which cursor to show when the pointer MOVES or a button changes. None of them re-ask when the content under a stationary pointer changes. So a layout pass that slides a different widget under a still pointer — a panel opening, a list reflowing, a JS style mutation — leaves the previous cursor on screen until the user jiggles the mouse or clicks.

HoverCursorTracker closes that gap: the host records where the pointer is, and re-resolves the style from its FRAME path rather than only from its mouse-event handlers. Change detection lives here so the host may poll every frame and only touch the platform when the answer actually differs.

It exists because simulate_click(pt, {.button = MouseButton::right}) does NOT open a context menu, and nothing about its name says so: that overload delivers a right-button press through the ordinary mouse channels, while the context-menu channel is a separate dispatch the hosts perform from rightMouseDown: and its siblings. A test author who reaches for the button field, sees no menu, and concludes the feature is broken has been misled by the API rather than by the code.

It is the blessed base for sequencer-style grids whose per-step data fits the channel's cell model. (Free-form procedural controls — arbitrary multi-value gestures on a painted canvas — are a different surface: DesignFrameView::Kind::custom.)

Structure (so the view generalizes over SequencerConfig without templating the expensive paint/geometry/interaction code):

  • StepGridViewBase — NON-template. Owns paint, geometry, hit-testing, the pump() orchestration, the flat visual cache, dirty accounting, playhead state, drag state, and the FrameClock probe. Config-independent.
  • StepGridViewT<Config, CellPolicy> — thin templated shim. Owns the typed channel pointer + typed render copy, and implements the handful of hooks that touch Config-typed state (apply an echo, resync, project a visual/ playhead, submit an edit). CellPolicy maps the cell type to a visual AND to the edit a click applies.

Contract with the channel: the engine owns authoritative state; this view NEVER mutates its render copy optimistically — a mouse edit only SUBMITS a command, and the render copy advances only when the engine's applied echo arrives (so the UI can never drift from engine-normalized state, randomize results, or rejected edits). Stale echoes are filtered (by engine_sequence) BEFORE they touch the typed render copy. Exactly one StepGridView* may bind a given channel (the applied-echo FIFO is single-consumer); debug builds assert on a second binding via the channel's consumer-claim token.

Typedef Documentation

◆ AffineTransform

The 2D affine transform value type.

Defined in pulp::canvas — which is the layer BELOW this one (core/view links core/canvas, not the reverse) and where Path needs it — and re-exported here so view code can spell it pulp::view::AffineTransform. One type, two names; never two types.

◆ AnnouncementSink

Initial value:
std::function<void(std::string_view text, AnnouncementPriority)>
@ text
Plain text (default color).
Definition code_editor_tokenizer.hpp:37
AnnouncementPriority
Politeness level for a live-region announcement.
Definition accessibility.hpp:225

Install a platform-specific announcement sink when a live-region backend is available.

Pass nullptr to detach (the default logger is restored). Not thread-safe — UI thread only.

◆ ClaudeClassNameRules

using pulp::view::ClaudeClassNameRules = std::map<std::string, std::map<std::string, std::string>>

◆ Color

◆ CommandID

typedef std::uint32_t pulp::view::CommandID = uint32_t

A unique command identifier.

Opaque 32-bit command identifier.

Apps define their own enum-style constants (e.g. constexpr CommandID kFileOpen = 0x1001). Zero is reserved for "no command".

◆ ContinuousFramePredicate

using pulp::view::ContinuousFramePredicate = bool (*)(const View*)

◆ CssColorParser

using pulp::view::CssColorParser = std::function<canvas::Color(const std::string&)>

Color parser callback: maps a single CSS color token (hex / rgb() / rgba()) to a canvas::Color.

When omitted, apply_css_background_gradient() uses a built-in parser covering #RGB / #RRGGBB / #RRGGBBAA, rgb(), rgba(), hsl(), hsla(), oklab(), oklch(), and transparent. The JS WidgetBridge passes its own richer parser so named colors continue to resolve there.

◆ DataDisplayFactory

using pulp::view::DataDisplayFactory = std::unique_ptr<View> (*)()

◆ DesignControlFactory

Initial value:
std::function<std::unique_ptr<View>(const DesignControlContext&)>
Definition design_frame_view.hpp:196

◆ EasingFunction

using pulp::view::EasingFunction = float(*)(float)

◆ FileDragBackend

using pulp::view::FileDragBackend = std::function<bool(const FileDragRequest&)>

◆ HostClock

using pulp::view::HostClock = std::chrono::steady_clock

◆ HSL

◆ ImageDecodeFn

using pulp::view::ImageDecodeFn = std::function<std::optional<DecodedImage>(const std::string& uri)>

Pluggable decode callback.

Returns nullopt on error. Separates the cache from the Skia code path so unit tests drive it with a fake decoder.

◆ ImageReleaseFn

using pulp::view::ImageReleaseFn = std::function<void(DecodedImage&)>

Release the platform handle when an entry is evicted.

Cache invokes this on LRU trim + clear(). May be called from any thread.

◆ LegacyImportBinder

Initial value:
Definition design_import.hpp:242
Definition view.hpp:73
A level display's binding.
Definition design_import.hpp:200

◆ LogCallback

using pulp::view::LogCallback = std::function<void(std::string_view level, std::string_view message)>

◆ MessageHandler

using pulp::view::MessageHandler = std::function<void(const WindowMessage&)>

◆ ModDestinationId

using pulp::view::ModDestinationId = uint32_t

◆ ModSourceId

using pulp::view::ModSourceId = uint32_t

◆ ModuleCompletionHandler

using pulp::view::ModuleCompletionHandler = std::function<void(const std::string& error, const choc::value::Value& result)>

◆ ModuleResolver

using pulp::view::ModuleResolver = std::function<std::optional<std::string>(std::string_view path)>

◆ NativeFunction

using pulp::view::NativeFunction = std::function<choc::value::Value(const choc::value::Value* args, size_t num_args)>

◆ NativePromiseFunction

◆ NativeViewHandle

typedef void * pulp::view::NativeViewHandle = void*

◆ PopupMenu

Design-system alias.

The Ink & Signal Figma library names this primitive "PopupMenu"; the Pulp framework class is ContextMenu. The alias lets design-system code use the Figma name without a breaking rename. See docs/reference/design-system-naming.md for the full Figma↔SDK name map. (No class PopupMenu exists in pulp::view, so this is collision-free.)

◆ ReloadCallback

using pulp::view::ReloadCallback = std::function<void(const std::string& code)>

◆ ScreenshotProvider

Initial value:
std::function<std::vector<uint8_t>(
View& root,
uint32_t width,
uint32_t height,
float scale,
ScreenshotBackend
Definition screenshot.hpp:12
@ scale
Definition css_animation.hpp:126
@ height
Definition css_animation.hpp:128
@ width
Definition css_animation.hpp:127

◆ ScriptedUiPrewarmRunner

prewarm_scripted_ui(), reachable without naming it.

The script runtime installs it when its session code is linked into the binary (any binary that constructs a ScriptedUiSession); until then it is null. Editor glue that is linked into every plug-in calls through this slot, so a plug-in whose editor never runs a script does not link the runtime just to schedule a prewarm it can never use.

◆ ScriptInspectorPortFactory

Builds the port every ScriptedUiSession constructed afterwards installs.

◆ Sidebar

Design-system alias.

The Ink & Signal Figma library names this primitive "Sidebar"; the Pulp framework class predates that library and is called SidePanel. The alias lets design-system code use the Figma name without a breaking rename. See docs/reference/design-system-naming.md for the full Figma↔SDK name map. (No class Sidebar exists in pulp::view, so this is collision-free.)

◆ StepGridView

◆ Table

Design-system alias.

The Ink & Signal Figma library names this primitive "Table"; the Pulp framework widget is TableListBox. The alias lets design-system code use the Figma name without a breaking rename. See docs/reference/design-system-naming.md for the full Figma↔SDK name map. (No class Table exists in pulp::view — note TableModel/TableColumn here are the canonical pair; the unrelated data-only structs of the same name in table_model.hpp must not be co-included with this header.)

◆ ValueChannelAccess

◆ ValueChannelContinuousPayload

◆ ValueChannelVisitor

Runs a value-channel operation while the hosting processor guarantees that the exposed set and all of its sources remain alive.

Callers must not retain either the set or a source obtained from it after the visitor returns.

◆ WindowId

using pulp::view::WindowId = uint32_t

Enumeration Type Documentation

◆ AccessToggleState

enum class pulp::view::AccessToggleState
strong

Tri-state check/press state, resolved from the ARIA slots a View carries (aria-checked first, then aria-pressed — a checkbox/switch state is more load-bearing than a toggle-button pressed state).

Enumerator
unset 
off 
on 
mixed 

◆ AlertIcon

enum class pulp::view::AlertIcon
strong
Enumerator
none 
info 
warning 
error 
question 

◆ AnchorStrategy

enum class pulp::view::AnchorStrategy
strong

Strategy for computing stable_anchor_id values. See header comment.

Enumerator
content_hash 
path 
adapter 

◆ AnimatableProperty

enum class pulp::view::AnimatableProperty
strong

Property whose values can be tweened.

The set is closed; dispatchers map these enum values onto property-specific interpolation and setters.

Enumerator
opacity 
background_color 
color 
border_color 
translate_x 
translate_y 
rotate_deg 
scale 
width 
height 
margin_top 
margin_right 
margin_bottom 
margin_left 
padding_top 
padding_right 
padding_bottom 
padding_left 
top 
right 
bottom 
left 
none 

◆ AnnouncementPriority

Politeness level for a live-region announcement.

Mirrors the WAI-ARIA aria-live values: polite announcements wait for the current reader utterance to finish; assertive announcements interrupt.

Enumerator
Polite 
Assertive 

◆ Appearance

enum class pulp::view::Appearance
strong

System appearance mode.

Enumerator
light 
dark 

◆ AppearanceDefectKind

Visual-appearance defect detection over a laid-out View tree.

These detectors assert PAINTED GEOMETRY, not the values that fed it. A parameter arriving at the runtime, a node existing in a snapshot, or a widget reporting a size are all proxies: each can be true while the user looks at two labels printed on top of each other. What is asserted here is where the glyphs land.

The report always carries a coverage statistic. A run that evaluated a fraction of the text on screen cannot distinguish "no defects" from "did not look", so AppearanceReport::clean() is only meaningful together with coverage.trustworthy().

Enumerator
text_overlap 

Two pieces of painted text share pixels.

painted_wider_than_box 

A run's glyphs are wider than the box that is supposed to contain them, so the tail is clipped or truncated.

canvas_text_overlap 

Two canvas-command text runs (CanvasDrawCmd::fill_text / stroke_text) share pixels.

These are drawn by a command stream, not by a layout node, so no box-based check can see them.

container_paints_no_text 

A visible clipping container holds text and shows none of it — the viewer sees an empty panel.

The signature is exact: N text runs in the subtree, all N clipped away, N >= 1. A scroll frame showing some of its rows measures at least one and is not this; a frame scrolled entirely past its text measures none and is, which is honest, because that frame is blank to look at. The container's own box may be collapsed to zero area, which is the same defect wearing a different geometry — a container closed on purpose is marked invisible instead, and the walk records that as an invisible skip without ever opening a clip scope. This is the one defect the collision detectors are structurally unable to see: text that never lands anywhere produces no pair to compare and no box to outgrow, so the report reads clean.

◆ ArrowDirection

enum class pulp::view::ArrowDirection
strong
Enumerator
up 
down 
left 
right 

◆ AudioInspectorMode

enum class pulp::view::AudioInspectorMode
strong
Enumerator
kSignal 
kScope 

◆ AudioWidgetType

enum class pulp::view::AudioWidgetType
strong

Audio widget type detected from naming conventions or annotations.

Enumerator
none 
knob 
fader 
meter 
xy_pad 
waveform 
spectrum 
toggle 
selector 
stepper 

◆ BindingOutcome

enum class pulp::view::BindingOutcome : std::uint8_t
strong

The outcome of one bindWidgetToParam / bindMeter call.

Enumerator
ok 

bound; the widget exists and accepts this target

deferred_widget_missing 

bound; the view does not exist YET, which is legal

replaced_prior_binding 

bound, displacing an earlier binding for this widget

empty_widget_id 

─── below here nothing was bound ───

empty_param_name 
null_widget 

the id maps to a null view

incompatible_widget 

the widget cannot accept this target (e.g. a meter on a Knob)

unknown_param 

the store declares no parameter with that name

unknown_value_channel 

A value:<name> source named no channel the processor declares — or the processor declares none at all, e.g.

a UI bound against the wrong build.

undeclared_uniform 

shader does not declare the requested uniform

◆ BindingTarget

enum class pulp::view::BindingTarget : std::uint8_t
strong

What a binding drives on its widget.

Enumerator
value 

the widget's primary value (Knob, Fader, RangeSlider, Toggle, ProgressBar)

meter 

a Meter's level

scope 

a block of samples for a SpectrumView / WaveformView

uniform 

a custom shader uniform

◆ BorderEdge

enum class pulp::view::BorderEdge
strong

Which edge of the box a border side is on.

Enumerator
top 
right 
bottom 
left 

◆ BoxSizing

enum class pulp::view::BoxSizing
strong

CSS box-sizing.

Yoga 3.x has YGNodeStyleSetBoxSizing which natively honors the spec: with border-box, the declared width/height includes padding + border (the inner content area shrinks); with content-box (CSS default), padding + border are outside the declared dimensions. Many imports only lay out correctly under border-box because web designs commonly reset * { box-sizing: border-box }.

Enumerator
content_box 
border_box 

◆ CalloutSide

enum class pulp::view::CalloutSide
strong

Which side of the anchor the callout BODY sits on.

The arrow points from the body toward the anchor, so above = body above the anchor with the arrow on the body's bottom edge pointing down at it.

Enumerator
above 
below 
left_of 
right_of 

◆ CaretStyle

enum class pulp::view::CaretStyle
strong

Caret shape. All three anchor at the same caret x.

Enumerator
ibeam 

Vertical rule spanning the glyph cell. The default.

underline 

Rule at the underline position, one glyph cell wide.

block 

Filled glyph cell; the covered glyph is drawn in the bg color.

◆ ChartProfile

enum class pulp::view::ChartProfile
strong

Cross-section of a tube or light pipe across its band.

Enumerator
round 

a cylinder: the normal turns smoothly from edge to edge

flat 

a flat face with a narrow rounded rim at each edge

chamfer 

a flat centre with 45 degree chamfers on the outer 40%

◆ CodeGenMode

enum class pulp::view::CodeGenMode
strong

Code generation output mode.

Enumerator
web_compat 
bridge_native_js 
native 

◆ CodeLanguage

enum class pulp::view::CodeLanguage
strong

Language mode for syntax highlighting.

Enumerator
PlainText 
Cpp 
JavaScript 
Lua 
Python 
JSON 
XML 
GLSL 
Faust 
JSFX 

◆ ContrastLevel

enum class pulp::view::ContrastLevel
strong

WCAG AA compliance levels.

Enumerator
aa_normal 
aa_large 
aaa_normal 
aaa_large 

◆ DefaultShortcutPattern

Which platform-convention surface a default binding maps to.

Used by detect_default_shortcuts to label matches and by generate_pulp_js to skip Pulp-framework-provided rows that don't exist on the target.

Enumerator
settings 
help 
cheatsheet 
new_file 
open_file 
save_file 
find 

◆ DesignKeyDiagnosticReason

Enumerator
missing 
duplicate 
mixed 

◆ DesignMdSeverity

enum class pulp::view::DesignMdSeverity
strong
Enumerator
info 
warning 
error 

◆ DesignSlotKind

enum class pulp::view::DesignSlotKind
strong
Enumerator
static_visual 
dynamic_scalar 
dynamic_vector 
dynamic_meter 
dynamic_text 
dynamic_action 

◆ DesignSource

enum class pulp::view::DesignSource
strong
Enumerator
figma 
stitch 
v0 
pencil 
claude 
designmd 
jsx 
figma_plugin 
html 
preconverted_svg 

◆ DesignUpdateKind

enum class pulp::view::DesignUpdateKind
strong
Enumerator
retained 
moved 
inserted 
removed 

◆ DialogResult

enum class pulp::view::DialogResult
strong
Enumerator
ok 
cancel 
closed 

User dismissed the dialog without explicitly choosing.

◆ DimensionUnit

enum class pulp::view::DimensionUnit
strong
Enumerator
px 

Absolute pixels.

percent 

Percentage of parent dimension.

vw 

Percentage of viewport width.

vh 

Percentage of viewport height.

vmin 

Percentage of min(viewport width, height).

vmax 

Percentage of max(viewport width, height).

auto_ 

Auto-sized (let layout decide).

◆ FidelityElement

enum class pulp::view::FidelityElement
strong

What codegen branch produced the emitted geometry — lets a check apply only where it is meaningful without re-deriving the element kind.

Enumerator
image 
container 
widget 
text 

◆ FlexAlign

enum class pulp::view::FlexAlign
strong
Enumerator
start 
center 
end 
stretch 
auto_ 
baseline 

◆ FlexDirection

enum class pulp::view::FlexDirection
strong
Enumerator
row 
column 
row_reverse 
column_reverse 

◆ FlexJustify

enum class pulp::view::FlexJustify
strong

Justify content modes (main axis space distribution).

Enumerator
start 

Pack items to start (default).

center 

Center items.

end_ 

Pack items to end.

space_between 

Equal space between items, no space at edges.

space_around 

Equal space around each item.

space_evenly 

Equal space between items AND at edges.

◆ FlexOverflow

enum class pulp::view::FlexOverflow
strong

Overflow behavior.

Enumerator
visible 

Content renders beyond bounds (default for views).

hidden 

Content clipped to bounds.

scroll 

Content clipped, scrollbar shown when needed.

auto_ 

Like scroll but scrollbar only when content overflows.

◆ FlexWrap

enum class pulp::view::FlexWrap
strong

Flex-wrap tri-state.

Yoga has YGWrapNoWrap / YGWrapWrap / YGWrapWrapReverse natively, so flex-wrap: wrap-reverse is distinct from plain wrap.

Enumerator
no_wrap 
wrap 
wrap_reverse 

◆ GesturePhase

enum class pulp::view::GesturePhase : uint8_t
strong
Enumerator
began 
changed 
ended 
cancelled 

◆ GestureState

enum class pulp::view::GestureState
strong
Enumerator
possible 
began 
changed 
ended 
cancelled 
failed 

◆ ImportDiagnosticKind

Enumerator
unknown 
unsupported_property 
unsupported_node 

A whole node family the producer could not represent — skipped (SLICE, FigJam/Slides families) or emitted as a diagnosed generic fallback (SLOT placeholder, unrecognized new node types).

unresolved_asset 
snapshot_semantics_warning 
legacy_field_shortcut 
capture_partial 
fallback_used 

◆ ImportDiagnosticSeverity

Enumerator
info 
warning 
error 

◆ InteractiveElementKind

Enumerator
knob 
fader 
toggle 
dropdown 
text_field 
tab_group 
stepper 
swap 
action 
xy_pad 
value_label 
custom 

◆ IRConfidence

enum class pulp::view::IRConfidence
strong

Confidence the adapter has that a node was lowered correctly.

Maps to the TS Confidence enum (PASS | DIVERGE | NOT_IMPL). Drives the pulp ui validate exit code in CI.

Enumerator
pass 
diverge 
not_impl 

◆ JsEngineType

enum class pulp::view::JsEngineType
strong
Enumerator
quickjs 
jsc 
v8 

◆ JsxLockStatus

enum class pulp::view::JsxLockStatus
strong

Outcome status for a single JSX/TSX lock attempt.

Enumerator
patched 

The prop existed and its literal value was rewritten.

already_current 

The element and prop were found and the prop already held exactly value — source unchanged (idempotent re-lock).

anchor_not_found 

No element carried data-pulp-anchor="<anchor_id>".

Source returned unchanged. Graceful failure — leave the tweak in sidecar.

anchor_ambiguous 

More than one element carried the same data-pulp-anchor.

The engine refuses to guess. Source unchanged.

unsupported_property 

The property_path does not map onto a lockable JSX prop / style key.

Source unchanged.

too_dynamic 

The element was found but the targeted prop is "too dynamic to lock" — its value is a spread, a computed key, a non-literal expression ({gap * 2}, {theme.fg}), or otherwise not a plain literal the engine can safely rewrite.

Source unchanged. The caller should keep the tweak in the sidecar and surface the message verbatim.

◆ KeyCode

enum class pulp::view::KeyCode : int
strong
Enumerator
unknown 
a 
b 
c 
d 
e 
f 
g 
h 
i 
j 
k 
l 
m 
n 
o 
p 
q 
r 
s 
t 
u 
v 
w 
x 
y 
z 
num0 
num1 
num2 
num3 
num4 
num5 
num6 
num7 
num8 
num9 
semicolon 
apostrophe 
left 
right 
up 
down 
home 
end_ 
page_up 
page_down 
backspace 
delete_ 
tab 
enter 
escape 
space 
f1 
f2 
f3 
f4 
f5 
f6 
f7 
f8 
f9 
f10 
f11 
f12 

◆ LabelAlign

enum class pulp::view::LabelAlign
strong

Text alignment for Label.

auto_ resolves at paint time to left (LTR) or right (RTL); pulp doesn't model RTL yet so auto_ currently degrades to left. justify wires through to the canvas TextAlign::justify enum value; SkParagraph kJustify rendering lands in a follow-up — existing canvas backends treat it as left until then. Both values are claimed in the rn/css catalog (Figma exports + Tailwind classes emit auto and justify routinely). match_parent resolves at paint time by walking the View parent chain (via inheritable_text_align()) and adopting the first ancestor's resolved value. If no ancestor set one, falls back to left (the CSS spec default for text-align). Symmetric with auto_ in that the resolution is paint-time, not setter-time — matches CSS match-parent semantics which inherit from the parent's computed (not specified) value.

Enumerator
left 
center 
right 
auto_ 
justify 
match_parent 

◆ LayoutAlign

enum class pulp::view::LayoutAlign
strong

Alignment values for flex containers.

Enumerator
flex_start 
flex_end 
center 
stretch 
space_between 
space_around 

◆ LayoutDirection

enum class pulp::view::LayoutDirection
strong

Layout direction for flex containers.

Enumerator
row 
column 

◆ LayoutMode

enum class pulp::view::LayoutMode
strong
Enumerator
flex 
grid 

◆ LockStatus

enum class pulp::view::LockStatus
strong

Outcome status for a single lock attempt.

Enumerator
rewritten 

The property line existed and its value was rewritten.

inserted 

No line for the property existed; a new el.style.

<prop> line was inserted into the element block.

already_current 

The element block was found and the property already held exactly value — the source text is unchanged (idempotent re-lock).

anchor_not_found 

No // @pulp-anchor <id> comment matched anchor_id.

The source text is returned unchanged. This is a graceful failure — the caller should leave the tweak in the sidecar.

unsupported_property 

The property_path could not be mapped onto a generated style property (unsupported path).

Source returned unchanged.

◆ ModCurve

enum class pulp::view::ModCurve : uint8_t
strong
Enumerator
Linear 
Exponential 
Logarithmic 
Quadratic 
SCurve 

◆ Modifier

enum pulp::view::Modifier : uint16_t
Enumerator
kModNone 
kModShift 
kModCtrl 

Control key (Ctrl on Windows/Linux).

kModAlt 

Alt / Option.

kModMeta 

Windows key / Command key.

kModCmd 

Command (macOS) — alias for platform primary modifier.

◆ MotionPolicy

enum class pulp::view::MotionPolicy
strong

Reduced-motion policy.

Animation primitives honor this on construction or reset().

Enumerator
Full 

Animate normally.

Reduced 

Animate, but scale duration by duration_scale.

Off 

Skip animation; jump to the target value.

◆ MouseButton

enum class pulp::view::MouseButton : uint8_t
strong

Mouse button identifiers.

Enumerator
none 
left 
right 
middle 

◆ MousePhase

enum class pulp::view::MousePhase : uint8_t
strong

Explicit press/drag/release phase for a pointer gesture.

MouseEvent::is_down alone is ambiguous for a multi-event gesture: the historical headless convention is press=is_down=true, drag-tick= is_down=false, release=is_down=true (is_down means "the button state CHANGED"), while a real platform host naturally delivers press=down, drag=down, release=up (is_down means "the button is currently held"). A consumer that infers press/drag/release from is_down alone therefore behaves OPPOSITELY between the two callers: a live mac drag ended its move/resize gesture on the FIRST drag tick and fell through to re-selection. phase lets a host state the gesture phase unambiguously. automatic (the default) preserves the legacy is_down inference for callers that don't set it.

Enumerator
automatic 

Infer from is_down (legacy / headless default).

press 

Initial button-down that begins a gesture.

drag 

Pointer moved with the button held (a drag tick).

release 

Button-up that ends a gesture.

hover 

Pointer moved with no button held.

◆ NativeCanvasBackendRequirement

Enumerator
any 
skia_dawn_allow_recording 

Production paints require Graphite-on-Dawn; RecordingCanvas remains accepted so deterministic command fixtures can exercise the painter.

skia_dawn 

◆ NodeRenderMode

enum class pulp::view::NodeRenderMode
strong

A single node in the normalized design IR.

Enumerator
normal 
faithful_svg 
faithful_capture 

◆ Notify

enum class pulp::view::Notify
strong

Whether a value write notifies listeners, and when.

Enumerator
none 

change the value silently

sync 

fire listeners before returning

async 

fire listeners at the next flush_async_notifications()

◆ OverlayEscapeResult

What an Escape keypress dismissed, in the order the policy tries them.

Enumerator
none 

Nothing was open under root.

The caller must handle Escape itself (blur a text field, hand the key back to the DAW, …).

modal 

A ModalOverlay in the tree consumed Escape through its own handler.

combo_popup 

An open native ComboBox dropdown was closed.

overlay 

The generalized overlay slot was dismissed, firing on_overlay_dismissed so React state can flip setOpen(false).

◆ OverlayPressRouting

What consulting the generalized overlay slot decided about a press.

Enumerator
no_overlay 

Nothing claimed the root's overlay slot; the caller proceeds normally.

routed 

The press landed inside the overlay and resolved to a view in its subtree.

Deliver to OverlayPressTarget::target and stop; the regular tree hit_test must not run, or an absolutely-positioned popover child loses the click to whatever sibling occupies that pixel.

not_hittable 

The press landed inside the overlay's rect, but the overlay's own visible / enabled / hit-testable / pointer-events guards rejected it.

The overlay stays claimed (it is still mounted, just not interactive here) and the caller falls through to the regular hit test.

dismissed 

The press landed outside the overlay, so it was dismissed.

The caller still falls through to the regular hit test, matching WebView's outside-click closes-and-clicks-through behavior.

◆ PluginKeyDisposition

enum class pulp::view::PluginKeyDisposition : std::uint8_t
strong

What an embedded plugin editor should do with a key it has been offered.

Enumerator
forward_to_host 

Nothing under the root claimed the key.

The adapter must report "not handled" to the host so transport, Musical Typing, and the host's accelerator table keep working while the editor is open.

consumed 

A view or the root's global hook consumed the key outright.

The host must not also see it.

insert_as_text 

A focused text field did not treat the key as a command, and the key is a plain printable candidate.

The platform seam must run its own text-insertion path (AppKit interpretKeyEvents:, or a direct on_text_input) and then report the key as consumed. Distinct from consumed because only the platform owns dead keys and IME composition — core/view cannot synthesize that text itself.

◆ PointerType

enum class pulp::view::PointerType : uint8_t
strong

Pointer device type (W3C PointerEvent.pointerType).

Enumerator
mouse 

Mouse cursor (default).

touch 

Direct touch (finger).

pen 

Stylus / Apple Pencil.

◆ PressChannel

enum class pulp::view::PressChannel
strong

Which handler channel a press looks for, and therefore which resolution rule applies.

The two are genuinely different, and conflating them is how a right-click audit silently passes.

Enumerator
click 

Left button.

View::on_click, resolved with the DOM-style bubble walk View::simulate_click and every platform host perform: the deepest hit view, then up the parent chain to the nearest ancestor carrying one.

context_menu 

Right button.

View::on_context_menu, resolved with the same bubble dispatch_context_menu performs: nearest handler from the hit view up to the root, first listener wins. A decorative child on top of a wired wrapper is therefore forgiven — correctly, since the real dispatch forgives it too. What is NOT forgiven is a press that leaves the control's subtree entirely, because the bubble then walks somebody else's ancestors.

◆ ReloadCapability

enum class pulp::view::ReloadCapability : std::uint8_t
strong

A capability gates one effectful bridge-API group.

Ungranted → the group's JS functions are absent. Ordering is stable (persisted/signed by name, never index).

Enumerator
Exec 

shell exec/execAsync — ALSO compiled out unless the PULP_DEV_BRIDGE_EXEC CMake option is ON (release/SDK: OFF)

Clipboard 

read/write the system clipboard

Filesystem 

read arbitrary file paths (asset file loads, native dialogs)

Storage 

persistent key/value + preset temp files

Ai 

AI-CLI bridge.

RuntimeImport 

evaluate a runtime-imported JS bundle (dynamic code load)

Network 

outbound network (reserved; used by remote-UX-push, not the bridge today)

◆ RuntimeViewKind

enum class pulp::view::RuntimeViewKind : std::uint8_t
strong

Internal concrete-type hint for the two whole-tree hot paths.

Stored in View's padding after AccessRole, so it adds neither a heap allocation nor a vtable slot. Only the named constructors set a non-generic value; readers may then use a checked static_cast without asking RTTI the same question for every node at every vsync.

Enumerator
generic 
knob 
fader 
toggle 
scroll 
eq_curve 
design_frame 

◆ ScreenshotBackend

enum class pulp::view::ScreenshotBackend
strong
Enumerator
default_backend 

Platform default raster (CoreGraphics on Apple).

coregraphics 

Apple CoreGraphics raster.

skia 

CPU Skia raster (SkSurfaces::Raster).

gpu 

Offscreen GPU (Dawn + Skia via pulp::render::HeadlessSurface).

The ONLY backend that renders requires_gpu_host() views correctly.

auto_select 

Smart dispatch (see capture_view): native-overlay → refuse; requires_gpu_host → gpu; else → raster.

◆ SizingMode

enum class pulp::view::SizingMode
strong

Sizing mode for an IR node dimension.

Enumerator
fixed 
hug 
fill 

◆ TableSortOrder

enum class pulp::view::TableSortOrder : uint8_t
strong
Enumerator
None 
Ascending 
Descending 

◆ TargetPlatform

enum class pulp::view::TargetPlatform
strong

Convert accepted candidates from detect_default_shortcuts into the DetectedShortcut form that V2 codegen expects.

The platform chord is selected based on target_platform: macOS gets the Cmd / Cmd+? chords, Win/Linux get Ctrl / F1. pattern is namespaced with a "default:" prefix so manifest readers can tell auto-bound from extracted entries at a glance.

Enumerator
macos 
win_linux 

◆ TextAccessibilityRole

enum class pulp::view::TextAccessibilityRole : std::uint8_t
strong

Coarse semantic role for a piece of accessible text.

The platform backend maps this to its native role (NSAccessibilityStaticTextRole, UIA_TextControlTypeId, AccessKit Role::StaticText, etc.).

Enumerator
Label 
Button 
TextEditor 
Heading 
Other 

◆ TextRunSkip

enum class pulp::view::TextRunSkip
strong

Why a piece of text was not evaluated.

Every skip is counted; a detector that silently drops what it cannot measure reports absence it never checked.

Enumerator
none 
invisible 

the node or an ancestor is not visible

empty_text 

nothing to paint

clipped_away 

ink falls entirely outside its effective clip

unmeasurable 

the shaper returned no extents for non-empty text

degenerate_box 

the layout box has no area to paint into

◆ ThemeMode

enum class pulp::view::ThemeMode
strong

User-facing theme preference.

system follows the OS appearance live; light/dark pin it regardless of the OS. A developer who doesn't want to offer the choice simply leaves the manager in one mode and never exposes a control — there is no requirement to support all three.

Enumerator
system 
light 
dark 

◆ TokenClass

enum class pulp::view::TokenClass
strong

Token classification for tokenize_line.

The colors the editor renders for each class are theme-driven; the tokenizer only labels the span.

Enumerator
text 

Plain text (default color).

keyword 

Language keyword (e.g. if, return, class).

type 

Built-in / common type name (e.g. int, Number).

identifier 

Identifier — the tokenizer rarely emits this on its own; callers can treat unmatched text as identifier.

number 

Numeric literal (int / float / hex / bin).

string 

String / character literal (single or double quote).

comment 

Single-line comment (//, #, --) or the start of a block comment.

preprocessor 

Preprocessor / directive line (e.g. #include).

punctuation 

Operators and structural punctuation.

heading 

Markdown heading (#, ##, …).

link 

Markdown / hyperlink span.

◆ TokenGroup

enum class pulp::view::TokenGroup
strong

The four canonical DESIGN.md frontmatter token groups this engine can lock into.

components is intentionally excluded — a component entry is a reference bundle, not a primitive token value, and locking one would mean rewriting a {group.name} reference, which this engine does not attempt.

Enumerator
colors 

colors: map — hex string values.

spacing 

spacing: map — dimension values.

rounded 

rounded: map — corner-radius dimension values.

typography 

typography: map — nested per-level field maps.

◆ Tone

enum class pulp::view::Tone
strong
Enumerator
neutral 
info 
success 
warning 
danger 

◆ ToolbarItemType

enum class pulp::view::ToolbarItemType
strong

Toolbar item types.

Enumerator
Button 
Toggle 
Separator 
Spacer 
Custom 

◆ UaColorScheme

enum class pulp::view::UaColorScheme
strong

The CSS color-scheme a chromium_refresh palette resolves against.

Enumerator
light 
dark 

◆ UaControlState

enum class pulp::view::UaControlState
strong

Interaction state a chromium_refresh palette is keyed on.

Enumerator
normal 
hovered 
pressed 
disabled 

◆ UaSkin

enum class pulp::view::UaSkin
strong

Which skin a form-control widget paints with.

platform is Pulp's own token-driven look; chromium_refresh is Chromium's form-control theme.

Enumerator
platform 
chromium_refresh 

◆ ValueChannelShape

The shape of a channel's payload.

◆ VisualizationBacklogPolicy

How poll() treats captured audio it has not analyzed yet.

◆ WaveformEditorOperationKind

Enumerator
none 
create_selection 
extend_selection 
drag_selection_start 
drag_selection_end 
move_playhead 

◆ WaveformGpuRenderActionKind

enum class pulp::view::WaveformGpuRenderActionKind : std::uint8_t
strong
Enumerator
NoOpInvalidPlan 
NoOpBackendUnavailable 
NoOpCpuFallbackUnavailable 
NoOpStagingTooSmall 
NoOpVertexFillFailed 
CpuFallbackReady 
UploadStaticLayerReady 
DrawCachedStaticLayer 
PlayheadOnlyRedraw 

◆ WaveformHandleKind

enum class pulp::view::WaveformHandleKind
strong
Enumerator
none 
selection_start 
selection_end 
trim_start 
trim_end 
fade_in 
fade_out 
loop_start 
loop_end 
slice_marker 
playhead 

◆ WaveformHeadlessRenderStatus

enum class pulp::view::WaveformHeadlessRenderStatus : std::uint8_t
strong
Enumerator
NoOp 
CpuFallbackReady 
UploadedStaticLayer 
DrawCachedStaticLayer 
PlayheadOnlyRedraw 
MissingCachedResource 
ResourceAllocationFailed 
ResourceCommitRejected 

◆ WaveformSnapSource

enum class pulp::view::WaveformSnapSource
strong
Enumerator
none 
bounds 
candidate 
grid 

◆ WidgetPromotionSignal

Heuristic signals that a parsed frame is interactive enough to promote from a static frame to a button widget.

Enumerator
none 
onclick_attribute 
aria_role_button 
cursor_pointer 

◆ WidgetRenderStyle

enum class pulp::view::WidgetRenderStyle
strong

Rendering style for widgets.

standard = interactive widget (arcs, thumbs, fills). minimal = design-preview mode (simple shapes matching design tools). silver = skeuomorphic chrome body, radial-gradient highlight, indicator notch. Vector all the way — works on CPU raster + GPU Graphite. Used by the figma-import lane as a native-vector alternative to sprite-strip PNGs (no PNG bleed, crisp at any scale).

Enumerator
standard 
minimal 
silver 

◆ WindowType

enum class pulp::view::WindowType
strong
Enumerator
main 

Primary editor window.

palette 

Floating palette (stays on top, no taskbar entry).

inspector 

Resizable inspector panel.

popup 

Ephemeral popup/dropdown (auto-dismiss on focus loss).

dialog 

Modal or modeless dialog.

Function Documentation

◆ access_role_from_aria()

View::AccessRole pulp::view::access_role_from_aria ( std::string_view role)
inline

Map an ARIA role token to a Pulp AccessRole.

Unknown, empty, none and presentation map to AccessRole::none, which removes the view from the accessibility tree (ARIA presentation semantics and the "clear the role" path both want that).

Roles whose ARIA meaning is a generic container (region, navigation, form, group, dialog's non-modal cousins, ...) map to group. Roles Pulp has no widget for and no platform mapping for (tree, grid, toolbar, ...) also map to group rather than being dropped: the author said "expose this", and a generic container is a truthful superset. That is a documented approximation, not silent breakage.

◆ accessibility_backend_name()

std::string_view pulp::view::accessibility_backend_name ( )
noexcept

Returns the active accessibility backend identifier.

The default backend is "none"; per-platform overlays return "macos-ax", "windows-uia", or "linux-accesskit". Stable across calls for the lifetime of the process.

◆ accessibility_interfaces()

AccessibilityInterfaceSet pulp::view::accessibility_interfaces ( const View & v)

◆ accessibility_pump()

void pulp::view::accessibility_pump ( void * handle)

Service any pending accessibility IPC for this handle.

On Linux AT-SPI the registry / screen reader calls methods on the exported objects over D-Bus; those calls hang the assistive tech unless the host pumps periodically. A host with an event loop should call this each frame or on a short timer.

No-op on platforms whose accessibility runs callback-driven on the OS side (macOS / iOS NSAccessibility, Windows UIA, Android TalkBack) and on a null / sentinel handle. Cheap when no assistive tech is connected.

◆ accessibility_retain_until_retired() [1/2]

void pulp::view::accessibility_retain_until_retired ( View & root,
std::shared_ptr< void > owner )
noexcept

◆ accessibility_retain_until_retired() [2/2]

void pulp::view::accessibility_retain_until_retired ( void * handle,
std::shared_ptr< void > owner )
noexcept

◆ accessibility_text_content()

std::string pulp::view::accessibility_text_content ( const View & v)

The string content a text interface exposes: AccessibilityTextInterface's content, else the access_value slot, else "".

This is what AT-SPI's Text.GetText / Text.CharacterCount serve.

◆ accessibility_text_editable()

bool pulp::view::accessibility_text_editable ( const View & v)

True when the text content is user-editable (an editable AccessibilityTextInterface).

Drives AT-SPI's EDITABLE state and UIA's IsReadOnly.

◆ accessibility_toggle_state()

AccessToggleState pulp::view::accessibility_toggle_state ( const View & v)

The View's check/press state.

unset for everything that is not a checkbox / switch / toggle button.

◆ accessibility_toggle_state_string()

std::string pulp::view::accessibility_toggle_state_string ( const View & v)

The state as the word a reader announces: "checked" / "unchecked" / "mixed" (aria-checked) or "pressed" / "not pressed" / "mixed" (aria-pressed).

Empty when unset.

◆ accessibility_tree_changed() [1/2]

void pulp::view::accessibility_tree_changed ( View & root)

Rebuild every native provider currently attached to root.

This is the retirement barrier for a scripted tree: Windows disconnects and drains UIA fragments that borrow Views before the old realm is destroyed; Linux unregisters its cached AT-SPI nodes. Call on the root's owning UI thread.

◆ accessibility_tree_changed() [2/2]

void pulp::view::accessibility_tree_changed ( void * handle)

Request the provider to re-walk the View tree.

Call after large structural changes (tabs switched, panels added, etc.). Focus / value updates don't need this — those fire per-property events.

◆ accessibility_tree_retirement_ready() [1/2]

bool pulp::view::accessibility_tree_retirement_ready ( View & root)

◆ accessibility_tree_retirement_ready() [2/2]

bool pulp::view::accessibility_tree_retirement_ready ( void * handle)

◆ accessibility_tree_will_change() [1/2]

void pulp::view::accessibility_tree_will_change ( View & root)

◆ accessibility_tree_will_change() [2/2]

void pulp::view::accessibility_tree_will_change ( void * handle)

Make every cached native node inert before a caller starts destructively editing the View tree.

Pair with accessibility_tree_changed() after the new structure is installed. Must run on the provider root's owning UI thread.

◆ accessibility_value_string()

std::string pulp::view::accessibility_value_string ( const View & v)

What assistive tech reads as the element's VALUE, resolved from the one source that is actually present, in priority order:

  1. AccessibilityValueInterface → get_value_string() (slider, meter, progress bar — "-6.0 dB", "60%")
  2. AccessibilityTextInterface → get_text() (text field — the content the user typed)
  3. View::access_value() → the manually-set string (combo box's selected item, or any app-set value)
  4. The check/press state → "checked" / "unchecked" / "mixed" (a Checkbox / Toggle / ToggleButton has no other value; without this slot iOS and Android announce "button" with no state at all — only macOS special-cases it into a native @YES/@NO accessibilityValue)
  5. "" — nothing to read.

Every platform bridge that reads a VALUE resolves it through THIS function: macOS (state → native @YES/@NO first, then this), iOS, Android, Windows (IValueProvider::get_Value + UIA_ValueValuePropertyId) and Linux (org.a11y.atspi.Text, via accessibility_text_content()). macOS's -accessibilityValue used to read only slot 3, so a TextEditor holding "hello" returned nil and VoiceOver announced "text field" and then silence.

NOT covered by this function: Windows never announces a check/press state at all, because the UIA Toggle pattern needs an IToggleProvider that PulpFragmentProvider does not implement (see accessibility_win.cpp).

◆ accumulate_overflow_extent()

void pulp::view::accumulate_overflow_extent ( const View * v,
float parent_abs_x,
float parent_abs_y,
float & min_x,
float & min_y,
float & max_x,
float & max_y )

◆ accumulate_scroll_content_extent()

void pulp::view::accumulate_scroll_content_extent ( const View & parent,
float parent_x,
float parent_y,
float & right,
float & bottom,
bool & found )

◆ adjust_for_contrast()

std::optional< Color > pulp::view::adjust_for_contrast ( Color foreground,
Color background,
ContrastLevel level = ContrastLevel::aa_normal )

Given a background color and a desired foreground, adjust the foreground lightness until it meets the required contrast level.

Returns the adjusted color, or std::nullopt if no adjustment can achieve the target.

◆ adjust_lightness()

Color pulp::view::adjust_lightness ( Color c,
float delta )

Adjust lightness by a delta (clamped to [0,1]).

◆ advance_host_frame()

void pulp::view::advance_host_frame ( View * root,
FrameClock & clock,
float dt )

Step 2 of a host tick, run only when HostFrameTick::should_render: advance every dt-integrating consumer in the tree by the SAME dt — the render clock (and its subscribers), widget animations, and CSS animation timelines — and pump the gesture recognizers.

Null-safe on root.

Gesture recognizers are deliberately NOT dt-driven: advance_gesture_recognizers() takes an absolute monotonic timestamp (defaulted to its own steady_clock read) and compares it against the timestamps stamped on the input events themselves, so it already measures real time and must keep using ONE epoch with those events. Feeding it the host's presentation clock would mix epochs.

◆ advance_widget_animations()

void pulp::view::advance_widget_animations ( View * view,
float dt )

Advance the built-in widget animations and the CSS animation timeline for view and every descendant.

Shared by all hosts so the set of animated widget types cannot drift per platform. Called by advance_host_frame; public for hosts that drive widgets without a FrameClock.

◆ all_presets()

const std::vector< ThemePreset > & pulp::view::all_presets ( )

Get all built-in theme presets (37 tweakcn-sourced + "Ink & Signal", Pulp's flagship design language = 38 total).

◆ analyze_screenshot_content()

ScreenshotContentStats pulp::view::analyze_screenshot_content ( const std::vector< uint8_t > & png)

Decode a PNG and compute content statistics suitable for catching empty or stable single-color captures before any parity claim is accepted.

◆ animatable_property_from_css_name()

AnimatableProperty pulp::view::animatable_property_from_css_name ( const std::string & name)
inline

Map CSS property name to AnimatableProperty enum.

Returns AnimatableProperty::none for unrecognized names; the caller should preserve the original string in TransitionSpec::property_name for later round-trip.

◆ announce_accessibility()

void pulp::view::announce_accessibility ( std::string_view text,
AnnouncementPriority priority = AnnouncementPriority::Polite )

Request the installed accessibility announcement sink speak text.

When no sink is installed (or no screen reader is active), the call is logged at info level and otherwise a no-op — it is always safe to call, including from test harnesses.

The C++ API and sink plumbing are present. Built-in platform bridge sinks are still pending: macOS/iOS should install the native announcement notification path, Android should route through TalkBack TYPE_ANNOUNCEMENT, Windows through UiaRaiseNotificationEvent, and Linux through AT-SPI announcement events.

◆ apply_css_background_gradient()

bool pulp::view::apply_css_background_gradient ( View & v,
std::string_view css,
const CssColorParser & parse_color = {} )

Parse a CSS linear-gradient(...), radial-gradient(...), or conic-gradient(...) string and apply it to v's background via the View::set_background_gradient_* API.

Returns true iff a gradient was recognized and at least one color stop was applied.

This is the single shared CSS-gradient path. The JS WidgetBridge, the native design-import materializer (apply_visual_style), and baked C++ codegen all route through it so the three import lanes resolve gradients identically.

◆ apply_default_shortcuts()

std::vector< DetectedShortcut > pulp::view::apply_default_shortcuts ( const std::vector< DefaultShortcutCandidate > & accepted,
TargetPlatform platform )

◆ apply_designed_control_skin()

void pulp::view::apply_designed_control_skin ( View & control,
const DesignedControlSkin & skin )

Install the value-only painter on control.

After this the widget draws no body pixels — the design's are the only ones.

◆ apply_motion_policy_to_duration()

float pulp::view::apply_motion_policy_to_duration ( float configured_seconds)
inline

Apply the current MotionPolicy to a configured duration.

Returns the effective duration in seconds. When the policy is Off, returns 0.

◆ apply_param_binding_manifest()

int pulp::view::apply_param_binding_manifest ( IRNode & root,
const std::unordered_map< std::string, std::string > & node_id_to_param_key )

Bind geometry-detected controls to host parameters from an out-of-band manifest that maps a Figma node id (IRInteractiveElement::source_node_id, stamped by the producer) to a host-param key.

For each interactive element whose source_node_id is present in node_id_to_param_key with a non-empty value AND whose param_key is still empty, sets param_key from the manifest. Recurses into children. Returns the number of controls bound.

This is the binding path for DESCRIPTIVELY-named controls — the common Figma case (a knob named "Cutoff", not param:filter.cutoff), where the producer stamps provenance but no key. An explicit producer binding (a layer-name sigil) always WINS: the manifest never overwrites a non-empty param_key, so a sigil and a manifest entry for the same node resolve to the sigil. A node id absent from the manifest, or mapped to an empty string, is left untouched.

◆ apply_placement_verification()

int pulp::view::apply_placement_verification ( IRNode & root,
float frame_w = 0.0f,
float frame_h = 0.0f )

◆ apply_recognition_resolver()

int pulp::view::apply_recognition_resolver ( IRNode & root,
const RecognitionResolver & resolver,
std::vector< UnmatchedComponent > * unmatched_out = nullptr )

◆ apply_swap_target_verification()

int pulp::view::apply_swap_target_verification ( IRNode & root)

◆ assign_anchors()

void pulp::view::assign_anchors ( IRNode & root,
AnchorStrategy strategy,
std::string_view adapter_name = "" )

Walk root and populate stable_anchor_id on every node according to strategy.

For the adapter strategy, adapter_name is the prefix before :<source_node_id> (e.g. "figma", "pencil") — required for adapter, ignored otherwise.

For nodes that already have a non-empty stable_anchor_id (e.g. set explicitly by an authored override), the existing value is preserved.

A content hash does not include the parent, so two identical subtrees under different parents (two cards each holding an unlabelled slider) hash alike. After the walk, every anchor this call derived from content (the content-hash strategy, and the adapter strategy's fallback for a node with no source id) that repeats an earlier anchor is disambiguated as resolve_anchor_collisions() describes. Explicit identities (source ids, authored overrides) are never rewritten.

◆ attach_combo()

std::pair< std::unique_ptr< ComboBox >, state::Binding > pulp::view::attach_combo ( state::StateStore & store,
state::ParamID id,
std::vector< std::string > items )
inline

Attach a ComboBox to an integer/stepped parameter.

◆ attach_fader() [1/2]

std::pair< std::unique_ptr< Fader >, state::ExternalBinding > pulp::view::attach_fader ( state::ExternalBindingConfig cfg)
inline

◆ attach_fader() [2/2]

std::pair< std::unique_ptr< Fader >, state::Binding > pulp::view::attach_fader ( state::StateStore & store,
state::ParamID id )
inline

Attach a Fader widget to a parameter.

◆ attach_knob() [1/2]

std::pair< std::unique_ptr< Knob >, state::ExternalBinding > pulp::view::attach_knob ( state::ExternalBindingConfig cfg,
float size = 60.0f )
inline

◆ attach_knob() [2/2]

std::pair< std::unique_ptr< Knob >, state::Binding > pulp::view::attach_knob ( state::StateStore & store,
state::ParamID id,
float size = 60.0f )
inline

Attach a Knob widget to a parameter.

Handles normalization and gestures.

auto [knob, binding] = attach_knob(store, kCutoff, 60);
root.add_child(std::move(knob));
// Call binding.poll() periodically to sync host automation
std::pair< std::unique_ptr< Knob >, state::Binding > attach_knob(state::StateStore &store, state::ParamID id, float size=60.0f)
Attach a Knob widget to a parameter.
Definition param_attachment.hpp:22
@ knob
Definition design_ir.hpp:260

◆ attach_toggle() [1/2]

std::pair< std::unique_ptr< Toggle >, state::ExternalBinding > pulp::view::attach_toggle ( state::ExternalBindingConfig cfg)
inline

◆ attach_toggle() [2/2]

std::pair< std::unique_ptr< Toggle >, state::Binding > pulp::view::attach_toggle ( state::StateStore & store,
state::ParamID id )
inline

Attach a Toggle widget to a boolean parameter.

◆ audio_widget_kind_from_manifest_id()

AudioWidgetType pulp::view::audio_widget_kind_from_manifest_id ( const std::string & id)

Map an AudioWidgetType to/from the lowercase id used in manifests and the figma-plugin envelope ("knob"/"fader"/...).

Shared so the resolver and the envelope parser stay in lockstep. Returns none for unknown ids.

◆ audio_widget_kind_to_manifest_id()

const char * pulp::view::audio_widget_kind_to_manifest_id ( AudioWidgetType kind)

◆ audit_press_reach()

PressReachAudit pulp::view::audit_press_reach ( View & root,
const PressReachOptions & options = {} )

Walk root and press every control that advertises a press handler, at the centre of the rect it paints.

A control counts as reachable when the real View::hit_test at that point lands on the control itself or inside its subtree AND the channel resolves to a live handler. The subtree rule is deliberate: a container whose own child wins the press is not sealed off, and reporting it would bury the real findings in nesting noise.

◆ auto_contrast_foreground()

Color pulp::view::auto_contrast_foreground ( Color background,
ContrastLevel level = ContrastLevel::aa_normal )

Given a background color, compute an accessible foreground color.

Tries white first; if that fails the contrast threshold, uses black. For more nuanced results, adjusts lightness of the provided hint color.

◆ auto_fix_contrast()

Theme pulp::view::auto_fix_contrast ( const Theme & theme,
ContrastLevel level = ContrastLevel::aa_normal )

Auto-fix contrast issues in a theme by adjusting foreground colors.

Returns a new theme with adjusted colors. Original is not modified.

◆ autocaps_function_table()

const std::vector< std::pair< std::string_view, ReloadCapability > > & pulp::view::autocaps_function_table ( )
inline

Effectful bridge function name → the capability that gates it.

Mirrors the bridge's register-group gating; new effectful functions must be added here too.

◆ begin_file_drag()

bool pulp::view::begin_file_drag ( void * native_view,
const FileDragRequest & request )

◆ begin_host_frame()

HostFrameTick pulp::view::begin_host_frame ( View * root,
FrameClock & clock,
HostFramePump & pump,
double now_seconds,
bool needs_repaint )

Step 1 of a host tick: measure dt, pump the FrameClock's activity probes with it, then decide whether this frame needs compositing.

Order matters: the activity probes run BEFORE the decision, so a probe that flips a liveness flag this tick (a meter that just started moving calling set_continuous_repaint) is reflected in this tick's answer instead of being missed for a frame. needs_repaint is the host's own dirty flag (input, resize, explicit invalidate). Null-safe on root.

◆ bind_imported_level_display()

void pulp::view::bind_imported_level_display ( NativeImportBindingContext & ctx,
View & view,
LevelDisplay & display,
const NativeImportMeterBindingDescriptor & descriptor )

Bind an imported level or series display through both binder generations: the provider-neutral virtual, then the deprecated concrete one through the provider's registered legacy binder.

The native materializer and generated C++ binding helpers both bind through these, so a context that overrides only bind_meter / bind_waveform_display is bound either way.

◆ bind_imported_series_display()

void pulp::view::bind_imported_series_display ( NativeImportBindingContext & ctx,
View & view,
SeriesDisplay & display,
const NativeImportWaveformBindingDescriptor & descriptor )

◆ bind_midi_cc() [1/5]

void pulp::view::bind_midi_cc ( Fader & fader,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t cc )
inline

Fader → MIDI CC.

◆ bind_midi_cc() [2/5]

void pulp::view::bind_midi_cc ( Knob & knob,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t cc )
inline

Knob → MIDI CC.

◆ bind_midi_cc() [3/5]

void pulp::view::bind_midi_cc ( RangeSlider & slider,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t cc )
inline

Range slider → MIDI CC.

◆ bind_midi_cc() [4/5]

void pulp::view::bind_midi_cc ( Toggle & toggle,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t cc )
inline

Toggle → MIDI CC (0 / 127).

◆ bind_midi_cc() [5/5]

void pulp::view::bind_midi_cc ( ToggleButton & button,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t cc )
inline

Toggle button → MIDI CC (0 / 127).

◆ bind_midi_note() [1/2]

void pulp::view::bind_midi_note ( Toggle & toggle,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t note,
uint8_t velocity = 100 )
inline

Toggle → MIDI note: note-on while on, note-off when off.

◆ bind_midi_note() [2/2]

void pulp::view::bind_midi_note ( ToggleButton & button,
midi::MidiControlBus & bus,
uint8_t channel,
uint8_t note,
uint8_t velocity = 100 )
inline

Toggle button → MIDI note: note-on while on, note-off when off.

◆ bind_native_view_tree()

void pulp::view::bind_native_view_tree ( View & root,
const DesignIR & ir,
NativeImportBindingContext & ctx,
const NativeImportBindingOptions & options = {} )

Apply explicit pulp* binding metadata from ir to an already materialized native view tree.

This is opt-in: building the tree does not install callbacks or touch host/parameter state unless a caller invokes this helper with a binding context.

◆ bind_parameter() [1/9]

ParameterBinding pulp::view::bind_parameter ( Checkbox & box,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Checkbox ↔ parameter, as a one-shot gesture per flip.

◆ bind_parameter() [2/9]

ParameterBinding pulp::view::bind_parameter ( ComboBox & combo,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

ComboBox ↔ stepped/index parameter.

A selection is a one-shot gesture so the host records the discrete change; automation playback drives the selection back (via set_selected_silent, so it does not re-fire on_change).

◆ bind_parameter() [3/9]

ParameterBinding pulp::view::bind_parameter ( DesignStepper & stepper,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

DesignStepper ↔ stepped/index parameter (same contract as ComboBox): user steps are one-shot gestures; automation playback drives the selection via set_selected_silent (which does not re-fire on_select).

◆ bind_parameter() [4/9]

ParameterBinding pulp::view::bind_parameter ( Fader & fader,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Fader ↔ parameter (normalized).

◆ bind_parameter() [5/9]

ParameterBinding pulp::view::bind_parameter ( Knob & knob,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Knob ↔ parameter (normalized).

◆ bind_parameter() [6/9]

ParameterBinding pulp::view::bind_parameter ( RangeSlider & slider,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Range slider ↔ parameter (normalized).

◆ bind_parameter() [7/9]

ParameterBinding pulp::view::bind_parameter ( Toggle & toggle,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Toggle (switch) ↔ parameter, as a one-shot gesture per flip.

◆ bind_parameter() [8/9]

ParameterBinding pulp::view::bind_parameter ( ToggleButton & button,
state::StateStore & store,
state::ParamID id )
inlinenodiscard

Toggle button ↔ parameter.

A press is a complete one-shot gesture so the host records the discrete change.

◆ bind_parameter() [9/9]

ParameterBinding pulp::view::bind_parameter ( XYPad & pad,
state::StateStore & store,
state::ParamID x_id,
state::ParamID y_id )
inlinenodiscard

XY pad ↔ two parameters (normalized). A single drag drives both.

◆ blend_colors()

Color pulp::view::blend_colors ( Color a,
Color b,
float t )

Blend two colors by factor t in [0,1]. t=0 returns a, t=1 returns b.

◆ border_band_color()

Color pulp::view::border_band_color ( View::BorderStyle style,
BorderEdge side,
bool outer_band,
Color side_color,
float width )

The colour style paints the outer or inner band of side in, for a side whose specified colour is side_color and width width.

◆ border_bands()

BorderBands pulp::view::border_bands ( View::BorderStyle style,
BorderEdge side,
float width )

◆ border_shades()

BorderShades pulp::view::border_shades ( Color side_color)

◆ border_style_from_css()

std::optional< View::BorderStyle > pulp::view::border_style_from_css ( std::string_view keyword)

The View::BorderStyle a CSS border-style / outline-style keyword names, or nullopt for anything that is not one of the ten CSS keywords.

Exact, lowercase match, as computed styles report them.

◆ box_shadow_to_css()

std::string pulp::view::box_shadow_to_css ( const std::vector< IRBoxShadow > & shadows)

Serialize ordered box-shadow layers back to a CSS box-shadow string, preferring each layer's raw text when present (lossless) and otherwise reconstructing from the parsed fields.

Empty input yields an empty string.

◆ build_embedded_script_bytecode()

std::vector< std::uint8_t > pulp::view::build_embedded_script_bytecode ( const std::string & source)

Build-time script bytecode (QuickJS backend).

build_embedded_script_bytecode() compiles source exactly as evaluate_script() would and wraps the bytecode in a self-describing blob: the SHA-256 and length of the source it was compiled from, and the engine's bytecode fingerprint. A product embeds the blob in its binary at build time (pulp_add_js_bytecode() in CMake) and hands it to register_embedded_script_bytecode() before its editor opens. On a bytecode-cache miss for a source of the registered length whose SHA-256 matches, the cache takes the embedded bytecode instead of compiling, so a fresh process skips the parse of a large UI runtime entirely.

A blob is only ever used for the exact source it was compiled from, and only by an engine whose fingerprint matches the one that compiled it; anything else (another engine build, a stale or corrupt blob, a source that changed since the build) is ignored and the source compiles as before.

The blob must stay valid for the process lifetime (it normally lives in the binary's read-only data). It is trusted code: never register bytes read from a writable location.

Returns an empty vector when the source does not compile or the backend is not QuickJS.

◆ build_native_view_tree()

std::unique_ptr< View > pulp::view::build_native_view_tree ( const DesignIR & ir,
const IRAssetManifest & manifest,
const NativeMaterializeOptions & options = {} )

◆ build_scrolling_widget_gallery()

std::unique_ptr< View > pulp::view::build_scrolling_widget_gallery ( const Theme & theme,
float viewport_w,
float viewport_h )

◆ build_svg_fragment_document()

std::string pulp::view::build_svg_fragment_document ( const std::string & source_svg,
const std::string & fragment,
const FragmentTransform & xform,
float opacity = 1.0f,
const std::string & recolor_hex = {} )

◆ build_waveform_gpu_layer_plan()

WaveformGpuLayerPlan pulp::view::build_waveform_gpu_layer_plan ( const pulp::audio::WaveformOverview & thumbnail,
const WaveformViewport & viewport,
int64_t playhead_sample,
const WaveformGpuLayerConfig & config = {},
const WaveformGpuUploadKey * previous_static_key = nullptr )
nodiscard

◆ build_waveform_gpu_static_layer_plan()

WaveformGpuStaticLayerPlan pulp::view::build_waveform_gpu_static_layer_plan ( const pulp::audio::WaveformOverview & thumbnail,
const WaveformViewport & viewport,
const WaveformGpuLayerConfig & config = {} )
nodiscard

◆ build_waveform_playhead_overlay()

WaveformPlayheadOverlay pulp::view::build_waveform_playhead_overlay ( const WaveformViewport & viewport,
int64_t playhead_sample )
nodiscard

◆ build_waveform_render_plan()

WaveformRenderPlan pulp::view::build_waveform_render_plan ( const WaveformViewport & viewport,
int max_spans = 0 )
nodiscard

◆ build_widget_gallery()

std::unique_ptr< View > pulp::view::build_widget_gallery ( const Theme & theme)

◆ capability_from_name()

bool pulp::view::capability_from_name ( std::string_view s,
ReloadCapability & out )
inline

Parse a wire name; returns false on an unknown token (caller fails closed — an unrecognized capability must never silently grant nothing-or-everything).

◆ capability_name()

std::string_view pulp::view::capability_name ( ReloadCapability c)
inline

Stable wire name for a capability (used in the SIGNED pack manifest + config).

Names are the contract; never serialize the enum index.

◆ capture_view()

CaptureResult pulp::view::capture_view ( View & root,
uint32_t width,
uint32_t height,
float scale = 2.0f,
ScreenshotBackend backend = ScreenshotBackend::auto_select )

◆ captured_baseline()

float pulp::view::captured_baseline ( float line_top,
float offset,
float root_y )

The baseline of a captured line whose rect top is at line_top in the label's coordinates and whose baseline sits offset below that top, snapped to a whole CSS px the way Chromium paints it.

root_y is the label's y offset from the captured frame, the grid the snap is measured on, so an embed offset, scroll or transform outside the frame never moves it. Returns label-local coordinates.

◆ captured_baseline_offset()

float pulp::view::captured_baseline_offset ( float line_height,
float css_descent,
const std::optional< LineMetrics > & measured )

Where the baseline of a captured line sits below the top of its run rect, for a rect line_height CSS px tall.

css_descent is the face's own typographic descent, used only when measured is absent.

Chromium's run rect is the text's content area whatever the line-height: round(fAscent) + round(fDescent), plus an ascent adjustment Blink applies to some faces on macOS (Times, Helvetica, Courier). Its baseline sits the descent above the rect's bottom: the measured descent when the capture recorded one, otherwise the face's descent rounded to a whole CSS px, as Chromium rounds it.

◆ caret_advance()

float pulp::view::caret_advance ( const CaretMetrics & metrics)
noexcept

The width the underline and block shapes cover: advance when there is a glyph at the caret, else nominal_advance.

◆ caret_rect_for_style()

Rect pulp::view::caret_rect_for_style ( CaretStyle style,
const CaretMetrics & metrics )
noexcept

The rect a caret of style occupies.

ibeam is stroke wide; underline is caret_advance() wide and sits just below the baseline; block is the whole glyph cell.

◆ caret_style_from_string()

CaretStyle pulp::view::caret_style_from_string ( std::string_view name)
noexcept

Parse a name produced by caret_style_to_string.

Unknown names, including the empty string, return CaretStyle::ibeam rather than failing — a caret that renders is always better than one that does not.

◆ caret_style_to_string()

const char * pulp::view::caret_style_to_string ( CaretStyle style)
noexcept

Stable lowercase names, for serialization and the JS bridge.

◆ chart_glow_reach()

float pulp::view::chart_glow_reach ( float sigma,
float intensity )

Distance past which a glow of sigma and intensity is below one 8-bit step (intensity * exp(-r^2 / (2 sigma^2)) < 1/255), and never less than three sigma.

Zero when either is zero.

◆ chart_shader_preset_names()

const std::vector< std::string > & pulp::view::chart_shader_preset_names ( )

The preset names: bevel, inset-channel, tube, light-pipe, centre-highlight and glow.

center-highlight is accepted as an alias.

◆ check_gross_size_divergence()

std::optional< FidelityIssue > pulp::view::check_gross_size_divergence ( const FidelityContext & )

Gross-size: a node the user pinned on BOTH axes (SizingMode::fixed) must not be emitted >3x its source box; hug/fill/absolute/display:none self-skip.

◆ check_image_sizing_fidelity()

std::optional< FidelityIssue > pulp::view::check_image_sizing_fidelity ( const FidelityContext & )

No-skew: a BLEED sprite (render_bounds or asset_bleed) must be emitted at an aspect matching its source PNG; missing PNG dims → aspect-unverified.

◆ check_text_vertical_centering()

std::optional< FidelityIssue > pulp::view::check_text_vertical_centering ( const FidelityContext & )

Text-vertical-centering: a SINGLE-LINE text given a reserved vertical slot (emitted box taller than one line, below the multi-line threshold) must be emitted vertically centered.

A top-aligned single-line label in a tall slot is "text-vcenter". Multi-line, no-slack, and missing-metric cases self-skip.

◆ check_vector_renderability()

void pulp::view::check_vector_renderability ( const IRNode & root,
const std::vector< ImportDiagnostic > & diagnostics,
const std::function< std::string(const IRNode &)> & node_id_of,
std::vector< FidelityIssue > & sink )

Vector-renderability: every visible vector/path-like node (svg path/rect/ line, ellipse, polygon, …) above an area threshold must map to a real renderable primitive — a rasterized asset, a native widget, child paint, or a visible fill — OR already carry an explicit unsupported diagnostic.

A bare vector that codegen would drop to an empty createRow frame (no asset, no children, no fill — its stroke/path/border art silently vanishes) is reported as "dropped-vector".

This is a TREE pass, not a per-element registry check, for two reasons the single-node FidelityContext cannot serve: (1) the dropped node hits codegen's generic-frame fall-through, which has no run_fidelity_checks call site; and (2) the false-positive gate "a vector child consumed into a parent widget is not dropped" needs subtree context. The walk mirrors generate_native_node's recursion exactly — it descends EXCEPT into the terminal image/widget/text branches — so a knob's consumed stroke-ellipse is never falsely flagged.

diagnostics is DesignIR::diagnostics: a node already carrying a render-affecting import diagnostic (matched by stable_anchor_id or structural path) is suppressed so the silent-drop finding never double-reports a drop the importer already surfaced. node_id_of maps a node to the bridge id codegen emitted for it (codegen passes a lookup over its real id map; tests pass an identity-ish stub).

◆ check_widget_intrinsic_size()

std::optional< FidelityIssue > pulp::view::check_widget_intrinsic_size ( const FidelityContext & )

Widget-intrinsic-size: a recognized audio widget whose emitted box diverges >1.5x from its source intrinsic size (shape_width/height attrs, else style box).

A source below the widget's native usable minimum is reported as informational "widget-undersized" (codegen clamps up); a real divergence is "widget-size". Heuristic detections with no source dims self-skip.

◆ clamp_oversize_absolute_view()

void pulp::view::clamp_oversize_absolute_view ( pulp::view::View & view,
float vw,
float vh,
std::uint32_t viewport_width,
std::uint32_t viewport_height,
int depth,
const char * parent_label )
inline

◆ classify_design_slots()

std::vector< DesignSlot > pulp::view::classify_design_slots ( const IRNode & node)

◆ classify_interactive_signal()

WidgetPromotionSignal pulp::view::classify_interactive_signal ( const IRNode & node)

Inspect one IR node for interactive-frame promotion signals.

◆ classify_sample_asset_file_drop()

SampleAssetDropPlan pulp::view::classify_sample_asset_file_drop ( const std::vector< std::string > & paths,
const audio::SampleAssetPolicy & policy = {} )
nodiscard

◆ classify_token_tweak()

std::optional< TokenTarget > pulp::view::classify_token_tweak ( const std::string & anchor_id,
const std::string & property_path )

Classify a tweak as token-typed or not.

Parameters
anchor_idThe tweak's stable_anchor_id (may be empty).
property_pathThe tweak's dotted property path.

Returns a populated TokenTarget when the tweak addresses a DESIGN.md token, std::nullopt when it is an element-only tweak. Classification is purely structural — it does NOT check whether the token actually exists in any DESIGN.md.

◆ clear_data_displays()

void pulp::view::clear_data_displays ( )

◆ clear_design_control_factories()

void pulp::view::clear_design_control_factories ( )

◆ clear_materialized_document_cache()

void pulp::view::clear_materialized_document_cache ( )

Drop every kept document (tests; a host that wants the memory back).

◆ clear_screenshot_provider()

void pulp::view::clear_screenshot_provider ( )

◆ clear_script_bytecode_cache()

void pulp::view::clear_script_bytecode_cache ( )

Drop every stored script (tests; a host that wants the memory back).

◆ collect_design_ir_assets()

IRAssetManifest pulp::view::collect_design_ir_assets ( const DesignIR & ir,
const DesignIrAssetOptions & options = {} )

Collect all external resources referenced by the IR into a manifest.

Network fetches require explicit opt-in through options.

A local file outside options.base_directory is recorded by its absolute path. A loader resolves assets only inside the saved document's directory and refuses that path, so a caller that serializes the IR must first copy such files beside the document and record relative paths, as pulp import-design does for every lane that writes a document.

◆ collect_import_report()

ImportReport pulp::view::collect_import_report ( const IRNode & root,
float low_confidence_threshold = 0.6f )

◆ color_from_hex()

Color pulp::view::color_from_hex ( uint32_t hex)
inline

◆ color_from_hex_alpha()

Color pulp::view::color_from_hex_alpha ( uint32_t hex)
inline

◆ compare_screenshot_files()

CompareResult pulp::view::compare_screenshot_files ( const std::string & reference_path,
const std::string & rendered_path,
uint8_t tolerance = 32 )

Compare two PNG files for visual similarity.

◆ compare_screenshots()

CompareResult pulp::view::compare_screenshots ( const std::vector< uint8_t > & reference_png,
const std::vector< uint8_t > & rendered_png,
uint8_t tolerance = 32 )

Compare two PNG images for visual similarity.

Parameters
reference_pngRaw PNG bytes of the reference (source design) image
rendered_pngRaw PNG bytes of the rendered Pulp output
tolerancePer-channel color tolerance (0-255). Pixels within this tolerance are considered matching. Default 32 allows for minor rendering differences (antialiasing, theme color variations, font rendering).

◆ compute_anchor_id()

std::string pulp::view::compute_anchor_id ( const IRNode & node,
std::string_view parent_anchor,
std::size_t sibling_tag_index_for_path,
std::size_t depth,
std::size_t sig_index_for_content_hash,
AnchorStrategy strategy,
std::string_view adapter_name = "" )

Compute a single anchor without walking.

Public for tests and for adapter code that wants to assign anchors incrementally.

Parameters
nodeThe node to anchor (read-only).
parent_anchorFor path strategy: the parent's already-computed anchor; otherwise ignored.
sibling_tag_index_for_pathFor path strategy: how many earlier siblings share node.type as their tag.
depthTree depth (root = 0).
sig_index_for_content_hashFor content-hash strategy: how many earlier siblings share the same {tag, role, text} signature.
strategyStrategy selector.
adapter_nameFor adapter strategy only.

◆ compute_effective_damage()

DamageDecision pulp::view::compute_effective_damage ( const View & root,
const Rect & requested_root_rect,
float device_scale = 1.0f )

Decide whether requested_root_rect can be repainted as a bounded clip (pixel-identical to a full repaint) or must escalate to a full repaint.

The rule is the pixel-identity constraint: clipping the repaint is identical to a full repaint iff no draw whose output touches the clip SAMPLES pixels whose value differs between "preserved previous frame" and "would-be-fully- repainted frame". Point-wise ops (plain draws, opacity/blend layers, colour-only filter chains, analytic box shadows) are safe. The hazards are ops that sample at a distance and can straddle the clip boundary:

  • a view with backdrop_blur > 0 (samples the backdrop behind it);
  • a view with filter_blur > 0 or a filter chain containing blur/ drop-shadow (spreads its own content past its box);
  • a view with a compositing effect that samples (effect() && effect()->needs_layer());
  • a view with a mask layer (mask geometry is layer-relative; a truncated layer is at minimum suspicious);
  • a view under a render transform or a child-paint-offset (scroll) — its painted box cannot be derived from the plain ancestor-origin walk, so its extent is unknown.

Each hazard's painted box (inflated by its sample radius) is tested against the requested damage. If any hazard reaches the damage, the decision is FULL. Otherwise the requested rect — snapped OUT to the device_scale pixel grid to avoid AA seams at the clip edge — is returned as the bounded clip.

v1 policy is ESCALATE, not grow-to-fixpoint: a hazard that intersects the damage returns full rather than unioning the hazard's extent and rescanning. This is always pixel-safe (it only forgoes the optimization) and matches the producer-side conservatism in View::request_repaint(Rect).

◆ compute_frame_clip()

bool pulp::view::compute_frame_clip ( View & root,
const PendingDamage::Snapshot & damage,
const FrameGeometry & geometry,
Rect & out_clip )

Decide the clip rect for a partial repaint, in SURFACE space.

Returns false when the frame must repaint in full — because the damage is full, because there is no bounded damage, or because the hazard model (compute_effective_damage) found something that samples at a distance reaching the damaged area, which is what makes a clipped repaint pixel-identical to a full one rather than merely similar.

On success out_clip is already mapped through the design-viewport letterbox transform and snapped OUT to whole surface pixels: the clip is installed BEFORE paint applies translate+scale, so an unmapped root-space rect would land in the wrong place, and a fractional edge would clip a partially covered pixel.

◆ contrast_ratio()

float pulp::view::contrast_ratio ( Color a,
Color b )

Compute WCAG contrast ratio between two colors.

Returns a value in [1, 21] where 1 = identical and 21 = black vs white.

◆ count_announceable()

std::size_t pulp::view::count_announceable ( const View & root)

Count nodes the platform bridges actually expose (snapshot node exposed — role != none AND named when the role requires a name).

Handy when a test only cares that some number of controls are exposed (e.g. preset- browser row widgets).

◆ count_strict_fidelity_failures()

std::size_t pulp::view::count_strict_fidelity_failures ( const std::vector< FidelityIssue > & issues)

Number of findings that should fail --strict-fidelity.

Informational findings (advisory clamp-ups etc.) are surfaced as warnings but never gate the import, so the CLI decides its exit code from this count, not the raw finding count.

◆ create_default_js_engine()

std::unique_ptr< JsEngine > pulp::view::create_default_js_engine ( )

◆ create_js_engine()

std::unique_ptr< JsEngine > pulp::view::create_js_engine ( JsEngineType type)

◆ crop_png()

std::vector< uint8_t > pulp::view::crop_png ( const std::vector< uint8_t > & png,
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height )

Crop a rectangular region from a PNG image and return it as a new PNG.

Returns an empty vector if decoding fails or the requested region does not intersect the source image.

◆ css_blend_mode()

std::optional< canvas::Canvas::BlendMode > pulp::view::css_blend_mode ( const std::string & keyword)

A CSS mix-blend-mode keyword.

Unknown keywords return nothing rather than falling back to normal, so a mode we cannot honor is visible as absent.

◆ css_blur_radius()

std::optional< float > pulp::view::css_blur_radius ( const std::string & filter)

The blur radius out of a CSS filter list, in px.

Only blur() is read. A list may carry brightness, saturate and the rest; those need a real filter chain, and lowering them to a blur radius would be a lie. Returning nothing leaves the node unfiltered rather than wrongly blurred — an unfiltered element is visibly missing, a wrongly blurred one looks intentional.

◆ css_color_syntax_supported()

bool pulp::view::css_color_syntax_supported ( std::string_view token)

True when token uses one of the CSS color syntaxes understood by parse_css_color().

This separates recognition from that parser's historical opaque-white fallback so callers can preserve a better authored fallback when a stale or hand-written token is invalid.

◆ css_filter_chain()

std::vector< canvas::Canvas::FilterChainEntry > pulp::view::css_filter_chain ( const std::string & filter)

A whole CSS filter list as the canvas layer verbs consume it, in source order — saturate(0.15), grayscale(1) brightness(1.6), blur(6px).

Percentages and bare numbers both resolve to the spec's 0..1-relative amount, so saturate(15%) and saturate(0.15) produce the same entry. hue-rotate is read as DEGREES: a computed style always serializes the angle that way, and a rad / turn / grad author value would be taken as degrees. Feed this computed values, not authored ones.

A function this parser does not know is DROPPED and the rest of the list is kept, because the alternative — refusing the list — turns one unrecognized function into no filtering at all. drop-shadow() is among the dropped: its colour argument needs the full colour parser, and a drop-shadow with the wrong colour is worse than an absent one. An empty result means nothing in the value was recognized; the caller then leaves the node unfiltered.

◆ css_keyword_is_none()

bool pulp::view::css_keyword_is_none ( std::string_view value)

True for an empty value or the CSS keyword none, which keywords match case-insensitively and with surrounding whitespace.

A style property that takes either is the initial value and must not install anything.

◆ css_transform_rotation()

std::optional< float > pulp::view::css_transform_rotation ( const std::string & transform)

The angle out of a rotate(<deg>deg) in a CSS transform, in degrees.

This is the ONE transform component both render lanes honor, because it is the one whose box the importers have already put in the pre-rotation frame: the .fig decoder compensates left/top for the pivot, and the browser capture solves the rectangle back out of its bounding box. Anything else in the value — a translate, a scale, a matrix — returns nothing, because applying it on top of a box that already includes it transforms the element twice.

Rotation is about the view's CENTRE, which is the renderer default and what both importers assume.

◆ data_display_registration_count()

std::size_t pulp::view::data_display_registration_count ( )

◆ dbfs_meter_fill()

float pulp::view::dbfs_meter_fill ( float linear)

Map a linear amplitude (1.0 == full scale) to a 0..1 meter fill on the SAME dBFS scale the panel's text labels print, so a bar and its "… dBFS" label agree.

kInspectorMeterFloorDb maps to an empty bar, 0 dBFS to a full bar; passing the raw linear amplitude to Meter::set_level would instead make the bar read amplitude while the label reads dBFS — two different scales.

◆ decode_webview_message_json()

bool pulp::view::decode_webview_message_json ( const std::string & json,
WebViewMessage & message )

Decode a structured WebView message from JSON.

Accepts either an object directly or a single-element argument array produced by some JS bridges.

◆ default_anchor_strategy()

AnchorStrategy pulp::view::default_anchor_strategy ( DesignSource source)

Map a DesignSource to its default anchor strategy.

Mirrors the DEFAULT_ANCHOR_STRATEGY map in @pulp/import-ir/src/anchors.ts.

◆ default_caret_blink()

const CaretBlinkConfig & pulp::view::default_caret_blink ( )
noexcept

◆ default_caret_style()

CaretStyle pulp::view::default_caret_style ( )
noexcept

Process-wide caret defaults.

A widget that never calls its own setter picks these up. Not synchronized; set them during app startup.

◆ deliver_gesture_handoff()

void pulp::view::deliver_gesture_handoff ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count )

Close the press bracket when a recognizer CLAIMS the pointer mid-gesture, after a press was already delivered to target.

The host stops its own delivery at that point (see should_yield_to_gesture) but the press it already delivered is still outstanding: a Knob opens on_gesture_begin and relative-mouse mode on press and clears them only on release, so bailing bare strands beginEdit with no endEdit — a stuck automation touch and a hidden cursor. Callers must clear their captured drag-target slot before invoking this user-callback pipeline, so a callback exception or a gesture that later goes terminal cannot retry or resume the raw drag with a position jump.

Runs the FULL release pipeline rather than a bare on_mouse_up, because the press ran the full press pipeline: a legacy-only close leaves the modern channel and the pointerdown bubble unmatched, and modern-only consumers stay stuck (VirtualList clears dragging_scrollbar_ solely on an event with is_down == false). No click is fired — a handoff is not a click.

Delivered as a RELEASE, not a cancellation. A takeover is arguably pointercancel (MouseEvent::is_cancelled and View::on_mouse_cancel exist for it), which would let a cancellation-aware control roll its partial drag back instead of committing it. It stays a release because that is what every path does today — View::simulate_drag closes its own mid-loop claim the same way — and splitting the hosts off from the portable simulation would reintroduce the host-vs-headless divergence this seam removes. Changing it means teaching the release pipeline a cancel mode and moving all three call paths together.

No-op when target is null or no longer in the tree.

◆ deliver_hover_move() [1/2]

void pulp::view::deliver_hover_move ( View & root,
Point root_pt,
uint16_t modifiers,
const PointerAttributes & pointer )

Attribute-carrying hover overload, for a host that knows the pointer device (a trackpad/stylus hover) or reports movement deltas.

◆ deliver_hover_move() [2/2]

void pulp::view::deliver_hover_move ( View & root,
Point root_pt,
uint16_t modifiers = 0 )

Deliver one BUTTONLESS pointer move — a hover — to the view under root_pt, which is in root-view space.

── Delivery contract (asserted by test_pointer_delivery.cpp) ───────────── In this order:

  1. hover STATE — View::simulate_hover, which raises set_hovered along the path to the hit view, clears it everywhere else, and hands the hit view a positioned on_hover_move;
  2. the MODERN channel — on_mouse_event(MouseEvent) with phase == MousePhase::hover, is_down == false and button == MouseButton::none;
  3. the JS channel — on_dom_pointer_move_event along the same target-to-root path a drag walks, which is what makes a scripted UI's pointermove / mousemove listener run.

Step 3 is the whole reason this verb exists. Hover was the ONLY phase with no portable delivery function, so every native host open-coded it as a bare simulate_hover — and simulate_hover runs no JavaScript. A scripted UI therefore received pointerdown, pointermove-while-dragging and pointerup, but never a plain hover, so a handler that picks the cursor (grab / col-resize / crosshair) from the pointer position only ever ran once a button went down. That is the shape of the defect a user reports as "the cursor only changes when I click".

Resolve the cursor AFTER calling this, never before: the value a scripted UI wants published is the one its handler just set.

◆ deliver_mouse_cancel()

void pulp::view::deliver_mouse_cancel ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
MouseButton button,
const PointerAttributes & pointer = {} )

Cancel an in-flight gesture through the same identity-safe terminal router as deliver_mouse_up.

The legacy channel receives on_mouse_cancel, the modern event and ancestor bubble carry is_cancelled, and clicks are always suppressed. Keeping cancellation here ensures release and cancel share the same pre-callback ancestor snapshot and liveness checks.

◆ deliver_mouse_down() [1/4]

bool pulp::view::deliver_mouse_down ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
bool bubble,
MouseButton button )

Button-aware overload; the original ABI remains the left-button wrapper.

◆ deliver_mouse_down() [2/4]

bool pulp::view::deliver_mouse_down ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
bool bubble,
MouseButton button,
const MouseDownHost & host )

Guarded button-aware overload.

Existing overloads remain ABI-compatible wrappers with an empty host.

◆ deliver_mouse_down() [3/4]

bool pulp::view::deliver_mouse_down ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
bool bubble,
MouseButton button,
const MouseDownHost & host,
const PointerAttributes & pointer )

Attribute-carrying overload.

The press is where a widget latches the device it is being driven by — a Knob deciding a touch needs a coarser slop than a mouse, a paint surface reading pressure. Every overload above delivers a default mouse pointer, so a caller that never opts in is unchanged.

◆ deliver_mouse_down() [4/4]

bool pulp::view::deliver_mouse_down ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count = 1,
bool bubble = true )

Deliver a press to an already-resolved target (the host has done the hit_test, any combo/overlay pre-routing, and the focus protocol before calling in — those steps diverge per platform/host and stay host-side).

── Delivery contract (asserted by test_pointer_delivery.cpp) ───────────── The target receives, in this order:

  1. the MODERN channel — on_mouse_event(MouseEvent) with phase == MousePhase::press, carrying modifiers and click_count;
  2. the LEGACY channel — on_mouse_down(Point) (bare local point);
  3. when bubble is true, the W3C pointerdown bubble — every ancestor with an on_pointer_event handler receives a copy re-localized to its own space (a wrap-div around a canvas child that wins hit_test still sees the press).

Liveness is re-checked between every hop: a modern handler can unmount the tree (a React state flip that frees target), so no later channel derefs a freed view. Returns true when target is still in the tree after delivery, false when it was null on entry, unmounted during delivery, or a guarded overload's host continuation check stopped the stale frame. A guarded caller must clear its captured slot only if it still owns the same generation.

bubble defaults to true (the normal press path and the plugin host). The standalone host's overlay-click path passes false to preserve its historical no-bubble behavior; see the call site for the rationale.

◆ deliver_mouse_drag() [1/3]

void pulp::view::deliver_mouse_drag ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
MouseButton button,
const PointerAttributes & pointer )

Attribute-carrying overload — the only drag form that also carries pointer_id.

Both scalar signatures above remain exported.

◆ deliver_mouse_drag() [2/3]

void pulp::view::deliver_mouse_drag ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
PointerType pointer_type,
float pressure,
MouseButton button )

Button-aware overload.

The original signature above remains exported so existing SDK clients keep their binary-compatible left-button symbol.

◆ deliver_mouse_drag() [3/3]

void pulp::view::deliver_mouse_drag ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count = 1,
PointerType pointer_type = PointerType::mouse,
float pressure = 0.5f )

Deliver one drag tick of an in-flight gesture to the captured target.

── Delivery contract (asserted by test_pointer_delivery.cpp) ───────────── The target receives, in this order, EXACTLY ONCE each:

  1. the MODERN channel — on_mouse_event(MouseEvent) with phase == MousePhase::drag, carrying modifiers, click_count, pointer_type, pressure, and host-reported movement deltas;
  2. the LEGACY channel — on_mouse_drag(Point) then on_drag(Point), which carry a bare local Point and are kept for compatibility;
  3. ancestor bubbling — on_drag on each ancestor that declares one, re-localized to that ancestor.

Modern-before-legacy is the documented order across every phase, so a widget that latches modifiers in on_mouse_event has them in hand before its legacy handler runs. Before this existed the hosts delivered a drag on the legacy channel ONLY, so a view could read modifiers on press and on release but not DURING a drag — making "hold Shift to fine-adjust", the most common plug-in knob idiom, inexpressible.

root_pt is in root-view space; each channel is handed the point localized to its own receiver. No-op when target is null or no longer in the tree.

◆ deliver_mouse_up() [1/3]

void pulp::view::deliver_mouse_up ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
const MouseUpHost & host )

Deliver a release for an in-flight gesture captured on target.

── Delivery contract (asserted by test_pointer_delivery.cpp) ─────────────

  1. resolve released = root.hit_test(root_pt) and capture the nearest on_click up from target BEFORE any delivery;
  2. the LEGACY channel — on_mouse_up(Point) (bare local point);
  3. the MODERN channel — on_mouse_event(MouseEvent) with phase == MousePhase::release;
  4. the W3C pointerup bubble to every on_pointer_event ancestor in its own space;
  5. if released == target, host.fire_click(click_handler, id, modifiers) — the same-target click-suppression rule.

Up is LEGACY-before-modern (opposite of drag) because that is the order both mac hosts have always delivered it. Liveness is re-checked before the modern and bubble derefs; the fire-click DECISION uses the captured pointers and runs regardless of an intervening unmount (the standalone token guards the deferred call, the plugin call is synchronous). No-op when target is null or not in the tree.

◆ deliver_mouse_up() [2/3]

void pulp::view::deliver_mouse_up ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
const MouseUpHost & host,
MouseButton button )

Button-aware overload; the original ABI remains the left-button wrapper.

◆ deliver_mouse_up() [3/3]

void pulp::view::deliver_mouse_up ( View & root,
View * target,
Point root_pt,
uint16_t modifiers,
int click_count,
const MouseUpHost & host,
MouseButton button,
const PointerAttributes & pointer )

Attribute-carrying overload.

A release that reported mouse after a touch press leaves a widget unable to match the two halves of one gesture, so the device travels with the release too. Both overloads above deliver a default mouse pointer.

◆ deliver_mouse_wheel() [1/2]

void pulp::view::deliver_mouse_wheel ( View & root,
Point root_pt,
float scroll_delta_x,
float scroll_delta_y,
const WheelHost & host )

Route one wheel/scroll tick to the view tree rooted at root.

This is the mouse-wheel verb shared by the macOS standalone and plugin hosts. Before it existed the identical routing lived inline in both, and drifted. The precedence, asserted by test_pointer_delivery.cpp, is:

  1. an open ComboBox popup whose (flip/scroll/clamp-aware) rect contains root_pt consumes the wheel to scroll its item list;
  2. with no hit-testable view under the point, the nearest wheel-scroll container under the cursor scrolls (so an empty scroll-pane background still scrolls without a click first);
  3. a value widget under the cursor (wants_wheel_value) steps its value, taking precedence over any enclosing ScrollView;
  4. otherwise the wheel bubbles up: the nearest wants_wheel_scroll ancestor scrolls and stops the walk, while each ancestor that registered on_pointer_event also receives the event (W3C wheel bubble; handlers self-filter on MouseEvent::is_wheel);
  5. with no consumer, the deepest hit receives the event for any default.

root_pt is in root-view space (design-viewport inverse already applied by the host). scroll_delta_y is Pulp-convention (already negated from NSEvent's bottom-up scrollingDeltaY). host.request_repaint fires once after any terminal dispatch that mutated the tree.

◆ deliver_mouse_wheel() [2/2]

void pulp::view::deliver_mouse_wheel ( View & root,
Point root_pt,
float scroll_delta_x,
float scroll_delta_y,
uint16_t modifiers,
const WheelHost & host )

Attribute-carrying wheel delivery.

modifiers is sampled from the native event so consumers can distinguish Cmd/Ctrl-wheel zoom from ordinary two-finger pan. The overload above remains source-compatible and supplies no modifiers for existing synthetic callers.

◆ derive_fader_skin()

FaderSkin pulp::view::derive_fader_skin ( const SkinImage & img)

Sample a captured fader PNG → FaderSkin.

Locates the widget art (tallest opaque vertical run in the center column), then recovers the dark track, the saturated fill, the bright thumb body, and its bevel edge.

◆ derive_meter_skin()

MeterSkin pulp::view::derive_meter_skin ( const SkinImage & img,
int stop_count = 5 )

Sample a captured meter PNG → MeterSkin.

Locates the widget art, then walks the contiguous saturated fill from the bottom up and samples stop_count gradient stops across it (low→high).

◆ derive_theme()

Theme pulp::view::derive_theme ( const SemanticColors & colors)

Derive a complete Theme from semantic colors.

This generates all standard Pulp tokens including audio-specific ones: accent.primary → knob.arc, slider.fill, progress.fill, spinner, tab.active background → knob.arc.bg, slider.track, control.track, waveform.grid bg foreground → knob.thumb, slider.thumb, control.thumb muted/mutedFg → waveform.grid, control.border, text.secondary, tab.inactive destructive → meter.red, accent.error accent + warm hue → meter.yellow, accent.warning accent + green hue→ meter.green, accent.success card → card.empty, card.ready card + muted tint → card.loading destructive low α → card.error border → modal.border, control.border secondary → bg.secondary, overlay.bg primary → gradient.start; secondary → gradient.end input → bg.surface

◆ describe()

const char * pulp::view::describe ( BindingOutcome o)
noexcept

Human-readable reason, for diagnostics and test failure messages.

◆ design_ir_text_raster_policy()

canvas::TextRasterPolicy pulp::view::design_ir_text_raster_policy ( const DesignIR & ir)

The text raster policy a surface showing ir should be created with: chromium when any captured text node was authored -webkit-font-smoothing: antialiased, otherwise legacy.

A Label built by build_native_view_tree paints that text unhinted, which reproduces Chromium's glyphs only on a chromium surface.

◆ design_source_name()

const char * pulp::view::design_source_name ( DesignSource source)

Convert DesignSource to display name.

◆ detect_appearance_defects()

AppearanceReport pulp::view::detect_appearance_defects ( const View & root,
const AppearanceOptions & options = {} )

Walk root (already laid out) and report painted-text defects.

◆ detect_audio_widget()

AudioWidgetType pulp::view::detect_audio_widget ( const std::string & name)

Detect audio widget type from a node name.

◆ detect_default_shortcuts()

DefaultShortcutScan pulp::view::detect_default_shortcuts ( const std::string & source,
const std::vector< DetectedShortcut > & existing_extracted )

Static-scan a TSX/JS source string for components matching the platform-convention defaults table.

Signals: component identifier (SettingsModal, HelpDialog, ShortcutsCheatsheet, etc.), canonical component name, role= attribute, aria-label= text, modal heading text, presence of <kbd> tags (cheatsheet disambiguator). Conservative — requires ≥2 signals to fire; multiple-candidate matches go into collisions not accepted.

Already-extracted shortcuts (existing_extracted) suppress the same- chord default so a developer's hand-written binding always wins.

Pure lexical pass; no JSX parsing. Returns an empty scan when no patterns match. Never throws.

◆ detect_jsx_snapshot_dynamic_apis()

SnapshotDynamicApiScan pulp::view::detect_jsx_snapshot_dynamic_apis ( std::string_view source)

Detect dynamic APIs that make a JSX baked snapshot non-deterministic unless the caller explicitly accepts or warns on snapshot semantics.

◆ detect_webview_backend()

std::string pulp::view::detect_webview_backend ( )

Identifies the live WebView backend on this platform / build.

Returned values:

  • "wkwebview" — macOS / iOS (WebKit.framework).
  • "webview2" — Windows (Microsoft Edge WebView2 runtime).
  • "webkitgtk" — Linux (WebKitGTK via libwebkit2gtk-4.1.so.0).
  • "chromium" — Android (system WebView).
  • "none" — PULP_BUILD_WEBVIEW=OFF or no runtime backend resolved on this OS at process start.

Useful for callers that need to surface a clear "no embedded browser available on this OS" message.

◆ diff_bounds()

DiffBounds pulp::view::diff_bounds ( const std::vector< uint8_t > & reference_png,
const std::vector< uint8_t > & rendered_png,
uint8_t tolerance = 32 )

Compute the bounding box of pixels that differ beyond the given tolerance.

Returns an invalid result when decoding fails or no pixels differ.

◆ diff_designmd()

DesignMdDiffResult pulp::view::diff_designmd ( const DesignMdParseResult & before,
const DesignMdParseResult & after )

Compute the token diff between two parsed DESIGN.md files plus a regression flag derived from their respective lint outputs.

◆ discover_package_design_controls()

PackageDesignControlSources pulp::view::discover_package_design_controls ( const std::filesystem::path & start_dir)

◆ dispatch_context_menu() [1/2]

bool pulp::view::dispatch_context_menu ( View & root,
Point root_pos )

Route a right-click at root_pos to the view under it.

Returns true when a view had an on_context_menu handler and it was invoked.

The callback BUBBLES: the walk runs from the hit view up to root and the nearest listener wins, matching the DOM and matching every other pointer verb here. Real pages depend on it — the handler is routinely on a wrapper while the ink on top is a child canvas or an absolutely-positioned overlay with no listener of its own.

◆ dispatch_context_menu() [2/2]

bool pulp::view::dispatch_context_menu ( View & root,
View * target,
Point root_pos )

Route a context menu to an already-resolved pointer target.

Platform hosts that perform overlay-aware hit testing must use this overload so the context-menu channel cannot fall through to a sibling beneath the overlay.

◆ dispatch_dom_pointer_event()

void pulp::view::dispatch_dom_pointer_event ( View & root,
View * target,
const MouseEvent & event,
bool moving,
bool bubble = true )

Enter rich + JS pointer delivery from a platform host.

The target receives on_mouse_event once, the deepest registered View receives the sole full DOM dispatch, and registered ancestors receive only their low-level callback so the JavaScript bubble walk is never re-entered.

◆ dispatch_drag_enter()

bool pulp::view::dispatch_drag_enter ( View & root,
DragSession & session,
const DropData & data,
Point root_pos )

◆ dispatch_drag_exit()

void pulp::view::dispatch_drag_exit ( View & root,
DragSession & session )

◆ dispatch_drag_move()

void pulp::view::dispatch_drag_move ( View & root,
DragSession & session,
const DropData & data,
Point root_pos )

◆ dispatch_drop()

bool pulp::view::dispatch_drop ( View & root,
DragSession & session,
const DropData & data,
Point root_pos )

◆ dump_layout_tree()

std::string pulp::view::dump_layout_tree ( const View & root,
const LayoutTreeSnapshotOptions & options = {} )

Dump the current, already-laid-out View tree as deterministic JSON.

Callers own layout timing: set root bounds and call layout_children() before dumping when they need post-Yoga coordinates. The snapshot is semantic rather than pixel-based, so it is portable across CI platforms.

◆ easing_by_name()

EasingFunction pulp::view::easing_by_name ( const std::string & name)
inline

Resolve an easing function by name string. Returns linear for unknown names.

◆ enclosing_text_selection_region()

View * pulp::view::enclosing_text_selection_region ( View & from)

The nearest enclosing text-content region of from (itself included), or null when it is not inside one.

A free function rather than a View method: the flag is View state, but resolving it is a selection-subsystem question, and keeping the walk here puts it beside the rest of the capability's arithmetic. Walked rather than cached, so a reparent cannot leave a stale answer behind.

◆ encode_webview_message_json()

std::string pulp::view::encode_webview_message_json ( const WebViewMessage & message)

Encode a structured WebView message to canonical JSON.

◆ engine_type_name()

std::string_view pulp::view::engine_type_name ( JsEngineType type)
constexpr

◆ enrich_imported_image_asset_metadata()

void pulp::view::enrich_imported_image_asset_metadata ( DesignIR & ir,
const IRAssetManifest & manifest,
std::string_view base_directory = {} )

Resolve imported image asset_ref nodes against an asset manifest and stamp source-derived metadata onto the nodes: absolute asset_path, PNG natural dimensions, opaque-core bounds for render-bounds sprites, and asset_bleed when the PNG is much larger than the logical box.

This is a preprocessing step for baked native/codegen paths; it does not modify the manifest.

◆ export_css_variables()

std::string pulp::view::export_css_variables ( const Theme & theme)

Export a Pulp Theme to CSS custom properties (variables).

Base (light/default) tokens are emitted under :root; tokens whose name ends in the .dark multi-mode suffix (the convention the Figma plugin and DESIGN.md body parser use for dark-mode values) are emitted as overrides under @media (prefers-color-scheme: dark) { :root { … } }. Token names map to custom properties by replacing . with - (e.g. color.bg → --color-bg); colors become hex, dimensions get a px unit, strings are emitted verbatim. This is the themed output sink for the modes the importers capture — consumable by Pulp's var(--x) runtime and by web tooling.

◆ export_designmd()

std::string pulp::view::export_designmd ( const Theme & theme,
const DesignMdProseHints & hints = {} )

Export DESIGN.md text or throw while the DESIGN.md merge path is gated.

◆ export_figma_variables()

std::string pulp::view::export_figma_variables ( const Theme & theme)

Export a Pulp Theme as Figma Variables-compatible JSON.

Produces the structure expected by Figma's variable creation APIs.

◆ export_stitch_design_system()

std::string pulp::view::export_stitch_design_system ( const Theme & theme)

Export a Pulp Theme as Stitch Design System-compatible JSON.

Produces the structure expected by Stitch's create/update_design_system APIs.

◆ export_tailwind_v3_json()

std::string pulp::view::export_tailwind_v3_json ( const DesignMdParseResult & parsed)

Emit a Tailwind v3 theme.extend-shaped JSON object from the parsed token tree.

Byte-compatible with @google/design.md's --format json-tailwind output for the common-case keys (colors, fontFamily, fontSize, lineHeight, letterSpacing, fontWeight, borderRadius, spacing).

◆ export_tailwind_v4_css()

std::string pulp::view::export_tailwind_v4_css ( const DesignMdParseResult & parsed)

Emit a Tailwind v4 @theme { ... } CSS block from the parsed token tree.

Uses Tailwind v4's CSS-variable token namespaces (--color-*, --font-*, --text-*, --leading-*, --tracking-*, --font-weight-*, --radius-*, --spacing-*).

◆ export_w3c_tokens()

std::string pulp::view::export_w3c_tokens ( const Theme & theme)

Export a Pulp Theme to W3C Design Tokens JSON.

◆ extract_claude_classnames()

ClaudeClassNameRules pulp::view::extract_claude_classnames ( const std::string & html)

Extract classname → declaration map from a Claude Design HTML export.

Walks every <style>...</style> block in document order. When a bundler <script type="__bundler/template"> envelope is present, the inner unwrapped HTML is also walked (that's where the real CSS lives for self-bundled exports). Returns an empty map when no recognizable CSS rules are found — never throws.

◆ extract_keyboard_shortcuts()

std::vector< DetectedShortcut > pulp::view::extract_keyboard_shortcuts ( const std::string & source,
const std::string & filename = "" )

Static-scan a TSX/JS source string for keyboard-shortcut patterns.

Recognized forms:

  • if (e.key === 'X') ... / if (e.code === 'X') ...
  • e.metaKey, e.ctrlKey, e.altKey, e.shiftKey (singular or combined with && or ||)
  • Inline onKeyDown={e => {...}} JSX prop bodies
  • window.addEventListener('keydown', handler) / document.addEventListener('keydown', handler) Pure regex / lexical pass — does NOT attempt to evaluate handler bodies or resolve dynamic e.key references. Returns an empty vector when no patterns match. Never throws. The filename arg is woven into each shortcut's source_location for traceability; pass "" if unknown.

◆ extract_svg_fragment()

std::string pulp::view::extract_svg_fragment ( const std::string & svg,
const std::string & marker )

◆ fader_chart_track_thickness()

float pulp::view::fader_chart_track_thickness ( float cross_extent)
inline

Height of the stadium a Fader's chart is drawn in, given the fader's extent across its track: half of it, kept between 8 and 24 units.

◆ fetch_webview_directory_resource()

std::optional< WebViewOptions::Resource > pulp::view::fetch_webview_directory_resource ( const std::string & path,
const std::filesystem::path & root_directory,
std::string index_filename = "index.html" )

Fetch a single file-system resource for a WebView custom resource server.

The root directory is treated as the web origin root, and requests are normalized so callers cannot escape it with .. path segments.

◆ fetch_webview_embedded_resource()

std::optional< WebViewOptions::Resource > pulp::view::fetch_webview_embedded_resource ( const std::string & path,
const std::string & html_embedded_name,
const std::vector< WebViewEmbeddedAsset > & assets )

Fetch a single embedded resource for a WebView custom resource server.

◆ fidelity_kind_info()

const FidelityKindInfo * pulp::view::fidelity_kind_info ( const std::string & kind)

Look up a kind by slug; nullptr if it is not in the taxonomy.

◆ fidelity_ledger_json()

std::string pulp::view::fidelity_ledger_json ( const std::vector< FidelityIssue > & issues,
const FidelityLedgerMeta & meta )

Serialize one import run's findings to a deterministic JSON ledger.

A finding's severity is "info" when it is informational (advisory, never gates –strict-fidelity) and "warning" otherwise, so the ledger's warning count equals count_strict_fidelity_failures(). Includes a per-kind summary and the taxonomy so a consumer can render kinds it does not know.

◆ fidelity_taxonomy()

const std::vector< FidelityKindInfo > & pulp::view::fidelity_taxonomy ( )

Every fidelity kind the checks can emit, in a stable documentation order.

This is the authoritative catalog; a kind a finding carries that is absent here is an unregistered kind (the ledger still records it, severity from the finding's own informational flag).

◆ fill_waveform_peak_vertices()

std::size_t pulp::view::fill_waveform_peak_vertices ( const pulp::audio::WaveformOverview & thumbnail,
const WaveformGpuStaticLayerPlan & plan,
std::span< WaveformPeakVertex > dst )
noexcept

Fill caller-owned vertices for CPU fallback or GPU upload staging.

Returns the number of vertices written, capped by dst.size(). This function performs no allocation and does not touch backend GPU resources.

◆ find_by_role_and_label()

const View * pulp::view::find_by_role_and_label ( const View & root,
View::AccessRole role,
std::string_view label )

Find the first descendant whose access_label exactly matches label and whose role equals role.

Returns nullptr if no match. Useful for test assertions that target a specific widget.

◆ find_duplicate_anchors()

std::vector< DuplicateAnchor > pulp::view::find_duplicate_anchors ( const IRNode & root)

◆ find_preset()

const ThemePreset * pulp::view::find_preset ( const std::string & id)

Look up a preset by id. Returns nullptr if not found.

◆ find_scroll_view_at()

ScrollView * pulp::view::find_scroll_view_at ( View & root,
Point root_point )

Find the deepest ScrollView whose bounds contain root_point (a point in root's local coordinate space).

Unlike View::hit_test, this ignores hit_testable / pointer-events gates and matches a ScrollView even over its EMPTY background (where hit_test can return null if no child sits under the point). The mac window host uses this so a wheel/trackpad scroll routes to the pane the cursor is over even when hovering blank space inside it — no click required. Returns nullptr if the point is over no ScrollView.

◆ find_unrenderable_alternate_frames()

std::vector< UnrenderableFrameSet > pulp::view::find_unrenderable_alternate_frames ( const IRNode & root)

◆ find_wheel_scroll_view_at()

View * pulp::view::find_wheel_scroll_view_at ( View & root,
Point root_point )

Find the deepest view that participates in native wheel scrolling.

◆ fit_combo_label()

float pulp::view::fit_combo_label ( std::string & text,
float avail,
float base,
float min,
const std::function< float(const std::string &, float)> & width_at )

◆ fit_corner_radii()

CornerRadii pulp::view::fit_corner_radii ( float width,
float height,
CornerRadii radii )

radii fitted to a width x height box the way CSS fits border radii (CSS Backgrounds 3, "Overlapping Curves"): a negative radius is 0, and when the two radii along any side sum to more than that side, every radius is scaled by f = min over the four sides of (side length / sum of its two radii), so adjacent curves meet instead of crossing.

One factor for all eight values keeps a circular corner circular, and radii that already fit come back unchanged. The background, the clip and every border style shape their corners from this, so a border's outer edge and the background under it are the same curve.

◆ flush_async_notifications()

void pulp::view::flush_async_notifications ( )

Deferred Notify::async callbacks, oldest first.

Called by the UI pump. Safe to call when empty. A callback queued DURING a flush runs on the next flush, not this one, so a self-retriggering listener cannot spin the pump.

◆ focused_input_under_root()

View * pulp::view::focused_input_under_root ( View & root)

Return this root's live focused input.

Uses RootInteractionState rather than the process-global compatibility shim.

◆ format_chord()

std::string pulp::view::format_chord ( KeyCode key,
std::uint16_t modifiers )

Render a (key + modifiers) chord as a user-facing string, e.g.

"Cmd+Shift+O" or "F5". Exposed so the editor and other UIs share one formatter. Modifier order is canonical (Ctrl, Alt, Shift, Cmd/Meta).

◆ format_press_reach_audit()

std::string pulp::view::format_press_reach_audit ( const PressReachAudit & audit)

Format an audit as a report a human reads in CI output.

Always includes the census, including when there are no findings.

◆ gather_package_design_controls()

PackageDesignControlSources pulp::view::gather_package_design_controls ( const std::filesystem::path & lockfile_path,
const std::filesystem::path & registry_path )

◆ generate_diff_image()

std::vector< uint8_t > pulp::view::generate_diff_image ( const std::vector< uint8_t > & reference_png,
const std::vector< uint8_t > & rendered_png,
uint8_t tolerance = 32 )

Generate a visual diff image highlighting differences between two PNGs.

Returns empty vector on failure. Matching pixels are dimmed, differing pixels are highlighted in red.

◆ generate_pulp_cpp()

CppExportResult pulp::view::generate_pulp_cpp ( const DesignIR & ir,
const IRAssetManifest & manifest,
const CppExportOptions & opts = {} )

Generate an ownable baked-C++ view artifact from a DesignIR.

The result contains a header/source pair: the header declares function_name() plus bake_asset_manifest(), and the source constructs the view tree directly with Pulp View widgets.

◆ generate_pulp_js()

std::string pulp::view::generate_pulp_js ( const DesignIR & ir,
const CodeGenOptions & opts = {} )

Generate Pulp JS code from a DesignIR.

Native mode (default) uses createCol/createRow/createKnob + setFlex. Web-compat mode uses document.createElement + el.style.

◆ generate_pulp_swift()

SwiftExportResult pulp::view::generate_pulp_swift ( const DesignIR & ir,
const IRAssetManifest & manifest,
const SwiftExportOptions & opts = {} )

Generate a baked SwiftUI artifact from a DesignIR.

Mirrors the C++ baker's core emit loop: resolves native widget kinds, walks the node tree, and emits a <root_view_name> View plus a <theme_type_name> token partition. The generated View binds knob/slider/toggle controls to PulpParameters via the PulpParameterResolving protocol (exact PulpParameter.name match — there is no stable string param key today).

◆ gpu_acquire_diagnostics()

GpuAcquireDiagnostics pulp::view::gpu_acquire_diagnostics ( double now_s,
double vsync_target_s,
double refresh_period_s,
int frames_in_flight )
noexcept

Build the record for one acquire.

now_s and vsync_target_s share one monotonic timebase (seconds); a non-positive target means the frame was not display-link driven. A non-positive or non-finite period reads as unknown.

◆ gpu_timing_requested()

bool pulp::view::gpu_timing_requested ( const char * env_value)
noexcept

Whether an environment value asks for GPU timing: "1", "true", "yes" or "on", case-insensitively.

Absent or anything else is off, because GPU timestamp queries relax the device's validation (see GpuSurface::Config::enable_gpu_timing) and must be a deliberate choice.

◆ guess_webview_mime_type()

std::string pulp::view::guess_webview_mime_type ( const std::string & path)

Best-effort MIME type guess for an HTML-linked asset path.

◆ has_accessibility_value()

bool pulp::view::has_accessibility_value ( const View & v)

True when the view has ANY value source at all (slots 1–4 above).

The Windows provider gates the UIA Value pattern on this: advertising IsValuePatternAvailable on an element whose get_Value returns a NULL BSTR is worse than not advertising it.

◆ has_data_display()

bool pulp::view::has_data_display ( std::string_view id)

◆ has_design_control_factory()

bool pulp::view::has_design_control_factory ( const std::string & factory_id)

◆ has_gpu_capture()

bool pulp::view::has_gpu_capture ( )

◆ has_screenshot_backend()

bool pulp::view::has_screenshot_backend ( )

◆ has_screenshot_decoder()

bool pulp::view::has_screenshot_decoder ( )

True when this build can decode PNG pixels for the mandatory capture content floor.

A host-provided encoded back buffer is not an honest capture capability without this validator.

◆ has_screenshot_provider()

bool pulp::view::has_screenshot_provider ( )

◆ hit_test_waveform_handles() [1/2]

WaveformHitResult pulp::view::hit_test_waveform_handles ( const WaveformViewport & viewport,
const WaveformHandleModel & model,
float x,
const HitMetrics & metrics,
float pixels_per_point = 1.0f )
nodiscard

Device-aware overload: the same hit test sized for the pointer driving it.

Projects metrics onto the tolerance the raw overload already takes, so a touch pointer widens the handle targets without a second geometry path.

◆ hit_test_waveform_handles() [2/2]

WaveformHitResult pulp::view::hit_test_waveform_handles ( const WaveformViewport & viewport,
const WaveformHandleModel & model,
float x,
float tolerance_px )
nodiscard

◆ hoist_captured_art_knobs()

void pulp::view::hoist_captured_art_knobs ( DesignIR & ir)

Captured-art knob promotion.

The figma-plugin "Export to Pulp" envelope captures a skeuomorphic knob's body as an asset-backed image child (a disc PNG) plus, often, a small separate indicator/pointer layer. Without this pass the native materializer synthesizes a default Knob and discards the captured art (the knob looks wrong — a generic value-arc instead of the design's disc). For each name/metadata-detected knob node:

  • exactly one substantial captured layer (+ only small pointer layers the native rotating notch replaces): HOIST the body disc's asset_ref + render_bounds onto the knob node and drop the captured children. The materializer then skins the knob with the disc and overlays the native notch — the knob stays INTERACTIVE and looks like the design.
  • two or more SUBSTANTIAL captured layers (body + highlight + logo …): demote to a plain container (audio_widget = none) so every layer renders as an image — faithful but not turnable; no silent layer loss.
  • zero captured layers: left as a default synthesized knob. Run this BEFORE enrich_imported_image_asset_metadata so the hoisted asset_ref receives its absolute asset_path + opaque-core metadata.

◆ host_elapsed_ms()

double pulp::view::host_elapsed_ms ( HostClock::time_point since)
inlinenoexcept

Milliseconds elapsed since since on the monotonic host clock.

◆ host_frame_composites()

bool pulp::view::host_frame_composites ( const HostFrameTick & tick,
bool damaged )
inlinenoexcept

Step 3 of a host tick, after advance_host_frame: does this frame composite?

damaged is the host's dirty flag read AFTER the advance, so it carries every repaint requested this tick — by input, by an activity probe, or by a FrameClock subscriber whose content moved. A tick that advanced only because a subscriber is live, and that no subscriber dirtied, composites nothing: the surface already shows the right pixels.

◆ hover_cursor_at()

View::CursorStyle pulp::view::hover_cursor_at ( View & root,
Point p )

The cursor style a pointer at p (root-view coordinates) should show over root: the style of the view hit_test resolves to, or default_ when the point hits nothing.

This is the same rule the platform hosts apply in their pointer handlers, factored out so the frame path can re-run it.

◆ hover_target_at()

View * pulp::view::hover_target_at ( View & root,
Point root_pt )

The view a HOVER at root_pt lands on: the deepest hit inside the topmost open overlay that contains the point, otherwise root.hit_test(root_pt).

An open overlay paints above everything else in its root, and a press over it is routed into it by route_press_to_active_overlay. A hover has to resolve the same way, or the cursor and the hover highlight report the content painted UNDER the menu: an overlay that reaches far outside the view it is mounted in (a dropdown that opens upward from a bottom rail) escapes the tree hit test, so the pointer over its rows shows the cursor of whatever the menu covers while a click on the same pixel operates the row.

Read-only: unlike a press, a hover never dismisses anything. An overlay whose own guards reject the point (for example pointerEvents: none) is skipped, so the one beneath it, or the ordinary tree, answers instead.

◆ hsl_to_rgb()

Color pulp::view::hsl_to_rgb ( HSL hsl,
float alpha = 1.0f )
inline

◆ import_report_to_json()

std::string pulp::view::import_report_to_json ( const ImportReport & report)

◆ import_report_to_text()

std::string pulp::view::import_report_to_text ( const ImportReport & report)

◆ infer_capabilities_from_js()

CapabilitySet pulp::view::infer_capabilities_from_js ( std::string_view js_source)
inline

Scan js_source and return the granted set it needs.

◆ infer_capability_names_from_js()

std::vector< std::string > pulp::view::infer_capability_names_from_js ( std::string_view js_source)
inline

The capability NAMES a scripted UI needs, sorted + de-duplicated — ready to drop into a manifest's declared_capabilities.

◆ init_accessibility()

void * pulp::view::init_accessibility ( View & root,
void * native_window )

Initialize the OS accessibility bridge for this root view.

On Windows this attaches a UIA fragment-root to the HWND; on Linux it registers the root AtkObject with AT-SPI. Called once per window on the main thread after the View tree is built.

Parameters
rootRoot of the View hierarchy exposed to a11y.
native_windowPlatform window handle. HWND on Windows; pointer to the GDK/Wayland surface on Linux. Ignored on platforms that derive it another way.
Returns
Opaque handle for later teardown via shutdown_accessibility; nullptr if the platform has no provider.

◆ inspect_capture_requirements()

CaptureRequirements pulp::view::inspect_capture_requirements ( View & root)

Inspect the tree once for requirements shared by capture routing and capability admission.

Host adapters should consume this instead of growing parallel native-overlay/GPU scans that can drift from capture_view().

◆ inspect_png_metadata()

PngMetadata pulp::view::inspect_png_metadata ( const std::vector< uint8_t > & png)

◆ install_script_inspector_bridge()

void pulp::view::install_script_inspector_bridge ( )
noexcept

Make every ScriptedUiSession constructed afterwards carry a ScriptInspectorBridge as its inspector port.

Process-wide and idempotent; a host that serves Runtime.* calls installs it before building its UI.

◆ invoke_file_drag_backend()

bool pulp::view::invoke_file_drag_backend ( const FileDragRequest & request)

◆ invoke_legacy_import_binder()

void pulp::view::invoke_legacy_import_binder ( std::string_view id,
NativeImportBindingContext & ,
View & ,
const NativeImportMeterBindingDescriptor * meter,
const NativeImportWaveformBindingDescriptor * waveform )

◆ ir_tokens_to_theme()

Theme pulp::view::ir_tokens_to_theme ( const IRTokens & tokens,
std::vector< std::string > * unresolved_widget_tokens = nullptr )

Convert IR tokens to a Pulp Theme.

Token names are copied across verbatim, then the widget keys Pulp's own primitives resolve (control.fill, knob.arc, meter.green, …) are filled from the design tokens that mean the same thing — accent, line-strong, signal-low and the shadcn / Material spellings of each. Every widget key is a direct copy of a colour the design stated: nothing is hue-shifted, blended, or defaulted, so a design's palette reaches its primitives without Pulp adding a colour of its own.

A widget key the design supplies no source for is left UNSET, and its name is appended to unresolved_widget_tokens when that is non-null. The widget then paints its own built-in default — an honest "the design did not say" — rather than a synthesized colour that would drift from the design's palette. A design that names a widget key itself always keeps its own value.

◆ is_accessibility_element()

bool pulp::view::is_accessibility_element ( const View & v)

The single gate EVERY accessibility bridge uses to decide whether a View enters the platform accessibility tree (macOS window host + plug-in editor host, iOS, Windows UIA fragments, Linux AT-SPI objects, Android TalkBack nodes) and the cross-platform snapshot's count_announceable().

A View is exposed when it has a role AND something to say with it:

  • a structural role (group / list / table / dialog / ... ) — it announces the children underneath it;
  • an accessible name;
  • a value source (slider, meter, progress bar, text field, combo box);
  • an ARIA state (aria-checked / aria-pressed — a checkbox or switch).

A role with NONE of those announces "button" (or "text field", or "image") and then falls silent: that is a WCAG 4.1.2 (Name, Role, Value) failure and pure noise in the tree, so the View is left out until it has a name. Keep this the ONLY predicate — a bridge that hand-rolls access_role() != none re-admits unnamed buttons on that one platform.

◆ is_authored_jsx_source()

bool pulp::view::is_authored_jsx_source ( const std::string & source)

Heuristic guard: does source look like hand-authored JSX/TSX (as opposed to a Pulp-generated web-compat artifact)?

This path only locks into authored source; a file that carries the generate_pulp_js banner or an @generated marker belongs to lock_to_source.hpp instead. Returns true when the source contains JSX (<Tag …> / </Tag> / <Tag/>) and is NOT flagged generated.

◆ is_banded_border_style()

bool pulp::view::is_banded_border_style ( View::BorderStyle style)

Whether style is painted in bands of per-side colour (double and the four 3D styles) rather than as one stroke.

◆ is_bound()

bool pulp::view::is_bound ( BindingOutcome o)
constexprnoexcept

True for the three outcomes that produced a live binding.

deferred_widget_missing counts as bound on purpose: scripts legitimately register a binding before creating the view, so treating it as a failure would report correct code as broken — the fastest way for a diagnostic to lose its audience.

◆ is_engine_available()

bool pulp::view::is_engine_available ( JsEngineType type)

◆ is_generated_source()

bool pulp::view::is_generated_source ( const std::string & source)

Heuristic guard for the generated-file boundary.

Pulp's generate_pulp_js emits // Generated by Pulp import-design from <source> as the first line; an // @generated marker is also accepted for files that adopt the conventional banner. Returns true when source looks like a Pulp-generated import artifact safe to rewrite.

◆ is_keyword()

bool pulp::view::is_keyword ( std::string_view name,
CodeLanguage language )

True when name is one of the keywords the tokenizer recognizes for language.

Useful for editor callers that want to do their own scanning but reuse the keyword set.

◆ is_main_modifier()

bool pulp::view::is_main_modifier ( uint16_t mods)
inline

True if the primary action modifier is held (Cmd on macOS, Ctrl on Windows/Linux).

◆ is_plugin_navigation_key()

bool pulp::view::is_plugin_navigation_key ( KeyCode key,
std::uint16_t modifiers )

The bounded navigation set a non-text widget may borrow from the host.

Not a statement about which keys the host wants — the host wants every key it is not denied. It is the floor that stops a merely navigable widget from consuming transport: a focused knob or list holding an active navigation interaction gets arrows/Home/End/Enter/Escape and nothing else, so Space still starts the transport and letters still reach Musical Typing. Any chord modifier removes a key from the set, because a chord belongs to the host or to the global hook.

◆ is_structural_access_role()

bool pulp::view::is_structural_access_role ( View::AccessRole role)
constexpr

Structural roles: a container announces the children underneath it, so it is meaningful without a name of its own.

Everything else is a leaf control that must announce a name, a value, a state, or text — otherwise it is a role and nothing else, which is a WCAG 4.1.2 (Name, Role, Value) failure.

◆ is_vector_kind()

bool pulp::view::is_vector_kind ( const std::string & type)

True for every normalized IR type that represents a vector / path-like shape (svg path/rect/line, ellipse/circle, polygon/polyline/star, …), matched on the IR type string only so the classification is identical across figma/pencil/stitch/v0.

Shared by the dropped-vector invariant and codegen's path-lowering branch so the two never drift.

◆ js_engine_creation_stats()

JsEngineCreationStats pulp::view::js_engine_creation_stats ( )

◆ jsx_lock_property_to_key()

std::optional< std::string > pulp::view::jsx_lock_property_to_key ( const std::string & property_path)

Map a dotted tweak property_path (paint.backgroundColor, style.width, layout.padding, a bare width, …) to the camelCase JSX style / prop key the engine looks for in style={{…}} or as a bare attribute.

Accepted leading namespaces — all collapse to the same prop surface:

  • paint.* — visual properties.
  • style.* — the C++ IRStyle field surface.
  • layout.* — box-model properties.
  • bare — a path with no dot is taken as the key directly.

Returns std::nullopt for paths with an unknown namespace, an empty leaf, a nested leaf (layout.padding.top), or a key that is not on the lockable allow-list — so the caller reports unsupported_property cleanly instead of producing a bogus edit.

◆ jsx_lock_tweak_into_source()

JsxLockResult pulp::view::jsx_lock_tweak_into_source ( const std::string & source,
const JsxLockTweak & tweak )

Locate the JSX element carrying data-pulp-anchor="<tweak.anchor_id>" in an authored JSX/TSX source string and surgically rewrite the literal value of the prop named by tweak.property_path so it carries tweak.value.

Behavior:

  • If the prop appears as a key inside an inline style={{…}} object literal, the matching property's value is rewritten.
  • Otherwise, if a bare attribute of that name exists (width={80} / color="#888"), its literal value is rewritten.
  • String-shaped values are emitted quoted; numeric-shaped values are emitted as bare JS number literals when the existing prop used a {…} expression, preserving the author's literal form.
  • Fails — source unchanged — on: no/duplicate anchor, an unsupported property path, or a prop whose value is not a plain literal the engine can rewrite (too_dynamic).

Pure function: never touches the filesystem, never throws.

◆ jsx_lock_tweaks_into_source()

std::vector< JsxLockResult > pulp::view::jsx_lock_tweaks_into_source ( const std::string & source,
const std::vector< JsxLockTweak > & tweaks )

Lock several tweaks into the same authored source in one pass.

Each tweak is applied to the running text so anchors stay valid even when two tweaks target the same element. The returned vector is parallel to tweaks; the fully-patched text is in every element's source (they share the running buffer at completion).

◆ key_string_to_keycode()

int pulp::view::key_string_to_keycode ( const std::string & key)

Map a W3C KeyboardEvent.key (or KeyboardEvent.code) string to a Pulp KeyCode integer.

Returns 0 (KeyCode::unknown) for unrecognized strings — caller should skip those shortcuts (with a warning) rather than wire them with a bogus binding.

◆ layout_tree_snapshots_equivalent()

bool pulp::view::layout_tree_snapshots_equivalent ( std::string_view actual_json,
std::string_view expected_json,
const LayoutTreeTolerance & tolerance = {},
LayoutTreeDiff * diff = nullptr )

Compare two dump_layout_tree() JSON strings with the layout oracle rules: node kind/id/visibility/z-order/overflow must match exactly, numeric layout bounds must match exactly by default, and text-box dimensions allow a small tolerance for text measurement.

Golden-file callers that compare snapshots produced on different platforms should pass an explicit numeric bounds tolerance instead of relying on the in-process exact-match default.

◆ lint_designmd()

std::vector< DesignMdDiagnostic > pulp::view::lint_designmd ( const DesignMdParseResult & parsed)

Run Pulp's Google design.md compatibility lint against a parsed DESIGN.md.

Findings carry severity (info/warning/error).

◆ load_webview_embedded_text()

std::string pulp::view::load_webview_embedded_text ( const std::string & embedded_name)

Load a UTF-8 text asset previously registered with AssetManager.

◆ lock_property_to_style_name()

std::optional< std::string > pulp::view::lock_property_to_style_name ( const std::string & property_path)

Map a dotted tweak property_path (paint.backgroundColor, style.width, layout.padding, …) to the camelCase CSS property name the web-compat codegen emits as el.style.

<name>.

Accepted path prefixes — all collapse to the same style surface:

  • paint.* — visual properties from the TS canonical IR.
  • style.* — the C++ IRStyle field surface.
  • layout.* — box-model properties (padding, gap, width, height …).
  • bare — a path with no dot is taken as the property directly.

Returns std::nullopt for paths the generated codegen has no line for (so the caller can report unsupported_property cleanly rather than emitting a bogus assignment).

◆ lock_token_in_designmd() [1/2]

TokenLockResult pulp::view::lock_token_in_designmd ( const std::string & markdown,
const std::string & anchor_id,
const std::string & property_path,
const std::string & new_value )

Convenience overload: classify + lock in one call.

Returns a failure result with a descriptive error when the tweak is not token-typed.

◆ lock_token_in_designmd() [2/2]

TokenLockResult pulp::view::lock_token_in_designmd ( const std::string & markdown,
const TokenTarget & target,
const std::string & new_value )

Lock a single token tweak back into DESIGN.md text.

Parameters
markdownThe current DESIGN.md file contents.
targetThe classified token (see classify_token_tweak).
new_valueThe corrected value to write. For colors this is a hex string ("#5a5a5a"); for spacing / rounded a dimension string ("12px", "1rem"); for typography the raw field value.

Behavior:

  • Parses the YAML frontmatter to confirm the token exists and is reachable unambiguously.
  • Rewrites ONLY that token's value in the original text, preserving every other byte (prose, comments, key order, indentation, the value's surrounding quotes if present).
  • Fails (ok=false, markdown unchanged) when:
    • DESIGN.md has no YAML frontmatter,
    • the token group is absent,
    • the token name is absent from its group,
    • a typography target's field is absent from the level,
    • the token line cannot be located unambiguously in the source text (e.g. the same name: key appears under more than one group and the parse cannot disambiguate).

The function never throws — all failure modes are reported via the result's error string.

◆ lock_tweak_into_source()

LockResult pulp::view::lock_tweak_into_source ( const std::string & source,
const LockToSourceTweak & tweak )

Locate the element anchored by tweak.anchor_id in a generated web-compat JS/TSX source string and rewrite (or insert) the style assignment for tweak.property_path so it carries tweak.value.

The element block is delimited by its // @pulp-anchor <id> trail comment and runs until the next // @pulp-anchor comment or a blank line — whichever comes first. Within that block the engine looks for <var>.style.<prop> = '<old>'; and rewrites the literal; if no such line exists it inserts one just before the block's appendChild / setAnchor tail (or at the end of the block).

Pure function: never touches the filesystem, never throws.

◆ lock_tweaks_into_source()

std::vector< LockResult > pulp::view::lock_tweaks_into_source ( const std::string & source,
const std::vector< LockToSourceTweak > & tweaks )

Lock several tweaks into the same source in one pass.

Each tweak is applied to the running text so anchors stay valid even when two tweaks target the same element. The returned vector is parallel to tweaks; the final fully-rewritten text is in the last element's source (and in every element's source, since they share the running buffer at completion).

◆ looks_like_bundler_entry()

bool pulp::view::looks_like_bundler_entry ( const std::string & html)

Heuristic: does this HTML look like a JS-bundler entry (React, Vue, Svelte, @pulp/react, generic webpack/vite/bun output) rather than a hand-authored Claude Design page?

The static-HTML parser only sees the literal DOM, so for bundler entries it captures the empty mount placeholder. Used by pulp import-design --from claude to print a "use pulp-design-tool --script <bundle>.js" hint instead of letting the user wonder why their 1000-element editor became a 9-element ui.js. Never throws; returns false on any empty/unparseable input.

◆ lower_faithful_capture_to_image()

std::optional< IRNode > pulp::view::lower_faithful_capture_to_image ( const IRNode & node)
inline

Canonical lowering from an authoritative browser-capture node to the ordinary image-node contract shared by JS, baked C++, and native materialization.

Semantic overlays are deliberately not promoted here.

◆ lower_faithful_captures_in_place()

void pulp::view::lower_faithful_captures_in_place ( IRNode & node)
inline

◆ make_chart_shader_preset()

ChartShaderPreset pulp::view::make_chart_shader_preset ( std::string_view name,
const ChartShaderPresetOptions & options = {} )

Build the named preset's chart shader with options baked in as constants.

Pure: no canvas or GPU is needed, and the same inputs give the same source. An unknown name or an out-of-range option is refused with a message naming it.

◆ make_data_display()

std::unique_ptr< View > pulp::view::make_data_display ( std::string_view id)

◆ make_open_settings_command_info()

CommandInfo pulp::view::make_open_settings_command_info ( )
inline

CommandInfo for kCommandOpenSettings with the platform-standard chord as its default binding.

register_command() skips the default binding when the chord (or the command) is already bound in the ShortcutMap, so a user rebind loaded from disk always wins over this default.

Nothing fires unless the app also registers a handler that claims kCommandOpenSettings — an app without settings leaves the chord unclaimed, and dispatch_key_event returns false so the host (a DAW owning the keyboard, or the OS menu bar) sees the event unchanged.

◆ make_webview_bridge_bootstrap_script()

std::string pulp::view::make_webview_bridge_bootstrap_script ( )

JavaScript helper that installs a small window.pulp bridge on a page.

Pages can append this script to their bundled HTML to use window.pulp.postMessage(type, payload, id) and receive window.pulp.on(type, callback) events from native code.

◆ make_webview_data_uri()

std::string pulp::view::make_webview_data_uri ( const std::string & mime_type,
const std::vector< uint8_t > & bytes )

Create a data: URI for an embedded WebView asset.

◆ make_webview_directory_resource_fetcher()

WebViewOptions::FetchResource pulp::view::make_webview_directory_resource_fetcher ( std::filesystem::path root_directory,
std::string index_filename = "index.html" )

Create a resource callback that serves files from a directory through CHOC's fetchResource/customSchemeURI path.

Useful for local development flows such as a separately-built Monaco distribution.

◆ make_webview_embedded_resource_fetcher()

WebViewOptions::FetchResource pulp::view::make_webview_embedded_resource_fetcher ( std::string html_embedded_name,
std::vector< WebViewEmbeddedAsset > assets )

Create a resource callback that serves embedded HTML/assets through CHOC's fetchResource/customSchemeURI path.

◆ make_webview_eval_script()

std::string pulp::view::make_webview_eval_script ( const std::string & request_id,
const std::string & js_source )

JavaScript wrapper that evaluates user code asynchronously and reports the result back through the internal __pulpEvalResult bridge.

◆ make_webview_offline_html()

std::string pulp::view::make_webview_offline_html ( const std::string & html,
const std::vector< WebViewEmbeddedAsset > & assets )

Rewrite simple src/href references in HTML to offline data: URIs backed by embedded assets.

◆ make_webview_offline_html_from_embedded()

std::string pulp::view::make_webview_offline_html_from_embedded ( const std::string & html_embedded_name,
const std::vector< WebViewEmbeddedAsset > & assets )

Load embedded HTML and rewrite its referenced assets for offline use.

◆ materialize_recognized_custom_controls()

int pulp::view::materialize_recognized_custom_controls ( IRNode & root)

◆ materialized_document_cache_stats()

MaterializedDocumentCacheStats pulp::view::materialized_document_cache_stats ( )

◆ meets_contrast()

bool pulp::view::meets_contrast ( Color foreground,
Color background,
ContrastLevel level = ContrastLevel::aa_normal )

Check if a foreground/background pair meets a given contrast level.

◆ min_contrast_for_level()

float pulp::view::min_contrast_for_level ( ContrastLevel level)

Get the minimum contrast ratio required for a given level.

◆ modifier_strings_to_mask()

int pulp::view::modifier_strings_to_mask ( const std::vector< std::string > & mods)

Combine modifier strings ("shift", "ctrl", "alt", "meta") into the bitmask registerShortcut consumes.

"meta" maps to kModCmd (the platform-primary modifier). "ctrl" maps separately to kModCtrl, including when extract_keyboard_shortcuts captures both modifiers from the metaKey || ctrlKey idiom. Unknown strings are silently dropped.

◆ motion_policy_from_string()

MotionPolicy pulp::view::motion_policy_from_string ( const std::string_view s)
inline

Parse a policy string (case-sensitive). Returns Full on unknown.

◆ motion_policy_is_off()

bool pulp::view::motion_policy_is_off ( )
inline

Returns true when the current policy says "do not animate" — i.e.

the primitive should jump straight to its target value.

◆ motion_policy_to_string()

const char * pulp::view::motion_policy_to_string ( MotionPolicy p)
inline

Returns the current policy string for fixture headers.

◆ needs_continuous_frames()

bool pulp::view::needs_continuous_frames ( const View * view)

True if view (or any descendant) needs continuous per-frame repaints.

Null-safe: a null pointer returns false. Read-only; does not advance any animation. Pair with FrameClock::has_active_subscribers() for the full "keep the render loop alive" decision.

◆ normalize_border_shorthand()

void pulp::view::normalize_border_shorthand ( IRNode & root)

Split the CSS border shorthand — "1px solid #333" — into the discrete border_color / border_width / border_style fields, for every node in the tree that set the shorthand but not the parts.

IRStyle carries both spellings, and the producers all write the shorthand: the .fig decoder, the Claude bundle reader, and the v0 TSX reader. Every native consumer reads only the parts — codegen's setBorder requires border_color AND border_width, and synthesize_node moves border_color onto a synthesized path. So a stroke declared in a design reached the IR and then went nowhere: six declared strokes lowered to zero setBorder + zero setSvgStroke calls in a real 1115-node import.

Only fills gaps — a producer that already set the parts wins, since it said what it meant more precisely than the shorthand can.

◆ notify_accessibility_focus_changed()

void pulp::view::notify_accessibility_focus_changed ( void * handle,
View & target )

Notify the provider that focus moved to a different View.

On Windows this raises UIA_AutomationFocusChangedEventId. On Linux AT-SPI this emits object::state-changed::focused (true on focus, false on blur).

◆ notify_accessibility_name_changed()

void pulp::view::notify_accessibility_name_changed ( void * handle,
View & target )

Notify the provider that a View's accessible name or role changed (e.g.

a button's label was updated). Fires UIA_AutomationPropertyChangedEvent for Name / LocalizedControlType; AT-SPI object::property-change.

◆ notify_accessibility_value_changed()

void pulp::view::notify_accessibility_value_changed ( void * handle,
View & target )

Notify the provider that a View's access_value has changed.

On Windows this raises UIA_AutomationPropertyChangedEvent(UIA_ValueValueProperty). On Linux AT-SPI this emits object::property-change::accessible-value. On macOS/iOS this forwards to the NSAccessibility/UIAccessibility notification APIs on the view side.

◆ operator!=()

bool pulp::view::operator!= ( const WaveformGpuUploadKey & a,
const WaveformGpuUploadKey & b )
nodiscardnoexcept

◆ operator==()

bool pulp::view::operator== ( const WaveformGpuUploadKey & a,
const WaveformGpuUploadKey & b )
nodiscardnoexcept

◆ opposite_side()

CalloutSide pulp::view::opposite_side ( CalloutSide s)

Opposite side, used by the auto-flip.

◆ overlay_dismissal_policy()

const OverlayDismissalPolicy & pulp::view::overlay_dismissal_policy ( )

The active policy. Reading is cheap and allocation-free.

◆ paint_banded_border()

void pulp::view::paint_banded_border ( canvas::Canvas & canvas,
const BandedBorder & border )

Paint border.

Each band is the region between two rounded rectangles — the outer one inset by the bands outside it, the inner one by the bands up to its inside edge, with corner radii shrunk by the inset on each axis as CSS shrinks them — so a rounded border keeps a curved inner edge. The band is divided between sides by the line from each outer box corner through the matching padding-box corner, and sides that share a colour are filled as one shape, so no antialiased seam runs down a mitre between them.

◆ paint_caret()

void pulp::view::paint_caret ( canvas::Canvas & canvas,
CaretStyle style,
const CaretMetrics & metrics,
canvas::Color color )

Fill the caret rect.

For block this covers the glyph — use paint_caret_over_text unless the caller redraws the glyph itself.

◆ paint_caret_over_text()

void pulp::view::paint_caret_over_text ( canvas::Canvas & canvas,
CaretStyle style,
const CaretMetrics & metrics,
canvas::Color color,
canvas::Color text_bg,
const std::string & text,
float text_x )

Paint the caret, and for block redraw the covered glyph in text_bg so it stays legible against the fill.

text is the full string the widget just painted, drawn from text_x at metrics.baseline; only the caret cell is repainted, clipped to the block rect. Fonts and alignment must be set on canvas exactly as they were for the original fill_text.

◆ paint_plugin_scene()

void pulp::view::paint_plugin_scene ( canvas::Canvas & canvas,
View & root,
const FrameGeometry & geometry,
const Rect * clip )

Paint one editor frame: background fill (geometry.background_rgb), design-viewport transform, view tree, overlays.

When clip is non-null the ENTIRE body is clipped, background fill included — everything outside the clip must remain the retained scene's previous pixels, and an unclipped background fill would erase them.

◆ param_index_to_normalized()

double pulp::dataplane::param_index_to_normalized ( int index,
int step_count )
inline

Map a discrete parameter's value index to a normalized [0, 1] value.

The denominator is step_count - 1, not step_count: with N values, index 0 maps to 0.0 and index N-1 maps to 1.0, so the top index reaches the top of the host's automation range. This is the same convention state::ParamRange::normalize() produces for an evenly-spaced discrete range, and the one every format adapter round-trips against.

Evenly-spaced is the assumption, and it is why this takes a bare count: a host surface may have no ParamRange behind it at all (an embedded framework's parameter tree reaches this surface over a C ABI). A discrete parameter whose ParamRange declares a skew is therefore OUT of this helper's contract — the range's own curve, not this line, defines its normalized values, and the two disagree. Declare discrete parameters with a linear range (ParamRange::is_linear()); reach for range.normalize() directly if one genuinely must be shaped.

Parameters
step_counta HostParamSurface::param_step_count() result. 0 (the continuous/unknown signal) and 1 (a single-value parameter) both have no index domain and yield 0.0 — this is the guard that keeps the 0 contract from becoming a division by zero at a call site.

◆ param_normalized_to_index()

int pulp::dataplane::param_normalized_to_index ( double normalized,
int step_count )
inline

Inverse of param_index_to_normalized: the nearest value index for a normalized [0, 1] value.

Rounds to nearest so a value landing between two indices snaps to the closer one. Yields 0 when step_count carries no index domain (0 or 1).

◆ parse_chart_profile()

bool pulp::view::parse_chart_profile ( std::string_view name,
ChartProfile & out )

Parse a profile name (round, flat, chamfer).

◆ parse_claude_bundle()

std::optional< ClaudeBundle > pulp::view::parse_claude_bundle ( const std::string & html)

Decode the bundler envelope from a Claude Design standalone HTML file.

Returns nullopt if the bundler tags are missing or the envelope is malformed. Bundle parsing failures degrade gracefully: callers fall back to parse_claude_html for the static-HTML pipeline.

◆ parse_claude_html()

DesignIR pulp::view::parse_claude_html ( const std::string & html)

Parse a Claude Design standalone HTML export into a DesignIR.

Claude Design exports the same HTML+CSS shape as other web tools, so the parse path delegates to the Stitch HTML parser. Source-tagged as DesignSource::claude so downstream code (CLI bridge scaffold, SKILL guidance) can route on it.

◆ parse_claude_html_with_runtime()

DesignIR pulp::view::parse_claude_html_with_runtime ( const std::string & html,
ClaudeRuntimeOptions opts = {} )

Run the Claude Design bundle in a headless JS engine and harvest the materialized DOM into a DesignIR.

The success bar is "more than 9 elements" (the loader-shell baseline that the static parser produces). On any failure — missing bundle envelope, JS engine error, empty walker output — returns the result of parse_claude_html(html) so the caller's behavior never drops below the static-parse floor.

◆ parse_css_box_shadow()

std::vector< IRBoxShadow > pulp::view::parse_css_box_shadow ( const std::string & css)

Parse a CSS box-shadow value into ordered layers.

Splits on top-level commas only (commas inside rgb()/rgba() are preserved), then parses each layer's offsets/blur/spread/color/inset. Numeric lengths accept an optional px suffix. Empty / "none" input yields an empty vector. Each layer keeps its trimmed original text in raw for lossless round-trip.

◆ parse_css_color()

canvas::Color pulp::view::parse_css_color ( const std::string & token)

The built-in CSS color parser: #RGB / #RRGGBB / #RRGGBBAA, rgb(), rgba(), hsl(), hsla(), oklab(), oklch(), and transparent.

oklab() / oklch() matter because Chromium serializes every modern colour syntax into them, so a captured design reaches this parser in Oklab whatever it was authored in. Returns opaque white on an unrecognized token. Exposed so other import lanes (e.g. the materializer's hairline-stroke path) can resolve rgba(...) strokes that parse_hex_color does not cover.

◆ parse_css_float_token()

bool pulp::view::parse_css_float_token ( const std::string & token,
float & out )
inline

◆ parse_css_time_seconds()

float pulp::view::parse_css_time_seconds ( const std::string & s)
inline

Parse a CSS time string (200ms / 0.3s / bare seconds) into seconds.

Returns 0 on parse failure.

◆ parse_design_ir_json()

DesignIR pulp::view::parse_design_ir_json ( const std::string & json)

Parse either the v1 canonical envelope or a legacy bare-node IR JSON document.

Legacy source adapters keep their JSON-first compatibility by routing through this reader. Malformed input throws DesignIrParseError; the bytes are bounds-checked before the JSON parser sees them, so a truncated or hostile document cannot read past the end of json.

◆ parse_design_source()

std::optional< DesignSource > pulp::view::parse_design_source ( const std::string & name)

Convert string to DesignSource, returns nullopt for unknown sources.

◆ parse_designmd()

DesignMdParseResult pulp::view::parse_designmd ( const std::string & markdown)

Parse a DESIGN.md file (YAML frontmatter + Markdown body) into a DesignIR.

Errors are reported via diagnostics, not exceptions; the IR is partially populated on parse error so callers can still surface what was readable.

◆ parse_designmd_yaml()

DesignIR pulp::view::parse_designmd_yaml ( const std::string & markdown)

Thin wrapper that returns just the IR.

The CLI uses parse_designmd() directly so it can emit structured diagnostics; this overload exists for parity with the other source adapters' signatures.

◆ parse_figma_json()

DesignIR pulp::view::parse_figma_json ( const std::string & json)

Parse a Figma export JSON into a DesignIR.

◆ parse_figma_make_react()

std::optional< ClaudeBundle > pulp::view::parse_figma_make_react ( const std::string & tsx)

Normalize a constrained Figma Make React TSX export into the runtime-import bundle payload shape.

C-2 accepts a sanitized single-file TSX component: Figma Make provenance must be explicit, versions/assets must already be stripped, and styling must use inline style={{...}} objects rather than Tailwind/Radix/default Figma Make dependencies.

◆ parse_figma_plugin_json()

DesignIR pulp::view::parse_figma_plugin_json ( const std::string & json)

Parse Pulp's "Design for Pulp" Figma-plugin export envelope.

◆ parse_figma_variables()

Theme pulp::view::parse_figma_variables ( const std::string & json)

Parse Figma Variables JSON (from MCP get_variable_defs) into a Pulp Theme.

Figma variables are organized into collections with modes. Each variable has resolvedValue for the default mode.

◆ parse_jsx_react()

std::optional< ClaudeBundle > pulp::view::parse_jsx_react ( const std::string & bundle_js,
const std::string & component_name = "JsxComponent" )

Wrap a pre-compiled JSX runtime bundle (esbuild IIFE of React plus either ReactDOM or the @pulp/react native bridge and the user's JSX component, produced by tools/import-design/jsx-runtime/ jsx-transform.mjs) as a synthetic ClaudeBundle so the existing runtime-import harness (parse_claude_html_with_runtime) can materialize it.

The C++ side does not compile JSX itself — the Node-side esbuild step is shelled out by the CLI before this is called.

component_name is purely cosmetic — it lands on the synthetic <div id="root" data-jsx-component="…"> template, useful for diagnostic inspection.

Returns nullopt for sources that are obviously too small to be a real bundle (< 100 bytes), so the CLI can surface a clean diagnostic when the upstream Node transform produced an empty file.

◆ parse_materialized_browser_document()

std::optional< ClaudeBundle > pulp::view::parse_materialized_browser_document ( const std::string & json)

Decode the deterministic pre-mount document emitted by Chromium browser capture.

The sidecar records the exact HTML passed to DOMParser after an adapter has patched the source, plus every Blob-backed asset it references. Returned bundles use stable synthetic asset IDs and can be evaluated by the same native runtime path as a regular Claude bundle.

◆ parse_materialized_browser_document_shared()

std::shared_ptr< const ClaudeBundle > pulp::view::parse_materialized_browser_document_shared ( const std::string & json)

parse_materialized_browser_document with process-wide reuse.

Decoding a captured document — JSON parse, base64 decode, and a SHA-256 check of every asset — costs on the order of 100 ms for a plug-in UI, and an editor runs it on every open. The first call for a document does the full decode and verification; every later call in the same process with byte-identical input returns the same immutable bundle. Keyed by the full input bytes (size, then an exact compare), so a hit is never a different document, and only accepted documents are kept: a rejected input is decoded again on every call and still returns nullptr. In-memory only and bounded; PULP_RUNTIME_IMPORT_CACHE=0 disables reuse.

◆ parse_param_binding_manifest_json()

std::optional< std::unordered_map< std::string, std::string > > pulp::view::parse_param_binding_manifest_json ( const std::string & json,
std::string * error )

Parse a --param-binding-manifest document — a flat JSON object mapping a Figma node id to a host-param key, e.g.

{"10:42": "filter.cutoff"} — into a map suitable for apply_param_binding_manifest. Entries with an empty key, a non-string value, or an empty value are skipped (lenient, like the IR parser). Returns std::nullopt only on malformed JSON or a non-object root, setting *error (when non-null).

◆ parse_pencil_json()

DesignIR pulp::view::parse_pencil_json ( const std::string & json)

Parse Pencil node tree JSON into a DesignIR.

◆ parse_pencil_react()

std::optional< ClaudeBundle > pulp::view::parse_pencil_react ( const std::string & tsx)

Normalize a constrained Pencil/OpenPencil sanitized Tailwind-JSX export into the runtime-import bundle payload shape.

The initial runtime-import slice requires the caller to pass source="pencil" and expects Tailwind utilities plus --pencil-* tokens to have already been resolved into inline React styles. Returns nullopt for unresolved tokens, MCP JSON, binary .pen/.fig references, external CSS, framework wrappers, or any surface outside Pulp's supported runtime-import DOM/CSS/API subset.

◆ parse_react_native_export()

std::optional< ClaudeBundle > pulp::view::parse_react_native_export ( const std::string & tsx)

Normalize a constrained React Native single-file component export into the runtime-import bundle payload shape.

RN has an unambiguous envelope (from "react-native"), so the runtime dispatch may auto-detect it when the source label is omitted. Returns nullopt for native/device APIs, navigation/Expo wrappers, images, style arrays, DOM tags, or any surface outside Pulp's supported runtime-import DOM/CSS/API subset.

◆ parse_stitch_design_system()

Theme pulp::view::parse_stitch_design_system ( const std::string & json)

Parse a Stitch Design System JSON (from MCP list_design_systems/get_screen) into a Pulp Theme.

Maps Stitch colors, fonts, and roundness to tokens.

◆ parse_stitch_html()

DesignIR pulp::view::parse_stitch_html ( const std::string & html)

Parse Stitch HTML export into a DesignIR.

◆ parse_stitch_react()

std::optional< ClaudeBundle > pulp::view::parse_stitch_react ( const std::string & tsx)

Normalize a constrained Google Stitch React export into the runtime-import bundle payload shape.

Stitch has no reliable standalone file marker, so callers should route here only from an explicit source: "stitch" manifest or runtime-import source label. Returns nullopt for Tailwind/default Stitch exports, external CSS, Next/Radix wrappers, RN imports, MCP JSON, or any surface outside Pulp's supported runtime-import DOM/CSS/API subset.

◆ parse_transition_shorthand()

std::vector< TransitionSpec > pulp::view::parse_transition_shorthand ( const std::string & css)
inline

Parse a CSS transition shorthand into a list of TransitionSpecs.

transition: opacity 200ms ease, transform 300ms ease-in 100ms

Per the CSS spec, each comma-separated entry has up to four tokens: property (default 'all'), duration (default 0s), timing-function (default ease), delay (default 0s). The first time-valued token is duration; the second is delay. Cubic-bezier(...) and steps(...) are parsed into the structured CssEasing form.

◆ parse_transition_shorthand_with_provenance()

std::vector< TransitionSpec > pulp::view::parse_transition_shorthand_with_provenance ( const std::string & css,
std::string source_file,
int source_line )
inline

Parse a transition shorthand AND stamp each emitted TransitionSpec with the source attribution (CSS file path + line number, or React/JS component file:line when the CSS came from an inline style="...").

The legacy parse_transition_shorthand() entry point continues to work unchanged for callers that don't have or don't care about a source location.

◆ parse_v0_dev_react()

std::optional< ClaudeBundle > pulp::view::parse_v0_dev_react ( const std::string & tsx_or_envelope)

Normalize a constrained v0.dev React TSX export into the runtime-import bundle payload shape.

Accepts either a bare single-file TSX component or a v0 code-project envelope with [V0_FILE]tsx:file="..." blocks. Returns nullopt when the artifact uses surfaces outside Pulp's supported runtime-import DOM/CSS/API subset (Tailwind/shadcn/Next wrappers, network APIs, storage APIs, unsupported JSX tags, etc.).

◆ parse_v0_tsx()

DesignIR pulp::view::parse_v0_tsx ( const std::string & tsx)

Parse v0-generated TSX/Tailwind into a DesignIR.

◆ parse_w3c_tokens()

Theme pulp::view::parse_w3c_tokens ( const std::string & json)

Parse W3C / DTCG Design Tokens JSON into a Pulp Theme.

◆ passes_capture_content_floor()

bool pulp::view::passes_capture_content_floor ( const std::vector< uint8_t > & png)

Apply the same deliberately lenient "did anything paint?" floor used by capture_view().

Host back-buffer adapters should use this before accepting an encoded frame so a valid but clear-only PNG can fall back or fail closed.

◆ place_callout()

CalloutPlacement pulp::view::place_callout ( const Rect & anchor,
float body_w,
float body_h,
const Rect & window,
CalloutSide preferred,
const CalloutStyle & style = {} )

Place a body_w×body_h callout tethered to anchor, kept inside window.

Starts from preferred; if the body wouldn't fit on that side but WOULD on the opposite side, flips. Centers the body on the anchor along the cross axis, then clamps that cross axis inside the window margins. The arrow tip points at the center of the anchor's facing edge, clamped so its base stays on the body edge clear of the corner radii — so a body pushed sideways by clamping still points back at the anchor. Robust for a tiny window (returns a best-effort box).

◆ plan_design_child_updates()

DesignChildUpdatePlan pulp::view::plan_design_child_updates ( std::span< const IRNode > old_children,
std::span< const IRNode > new_children )

◆ plugin_key_focus()

View * pulp::view::plugin_key_focus ( View & root)

The focused view under root, or nullptr.

View::focused_input_ is process-global, so with two plugin editors open it names whichever field the user last typed in — possibly the OTHER editor's. Answering a key from that slot lets editor B consume a key aimed at editor A and report it handled, so the host never sees it either. The ancestor walk is what scopes the answer to this tree.

◆ point_to_local()

Point pulp::view::point_to_local ( Point root_pos,
View * target,
View * root )

Convert root_pos (root-local, i.e.

window space) into target's local-pre-scale coordinates, peeling off the root's scale plus each descendant's bounds offset, set_scale transform, and ScrollView scroll offset along the way. target must be root or a descendant of it.

◆ poll_bindings()

void pulp::view::poll_bindings ( std::vector< state::Binding > & bindings)
inline

Poll all bindings in a vector to sync with host automation.

Note
Soft-deprecated alongside Binding::poll(). Prefer the VBlank-locked dirty-flag pattern: have parameter changes call WindowHost::mark_dirty() so the UI repaints once on the next vsync instead of polling every binding on a timer. This helper remains for hosts without a vblank-driven RenderLoop.

◆ precompile_scripts()

std::size_t pulp::view::precompile_scripts ( const std::vector< std::string > & sources,
const std::atomic< bool > * cancel = nullptr )

Compile whole scripts into the bytecode cache without running them, on the calling thread, in a private QuickJS runtime.

A later realm that evaluates byte-identical source with evaluate_script() reads the bytecode instead of parsing; one that asks while this call is still compiling that source waits for it rather than compiling it a second time. Sources already cached, being compiled elsewhere, or below the cache's size floor are skipped. cancel, when set, is checked between scripts. Returns how many scripts it compiled. A no-op (0) when the cache is disabled. The calling thread needs a stack of a few MB: QuickJS's parser recurses on the native stack (ScriptedUiPrewarmer runs it on such a thread).

◆ preset_ids()

std::vector< std::string > pulp::view::preset_ids ( )

Get the list of preset ids.

◆ press_channel_name()

const char * pulp::view::press_channel_name ( PressChannel channel)

Human-readable channel name, for reports and test failure messages.

◆ prewarm_scripted_ui()

void pulp::view::prewarm_scripted_ui ( ScriptedUiPrewarmRequest request)

Queue request for the process's prewarm worker and return at once.

The worker is one background thread, started on first use, that processes requests in order and is joined when the process (or the plug-in image) tears down. Work already cached, or in flight on another thread, is skipped, so every plug-in instance may call this with the same request; an editor that opens while its scripts are still compiling waits for that compile instead of starting its own.

A no-op when PULP_EDITOR_PREWARM=0 is set in the environment (A/B and negative controls), or when the default script engine is not QuickJS.

◆ promote_interactive_frames()

std::size_t pulp::view::promote_interactive_frames ( IRNode & root)

Promote parsed frame nodes carrying click/ARIA/cursor signals to button.

Runs automatically from the parse APIs; exposed for tests and callers that construct IR manually.

◆ pulp_audio_control_library_source()

RecognitionSource pulp::view::pulp_audio_control_library_source ( )

The built-in library as one recognition source named "builtin-library".

Mirrors tools/figma-plugin/library-manifest.json; a unit test pins the two against each other so they cannot drift.

◆ queue_async_notification()

void pulp::view::queue_async_notification ( std::function< void()> fn)

Queue a callback for the next flush.

Exposed so a widget that owns extra listeners (gesture callbacks, say) can defer them with the same policy.

◆ raw_rgba_render_available()

bool pulp::view::raw_rgba_render_available ( )

◆ reach_of_press()

PressReach pulp::view::reach_of_press ( View & root,
Point root_pt,
PressChannel channel = PressChannel::click )

Resolve — without delivering — what a press at root_pt would reach.

root_pt is in root-local (window) coordinates, the same space the platform hosts hand to route_context_press and View::simulate_click.

◆ recognition_resolver_with_builtin_library()

RecognitionResolver pulp::view::recognition_resolver_with_builtin_library ( )

A resolver seeded with the built-in library as source 0.

Equivalent to RecognitionResolver{}.add_source(pulp_audio_control_library_source()).

◆ recolor_svg_fragment()

std::string pulp::view::recolor_svg_fragment ( std::string fragment,
const std::string & hex,
bool include_stroke = false )

◆ recommend_engine_for_script()

EngineRecommendation pulp::view::recommend_engine_for_script ( std::string_view js_source,
JsEngineType current = JsEngineType::quickjs )

◆ recommend_engine_for_workload()

EngineRecommendation pulp::view::recommend_engine_for_workload ( std::string_view workload,
JsEngineType current = JsEngineType::quickjs )

◆ reconcile_disabled_by_env()

bool pulp::view::reconcile_disabled_by_env ( const char * raw)
inline

Whether a caller has opted out of reconciliation, given the raw value of PULP_SHOT_NO_RECONCILE (nullptr when the variable is unset).

Reconciliation stays ON by default: it exists so runtime-imported React trees with hardcoded oversize containers still land inside the captured frame, and every screenshot path relies on that.

The opt-out exists for the one shape where clamping is wrong rather than helpful: a design imported as a faithful capture is a backdrop with position:absolute and a literal width (1280px in a 920px root) carrying bound controls positioned against it. That matches the clamp's predicate exactly, so the artwork is rescaled out from under the controls — which does not fail, it just scores a different image than the one on disk. Anything comparing a rendered panel against a reference render must set this, or it measures the clamp.

Unset, empty, 0 and false all mean "reconcile" so that a variable left exported as 0 does not silently disable it.

◆ reconcile_oversize_absolute_subtree()

void pulp::view::reconcile_oversize_absolute_subtree ( pulp::view::View & root,
std::uint32_t viewport_width,
std::uint32_t viewport_height )
inline

◆ reconnect_slider_fill()

void pulp::view::reconnect_slider_fill ( IRNode & root)

Reconnect a slider's progress fill to its thumb.

A Figma slider component stores three absolutely-positioned children — a full-width track, a short progress "fill", and a round thumb — and the fill's stored x/width is a per-instance, value-driven position. Figma's live component render recomputes the fill from the current value so it always touches the thumb, but the stored geometry in a .fig (or a REST/plugin export of one) does not: an instance can persist a fill that floats in a gap away from the thumb. Rendering that stored geometry faithfully reproduces a visually broken "detached red bar" that no design ever intended to show.

This pass detects the track+fill+thumb triplet structurally (never by layer name) and, ONLY when the fill and thumb are horizontally disjoint, extends the fill across the gap so it meets the thumb — the minimal edit that removes the detached-bar artifact without inventing a value. A fill that already touches or overlaps its thumb is left exactly as stored. Detection is tight (short wide container, near-full-width thin track, thin colored fill, round thumb) so non-slider rows are never rewritten.

◆ rect_in_root()

std::optional< Rect > pulp::view::rect_in_root ( const View & view,
View & root )

view's painted rect in root-local coordinates, or std::nullopt when that cannot be established exactly.

Exactly, not approximately. The walk sums bounds() offsets and subtracts every ScrollView ancestor's scroll — but a set_scale or explicit transform matrix anywhere on the path makes that walk wrong, and a wrong rect turns this whole instrument into a generator of confident nonsense. So the result is VERIFIED against point_to_local, the same function the hosts route real presses through, and the walk reports failure rather than a guess when the round trip does not land inside view.

◆ refresh_design_ir_asset_manifest()

void pulp::view::refresh_design_ir_asset_manifest ( DesignIR & ir,
const DesignIrAssetOptions & options = {} )

Refresh ir.asset_manifest from the current tree while preserving embedded manifest entries whose stable asset_id may already be referenced by nodes.

◆ register_audio_widgets()

void pulp::view::register_audio_widgets ( )

Registers the optional audio display factories.

Safe and cheap to call on every editor creation; direct applications should call it once at startup. The build-tree INTERFACE_SOURCES shim covers simple direct consumers, but installed consumers and applications that do not use a Pulp host must call this function explicitly after linking pulp::view-audio.

◆ register_continuous_frame_predicate()

void pulp::view::register_continuous_frame_predicate ( RuntimeViewKind kind,
ContinuousFramePredicate predicate )

Install the allocation-free predicate for a framework-owned runtime kind.

The owning widget registers its predicate when constructed; the generic traversal only invokes the callback for that exact kind.

◆ register_data_display()

void pulp::view::register_data_display ( DataDisplayRegistration registration)

◆ register_design_control_factory()

void pulp::view::register_design_control_factory ( std::string factory_id,
DesignControlFactory factory )

◆ register_drop_target()

bool pulp::view::register_drop_target ( void * native_view,
DropTarget & target )

◆ register_embedded_script_bytecode()

bool pulp::view::register_embedded_script_bytecode ( const std::uint8_t * blob,
std::size_t size )

Returns false (and registers nothing) for a malformed blob, or one whose engine fingerprint differs from this process's engine.

◆ register_legacy_import_binder()

void pulp::view::register_legacy_import_binder ( std::string id,
LegacyImportBinder binder )

◆ register_platform_plugin_view_host()

void pulp::view::register_platform_plugin_view_host ( )

◆ register_text_accessibility_node()

void pulp::view::register_text_accessibility_node ( const TextAccessibilityNode & node)

Register or replace a text node with the active a11y backend.

The default backend stores the node in a process-local table that tests can read back via snapshot_accessibility_nodes(). Registering with an id that already exists replaces the previous entry — registration is idempotent on the id.

◆ relative_luminance()

float pulp::view::relative_luminance ( Color c)

Compute relative luminance of a color per WCAG 2.1 definition.

Returns a value in [0, 1] where 0 = black and 1 = white.

◆ render_claude_bridge_scaffold()

std::string pulp::view::render_claude_bridge_scaffold ( const std::string & generated_js_path)

Build the starter bridge_handlers.cpp text the CLI emits next to the generated JS view when --from claude runs.

Pure string-builder; no I/O. The output references pulp::view::EditorBridge and shows add_handler() registrations + an attach_webview() call so users have a runnable shape to fill in. Defined in pulp-view-tooling with the bridge itself, so the extracted design-import headers do not declare it.

◆ render_schema()

void pulp::view::render_schema ( canvas::Canvas & canvas,
const std::string & json,
float w,
float h,
float value,
View & view )

◆ render_to_file()

bool pulp::view::render_to_file ( View & root,
uint32_t width,
uint32_t height,
const std::string & output_path,
float scale = 2.0f,
ScreenshotBackend backend = ScreenshotBackend::default_backend,
canvas::TextRasterPolicy text_raster = canvas::TextRasterPolicy::legacy )

◆ render_to_png()

std::vector< uint8_t > pulp::view::render_to_png ( View & root,
uint32_t width,
uint32_t height,
float scale = 2.0f,
ScreenshotBackend backend = ScreenshotBackend::default_backend,
canvas::TextRasterPolicy text_raster = canvas::TextRasterPolicy::legacy )

◆ render_to_png_gpu()

std::vector< uint8_t > pulp::view::render_to_png_gpu ( View & root,
uint32_t width,
uint32_t height,
float scale = 2.0f,
canvas::TextRasterPolicy text_raster = canvas::TextRasterPolicy::legacy )

◆ render_to_rgba()

std::vector< uint8_t > pulp::view::render_to_rgba ( View & root,
uint32_t width,
uint32_t height,
float scale,
uint32_t * out_width,
uint32_t * out_height,
canvas::TextRasterPolicy text_raster = canvas::TextRasterPolicy::legacy )

◆ reorder_target_index()

int pulp::view::reorder_target_index ( int from,
float offset,
float pitch,
int count )

Target index for a drag that started on item from, moved offset along the main axis, over a list of count items spaced pitch apart.

Rounds the offset to the nearest whole item and clamps into [0, count-1]. A non-positive pitch or empty list returns from (no move). Pure — the reorder brain, no view state.

◆ reparent_in_source()

LockResult pulp::view::reparent_in_source ( const std::string & source,
const ReparentToSourceEdit & edit )

Rewrite the dragged element's appendChild receiver so the generated source wires it under the new parent.

Locates the child block by its // @pulp-anchor comment, finds its <oldParent>.appendChild(<childVar>); line, resolves the new parent block's const <var> = … variable name, and rewrites the receiver to that var. Status semantics mirror lock_tweak_into_source: rewritten on success, already_current when the child already appends to the new parent, anchor_not_found when either anchor (or the appendChild line, or the parent's var) cannot be located. anchor_not_found is ALSO returned — with the source left byte-identical — when the new parent's anchor lies inside the moved child's subtree (a cyclic reparent) or the subtree span cannot be resolved: rewriting the receiver alone would emit <descendant>.appendChild(<ancestor>);, so the engine refuses and mutates nothing. unsupported_property is never returned. Pure function; never throws.

◆ resample_spectrum_log()

void pulp::view::resample_spectrum_log ( std::span< const float > bins_db,
float sample_rate,
const LogFrequencyScale & scale,
std::span< float > out )

Resample a real-FFT magnitude array (bins spanning DC..Nyquist) onto out.size() log-spaced frequencies across [scale.min_hz, scale.max_hz], linearly interpolating in dB between adjacent bins.

Plotting raw bins on a log axis directly does not work: FFT bins are linearly spaced, so on a log axis the bottom decade receives almost no bins (leaving visible gaps) while the top decade piles hundreds into a few pixel columns. Resampling to one value per pixel column produces a continuous curve at every frequency, and puts the spectrum in the same x-spacing as a response curve sampled with signal::response_curve_db — so the two overlay exactly.

Allocation-free; out is caller-owned.

◆ reset_js_engine_creation_stats_for_tests()

void pulp::view::reset_js_engine_creation_stats_for_tests ( )

◆ resolve_anchor_collisions()

std::vector< AnchorDisambiguation > pulp::view::resolve_anchor_collisions ( IRNode & root)

Makes every derived anchor in root unique, in document order over children.

The first node holding an anchor keeps it, and so does every node whose anchor is already unique, so re-import identity is preserved wherever it already worked. Each later node with a derived anchor gets the hash of its anchor folded with its parent's anchor, then with each further ancestor's until the result is held by no other node in the tree.

"Derived" means the node's anchor_strategy says the anchor was computed from content: content-hash, or adapter on a node with no source_node_id. A repeated explicit identity is left as it is: that is a source defect for the caller to refuse (find_duplicate_anchors()).

◆ resolve_waveform_snap()

WaveformSnapResult pulp::view::resolve_waveform_snap ( int64_t sample,
int64_t total_samples,
const WaveformSnapSettings & settings )
nodiscard

◆ rgb_to_hsl()

HSL pulp::view::rgb_to_hsl ( Color c)
inline

◆ root_overlay_owns_keyboard()

bool pulp::view::root_overlay_owns_keyboard ( View & root)

Whether an overlay under root is the kind that should own the keyboard.

A plugin host needs this before the key ever arrives. An embedded editor borrows the DAW keyboard only for an active bounded interaction, so with nothing focused it is not first responder and never receives Escape at all — which is precisely the state an open popover leaves behind.

Deliberately NARROWER than what route_escape_to_active_overlay acts on, because holding a DAW's keyboard when nothing needs it is the more expensive mistake: the user experiences it as transport and Musical Typing going dead. Three things qualify, and a bare claim does not:

  • A visible ModalOverlay. It traps interaction by definition.
  • An open ComboBox dropdown. An open menu owns arrows, Enter, Escape.
  • A claimed overlay that consumes its outside click. That flag is the author's STATEMENT that the view is a popover — @pulp/react's <View overlay> prop and data-overlay="true" both set it. The web-compat CSS-shape heuristic (position:absolute + a high z-index) deliberately does not, because it is an INFERENCE that can fire on a decorative absolutely-positioned box; such a box can hold the slot for an editor's whole lifetime, and keeping the keyboard that long would be indistinguishable from the plug-in stealing it.

◆ route_context_press()

ContextPressResult pulp::view::route_context_press ( View & root,
Point root_pt )

Route a context (right-button) press at root_pt, consulting the generalized overlay slot first.

This is the right-button counterpart of the left-button overlay routing a host performs around route_press_to_active_overlay, and it exists because honoring OverlayPressTarget::consume_press is easy to omit: a host that forgets it dismisses the overlay and THEN hit-tests the underlay, so one right-click both closes the popover and opens a context menu on the control underneath it. Keeping the decision here rather than in each host makes it headlessly testable and gives every host one call to make.

◆ route_escape_to_active_overlay()

OverlayEscapeResult pulp::view::route_escape_to_active_overlay ( View & root,
std::uint16_t modifiers = 0,
bool is_repeat = false )

Dismiss the topmost thing Escape should close under root.

Order, and why it is this order:

  1. A ModalOverlay — it traps interaction, so nothing behind it may act on the key. Found by tree walk rather than by focus, because a modal that never took focus still owns the screen, and because in a plugin host the DAW may hold focus entirely.
  2. An open ComboBox dropdown. ComboBox::on_key_event fires only while the combo owns focus, which a sibling React popover routinely steals; without a host-level fallback the still-visible dropdown wedges open with no keyboard escape route.
  3. The generalized overlay slot. ModalOverlay, ComboBox, and CallOutBox each own their Escape; a bare <View overlay> popover has no widget-specific owner, so this is the only path that closes it.

modifiers and is_repeat shape the KeyEvent handed to a modal, so an Escape chord a modal declines still falls through to the rest of the policy.

Every host must call this BEFORE any focus-gated key dispatch. A plugin host returns early when nothing in its tree holds focus — which is exactly the state an open popover leaves behind — so an Escape path placed after that check can never run.

◆ route_global_keys()

void pulp::view::route_global_keys ( View & root,
CommandRegistry & registry )

Install registry as the root view's single global-key dispatcher: assigns root.on_global_key to forward every key event into registry.dispatch_key_event().

This is the one sanctioned writer of View::on_global_key in shells that adopt command routing — tools register CommandHandlers with the shared registry instead of competing for (and clobbering) the raw hook. The registry must outlive the root view, or the caller must clear root.on_global_key first.

◆ route_passive_pointer()

PassivePointerRoute pulp::view::route_passive_pointer ( View & root,
Point root_pt )

Resolve a passive pointer input through the root's open overlays.

Presses and hovers already resolve through the overlay stack (route_press_to_active_overlay, hover_target_at). A wheel or a pinch that used the plain tree hit_test instead reached the content painted UNDER an open dialog: an overlay painted through the overlay queue can sit earlier in tree order than the plot it covers, so the tree hit test lands on the plot and a scroll over a dialog's backdrop zooms the content behind it.

Rules, top of the stack first; like a hover, nothing is ever dismissed:

  1. The point lies inside a shown overlay that resolves it to a view: that view is the target (a scroll inside a dialog scrolls the dialog) and that overlay is PassivePointerRoute::overlay, the boundary the input may not chain past.
  2. The point lies outside every shown overlay, and one of them is MODAL — a ModalOverlay, or an overlay whose accessible role is dialog (role="dialog" / role="alertdialog"): the input is blocked. A modal dialog makes the content behind it inert, and inert content receives no scroll or zoom.
  3. The point lies outside every shown overlay and the open ones are all non-modal popovers (menus, dropdowns, submenus): the input is blocked too, while OverlayDismissalPolicy::passive_input_outside_overlay_blocked is set (the default) — scrolling elsewhere while a menu is open does nothing, as on macOS. An overlay with pointer-events: none takes no input and blocks none. With the policy off, the ordinary tree answers here.
  4. Otherwise — no overlay open — the ordinary tree hit_test answers.

Hidden overlays and overlays detached from root are ignored. Read-only.

◆ route_plugin_key()

PluginKeyDisposition pulp::view::route_plugin_key ( View & root,
const PluginKeyOffer & offer )

Resolve who consumes offer under root.

Order, and why it is this order:

  1. Escape against an open overlay. A modal, an open dropdown, or a declared popover owns Escape even when nothing holds focus — which is the ordinary state while a popover is open — so this must precede the focus gate or the key never reaches it. Delegates to route_escape_to_active_overlay, whose contract decides what counts.
  2. The focused view under root, and only under root: the focus slot is process-global, so a second open editor's focused field must never answer for this one. A view that accepts navigation input but not text is offered only the bounded navigation set (see is_plugin_navigation_key) — that floor keeps a focusable knob from swallowing Space — and its own on_key_event return value decides from there. A view that accepts text input is offered every key; a chord or function key it declines cannot become text, so it falls through to step 3 and, unclaimed there, to the host — rather than being swallowed because a field happened to hold focus.
  3. root.on_global_key, the framework-level hook a CommandRegistry or the script bridge installs, when the seam asked for it (PluginKeyOffer::offer_global_hook). It sees only what the focused view declined, so an editor-wide ⌘Z does not fight a text field's own undo.

Anything none of those claimed is forward_to_host. No allowlist of "host keys" appears anywhere in the policy: forwarding is the DEFAULT, and consumption is what has to be earned.

◆ route_press_to_active_overlay()

OverlayPressTarget pulp::view::route_press_to_active_overlay ( View & root,
Point root_pt )

Consult root's generalized overlay slot for a press at root_pt.

Scoped to root's own interaction state, never the process-global shim mirror: two Pulp editors in one host process (the documented shared AUHostingService case) each own their overlay, and a press in one must not dismiss the other's popover.

Call this AFTER the ComboBox popup routing — which stays exact-as-was, per the regression in test_combo_dropdown.cpp — and BEFORE the regular tree hit_test.

Call it for EVERY press, including one with nothing open: it also records which overlay trigger the press is about to reach, so a popover that trigger's handler opens learns its anchor, and a second press on the same trigger closes it (OverlayPressTarget::trigger_closed) rather than closing and reopening it.

◆ run_fidelity_checks()

void pulp::view::run_fidelity_checks ( const FidelityContext & ctx,
std::vector< FidelityIssue > & sink )

Run every registered fidelity check against ctx, appending findings to sink.

This is the ONLY entry point codegen calls. The registry below is the single place to add a new invariant.

◆ runtime_import_whole_scripts()

std::vector< std::string > pulp::view::runtime_import_whole_scripts ( const ClaudeBundle & bundle)

The whole scripts a live editor evaluates when it imports bundle at run time (__pulpRuntimeImport__): each JavaScript asset payload and each text/javascript inline script, byte-identical to what the payload pipeline hands evaluate_script().

A prewarm compiles exactly these.

◆ script_bytecode_cache_stats()

ScriptBytecodeCacheStats pulp::view::script_bytecode_cache_stats ( )

◆ script_bytecode_cached()

bool pulp::view::script_bytecode_cached ( const std::string & source)

True when byte-identical source has stored bytecode (tests, diagnostics).

◆ script_bytecode_engine_fingerprint()

std::string pulp::view::script_bytecode_engine_fingerprint ( )

The engine's bytecode fingerprint: the QuickJS version plus a digest of the bytecode this engine emits for a fixed probe script, so any change to the bytecode format or opcode/atom numbering changes it.

◆ script_inspector()

ScriptInspectorBridge * pulp::view::script_inspector ( ScriptedUiSession & session)
noexcept

The session's ScriptInspectorBridge, or nullptr when the session was built without one (install_script_inspector_bridge() had not run).

◆ script_inspector_port_factory()

ScriptInspectorPortFactory pulp::view::script_inspector_port_factory ( )
noexcept

◆ scripted_ui_prewarm_runner()

std::atomic< ScriptedUiPrewarmRunner > & pulp::view::scripted_ui_prewarm_runner ( )
inlinenoexcept

◆ scripted_ui_prewarm_stats()

ScriptedUiPrewarmStats pulp::view::scripted_ui_prewarm_stats ( )

◆ selectable_first_index()

int pulp::view::selectable_first_index ( const SelectableLayout & layout)

First / last selectable byte offset in layout.

Both return -1 when the layout is unmeasured. selectable_last_index is the offset one past the final cluster, i.e. where a caret sits at end-of-text.

◆ selectable_index_at_point()

int pulp::view::selectable_index_at_point ( const SelectableLayout & layout,
Point local )

Nearest cluster boundary to local within layout.

Rows are picked by y (clamped to the first/last row, so a point above or below the text still resolves), then the closest boundary on that row by x — the half-glyph convention TextEditor::char_index_at_point already uses. Returns -1 when layout.measured is false, so "unknown" stays distinguishable from "offset 0".

◆ selectable_last_index()

int pulp::view::selectable_last_index ( const SelectableLayout & layout)

◆ selectable_rects_for_range()

std::vector< Rect > pulp::view::selectable_rects_for_range ( const SelectableLayout & layout,
int start_utf8,
int end_utf8 )

The painted rects covering [start_utf8, end_utf8), in local coordinates, one per touched line.

A collapsed range yields no rects.

◆ selector_segment_index()

int pulp::view::selector_segment_index ( float value,
int count )
inline

◆ selector_segment_value()

float pulp::view::selector_segment_value ( int index,
int count )
inline

The value a segmented selector writes for segment index of count, and the segment a parameter value selects.

Stated once, here, because BOTH script emitters and every native host binder have to agree on it: a panel whose segments write one mapping while the host reads another lights the wrong segment for the value it just wrote, and looks like a rendering bug.

A single-segment selector is degenerate and pinned at 0 rather than dividing by zero.

◆ serialize_claude_classnames()

std::string pulp::view::serialize_claude_classnames ( const ClaudeClassNameRules & rules)

Serialize a ClaudeClassNameRules map to the JSON shape Spectr's extract.mjs produces.

Keys are emitted in alphabetical order so the output is stable across runs (deterministic CI fixture comparison). CSS values are emitted verbatim — callers downstream of this artifact (e.g. @pulp/css-adapt) handle lowering to bridge calls.

◆ serialize_default_shortcut_scan()

std::string pulp::view::serialize_default_shortcut_scan ( const DefaultShortcutScan & scan)

Render the auto-bound defaults + collisions into JSON for emission alongside the extracted-shortcuts manifest.

Mirror of serialize_detected_shortcuts shape but namespaced under "defaults" and "collisions" top-level keys.

◆ serialize_design_ir()

std::string pulp::view::serialize_design_ir ( const DesignIR & ir,
const DesignIrJsonOptions & options = {} )

Serialize a DesignIR as a deterministic, versioned canonical JSON envelope.

The reader remains permissive; this writer emits only the canonical nested form.

◆ serialize_detected_shortcuts()

std::string pulp::view::serialize_detected_shortcuts ( const std::vector< DetectedShortcut > & shortcuts)

Serialize a list of DetectedShortcuts to JSON in the caller-provided order.

extract_keyboard_shortcuts already sorts by (key, modifiers, source_location) before returning its deterministic scan result.

◆ set_announcement_sink()

void pulp::view::set_announcement_sink ( AnnouncementSink sink)

◆ set_default_caret_blink()

void pulp::view::set_default_caret_blink ( const CaretBlinkConfig & config)
noexcept

◆ set_default_caret_style()

void pulp::view::set_default_caret_style ( CaretStyle style)
noexcept

◆ set_file_drag_backend()

FileDragBackend pulp::view::set_file_drag_backend ( FileDragBackend backend)

◆ set_overlay_dismissal_policy()

void pulp::view::set_overlay_dismissal_policy ( const OverlayDismissalPolicy & policy)

Replace the active policy. Call from application setup, not mid-gesture.

◆ set_screenshot_provider()

void pulp::view::set_screenshot_provider ( ScreenshotProvider provider)

◆ set_script_inspector_port_factory()

void pulp::view::set_script_inspector_port_factory ( ScriptInspectorPortFactory factory)
noexcept

Process-wide: set before the sessions that should carry an inspector are constructed (sessions built earlier keep what they had).

nullptr, the default, builds sessions with no inspector port.

◆ set_tracing_badge_placement()

void pulp::view::set_tracing_badge_placement ( const TracingBadgePlacement & placement)

◆ set_tracing_badge_visible()

void pulp::view::set_tracing_badge_visible ( bool visible)

◆ shift_hue()

Color pulp::view::shift_hue ( Color c,
float degrees )

Shift hue by degrees (wraps around 360).

◆ should_dispatch_host_frame()

bool pulp::view::should_dispatch_host_frame ( HostFramePump & pump,
bool needs_repaint,
bool continuous,
bool has_idle_callback )

Step 0 of a host tick, on the VSYNC SOURCE'S OWN THREAD: does this vsync need to reach the UI thread at all?

The macOS display links keep firing at the display's refresh rate even when the tree is completely static. Rather than hop to the main thread 120x/sec to walk a tree that cannot have changed, the gated hosts answer that question on the link thread from three flags they maintain atomically: their own dirty flag, whether the last dispatched frame reported HostFrameTick::continuous, and whether a scripted idle callback is installed (a JS rAF / timer / async queue must be pumped every vsync regardless of native dirtiness).

The frame-timing consequence, and the reason this lives here rather than being open-coded per host: a skipped vsync is a vsync the pump never measured. If the host just drops it, the pump's last timestamp goes stale and the NEXT real frame measures the whole idle gap — so an animation starting on that frame is advanced by the time the UI spent doing nothing (an 80 ms hover fade handed a 100 ms first frame completes instantly). So the skip is recorded on the pump, and the next measured frame is a resume. Idle time is never animation time.

Returns true if the host should dispatch a frame; false records the skip.

◆ should_yield_to_gesture()

bool pulp::view::should_yield_to_gesture ( View & root,
const MouseEvent & event )

Feed one pointer event to root's gesture arbiter and report whether the host must now YIELD — i.e.

whether a recognizer actually took the pointer, so the host skips its own delivery for this event.

This is the whole gesture-vs-delivery gating decision, in one place. Every host phase (press / drag / release) calls it and early-returns on true.

The distinction it encodes is the one that is easy to get wrong: View::dispatch_gesture_pointer_event returns whether the event was CONSUMED, which is true whenever a recognizer merely EXISTS anywhere on the hit chain — candidates are never pruned mid-session. Only View::gesture_claimed_pointer reports an actual claim. A host that yields on the consumed flag makes any control carrying a recognizer permanently undraggable: normal delivery never runs, so the widget sees no press, no drag and no release while looking perfectly alive. Both macOS hosts had that bug; each was fixed separately, and the standalone one was missed, which is why the decision now lives here instead of being spelled out at six call sites.

Always dispatches, including when it returns false. The arbiter has to see every event to advance its session, so this is NOT a predicate a caller may skip — the return value gates DELIVERY, never the dispatch itself.

◆ shutdown_accessibility()

void pulp::view::shutdown_accessibility ( void * handle)

Release any OS-side resources acquired in init_accessibility.

◆ snapshot_accessibility_nodes()

std::vector< TextAccessibilityNode > pulp::view::snapshot_accessibility_nodes ( )

Read back the currently-registered nodes.

Returns by value (a copy) so callers do not race with concurrent register/unregister activity. Order is unspecified.

◆ snapshot_accessibility_tree()

std::vector< AccessibilityNodeSnapshot > pulp::view::snapshot_accessibility_tree ( const View & root)

Depth-first snapshot of root and every descendant.

Views with AccessRole::none are still included — callers can filter if they want only announceable nodes. Tests commonly assert on (role, label) pairs; the value fields support slider / progress checks.

◆ stepper_normalized_value()

float pulp::view::stepper_normalized_value ( double plain,
double min,
double max )
inline

A stepper's plain value (voices, octaves) against the normalized parameter behind it.

Stated here for the same reason the selector's mapping is: the script emitter, the bridge's host-to-widget push and every native host binder have to agree, and a stepper that reads one mapping while the store writes another shows a number nobody chose.

◆ stepper_plain_value()

double pulp::view::stepper_plain_value ( float normalized,
double min,
double max,
double step )
inline

◆ suppress_svg_glow_at()

bool pulp::view::suppress_svg_glow_at ( std::string & svg,
float x,
float y,
float w,
float h )

◆ suppress_svg_glyph_at()

bool pulp::view::suppress_svg_glyph_at ( std::string & svg,
float x,
float y,
float w,
float h )

◆ suppress_svg_rect()

bool pulp::view::suppress_svg_rect ( std::string & svg,
float x,
float y,
float w,
float h,
float tol = 2.0f )

◆ svg_open_tag()

std::string pulp::view::svg_open_tag ( const std::string & svg)

◆ synthesize_primitive_paths()

void pulp::view::synthesize_primitive_paths ( IRNode & root)

Source-agnostic IR normalization for vector SHAPE PRIMITIVES.

Walks the tree and, for each rect/rectangle/line/ellipse/circle/polygon/star node that would otherwise be dropped to an empty frame — no path_data, no children, no visible fill, no rasterized asset, not an audio widget — synthesizes an SVG path d (plus svg_viewbox and, when the node carries a border, an svg_stroke/svg_stroke_width; svg_fill is forced to "none" so the SvgPathWidget's default opaque-black fill never paints a phantom box) from the node's geometry. Codegen then lowers it to a native SvgPath via createSvgPath+setSvgPath instead of silently dropping the shape. Idempotent: nodes that already carry path_data, render some other way, or are not synthesizable primitives are left untouched. Geometry is derived from IR fields only (width/height, corner radii, and optional pointCount/innerRadius attributes) — never a layer name or source quirk.

◆ synthesize_runtime_envelope()

std::string pulp::view::synthesize_runtime_envelope ( const ClaudeBundle & bundle)

Synthesize a Claude-style HTML envelope around an arbitrary ClaudeBundle so the existing parse_claude_html_with_runtime harness can consume it without a real Claude Design HTML wrapper on input.

Used by --from jsx (and future direct-bundle import sources) so they can ride the existing runtime materialization path without each one re-implementing the ScriptEngine + WidgetBridge + DOM-walker boot sequence.

The envelope uses compressed:false raw base64 for the manifest entries — gzip+deflate is unnecessary overhead for in-process synthesis (the existing test harness already exercises this code path). The template HTML is JSON-escaped per the bundler/template script-tag contract.

◆ theme_from_preset()

Theme pulp::view::theme_from_preset ( const ThemePreset & preset,
bool dark )

Build a complete Theme from a preset for the given appearance.

Applies derivation, then overlays any explicit overrides from the preset.

◆ theme_to_ir_tokens()

IRTokens pulp::view::theme_to_ir_tokens ( const Theme & theme)

Convert a Pulp Theme to W3C-compatible IR tokens.

◆ threejs_iife_source()

std::optional< std::string > pulp::view::threejs_iife_source ( )

◆ to_string() [1/2]

const char * pulp::view::to_string ( AppearanceDefectKind kind)

◆ to_string() [2/2]

std::string_view pulp::view::to_string ( DesignKeyDiagnosticReason reason)
noexcept

◆ to_w3c_tokens_json()

std::string pulp::view::to_w3c_tokens_json ( const IRTokens & tokens,
bool pretty = true )

Serialize design-import tokens to a W3C Design Tokens (DTCG) JSON document.

Top-level groups are colors, dimensions, and strings; an empty category is omitted, and empty IRTokens yield {}. Within a group, token names split on "/" into nested DTCG groups ("brand/primary" → {"brand": {"primary": {...}}}). Leaf shapes:

  • color: {"$type": "color", "$value": "#rrggbb"}
  • dimension: {"$type": "dimension", "$value": {"value": N, "unit": "px"}}

IRTokens::strings have no standard DTCG type, so no $type is invented:

  • Names that clearly denote a font family (a "/"- or "."-segment equal to font/fontFamily/font-family/typeface, or a final segment of family/font, case-insensitive) are promoted to {"$type": "fontFamily", "$value": ...} inside the strings group. A comma-separated value ("Inter, sans-serif") becomes the DTCG array form ["Inter", "sans-serif"] (entries trimmed); otherwise the plain string.
  • Every other string is PARKED — never dropped — under the document-root $extensions["dev.pulp.nonStandardTokens"] as {"<full name>": {"value": "<text>", "id", "collection", "mode", "adapter"}} with the provenance subfields from source_identity (empties omitted). The real token groups therefore carry only standard-typed tokens, and validate_dtcg() passes on emitted output.

A source_identity entry for the token's canonical path ("colors." + name, etc.) is attached as {"$extensions": {"dev.pulp.source": {"id", "collection", "mode", "adapter"}}} with empty subfields omitted. Output key order is deterministic (sorted).

◆ toggle_on_from_normalized()

bool pulp::view::toggle_on_from_normalized ( double value)
inline

The single threshold used by every toggle import/binding path.

Invalid host values fail closed instead of changing UI state unpredictably.

◆ token_css_var()

std::string pulp::view::token_css_var ( const std::string & token_name)

The CSS custom-property id a token binds through: -- + the token name with its trailing .dark mode suffix stripped and every .

mapped to - (e.g. color.bg → --color-bg, color.bg.dark → --color-bg). This is the single owner of the token → var(--x) mapping; export_css_variables and the adherence lint both call it so they can never disagree about a token's id.

◆ token_group_key()

const char * pulp::view::token_group_key ( TokenGroup group)

Stringify a TokenGroup as its DESIGN.md frontmatter key.

◆ tokenize_cpp_line()

std::vector< Token > pulp::view::tokenize_cpp_line ( std::string_view line)

◆ tokenize_javascript_line()

std::vector< Token > pulp::view::tokenize_javascript_line ( std::string_view line)

◆ tokenize_json_line()

std::vector< Token > pulp::view::tokenize_json_line ( std::string_view line)

◆ tokenize_line()

std::vector< Token > pulp::view::tokenize_line ( std::string_view line,
CodeLanguage language )

Tokenize a single line of source text for language.

Returns an ordered, non-overlapping list of spans. Characters not covered by a span are treated as TokenClass::text by the editor.

language mappings:

Markdown does not have an entry in CodeLanguage yet — callers can invoke tokenize_markdown_line directly for *.md content.

◆ tokenize_lua_line()

std::vector< Token > pulp::view::tokenize_lua_line ( std::string_view line)

◆ tokenize_markdown_line()

std::vector< Token > pulp::view::tokenize_markdown_line ( std::string_view line)

◆ tokenize_python_line()

std::vector< Token > pulp::view::tokenize_python_line ( std::string_view line)

◆ tracing_badge_layout()

TracingBadgeLayout pulp::view::tracing_badge_layout ( float root_width,
float text_width,
float ascent,
float descent,
const TracingBadgePlacement & placement )

◆ tracing_badge_placement()

TracingBadgePlacement pulp::view::tracing_badge_placement ( )

◆ tracing_badge_should_paint()

bool pulp::view::tracing_badge_should_paint ( )

◆ transfer_input_focus()

bool pulp::view::transfer_input_focus ( View & root,
View * target )

Move input focus within one hosted root while tolerating callbacks that synchronously unmount either the previous or requested focus target.

Returns true when non-null target remains live after the focus protocol. A null target explicitly blurs this root and returns false. A live non-focusable target is still a valid pointer target; it simply clears any previous focus in this root. The root-owned interaction slot is the source of truth; the process-global focus shim is never consulted.

◆ truncate_to_width()

std::string pulp::view::truncate_to_width ( canvas::Canvas & canvas,
std::string_view text,
float available_width,
bool force_ellipsis = false )
inline

If text already fits within available_width, return it as-is unless force_ellipsis is true.

The forced form is for a styled fragment that fits by itself but must still reserve the trailing edge for omitted spans. Otherwise return the longest UTF-8 prefix of text that — appended with U+2026 — still fits. Falls back to "…" alone if no prefix fits.

available_width <= 0.0f (zero / collapsed content-box) returns "…" rather than the original — leaking the full text on a tiny button defeats the whole point of the feature.

Uses binary search over codepoint indices, so cost is O(log N · measure_text). The caller is responsible for setting the canvas's font state before invoking; this helper only measures.

◆ ua_scheme_for_accent()

UaColorScheme pulp::view::ua_scheme_for_accent ( canvas::Color accent,
UaColorScheme scheme,
canvas::Color contrast_light,
canvas::Color contrast_dark )

The scheme Chromium actually paints a control in when an author accent is set: it flips scheme to the other one when the accent's WCAG contrast with contrast_light (the part's light-scheme colour adjacent to the accent) is under 3:1 and lower than with contrast_dark; symmetrically from dark.

◆ unmapped_widget_token_diagnostic()

std::optional< ImportDiagnostic > pulp::view::unmapped_widget_token_diagnostic ( const std::vector< std::string > & unresolved)

The diagnostic naming the widget keys a design supplied no colour for, or nothing when it supplied them all.

Takes the unresolved_widget_tokens that ir_tokens_to_theme filled. One diagnostic lists every key, because a design with no tokens at all leaves them all unset and one warning per key would bury the rest of the import's diagnostics.

◆ unregister_drop_target()

void pulp::view::unregister_drop_target ( void * native_view)

◆ unregister_text_accessibility_node()

void pulp::view::unregister_text_accessibility_node ( std::string_view id)

Drop the node registered under id.

Silently does nothing if no such node is registered.

◆ utf8_advance()

std::size_t pulp::view::utf8_advance ( std::string_view text,
std::size_t count )
inline

Walk forward over UTF-8 leading bytes.

Returns the byte index after count codepoints, or text.size() if count runs off the end.

◆ utf8_codepoint_count()

std::size_t pulp::view::utf8_codepoint_count ( std::string_view text)
inline

Count the number of UTF-8 leading-byte codepoints in text.

Stray continuation bytes are skipped silently (best-effort, never panics).

◆ validate_dtcg()

std::vector< std::string > pulp::view::validate_dtcg ( const std::string & json)

Validate a JSON document against the DTCG invariants the emitter targets.

Returns human-readable violations; an empty vector means conformant. Dependency-free (choc::json only) and best-effort by design — it checks:

  • every leaf token (object with $value) has a resolvable $type (own or inherited from an ancestor group) drawn from the standard DTCG set (color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography);
  • $value shape matches $type where checkable: color → string, dimension → {value: number, unit: string}, fontFamily → string or array of strings;
  • only the reserved keys $value/$type/$description/$extensions/ $deprecated appear; any other $-prefixed member is a violation;
  • $extensions is an object whose keys are namespaced (contain ".");
  • group members are objects (tokens or groups), and non-JSON input or a non-object root is reported rather than thrown.

◆ validate_theme_contrast()

std::vector< ContrastIssue > pulp::view::validate_theme_contrast ( const Theme & theme,
ContrastLevel level = ContrastLevel::aa_normal )

Validate a theme for contrast issues.

Checks standard token pairs: text.primary on bg.primary, text.secondary on bg.secondary, etc. Returns a list of pairs that fail the required contrast level.

◆ value_channel_shape_name()

Stable wire name for a channel's shape.

Spelled out per case rather than derived from the enum's order, so landing the reserved events shape cannot renumber what a UI or a lint already matches on.

◆ value_channel_to_value()

choc::value::Value pulp::dataplane::value_channel_to_value ( const ValueChannelInfo & info)

One channel as {name, unit, shape, neutral}.

◆ value_channels_to_value()

choc::value::Value pulp::dataplane::value_channels_to_value ( const ValueChannelSet * channels)

Every declared channel, in declaration order.

A null set yields an EMPTY ARRAY, never undefined: no channels is the default every processor inherits, so iterating the result must be safe without a guard.

◆ view_type_name()

std::string pulp::view::view_type_name ( const View & view)

The type name the inspector and the layout/appearance diagnostics show for view ("Knob", "Fader", "Label", ...): the built-in widget name, else the InspectorFacts name a widget reports, else "View".

This is the one classification shared by view-core's diagnostics and the Pulp inspector.

◆ wait_for_scripted_ui_prewarm()

bool pulp::view::wait_for_scripted_ui_prewarm ( std::chrono::milliseconds timeout)

Block until the worker is idle or timeout passes; true when idle.

For tests and measurement harnesses; an editor never needs it.

◆ walk_and_clamp()

void pulp::view::walk_and_clamp ( pulp::view::View & view,
float vw,
float vh,
std::uint32_t viewport_width,
std::uint32_t viewport_height,
int depth,
const char * parent_label )
inline

◆ warn_capability_fallback_once()

void pulp::view::warn_capability_fallback_once ( canvas::CanvasCapability cap,
const char * msg )
inline

Warn at most once per process, per capability, when a paint path degrades because the active canvas backend does not support the capability it needs.

The dedup is a relaxed atomic bitmask keyed by the CanvasCapability ordinal: allocation-free on every call after the first, so it is safe inside paint_all's ScopedNoAlloc guard (the one-time first-warn log is a non-realtime event by construction, and the guard is a no-op in Release). msg must be a string literal — passed straight to log_warn without format.

Shared home for the ONE warn-once vocabulary: both View::paint_all's capability-fallback sites and ImageView's image-decoder-missing path route through here, so a new adoption site never re-hand-rolls a second dedup. inline gives the static counter a single process-wide instance across every translation unit that includes this header.

◆ webview_backend_available()

bool pulp::view::webview_backend_available ( )

Returns true if the host process has a usable WebView backend.

◆ widget_chart_shape()

std::optional< canvas::Canvas::SDFShape > pulp::view::widget_chart_shape ( const View & view)

The SDF shape a widget's chart shader is drawn on: flat_arc for a Knob's value arc, stadium for a Fader's track (a vertical Fader turns it a quarter counter-clockwise, so t runs from the bottom up).

Empty for a widget that draws no chart.

◆ with_alpha()

Color pulp::view::with_alpha ( Color c,
float alpha )

Apply alpha to a color [0.0-1.0].

◆ yield_to_gesture_with_handoff()

bool pulp::view::yield_to_gesture_with_handoff ( View & root,
View *& drag_target,
const MouseEvent & event,
int click_count = 1 )

Apply the host-side gesture gate and close an already-delivered press when a recognizer claims after that press.

Returns true when the caller must skip normal pointer delivery for this event.

drag_target is cleared BEFORE the release callbacks run so an exception or re-entrant message cannot retry the raw drag. A claim on the initial press has no bracket to close; the target is simply cleared. Non-left buttons do not participate in the gesture arbiter and always return false.

Variable Documentation

◆ GALLERY_WIDTH

float pulp::view::GALLERY_WIDTH = 940.0f
constexpr

◆ kChartGlowSigmaMax

float pulp::view::kChartGlowSigmaMax = 256.0f
inlineconstexpr

Largest accepted glow_sigma.

The draw rect grows by several sigma on every side, so an unbounded sigma would grow it without limit.

◆ kCommandOpenSettings

CommandID pulp::view::kCommandOpenSettings = 0x504C5354
inlineconstexpr

Framework-reserved CommandID for "open the app's settings / preferences" (ASCII 'PLST').

Reserving ONE well-known id is what makes Cmd/Ctrl+, a platform convention rather than a per-app accident: any handler registered for this id gets the standard chord by default, and shells, docs, and rebind UIs can all point at the same name.

◆ kDefaultJsMemoryLimitBytes

std::size_t pulp::view::kDefaultJsMemoryLimitBytes = std::size_t{512} * 1024 * 1024
constexpr

◆ kDefaultSimilarityThreshold

float pulp::view::kDefaultSimilarityThreshold = 0.85f
inlineconstexpr

The default similarity a render must reach to count as matching its reference, as a fraction (0.0-1.0).

This is the single source of truth for the C++ side — passes(), pulp-screenshot --compare, and pulp import-design --validate all resolve their default here rather than hard-coding a literal. The out-of-process harnesses under tools/import-validation/ mirror this value in their own language and should be updated alongside it.

◆ kEditorHostClearB

std::uint8_t pulp::view::kEditorHostClearB = kEditorHostClearRgb & 0xff
inlineconstexpr

◆ kEditorHostClearG

std::uint8_t pulp::view::kEditorHostClearG = (kEditorHostClearRgb >> 8) & 0xff
inlineconstexpr

◆ kEditorHostClearR

std::uint8_t pulp::view::kEditorHostClearR = (kEditorHostClearRgb >> 16) & 0xff
inlineconstexpr

◆ kEditorHostClearRgb

std::uint32_t pulp::view::kEditorHostClearRgb = 0x1E1E2E
inlineconstexpr

The background a plug-in editor host paints when the plug-in has not declared its own (Processor::editor_background()): RGB 30,30,46, which is also Theme::dark()'s bg.primary.

See PluginViewHost::Options::background_rgb.

◆ kEllipsis

const char* pulp::view::kEllipsis = "\xe2\x80\xa6"
inlineconstexpr

UTF-8 horizontal ellipsis character (U+2026, "…").

Three bytes: 0xE2 0x80 0xA6. Exposed for tests that need to assert paint output.

◆ kFidelityLedgerVersion

std::string_view pulp::view::kFidelityLedgerVersion = "2026.07-fidelity-ledger-v1"
inlineconstexpr

Format id stamped into the ledger JSON; bump on a non-additive shape change.

◆ kGpuTimingEnvVar

std::string_view pulp::view::kGpuTimingEnvVar = "PULP_GPU_TIMING"
inlineconstexpr

The environment variable a standalone GPU window reads to enable GPU render timing.

◆ kInspectorMeterFloorDb

float pulp::view::kInspectorMeterFloorDb = -60.0f
inlineconstexpr

dBFS floor used by the inspector's meter fill (and the empty-bar anchor).

◆ kInvalidCommandID

CommandID pulp::view::kInvalidCommandID = 0
inlineconstexpr

◆ kKeyComma

KeyCode pulp::view::kKeyComma = static_cast<KeyCode>(',')
inlineconstexpr

ASCII comma as a KeyCode.

Punctuation-valued key codes are part of the input contract even when a platform header does not expose a named enum member for every punctuation key.

◆ kMaxDesignIrJsonDepth

std::size_t pulp::view::kMaxDesignIrJsonDepth = 512
inlineconstexpr

Deepest object/array nesting parse_design_ir_json accepts.

The JSON parser recurses once per level, so unbounded nesting would exhaust the stack instead of failing.

◆ kOpenSettingsModifiers

std::uint16_t pulp::view::kOpenSettingsModifiers = kModCmd
inlineconstexpr

The platform-standard open-settings chord: Cmd+, on macOS, Ctrl+, elsewhere.

Exposed so a host that builds its own CommandInfo (rather than calling make_open_settings_command_info()) still binds the same chord.

◆ kPianoFrame

int pulp::view::kPianoFrame = 1
inlineconstexpr

◆ kTracingBadgeLabel

const char* pulp::view::kTracingBadgeLabel = "\u25C9 TRACING"
inlineconstexpr

◆ kTypingFrame

int pulp::view::kTypingFrame = 0
inlineconstexpr