Editor structure

The Graphite editor is the application users interact with to create documents. Its code is a single Rust crate that lives below the frontend (web code) and above Graphene (the node-based graphics engine). The main business logic of all visual editing is handled by the editor backend. When running in the browser, it is compiled to WebAssembly and passes messages to the frontend.

Message system

The Graphite editor backend is organized into a hierarchy of subsystems which talk to one another through message passing. Messages are pushed to the front or back of a queue and each one is processed sequentially by the editor's dispatcher.

The dispatcher lives at the root of the editor hierarchy and acts as the owner of all its top-level message handlers. This satisfies Rust's restrictions on mutable borrows because only the dispatcher may mutate its message handlers, one at a time, while each message is processed.

Editor outline

# Access this quickly in the future:
cargo run explore editor

Click to explore the outline of the editor subsystem hierarchy which forms the structure of the editor's subsystems, state, and interactions. Also available as a searchable plain text file.

  • Messagemessage.rs:6
    • Animation
      • AnimationMessageanimation_message.rs:6
        • ToggleLivePreview
        • EnableLivePreview
        • DisableLivePreview
        • RestartAnimation
        • SetFrameIndex
          • frame: f64
        • SetTime
          • time: f64
        • UpdateTime
        • IncrementFrameCounter
        • SetAnimationTimeMode
          • animation_time_mode: AnimationTimeMode
        • AnimationMessageHandleranimation_message_handler.rs:28
          • live_preview_recently_zero: bool
          • timestamp: f64
          • frame_index: f64
          • animation_state: AnimationState
          • fps: f64
          • animation_time_mode: AnimationTimeMode
    • AppWindow
    • Broadcast
    • Clipboard
    • Debug
    • Defer
      • DeferMessagedefer_message.rs:5
        • SetGraphSubmissionIndex
          • execution_id: u64
        • TriggerGraphRun
          • execution_id: u64
          • document_id: DocumentId
        • AfterGraphRun
          • messages: Vec<Message>
        • TriggerNavigationReady
        • AfterNavigationReady
          • messages: Vec<Message>
        • DeferMessageHandlerdefer_message_handler.rs:9
          • after_graph_run: HashMap<DocumentId, Vec<(u64, Message)>>
          • after_viewport_resize: Vec<Message>
          • current_graph_submission_id: u64
        • DeferMessageContextdefer_message_handler.rs:4
          • portfolio: &'a PortfolioMessageHandler
    • Dialog
      • DialogMessagedialog_message.rs:5
        • ExportDialog
          • ExportDialogMessageexport_dialog_message.rs:6
            • FileType
              • file_type: FileType
            • ScaleFactor
              • factor: f64
            • TransparentBackground
              • transparent: bool
            • ExportBounds
              • bounds: ExportBounds
            • Submit
            • ExportDialogMessageHandlerexport_dialog_message_handler.rs:13
              • file_type: FileType
              • scale_factor: f64
              • bounds: ExportBounds
              • transparent_background: bool
              • artboards: HashMap<LayerNodeIdentifier, String>
              • has_selection: bool
            • ExportDialogMessageContextexport_dialog_message_handler.rs:7
              • portfolio: &'a PortfolioMessageHandler
        • NewDocumentDialog
        • PreferencesDialog
        • Dismiss
        • Close
        • CloseAndThen
          • followups: Vec<Message>
        • CloseAllDocumentsWithConfirmation
        • DisplayDialogError
          • title: String
          • description: String
        • RequestAboutGraphiteDialog
        • RequestAboutGraphiteDialogWithLocalizedCommitDate
          • localized_commit_date: String
          • localized_commit_year: String
        • RequestDemoArtworkDialog
        • RequestExportDialog
        • RequestLicensesDialogWithLocalizedCommitDate
          • localized_commit_year: String
        • RequestLicensesThirdPartyDialogWithLicenseText
          • license_text: String
        • RequestNewDocumentDialog
        • RequestPreferencesDialog
        • RequestConfirmRestartDialog
          • preferences_requiring_restart: Vec<String>
        • DialogMessageHandlerdialog_message_handler.rs:16
          • on_dismiss: Option<Message>
          • export_dialog: ExportDialogMessageHandler
          • new_document_dialog: NewDocumentDialogMessageHandler
          • preferences_dialog: PreferencesDialogMessageHandler
        • DialogMessageContextdialog_message_handler.rs:9
          • portfolio: &'a PortfolioMessageHandler
          • preferences: &'a PreferencesMessageHandler
    • Frontend
      • FrontendMessagefrontend_message.rs:27
        • DisplayDialog
          • title: String
          • icon: IconName
        • DialogClose
        • DisplayDialogPanic
          • panic_info: String
        • DisplayEditableTextbox
          • text: String
          • line_height_ratio: f64
          • font_size: f64
          • color: String
          • font_data: serde_bytes::ByteBuf
          • transform: [f64; 6]
          • max_width: Option<f64>
          • max_height: Option<f64>
          • align: TextAlign
        • DisplayEditableTextboxUpdateFontData
          • font_data: serde_bytes::ByteBuf
        • DisplayEditableTextboxTransform
          • transform: [f64; 6]
        • DisplayRemoveEditableTextbox
        • SendUIMetadata
          • node_descriptions: Vec<(String, String)>
          • node_types: Vec<FrontendNodeType>
        • SendShortcutFullscreen
          • shortcut: Option<ActionShortcut>
          • shortcut_mac: Option<ActionShortcut>
        • SendShortcutAltClick
          • shortcut: Option<ActionShortcut>
        • SendShortcutShiftClick
          • shortcut: Option<ActionShortcut>
        • TriggerAboutGraphiteLocalizedCommitDate
          • commit_date: String
        • TriggerDisplayThirdPartyLicensesDialog
        • TriggerSaveDocument
          • document_id: DocumentId
          • name: String
          • path: Option<PathBuf>
          • content: serde_bytes::ByteBuf
        • TriggerSaveFile
          • name: String
          • content: serde_bytes::ByteBuf
        • TriggerExportImage
          • svg: String
          • name: String
          • mime: String
          • size: (f64, f64)
        • TriggerFetchAndOpenDocument
          • name: String
          • filename: String
        • TriggerFontCatalogLoad
        • TriggerFontDataLoad
          • font: Font
          • url: String
        • TriggerPersistenceRemoveDocument
          • document_id: DocumentId
        • TriggerPersistenceWriteDocument
          • document_id: DocumentId
          • document: String
          • details: DocumentDetails
        • TriggerLoadFirstAutoSaveDocument
        • TriggerLoadRestAutoSaveDocuments
        • TriggerOpenLaunchDocuments
        • TriggerLoadPreferences
        • TriggerOpen
        • TriggerImport
        • TriggerSavePreferences
          • preferences: PreferencesMessageHandler
        • TriggerSaveActiveDocument
          • document_id: DocumentId
        • TriggerTextCommit
        • TriggerVisitLink
          • url: String
        • TriggerClipboardRead
        • TriggerClipboardWrite
          • content: String
        • TriggerSelectionRead
          • cut: bool
        • TriggerSelectionWrite
          • content: String
        • UpdateActiveDocument
          • document_id: DocumentId
        • UpdateGradientStopColorPickerPosition
          • color: Color
          • position: (f64, f64)
        • UpdateImportsExports
          • imports: Vec<Option<FrontendGraphOutput>>
          • exports: Vec<Option<FrontendGraphInput>>
          • import_position: (i32, i32)
          • export_position: (i32, i32)
          • add_import_export: bool
        • UpdateInSelectedNetwork
          • in_selected_network: bool
        • UpdateBox
          • box_selection: Option<BoxSelection>
        • UpdateContextMenuInformation
          • context_menu_information: Option<ContextMenuInformation>
        • UpdateClickTargets
          • click_targets: Option<FrontendClickTargets>
        • UpdateGraphViewOverlay
          • open: bool
        • UpdateDataPanelState
          • open: bool
        • UpdatePropertiesPanelState
          • open: bool
        • UpdateLayersPanelState
          • open: bool
        • UpdateLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateImportReorderIndex
          • index: Option<usize>
        • UpdateExportReorderIndex
          • index: Option<usize>
        • UpdateLayerWidths
          • layer_widths: HashMap<NodeId, u32>
          • chain_widths: HashMap<NodeId, u32>
          • has_left_input_wire: HashMap<NodeId, bool>
        • UpdateDocumentArtwork
          • svg: String
        • UpdateImageData
          • image_data: Vec<(u64, Image<Color>)>
        • UpdateDocumentLayerDetails
          • data: LayerPanelEntry
        • UpdateDocumentLayerStructure
          • layer_structure: Vec<LayerStructureEntry>
        • UpdateDocumentRulers
          • origin: (f64, f64)
          • spacing: f64
          • interval: f64
          • visible: bool
        • UpdateDocumentScrollbars
          • position: (f64, f64)
          • size: (f64, f64)
          • multiplier: (f64, f64)
        • UpdateEyedropperSamplingState
          • image: Option<EyedropperPreviewImage>
          • mouse_position: Option<(f64, f64)>
          • primary_color: String
          • secondary_color: String
          • set_color_choice: Option<PrimarySecondary>
        • UpdateGraphFadeArtwork
          • percentage: f64
        • UpdateMouseCursor
          • cursor: MouseCursorIcon
        • UpdateNodeGraphNodes
          • nodes: Vec<FrontendNode>
        • UpdateNodeGraphErrorDiagnostic
          • error: Option<NodeGraphErrorDiagnostic>
        • UpdateVisibleNodes
          • nodes: Vec<NodeId>
        • UpdateNodeGraphWires
          • wires: Vec<WirePathUpdate>
        • ClearAllNodeGraphWires
        • UpdateNodeGraphSelection
          • selected: Vec<NodeId>
        • UpdateNodeGraphTransform
          • translation: (f64, f64)
          • scale: f64
        • UpdateNodeThumbnail
          • id: NodeId
          • value: String
        • UpdateOpenDocumentsList
          • open_documents: Vec<OpenDocument>
        • UpdateWirePathInProgress
          • wire_path: Option<WirePath>
        • UpdatePlatform
          • platform: AppWindowPlatform
        • UpdateMaximized
          • maximized: bool
        • UpdateFullscreen
          • fullscreen: bool
        • UpdateViewportHolePunch
          • active: bool
        • UpdateViewportPhysicalBounds
          • x: f64
          • y: f64
          • width: f64
          • height: f64
        • UpdateUIScale
          • scale: f64
        • RenderOverlays
          • context: OverlayContext
        • WindowPointerLock
        • WindowPointerLockMove
          • position: (f64, f64)
        • WindowClose
        • WindowMinimize
        • WindowMaximize
        • WindowFullscreen
        • WindowDrag
        • WindowHide
        • WindowHideOthers
        • WindowShowAll
        • WindowRestart
    • InputPreprocessor
      • InputPreprocessorMessageinput_preprocessor_message.rs:7
        • DoubleClick
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • KeyDown
          • key: Key
          • key_repeat: bool
          • modifier_keys: ModifierKeys
        • KeyUp
          • key: Key
          • key_repeat: bool
          • modifier_keys: ModifierKeys
        • PointerDown
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • PointerMove
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • PointerUp
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • PointerShake
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • CurrentTime
          • timestamp: u64
        • WheelScroll
          • editor_mouse_state: EditorMouseState
          • modifier_keys: ModifierKeys
        • InputPreprocessorMessageHandlerinput_preprocessor_message_handler.rs:14
          • frame_time: FrameTimeInfo
          • time: u64
          • keyboard: KeyStates
          • mouse: MouseState
        • InputPreprocessorMessageContextinput_preprocessor_message_handler.rs:9
          • viewport: &'a ViewportMessageHandler
    • KeyMapping
    • Layout
      • LayoutMessagelayout_message.rs:6
        • ResendActiveWidget
          • layout_target: LayoutTarget
          • widget_id: WidgetId
        • SendLayout
          • layout: Layout
          • layout_target: LayoutTarget
        • DestroyLayout
          • layout_target: LayoutTarget
        • WidgetValueCommit
          • layout_target: LayoutTarget
          • widget_id: WidgetId
          • value: serde_json::Value
        • WidgetValueUpdate
          • layout_target: LayoutTarget
          • widget_id: WidgetId
          • value: serde_json::Value
        • LayoutMessageHandlerlayout_message_handler.rs:14
          • layouts: [Layout; LayoutTarget::_LayoutTargetLength as usize]
        • LayoutMessageContextlayout_message_handler.rs:9
          • action_input_mapping: &'a dyn Fn(&MessageDiscriminant) -> Option<KeysGroup>
    • MenuBar
      • MenuBarMessagemenu_bar_message.rs:5
        • SendLayout
        • MenuBarMessageHandlermenu_bar_message_handler.rs:9
          • has_active_document: bool
          • canvas_tilted: bool
          • canvas_flipped: bool
          • rulers_visible: bool
          • node_graph_open: bool
          • has_selected_nodes: bool
          • has_selected_layers: bool
          • has_selection_history: (bool, bool)
          • message_logging_verbosity: MessageLoggingVerbosity
          • reset_node_definitions_on_open: bool
          • make_path_editable_is_allowed: bool
          • data_panel_open: bool
          • layers_panel_open: bool
          • properties_panel_open: bool
          • focus_document: bool
    • Portfolio
      • PortfolioMessageportfolio_message.rs:14
        • Document
          • DocumentMessagedocument_message.rs:25
            • Noop
            • GraphOperation
              • GraphOperationMessagegraph_operation_message.rs:20
                • FillSet
                  • layer: LayerNodeIdentifier
                  • fill: Fill
                • BlendingFillSet
                  • layer: LayerNodeIdentifier
                  • fill: f64
                • OpacitySet
                  • layer: LayerNodeIdentifier
                  • opacity: f64
                • BlendModeSet
                  • layer: LayerNodeIdentifier
                  • blend_mode: BlendMode
                • ClipModeToggle
                  • layer: LayerNodeIdentifier
                • StrokeSet
                  • layer: LayerNodeIdentifier
                  • stroke: Stroke
                • TransformChange
                  • layer: LayerNodeIdentifier
                  • transform: DAffine2
                  • transform_in: TransformIn
                  • skip_rerender: bool
                • TransformSet
                  • layer: LayerNodeIdentifier
                  • transform: DAffine2
                  • transform_in: TransformIn
                  • skip_rerender: bool
                • Vector
                  • layer: LayerNodeIdentifier
                  • modification_type: VectorModificationType
                • Brush
                  • layer: LayerNodeIdentifier
                  • strokes: Vec<BrushStroke>
                • SetUpstreamToChain
                  • layer: LayerNodeIdentifier
                • NewArtboard
                  • id: NodeId
                  • artboard: Artboard
                • NewBitmapLayer
                  • id: NodeId
                  • image_frame: Table<Raster<CPU>>
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • NewBooleanOperationLayer
                  • id: NodeId
                  • operation: graphene_std::vector::misc::BooleanOperation
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • NewCustomLayer
                  • id: NodeId
                  • nodes: Vec<(NodeId, NodeTemplate)>
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • NewVectorLayer
                  • id: NodeId
                  • subpaths: Vec<Subpath<PointId>>
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • NewTextLayer
                  • id: NodeId
                  • text: String
                  • font: Font
                  • typesetting: TypesettingConfig
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • ResizeArtboard
                  • layer: LayerNodeIdentifier
                  • location: IVec2
                  • dimensions: IVec2
                • RemoveArtboards
                • NewSvg
                  • id: NodeId
                  • svg: String
                  • transform: DAffine2
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • GraphOperationMessageHandlergraph_operation_message_handler.rs:27
                • GraphOperationMessageContextgraph_operation_message_handler.rs:20
                  • network_interface: &'a mut NodeNetworkInterface
                  • collapsed: &'a mut CollapsedLayers
                  • node_graph: &'a mut NodeGraphMessageHandler
            • Navigation
              • NavigationMessagenavigation_message.rs:7
                • BeginCanvasPan
                • BeginCanvasTilt
                  • was_dispatched_from_menu: bool
                • BeginCanvasZoom
                • CanvasPan
                  • delta: DVec2
                • CanvasPanAbortPrepare
                  • x_not_y_axis: bool
                • CanvasPanAbort
                  • x_not_y_axis: bool
                • CanvasPanByViewportFraction
                  • delta: DVec2
                • CanvasPanMouseWheel
                  • use_y_as_x: bool
                • CanvasTiltResetAndZoomTo100Percent
                • CanvasTiltSet
                  • angle_radians: f64
                • CanvasZoomDecrease
                  • center_on_mouse: bool
                • CanvasZoomIncrease
                  • center_on_mouse: bool
                • CanvasZoomMouseWheel
                • CanvasZoomSet
                  • zoom_factor: f64
                • CanvasFlip
                • EndCanvasPTZ
                  • abort_transform: bool
                • EndCanvasPTZWithClick
                  • commit_key: Key
                • FitViewportToBounds
                  • bounds: [DVec2; 2]
                  • prevent_zoom_past_100: bool
                • FitViewportToSelection
                • PointerMove
                  • snap: Key
                • NavigationMessageHandlernavigation_message_handler.rs:29
                  • navigation_operation: NavigationOperation
                  • mouse_position: ViewportPosition
                  • finish_operation_with_click: bool
                  • abortable_pan_start: Option<f64>
                • NavigationMessageContextnavigation_message_handler.rs:18
                  • network_interface: &'a mut NodeNetworkInterface
                  • breadcrumb_network_path: &'a [NodeId]
                  • ipp: &'a InputPreprocessorMessageHandler
                  • document_ptz: &'a mut PTZ
                  • graph_view_overlay_open: bool
                  • preferences: &'a PreferencesMessageHandler
                  • viewport: &'a ViewportMessageHandler
            • NodeGraph
              • NodeGraphMessagenode_graph_message.rs:15
                • AddNodes
                  • nodes: Vec<(NodeId, NodeTemplate)>
                  • new_ids: HashMap<NodeId, NodeId>
                • AddPathNode
                • AddImport
                • AddPrimaryImport
                • AddSecondaryImport
                • AddExport
                • AddPrimaryExport
                • AddSecondaryExport
                • Init
                • SelectedNodesUpdated
                • Copy
                • CreateNodeInLayerNoTransaction
                  • node_type: DefinitionIdentifier
                  • layer: LayerNodeIdentifier
                • CreateNodeInLayerWithTransaction
                  • node_type: DefinitionIdentifier
                  • layer: LayerNodeIdentifier
                • CreateNodeFromContextMenu
                  • node_id: Option<NodeId>
                  • node_type: DefinitionIdentifier
                  • xy: Option<(i32, i32)>
                  • add_transaction: bool
                • CreateWire
                  • output_connector: OutputConnector
                  • input_connector: InputConnector
                • ConnectUpstreamOutputToInput
                  • downstream_input: InputConnector
                  • input_connector: InputConnector
                • Cut
                • DeleteNodes
                  • node_ids: Vec<NodeId>
                  • delete_children: bool
                • DeleteSelectedNodes
                  • delete_children: bool
                • DisconnectInput
                  • input_connector: InputConnector
                • DisconnectRootNode
                • EnterNestedNetwork
                • DuplicateSelectedNodes
                • ExposeInput
                  • input_connector: InputConnector
                  • set_to_exposed: bool
                  • start_transaction: bool
                • ExposeEncapsulatingPrimaryInput
                  • exposed: bool
                • ExposePrimaryExport
                  • exposed: bool
                • InsertNode
                  • node_id: NodeId
                  • node_template: Box<NodeTemplate>
                • InsertNodeBetween
                  • node_id: NodeId
                  • input_connector: InputConnector
                  • insert_node_input_index: usize
                • MergeSelectedNodes
                • MoveLayerToStack
                  • layer: LayerNodeIdentifier
                  • parent: LayerNodeIdentifier
                  • insert_index: usize
                • MoveNodeToChainStart
                  • node_id: NodeId
                  • parent: LayerNodeIdentifier
                • SetChainPosition
                  • node_id: NodeId
                • PasteNodes
                  • serialized_nodes: String
                • PointerDown
                  • shift_click: bool
                  • control_click: bool
                  • alt_click: bool
                  • right_click: bool
                • PointerMove
                  • shift: Key
                • PointerUp
                • PointerOutsideViewport
                  • shift: Key
                • ShakeNode
                • UpdateNodeGraphWidth
                • RemoveImport
                  • import_index: usize
                • RemoveExport
                  • export_index: usize
                • ReorderImport
                  • start_index: usize
                  • end_index: usize
                • ReorderExport
                  • start_index: usize
                  • end_index: usize
                • RunDocumentGraph
                • ForceRunDocumentGraph
                • SelectedNodesAdd
                  • nodes: Vec<NodeId>
                • SelectedNodesRemove
                  • nodes: Vec<NodeId>
                • SelectedNodesSet
                  • nodes: Vec<NodeId>
                • SendClickTargets
                • EndSendClickTargets
                • UnloadWires
                • SendWires
                • UpdateVisibleNodes
                • SendGraph
                • SetInputValue
                  • node_id: NodeId
                  • input_index: usize
                  • value: TaggedValue
                • SetInput
                  • input_connector: InputConnector
                  • input: NodeInput
                • SetDisplayName
                  • node_id: NodeId
                  • alias: String
                  • skip_adding_history_step: bool
                • SetDisplayNameImpl
                  • node_id: NodeId
                  • alias: String
                • SetToNodeOrLayer
                  • node_id: NodeId
                  • is_layer: bool
                • ShiftNodePosition
                  • node_id: NodeId
                  • x: i32
                  • y: i32
                • ShiftSelectedNodes
                  • direction: Direction
                  • rubber_band: bool
                • ShiftSelectedNodesByAmount
                  • graph_delta: IVec2
                  • rubber_band: bool
                • TogglePreview
                  • node_id: NodeId
                • TogglePreviewImpl
                  • node_id: NodeId
                • SetImportExportName
                  • name: String
                  • index: ImportOrExport
                • SetImportExportNameImpl
                  • name: String
                  • index: ImportOrExport
                • ToggleSelectedAsLayersOrNodes
                • ToggleSelectedLocked
                • ToggleLocked
                  • node_id: NodeId
                • SetLocked
                  • node_id: NodeId
                  • locked: bool
                • ToggleSelectedIsPinned
                • ToggleSelectedVisibility
                • ToggleVisibility
                  • node_id: NodeId
                • SetPinned
                  • node_id: NodeId
                  • pinned: bool
                • SetVisibility
                  • node_id: NodeId
                  • visible: bool
                • SetLockedOrVisibilitySideEffects
                  • node_ids: Vec<NodeId>
                • UpdateEdges
                • UpdateBoxSelection
                • UpdateImportsExports
                • UpdateLayerPanel
                • UpdateNewNodeGraph
                • UpdateTypes
                  • resolved_types: ResolvedDocumentNodeTypesDelta
                  • node_graph_errors: GraphErrors
                • UpdateActionButtons
                • UpdateGraphBarRight
                • UpdateInSelectedNetwork
                • UpdateHints
                • SendSelectedNodes
                • NodeGraphMessageHandlernode_graph_message_handler.rs:54
                  • network: Vec<NodeId>
                  • has_selection: bool
                  • widgets: [LayoutGroup; 2]
                  • begin_dragging: bool
                  • node_has_moved_in_drag: bool
                  • drag_start: Option<(DragStart, bool)>
                  • drag_start_chain_nodes: Vec<NodeId>
                  • box_selection_start: Option<(DVec2, bool)>
                  • selection_before_pointer_down: Vec<NodeId>
                  • shift_without_push: bool
                  • disconnecting: Option<InputConnector>
                  • initial_disconnecting: bool
                  • select_if_not_dragged: Option<NodeId>
                  • wire_in_progress_from_connector: Option<DVec2>
                  • wire_in_progress_to_connector: Option<DVec2>
                  • wire_in_progress_type: FrontendGraphDataType
                  • context_menu: Option<ContextMenuInformation>
                  • deselect_on_pointer_up: Option<usize>
                  • auto_panning: AutoPanning
                  • preview_on_mouse_up: Option<NodeId>
                  • reordering_import: Option<usize>
                  • reordering_export: Option<usize>
                  • end_index: Option<usize>
                  • frontend_nodes: Vec<NodeId>
                  • frontend_wires: HashSet<(NodeId, usize)>
                • NodeGraphMessageContextnode_graph_message_handler.rs:38
                  • network_interface: &'a mut NodeNetworkInterface
                  • selection_network_path: &'a [NodeId]
                  • breadcrumb_network_path: &'a [NodeId]
                  • document_id: DocumentId
                  • collapsed: &'a mut CollapsedLayers
                  • ipp: &'a InputPreprocessorMessageHandler
                  • graph_view_overlay_open: bool
                  • graph_fade_artwork_percentage: f64
                  • navigation_handler: &'a NavigationMessageHandler
                  • preferences: &'a PreferencesMessageHandler
                  • layers_panel_open: bool
                  • viewport: &'a ViewportMessageHandler
            • Overlays
            • PropertiesPanel
            • DataPanel
              • DataPanelMessagedata_panel_message.rs:7
                • UpdateLayout
                  • inspect_result: InspectResult
                • ClearLayout
                • PushToElementPath
                  • index: usize
                • TruncateElementPath
                  • len: usize
                • ViewVectorTableTab
                  • tab: VectorTableTab
                • DataPanelMessageHandlerdata_panel_message_handler.rs:29
                  • introspected_node: Option<NodeId>
                  • introspected_data: Option<Arc<dyn Any + Send + Sync>>
                  • element_path: Vec<usize>
                  • active_vector_table_tab: VectorTableTab
                • DataPanelMessageContextdata_panel_message_handler.rs:22
                  • network_interface: &'a mut NodeNetworkInterface
                  • data_panel_open: bool
            • AlignSelectedLayers
              • axis: AlignAxis
              • aggregate: AlignAggregate
            • RemoveArtboards
            • ClearLayersPanel
            • CreateEmptyFolder
            • DeleteNode
              • node_id: NodeId
            • DeleteSelectedLayers
            • DeselectAllLayers
            • DocumentHistoryBackward
            • DocumentHistoryForward
            • DocumentStructureChanged
            • DrawArtboardOverlays
              • context: OverlayContext
            • DuplicateSelectedLayers
            • EnterNestedNetwork
              • node_id: NodeId
            • Escape
            • ExitNestedNetwork
              • steps_back: usize
            • FlipSelectedLayers
              • flip_axis: FlipAxis
            • RotateSelectedLayers
              • degrees: f64
            • GraphViewOverlay
              • open: bool
            • GraphViewOverlayToggle
            • GridOptions
              • options: GridSnapping
            • GridOverlays
              • context: OverlayContext
            • GridVisibility
              • visible: bool
            • GroupSelectedLayers
              • group_folder_type: GroupFolderType
            • MoveSelectedLayersTo
              • parent: LayerNodeIdentifier
              • insert_index: usize
            • MoveSelectedLayersToGroup
              • parent: LayerNodeIdentifier
            • NudgeSelectedLayers
              • delta_x: f64
              • delta_y: f64
              • resize: Key
              • resize_opposite_corner: Key
            • PasteImage
              • name: Option<String>
              • image: Image<Color>
              • mouse: Option<(f64, f64)>
              • parent_and_insert_index: Option<(LayerNodeIdentifier, usize)>
            • PasteSvg
              • name: Option<String>
              • svg: String
              • mouse: Option<(f64, f64)>
              • parent_and_insert_index: Option<(LayerNodeIdentifier, usize)>
            • Redo
            • RenameDocument
              • new_name: String
            • RenderRulers
            • RenderScrollbars
            • SaveDocument
            • SaveDocumentAs
            • SavedDocument
              • path: Option<PathBuf>
            • MarkAsSaved
            • SelectParentLayer
            • SelectAllLayers
            • SelectedLayersLower
            • SelectedLayersLowerToBack
            • SelectedLayersRaise
            • SelectedLayersRaiseToFront
            • SelectedLayersReverse
            • SelectedLayersReorder
              • relative_index_offset: isize
            • ClipLayer
              • id: NodeId
            • SelectLayer
              • id: NodeId
              • ctrl: bool
              • shift: bool
            • SetActivePanel
              • active_panel: PanelType
            • SetBlendModeForSelectedLayers
              • blend_mode: BlendMode
            • SetGraphFadeArtwork
              • percentage: f64
            • SetNodePinned
              • node_id: NodeId
              • pinned: bool
            • SetOpacityForSelectedLayers
              • opacity: f64
            • SetFillForSelectedLayers
              • fill: f64
            • SetOverlaysVisibility
              • visible: bool
              • overlays_type: Option<OverlaysType>
            • SetRangeSelectionLayer
              • new_layer: Option<LayerNodeIdentifier>
            • SetSnapping
              • closure: Option<for<'a>fn(&'a mut SnappingState) -> &'a mut bool>
              • snapping_state: bool
            • SetToNodeOrLayer
              • node_id: NodeId
              • is_layer: bool
            • SetRenderMode
              • render_mode: RenderMode
            • AddTransaction
            • StartTransaction
            • EndTransaction
            • CommitTransaction
            • CancelTransaction
            • AbortTransaction
            • RepeatedAbortTransaction
              • undo_count: usize
            • ToggleLayerExpansion
              • id: NodeId
              • recursive: bool
            • ToggleSelectedVisibility
            • ToggleSelectedLocked
            • ToggleGridVisibility
            • ToggleOverlaysVisibility
            • ToggleSnapping
            • UpdateUpstreamTransforms
              • upstream_footprints: HashMap<NodeId, Footprint>
              • local_transforms: HashMap<NodeId, DAffine2>
              • first_element_source_id: HashMap<NodeId, Option<NodeId>>
            • UpdateClickTargets
              • click_targets: HashMap<NodeId, Vec<Arc<ClickTarget>>>
            • UpdateClipTargets
              • clip_targets: HashSet<NodeId>
            • UpdateVectorData
              • vector_data: HashMap<NodeId, Arc<Vector>>
            • Undo
            • UngroupSelectedLayers
            • UngroupLayer
              • layer: LayerNodeIdentifier
            • PTZUpdate
            • SelectionStepBack
            • SelectionStepForward
            • WrapContentInArtboard
              • place_artboard_at_origin: bool
            • ZoomCanvasTo100Percent
            • ZoomCanvasTo200Percent
            • ZoomCanvasToFitAll
            • DocumentMessageHandlerdocument_message_handler.rs:63
              • navigation_handler: NavigationMessageHandler
              • node_graph_handler: NodeGraphMessageHandler
              • overlays_message_handler: OverlaysMessageHandler
              • properties_panel_message_handler: PropertiesPanelMessageHandler
              • data_panel_message_handler: DataPanelMessageHandler
              • network_interface: NodeNetworkInterface
              • collapsed: CollapsedLayers
              • commit_hash: String
              • document_ptz: PTZ
              • render_mode: RenderMode
              • overlays_visibility_settings: OverlaysVisibilitySettings
              • rulers_visible: bool
              • snapping_state: SnappingState
              • graph_view_overlay_open: bool
              • graph_fade_artwork_percentage: f64
              • name: String
              • path: Option<PathBuf>
              • breadcrumb_network_path: Vec<NodeId>
              • selection_network_path: Vec<NodeId>
              • document_undo_history: VecDeque<NodeNetworkInterface>
              • document_redo_history: VecDeque<NodeNetworkInterface>
              • saved_hash: Option<u64>
              • auto_saved_hash: Option<u64>
              • layer_range_selection_reference: Option<LayerNodeIdentifier>
              • is_loaded: bool
            • DocumentMessageContextdocument_message_handler.rs:48
              • document_id: DocumentId
              • ipp: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • executor: &'a mut NodeGraphExecutor
              • current_tool: &'a ToolType
              • preferences: &'a PreferencesMessageHandler
              • data_panel_open: bool
              • layers_panel_open: bool
              • properties_panel_open: bool
              • viewport: &'a ViewportMessageHandler
        • Init
        • DocumentPassMessage
          • document_id: DocumentId
          • message: DocumentMessage
        • AutoSaveActiveDocument
        • AutoSaveAllDocuments
        • AutoSaveDocument
          • document_id: DocumentId
        • CloseActiveDocumentWithConfirmation
        • CloseAllDocuments
        • CloseAllDocumentsWithConfirmation
        • CloseDocument
          • document_id: DocumentId
        • CloseDocumentWithConfirmation
          • document_id: DocumentId
        • Copy
          • clipboard: Clipboard
        • Cut
          • clipboard: Clipboard
        • DeleteDocument
          • document_id: DocumentId
        • DestroyAllDocuments
        • EditorPreferences
        • FontCatalogLoaded
          • catalog: FontCatalog
        • LoadFontData
          • font: Font
        • FontLoaded
          • font_family: String
          • font_style: String
          • data: Vec<u8>
        • LoadDocumentResources
          • document_id: DocumentId
        • NewDocumentWithName
          • name: String
        • NextDocument
        • Open
        • Import
        • OpenFile
          • path: PathBuf
          • content: Vec<u8>
        • ImportFile
          • path: PathBuf
          • content: Vec<u8>
        • OpenDocumentFile
          • document_name: Option<String>
          • document_path: Option<PathBuf>
          • document_serialized_content: String
        • OpenDocumentFileWithId
          • document_id: DocumentId
          • document_name: Option<String>
          • document_path: Option<PathBuf>
          • document_is_auto_saved: bool
          • document_is_saved: bool
          • document_serialized_content: String
          • to_front: bool
          • select_after_open: bool
        • OpenImage
          • name: Option<String>
          • image: Image<Color>
        • OpenSvg
          • name: Option<String>
          • svg: String
        • PasteSerializedData
          • data: String
        • PasteSerializedVector
          • data: String
        • PasteImage
          • name: Option<String>
          • image: Image<Color>
          • mouse: Option<(f64, f64)>
          • parent_and_insert_index: Option<(LayerNodeIdentifier, usize)>
        • PasteSvg
          • name: Option<String>
          • svg: String
          • mouse: Option<(f64, f64)>
          • parent_and_insert_index: Option<(LayerNodeIdentifier, usize)>
        • PasteIntoFolder
          • clipboard: Clipboard
          • parent: LayerNodeIdentifier
          • insert_index: usize
        • CenterPastedLayers
          • layers: Vec<LayerNodeIdentifier>
        • PrevDocument
        • RequestWelcomeScreenButtonsLayout
        • RequestStatusBarInfoLayout
        • SetActivePanel
          • panel: PanelType
        • SelectDocument
          • document_id: DocumentId
        • SubmitDocumentExport
          • name: String
          • file_type: FileType
          • scale_factor: f64
          • bounds: ExportBounds
          • transparent_background: bool
          • artboard_name: Option<String>
          • artboard_count: usize
        • SubmitActiveGraphRender
        • SubmitGraphRender
          • document_id: DocumentId
          • ignore_hash: bool
        • SubmitEyedropperPreviewRender
        • ToggleResetNodesToDefinitionsOnOpen
        • ToggleFocusDocument
        • ToggleDataPanelOpen
        • TogglePropertiesPanelOpen
        • ToggleLayersPanelOpen
        • ToggleRulers
        • UpdateDocumentWidgets
        • UpdateOpenDocumentsList
        • PortfolioMessageHandlerportfolio_message_handler.rs:53
          • documents: HashMap<DocumentId, DocumentMessageHandler>
          • document_ids: VecDeque<DocumentId>
          • active_panel: PanelType
          • active_document_id: Option<DocumentId>
          • copy_buffer: [Vec<CopyBufferEntry>; INTERNAL_CLIPBOARD_COUNT as usize]
          • persistent_data: PersistentData
          • executor: NodeGraphExecutor
          • selection_mode: SelectionMode
          • reset_node_definitions_on_open: bool
          • focus_document: bool
          • properties_panel_open: bool
          • layers_panel_open: bool
          • data_panel_open: bool
        • PortfolioMessageContextportfolio_message_handler.rs:41
          • ipp: &'a InputPreprocessorMessageHandler
          • preferences: &'a PreferencesMessageHandler
          • animation: &'a AnimationMessageHandler
          • current_tool: &'a ToolType
          • reset_node_definitions_on_open: bool
          • timing_information: TimingInformation
          • viewport: &'a ViewportMessageHandler
    • Preferences
      • PreferencesMessagepreferences_message.rs:7
        • Load
          • preferences: PreferencesMessageHandler
        • ResetToDefaults
        • SelectionMode
          • selection_mode: SelectionMode
        • BrushTool
          • enabled: bool
        • ModifyLayout
          • zoom_with_scroll: bool
        • GraphWireStyle
          • style: GraphWireStyle
        • ViewportZoomWheelRate
          • rate: f64
        • UIScale
          • scale: f64
        • MaxRenderRegionSize
          • size: u32
        • DisableUIAcceleration
          • disable_ui_acceleration: bool
        • PreferencesMessageHandlerpreferences_message_handler.rs:17
          • selection_mode: SelectionMode
          • zoom_with_scroll: bool
          • brush_tool: bool
          • graph_wire_style: GraphWireStyle
          • viewport_zoom_wheel_rate: f64
          • ui_scale: f64
          • max_render_region_size: u32
          • disable_ui_acceleration: bool
        • PreferencesMessageContextpreferences_message_handler.rs:10
          • tool_message_handler: &'a ToolMessageHandler
    • Tool
      • ToolMessagetool_message.rs:8
        • TransformLayer
          • TransformLayerMessagetransform_layer_message.rs:10
            • Overlays
              • context: OverlayContext
            • ApplyTransformOperation
              • final_transform: bool
            • BeginTransformOperation
              • operation: TransformType
            • BeginGrab
            • BeginRotate
            • BeginScale
            • BeginGRS
              • operation: TransformType
            • BeginGrabPen
              • last_point: DVec2
              • handle: DVec2
            • BeginRotatePen
              • last_point: DVec2
              • handle: DVec2
            • BeginScalePen
              • last_point: DVec2
              • handle: DVec2
            • CancelTransformOperation
            • ConstrainX
            • ConstrainY
            • PointerMove
              • slow_key: Key
              • increments_key: Key
            • SelectionChanged
            • TypeBackspace
            • TypeDecimalPoint
            • TypeDigit
              • digit: u8
            • TypeNegate
            • SetPivotGizmo
              • pivot_gizmo: PivotGizmo
            • TransformLayerMessageHandlertransform_layer_message_handler.rs:71
              • transform_operation: TransformOperation
              • state: TransformationState
              • slow: bool
              • layer_bounding_box: Quad
              • typing: Typing
              • mouse_position: ViewportPosition
              • start_mouse: ViewportPosition
              • original_transforms: OriginalTransforms
              • pivot_gizmo: PivotGizmo
              • pivot: ViewportPosition
              • path_bounds: Option<[DVec2; 2]>
              • local_mouse_start: DocumentPosition
              • grab_target: DocumentPosition
              • ptz: PTZ
              • initial_transform: DAffine2
              • operation_count: usize
              • was_grabbing: bool
              • handle: DVec2
              • last_point: DVec2
              • grs_pen_handle: bool
              • ghost_outline: Vec<(Vec<ClickTargetType>, DAffine2)>
            • TransformLayerMessageContexttransform_layer_message_handler.rs:28
              • document: &'a DocumentMessageHandler
              • input: &'a InputPreprocessorMessageHandler
              • tool_data: &'a ToolData
              • shape_editor: &'a mut ShapeState
              • viewport: &'a ViewportMessageHandler
        • Select
          • SelectToolMessageselect_tool.rs:83
            • Abort
            • Overlays
              • context: OverlayContext
            • DragStart
              • extend_selection: Key
              • remove_from_selection: Key
              • select_deepest: Key
              • lasso_select: Key
              • skew: Key
            • DragStop
              • remove_from_selection: Key
            • EditLayer
            • EditLayerExec
            • Enter
            • PointerMove
              • modifier_keys: SelectToolPointerKeys
            • PointerOutsideViewport
              • modifier_keys: SelectToolPointerKeys
            • SelectOptions
              • options: SelectOptionsUpdate
            • SetPivot
              • position: ReferencePoint
            • SyncHistory
            • ShiftSelectedNodes
              • offset: DVec2
            • PivotShift
              • offset: Option<DVec2>
              • flush: bool
            • SelectToolselect_tool.rs:34(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: SelectToolFsmState
              • tool_data: SelectToolData
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Artboard
          • ArtboardToolMessageartboard_tool.rs:27
            • Abort
            • Overlays
              • context: OverlayContext
            • UpdateSelectedArtboard
            • DeleteSelected
            • NudgeSelected
              • delta_x: f64
              • delta_y: f64
              • resize: Key
              • resize_opposite_corner: Key
            • PointerDown
            • PointerMove
              • constrain_axis_or_aspect: Key
              • center: Key
            • PointerOutsideViewport
              • constrain_axis_or_aspect: Key
              • center: Key
            • PointerUp
            • ArtboardToolartboard_tool.rs:19(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: ArtboardToolFsmState
              • data: ArtboardToolData
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Navigate
          • NavigateToolMessagenavigate_tool.rs:12
            • Abort
            • PointerUp
              • zoom_in: bool
            • PointerMove
              • snap: Key
            • TiltCanvasBegin
            • ZoomCanvasBegin
            • End
            • NavigateToolnavigate_tool.rs:4(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: NavigateToolFsmState
              • tool_data: NavigateToolData
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Eyedropper
          • EyedropperToolMessageeyedropper_tool.rs:15
            • Abort
            • SamplePrimaryColorBegin
            • SamplePrimaryColorEnd
            • PointerMove
            • SampleSecondaryColorBegin
            • SampleSecondaryColorEnd
            • PreviewImage
              • data: Vec<u8>
              • width: u32
              • height: u32
            • EyedropperTooleyedropper_tool.rs:7(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: EyedropperToolFsmState
              • data: EyedropperToolData
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Fill
          • FillToolMessagefill_tool.rs:14
            • Abort
            • WorkingColorChanged
            • Overlays
              • context: OverlayContext
            • PointerMove
            • PointerUp
            • FillPrimaryColor
            • FillSecondaryColor
            • FillToolfill_tool.rs:7(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: FillToolFsmState
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Gradient
          • GradientToolMessagegradient_tool.rs:29
            • Abort
            • Overlays
              • context: OverlayContext
            • SelectionChanged
            • DeleteStop
            • DoubleClick
            • InsertStop
            • PointerDown
            • PointerMove
              • constrain_axis: Key
              • lock_angle: Key
            • PointerOutsideViewport
              • constrain_axis: Key
              • lock_angle: Key
            • PointerUp
            • StartTransactionForColorStop
            • CommitTransactionForColorStop
            • CloseStopColorPicker
            • UpdateStopColor
              • color: Color
            • UpdateOptions
              • options: GradientOptionsUpdate
            • GradientToolgradient_tool.rs:15(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: GradientToolFsmState
              • data: GradientToolData
              • options: GradientOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Path
          • PathToolMessagepath_tool.rs:55
            • Abort
            • SelectionChanged
            • Overlays
              • context: OverlayContext
            • BreakPath
            • DeselectAllSelected
            • Delete
            • DeleteAndBreakPath
            • DragStop
              • extend_selection: Key
              • shrink_selection: Key
            • Enter
              • extend_selection: Key
              • shrink_selection: Key
            • Escape
            • ClosePath
            • ConnectPointsByPosition
              • layer: LayerNodeIdentifier
              • start_position: DVec2
              • end_position: DVec2
            • DoubleClick
              • extend_selection: Key
              • shrink_selection: Key
            • GRS
              • key: Key
            • ManipulatorMakeHandlesFree
            • ManipulatorMakeHandlesColinear
            • MouseDown
              • extend_selection: Key
              • lasso_select: Key
              • handle_drag_from_anchor: Key
              • drag_restore_handle: Key
              • segment_editing_modifier: Key
            • NudgeSelectedPoints
              • delta_x: f64
              • delta_y: f64
            • PointerMove
              • equidistant: Key
              • toggle_colinear: Key
              • move_anchor_with_handles: Key
              • snap_angle: Key
              • lock_angle: Key
              • delete_segment: Key
              • break_colinear_molding: Key
              • segment_editing_modifier: Key
            • PointerOutsideViewport
              • equidistant: Key
              • toggle_colinear: Key
              • move_anchor_with_handles: Key
              • snap_angle: Key
              • lock_angle: Key
              • delete_segment: Key
              • break_colinear_molding: Key
              • segment_editing_modifier: Key
            • RightClick
            • SelectAll
            • SelectedPointUpdated
            • SelectedPointXChanged
              • new_x: f64
            • SelectedPointYChanged
              • new_y: f64
            • SetPivot
              • position: ReferencePoint
            • SwapSelectedHandles
            • UpdateOptions
              • options: PathOptionsUpdate
            • UpdateSelectedPointsStatus
              • overlay_context: OverlayContext
            • StartSlidingPoint
            • Copy
              • clipboard: Clipboard
            • Cut
              • clipboard: Clipboard
            • Paste
              • data: String
            • DeleteSelected
            • Duplicate
            • TogglePointEditing
            • ToggleSegmentEditing
            • PathToolpath_tool.rs:40(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: PathToolFsmState
              • tool_data: PathToolData
              • options: PathToolOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Pen
          • PenToolMessagepen_tool.rs:50
            • Abort
            • SelectionChanged
            • WorkingColorChanged
            • Overlays
              • context: OverlayContext
            • AddPointLayerPosition
              • layer: LayerNodeIdentifier
              • viewport: DVec2
            • Confirm
            • DragStart
              • append_to_selected: Key
            • DragStop
            • PointerMove
              • snap_angle: Key
              • break_handle: Key
              • lock_angle: Key
              • colinear: Key
              • move_anchor_with_handles: Key
            • PointerOutsideViewport
              • snap_angle: Key
              • break_handle: Key
              • lock_angle: Key
              • colinear: Key
              • move_anchor_with_handles: Key
            • Redo
            • Undo
            • UpdateOptions
              • options: PenOptionsUpdate
            • RecalculateLatestPointsPosition
            • RemovePreviousHandle
            • GRS
              • grab: Key
              • rotate: Key
              • scale: Key
            • FinalPosition
              • final_position: DVec2
            • SwapHandles
            • PenToolpen_tool.rs:23(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: PenToolFsmState
              • tool_data: PenToolData
              • options: PenOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Freehand
          • FreehandToolMessagefreehand_tool.rs:43
            • Overlays
              • context: OverlayContext
            • Abort
            • WorkingColorChanged
            • DragStart
              • append_to_selected: Key
            • DragStop
            • PointerMove
            • UpdateOptions
              • options: FreehandOptionsUpdate
            • FreehandToolfreehand_tool.rs:18(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: FreehandToolFsmState
              • data: FreehandToolData
              • options: FreehandOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Spline
          • SplineToolMessagespline_tool.rs:44
            • Overlays
              • context: OverlayContext
            • CanvasTransformed
            • Abort
            • WorkingColorChanged
            • Confirm
            • DragStart
              • append_to_selected: Key
            • DragStop
            • MergeEndpoints
            • PointerMove
            • PointerOutsideViewport
            • Undo
            • UpdateOptions
              • options: SplineOptionsUpdate
            • SplineToolspline_tool.rs:19(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: SplineToolFsmState
              • tool_data: SplineToolData
              • options: SplineOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Shape
          • ShapeToolMessageshape_tool.rs:94
            • Overlays
              • context: OverlayContext
            • Abort
            • WorkingColorChanged
            • DragStart
            • DragStop
            • HideShapeTypeWidget
              • hide: bool
            • PointerMove
              • modifier: ShapeToolModifierKey
            • PointerOutsideViewport
              • modifier: ShapeToolModifierKey
            • UpdateOptions
              • options: ShapeOptionsUpdate
            • SetShape
              • shape: ShapeType
            • SyncShapeWithOptions
            • IncreaseSides
            • DecreaseSides
            • NudgeSelectedLayers
              • delta_x: f64
              • delta_y: f64
              • resize: Key
              • resize_opposite_corner: Key
            • ShapeToolshape_tool.rs:31(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: ShapeToolFsmState
              • tool_data: ShapeToolData
              • options: ShapeToolOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Text
          • TextToolMessagetext_tool.rs:60
            • Abort
            • WorkingColorChanged
            • Overlays
              • context: OverlayContext
            • DragStart
            • DragStop
            • EditSelected
            • Interact
            • PointerMove
              • center: Key
              • lock_ratio: Key
            • PointerOutsideViewport
              • center: Key
              • lock_ratio: Key
            • TextChange
              • new_text: String
              • is_left_or_right_click: bool
            • UpdateBounds
              • new_text: String
            • UpdateOptions
              • options: TextOptionsUpdate
            • RefreshEditingFontData
            • TextTooltext_tool.rs:27(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: TextToolFsmState
              • tool_data: TextToolData
              • options: TextOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • Brush
          • BrushToolMessagebrush_tool.rs:58
            • Abort
            • WorkingColorChanged
            • DragStart
            • DragStop
            • PointerMove
            • UpdateOptions
              • options: BrushToolMessageOptionsUpdate
            • BrushToolbrush_tool.rs:25(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
              • fsm_state: BrushToolFsmState
              • data: BrushToolData
              • options: BrushOptions
            • &mut ToolActionMessageContext<'a>utility_types.rs:22
              • document: &'a mut DocumentMessageHandler
              • document_id: DocumentId
              • global_tool_data: &'a DocumentToolData
              • input: &'a InputPreprocessorMessageHandler
              • persistent_data: &'a PersistentData
              • shape_editor: &'a mut ShapeState
              • node_graph: &'a NodeGraphExecutor
              • preferences: &'a PreferencesMessageHandler
              • viewport: &'a ViewportMessageHandler
        • ActivateToolSelect
        • ActivateToolArtboard
        • ActivateToolNavigate
        • ActivateToolEyedropper
        • ActivateToolFill
        • ActivateToolGradient
        • ActivateToolPath
        • ActivateToolPen
        • ActivateToolFreehand
        • ActivateToolSpline
        • ActivateToolShapeLine
        • ActivateToolShapeRectangle
        • ActivateToolShapeEllipse
        • ActivateToolShape
        • ActivateToolText
        • ActivateToolBrush
        • ActivateTool
          • tool_type: ToolType
        • DeactivateTools
        • InitTools
        • PreUndo
        • Redo
        • RefreshToolOptions
        • RefreshToolShelf
        • ResetColors
        • SelectWorkingColor
          • color: Color
          • primary: bool
        • SelectRandomWorkingColor
          • primary: bool
        • ToggleSelectVsPath
        • SwapColors
        • Undo
        • UpdateCursor
        • UpdateHints
        • UpdateSelectionMode
          • selection_mode: SelectionMode
        • ToolMessageHandlertool_message_handler.rs:28
          • tool_state: ToolFsmState
          • transform_layer_handler: TransformLayerMessageHandler
          • shape_editor: ShapeState
          • tool_is_active: bool
        • ToolMessageContexttool_message_handler.rs:17
          • document_id: DocumentId
          • document: &'a mut DocumentMessageHandler
          • input: &'a InputPreprocessorMessageHandler
          • persistent_data: &'a PersistentData
          • node_graph: &'a NodeGraphExecutor
          • preferences: &'a PreferencesMessageHandler
          • viewport: &'a ViewportMessageHandler
    • Viewport
    • Batched
      • messages: Box<[Message]>
    • NoOp

Parts of the hierarchy

Subsystem components

  • A *Message enum is the component of an editor subsystem that defines its message interfaces as enum variants. Messages are used for passing a request from anywhere in the application, optionally with some included data, to have a particular block of code be run by its respective message handler.

  • A *MessageHandler struct is the component of an editor subsystem that has ownership over its persistent editor state and its child message handlers for the lifetime of the application. It also defines the logic for handling each of its messages that it receives from the dispatcher. Those blocks of logic may further enqueue additional messages to be processed by itself or other message handlers during the same dispatch cycle.

  • A *MessageContext struct is the component of an editor subsystem that defines what data is made available from other subsystems when running the logic to handle a dispatched message. It is a struct that is passed to the message handler when processing a message, and it gets filled in with data (owned, borrowed, or mutably borrowed) from its parent message handler. Intermediate subsystem layers may forward data from their parent to their child contexts to make state available from further up the hierarchy.

Sub-messages

  • A #[child] * attribute-decorated message enum variant is a special kind of message that encapsulates a nested subsystem. As with all messages, its handler has a manually written code block. But that code must call its corresponding child message handler's process_message method. The child message handler is a field of this parent message handler's state struct.

Messages

  • A * message enum variant is used throughout the editor to request that a certain subsystem performs some action, potentially given some data. In that sense, it resembles a function call, but a key difference is that messages are queued up and processed sequentially in a flat order, always invoked by the dispatcher.

How messages work

Messages are enum variants that are dispatched to perform some intended activity within their respective message handlers. Here are two message definitions from DocumentMessage:

pub enum DocumentMessage {
	...
	// A message that carries one data field
	DeleteLayer {
		id: NodeId,
	}
	// A message that carries no data
	DeleteSelectedLayers,
	...
}

As shown above, additional data fields can be included with each message. But as a special case denoted by a #[child] attribute, that data can also be a sub-message enum, which enables hierarchical nesting of message handler subsystems.

By convention, regular data must be written as struct-style named fields (shown above), while a sub-message enum must be written as a tuple/newtype-style field (shown below). The DocumentMessage enum of the previous example is defined as a child of PortfolioMessage which wraps it like this:

pub enum PortfolioMessage {
	...
	// A message that carries the `DocumentMessage` child enum as data
	#[child]
	Document(DocumentMessage),
	...
}

Likewise, the PortfolioMessage enum is wrapped by the top-level Message enum. The dispatcher operates on the queue of these base-level Message types.

So for example, the DeleteSelectedLayers message mentioned previously will look like this as a Message data type:

Message::Portfolio(
	PortfolioMessage::Document(
		DocumentMessage::DeleteSelectedLayers
	)
)

Writing out these nested message enum variants would be cumbersome, so that #[child] attribute shown earlier invokes a proc macro that automatically implements the From trait, letting you write this instead to get a Message data type:

DocumentMessage::DeleteSelectedLayers.into()

Most often, this is simplified even further because the .into() is called for you when pushing a message to the queue with .add() or .add_front(). So this becomes as simple as:

responses.add(DocumentMessage::DeleteSelectedLayers);

The responses message queue is composed of Message data types, and thanks to this system, child messages like DocumentMessage::DeleteSelectedLayers are automatically wrapped in their ancestor enum variants to become a Message, saving you from writing the verbose nested form.