Editor structure

The Graphite editor is the application users interact with to create documents. Its code is one Rust crate sandwiched between the frontend and 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

Click to explore the outline of the editor subsystem hierarchy which forms the structure of the editor's subsystems, state, and interactions. Bookmark this page to reference it later.

  • Messagemessage.rs
    • Animation
      • AnimationMessageanimation_message.rs
        • ToggleLivePreview
        • EnableLivePreview
        • DisableLivePreview
        • RestartAnimation
        • SetFrameIndex
          • frame: f64
        • SetTime
          • time: f64
        • UpdateTime
        • IncrementFrameCounter
        • SetAnimationTimeMode
          • animation_time_mode: AnimationTimeMode
      • AnimationMessageHandleranimation_message_handler.rs
        • live_preview_recently_zero: bool
        • timestamp: f64
        • frame_index: f64
        • animation_state: AnimationState
        • fps: f64
        • animation_time_mode: AnimationTimeMode
    • AppWindow
    • Broadcast
    • Debug
    • Defer
      • DeferMessagedefer_message.rs
        • SetGraphSubmissionIndex
          • execution_id: u64
        • TriggerGraphRun
          • execution_id: u64
          • document_id: DocumentId
        • AfterGraphRun
          • messages: Vec<Message>
        • TriggerNavigationReady
        • AfterNavigationReady
          • messages: Vec<Message>
      • DeferMessageHandlerdefer_message_handler.rs
        • after_graph_run: HashMap<DocumentId, Vec<(u64, Message)>>
        • after_viewport_resize: Vec<Message>
        • current_graph_submission_id: u64
      • DeferMessageContextdefer_message_handler.rs
        • portfolio: &'a PortfolioMessageHandler
    • Dialog
      • DialogMessagedialog_message.rs
        • ExportDialog
          • ExportDialogMessageexport_dialog_message.rs
            • FileType
              • file_type: FileType
            • ScaleFactor
              • factor: f64
            • TransparentBackground
              • transparent: bool
            • ExportBounds
              • bounds: ExportBounds
            • Submit
          • ExportDialogMessageHandlerexport_dialog_message_handler.rs
            • file_type: FileType
            • scale_factor: f64
            • bounds: ExportBounds
            • transparent_background: bool
            • artboards: HashMap<LayerNodeIdentifier, String>
            • has_selection: bool
          • ExportDialogMessageContextexport_dialog_message_handler.rs
            • portfolio: &'a PortfolioMessageHandler
        • NewDocumentDialog
        • PreferencesDialog
        • CloseAllDocumentsWithConfirmation
        • CloseDialogAndThen
          • followups: Vec<Message>
        • DisplayDialogError
          • title: String
          • description: String
        • RequestAboutGraphiteDialog
        • RequestAboutGraphiteDialogWithLocalizedCommitDate
          • localized_commit_date: String
          • localized_commit_year: String
        • RequestComingSoonDialog
          • issue: Option<u32>
        • RequestDemoArtworkDialog
        • RequestExportDialog
        • RequestLicensesDialogWithLocalizedCommitDate
          • localized_commit_year: String
        • RequestNewDocumentDialog
        • RequestPreferencesDialog
      • DialogMessageHandlerdialog_message_handler.rs
        • export_dialog: ExportDialogMessageHandler
        • new_document_dialog: NewDocumentDialogMessageHandler
        • preferences_dialog: PreferencesDialogMessageHandler
      • DialogMessageContextdialog_message_handler.rs
        • portfolio: &'a PortfolioMessageHandler
        • viewport_bounds: &'a ViewportBounds
        • preferences: &'a PreferencesMessageHandler
    • Frontend
      • FrontendMessagefrontend_message.rs
        • DisplayDialog
          • title: String
          • icon: String
        • DisplayDialogDismiss
        • DisplayDialogPanic
          • panic_info: String
        • DisplayEditableTextbox
          • text: String
          • line_height_ratio: f64
          • font_size: f64
          • color: Color
          • url: String
          • transform: [f64; 6]
          • max_width: Option<f64>
          • max_height: Option<f64>
          • align: TextAlign
        • DisplayEditableTextboxTransform
          • transform: [f64; 6]
        • DisplayRemoveEditableTextbox
        • SendUIMetadata
          • node_descriptions: Vec<(String, String)>
          • node_types: Vec<FrontendNodeType>
        • TriggerAboutGraphiteLocalizedCommitDate
          • commit_date: String
        • TriggerSaveDocument
          • document_id: DocumentId
          • name: String
          • path: Option<PathBuf>
          • content: Vec<u8>
        • TriggerSaveFile
          • name: String
          • content: Vec<u8>
        • TriggerExportImage
          • svg: String
          • name: String
          • mime: String
          • size: (f64, f64)
        • TriggerFetchAndOpenDocument
          • name: String
          • filename: String
        • TriggerFontLoad
          • font: Font
        • TriggerImport
        • TriggerIndexedDbRemoveDocument
          • document_id: DocumentId
        • TriggerIndexedDbWriteDocument
          • document: String
          • details: FrontendDocumentDetails
        • TriggerLoadFirstAutoSaveDocument
        • TriggerLoadRestAutoSaveDocuments
        • TriggerLoadPreferences
        • TriggerOpenDocument
        • TriggerPaste
        • TriggerSavePreferences
          • preferences: PreferencesMessageHandler
        • TriggerSaveActiveDocument
          • document_id: DocumentId
        • TriggerTextCommit
        • TriggerTextCopy
          • copy_text: String
        • TriggerVisitLink
          • url: String
        • UpdateActiveDocument
          • document_id: DocumentId
        • UpdateImportsExports
          • imports: Vec<(FrontendGraphOutput, i32, i32)>
          • exports: Vec<(FrontendGraphInput, i32, i32)>
          • add_import: Option<(i32, i32)>
          • add_export: Option<(i32, i32)>
        • 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
        • UpdateDataPanelLayout
          • 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>
        • UpdateDialogButtons
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateDialogColumn1
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateDialogColumn2
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateDocumentArtwork
          • svg: String
        • UpdateImageData
          • image_data: Vec<(u64, Image<Color>)>
        • UpdateDocumentBarLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateDocumentLayerDetails
          • data: LayerPanelEntry
        • UpdateDocumentLayerStructure
          • data_buffer: RawBuffer
        • UpdateDocumentLayerStructureJs
          • data_buffer: JsRawBuffer
        • UpdateDocumentModeLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateDocumentRulers
          • origin: (f64, f64)
          • spacing: f64
          • interval: f64
          • visible: bool
        • UpdateDocumentScrollbars
          • position: (f64, f64)
          • size: (f64, f64)
          • multiplier: (f64, f64)
        • UpdateEyedropperSamplingState
          • mouse_position: Option<(f64, f64)>
          • primary_color: String
          • secondary_color: String
          • set_color_choice: Option<String>
        • UpdateGraphFadeArtwork
          • percentage: f64
        • UpdateInputHints
          • hint_data: HintData
        • UpdateLayersPanelControlBarLeftLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateLayersPanelControlBarRightLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateLayersPanelBottomBarLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateMenuBarLayout
          • layout_target: LayoutTarget
          • layout: Vec<MenuBarEntry>
        • UpdateMouseCursor
          • cursor: MouseCursorIcon
        • UpdateNodeGraphNodes
          • nodes: Vec<FrontendNode>
        • UpdateVisibleNodes
          • nodes: Vec<NodeId>
        • UpdateNodeGraphWires
          • wires: Vec<WirePathUpdate>
        • ClearAllNodeGraphWires
        • UpdateNodeGraphControlBarLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateNodeGraphSelection
          • selected: Vec<NodeId>
        • UpdateNodeGraphTransform
          • transform: Transform
        • UpdateNodeThumbnail
          • id: NodeId
          • value: String
        • UpdateOpenDocumentsList
          • open_documents: Vec<FrontendDocumentDetails>
        • UpdatePropertiesPanelLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateToolOptionsLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateToolShelfLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdateWirePathInProgress
          • wire_path: Option<WirePath>
        • UpdateWorkingColorsLayout
          • layout_target: LayoutTarget
          • diff: Vec<WidgetDiff>
        • UpdatePlatform
          • platform: AppWindowPlatform
        • UpdateMaximized
          • maximized: bool
        • UpdateViewportHolePunch
          • active: bool
        • RenderOverlays
          • context: OverlayContext
    • Globals
    • InputPreprocessor
      • InputPreprocessorMessageinput_preprocessor_message.rs
        • BoundsOfViewports
          • bounds_of_viewports: Vec<ViewportBounds>
        • 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
        • frame_time: FrameTimeInfo
        • time: u64
        • keyboard: KeyStates
        • mouse: MouseState
        • viewport_bounds: ViewportBounds
      • InputPreprocessorMessageContextinput_preprocessor_message_handler.rs
        • keyboard_platform: KeyboardPlatformLayout
    • KeyMapping
    • Layout
      • LayoutMessagelayout_message.rs
        • ResendActiveWidget
          • layout_target: LayoutTarget
          • widget_id: WidgetId
        • SendLayout
          • layout: Layout
          • 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
        • layouts: [Layout; LayoutTarget::LayoutTargetLength as usize]
      • LayoutMessageContextlayout_message_handler.rs
        • action_input_mapping: &'a dyn Fn(&MessageDiscriminant) -> Option<KeysGroup>
    • Portfolio
      • PortfolioMessageportfolio_message.rs
        • MenuBar
          • MenuBarMessagemenu_bar_message.rs
            • SendLayout
          • MenuBarMessageHandlermenu_bar_message_handler.rs
            • 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
        • Document
          • DocumentMessagedocument_message.rs
            • Noop
            • GraphOperation
              • GraphOperationMessagegraph_operation_message.rs
                • 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::path_bool::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
              • GraphOperationMessageContextgraph_operation_message_handler.rs
                • network_interface: &'a mut NodeNetworkInterface
                • collapsed: &'a mut CollapsedLayers
                • node_graph: &'a mut NodeGraphMessageHandler
            • Navigation
              • NavigationMessagenavigation_message.rs
                • 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
                • navigation_operation: NavigationOperation
                • mouse_position: ViewportPosition
                • finish_operation_with_click: bool
                • abortable_pan_start: Option<f64>
              • NavigationMessageContextnavigation_message_handler.rs
                • 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
            • NodeGraph
              • NodeGraphMessagenode_graph_message.rs
                • AddNodes
                  • nodes: Vec<(NodeId, NodeTemplate)>
                  • new_ids: HashMap<NodeId, NodeId>
                • AddPathNode
                • AddImport
                • AddExport
                • Init
                • SelectedNodesUpdated
                • Copy
                • CreateNodeInLayerNoTransaction
                  • node_type: String
                  • layer: LayerNodeIdentifier
                • CreateNodeInLayerWithTransaction
                  • node_type: String
                  • layer: LayerNodeIdentifier
                • CreateNodeFromContextMenu
                  • node_id: Option<NodeId>
                  • node_type: String
                  • 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
                • InsertNode
                  • node_id: NodeId
                  • node_template: 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
                • 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
                • SetGridAlignedEdges
                • 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
                • network: Vec<NodeId>
                • node_graph_errors: GraphErrors
                • 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_type: FrontendGraphDataType
                • wire_in_progress_to_connector: Option<DVec2>
                • 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
                • 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
            • Overlays
            • PropertiesPanel
            • DataPanel
              • DataPanelMessagedata_panel_message.rs
                • UpdateLayout
                  • inspect_result: InspectResult
                • ClearLayout
                • PushToElementPath
                  • index: usize
                • TruncateElementPath
                  • len: usize
                • ViewVectorTableTab
                  • tab: VectorTableTab
              • DataPanelMessageHandlerdata_panel_message_handler.rs
                • 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
                • 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>
            • 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
            • SetViewMode
              • view_mode: ViewMode
            • AddTransaction
            • StartTransaction
            • EndTransaction
            • CommitTransaction
            • 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<ClickTarget>>
            • UpdateClipTargets
              • clip_targets: HashSet<NodeId>
            • Undo
            • UngroupSelectedLayers
            • UngroupLayer
              • layer: LayerNodeIdentifier
            • PTZUpdate
            • SelectionStepBack
            • SelectionStepForward
            • WrapContentInArtboard
              • place_artboard_at_origin: bool
            • ZoomCanvasTo100Percent
            • ZoomCanvasTo200Percent
            • ZoomCanvasToFitAll
          • DocumentMessageHandlerdocument_message_handler.rs
            • 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
            • document_mode: DocumentMode
            • view_mode: ViewMode
            • 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
            • document_id: DocumentId
            • ipp: &'a InputPreprocessorMessageHandler
            • persistent_data: &'a PersistentData
            • executor: &'a mut NodeGraphExecutor
            • current_tool: &'a ToolType
            • preferences: &'a PreferencesMessageHandler
            • device_pixel_ratio: f64
            • data_panel_open: bool
            • layers_panel_open: bool
            • properties_panel_open: bool
        • 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
        • FontLoaded
          • font_family: String
          • font_style: String
          • preview_url: String
          • data: Vec<u8>
        • Import
        • LoadDocumentResources
          • document_id: DocumentId
        • LoadFont
          • font: Font
        • NewDocumentWithName
          • name: String
        • NextDocument
        • OpenDocument
        • 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
        • ToggleResetNodesToDefinitionsOnOpen
        • PasteIntoFolder
          • clipboard: Clipboard
          • parent: LayerNodeIdentifier
          • insert_index: usize
        • PasteSerializedData
          • data: String
        • PasteSerializedVector
          • data: String
        • CenterPastedLayers
          • layers: Vec<LayerNodeIdentifier>
        • 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)>
        • PrevDocument
        • SetActivePanel
          • panel: PanelType
        • SetDevicePixelRatio
          • ratio: f64
        • SelectDocument
          • document_id: DocumentId
        • SubmitDocumentExport
          • name: String
          • file_type: FileType
          • scale_factor: f64
          • bounds: ExportBounds
          • transparent_background: bool
        • SubmitActiveGraphRender
        • SubmitGraphRender
          • document_id: DocumentId
          • ignore_hash: bool
        • ToggleDataPanelOpen
        • TogglePropertiesPanelOpen
        • ToggleLayersPanelOpen
        • ToggleRulers
        • UpdateDocumentWidgets
        • UpdateOpenDocumentsList
        • UpdateVelloPreference
      • PortfolioMessageHandlerportfolio_message_handler.rs
        • menu_bar_message_handler: MenuBarMessageHandler
        • 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
        • device_pixel_ratio: Option<f64>
        • reset_node_definitions_on_open: bool
        • data_panel_open: bool
        • layers_panel_open: bool
        • properties_panel_open: bool
      • PortfolioMessageContextportfolio_message_handler.rs
        • ipp: &'a InputPreprocessorMessageHandler
        • preferences: &'a PreferencesMessageHandler
        • animation: &'a AnimationMessageHandler
        • current_tool: &'a ToolType
        • message_logging_verbosity: MessageLoggingVerbosity
        • reset_node_definitions_on_open: bool
        • timing_information: TimingInformation
    • Preferences
      • PreferencesMessagepreferences_message.rs
        • Load
          • preferences: String
        • ResetToDefaults
        • UseVello
          • use_vello: bool
        • SelectionMode
          • selection_mode: SelectionMode
        • VectorMeshes
          • enabled: bool
        • ModifyLayout
          • zoom_with_scroll: bool
        • GraphWireStyle
          • style: GraphWireStyle
        • ViewportZoomWheelRate
          • rate: f64
      • PreferencesMessageHandlerpreferences_message_handler.rs
        • selection_mode: SelectionMode
        • zoom_with_scroll: bool
        • use_vello: bool
        • vector_meshes: bool
        • graph_wire_style: GraphWireStyle
        • viewport_zoom_wheel_rate: f64
    • Tool
      • ToolMessagetool_message.rs
        • TransformLayer
          • TransformLayerMessagetransform_layer_message.rs
            • 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
            • transform_operation: TransformOperation
            • slow: bool
            • increments: bool
            • local: 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_pivot: DocumentPosition
            • local_mouse_start: DocumentPosition
            • grab_target: DocumentPosition
            • ptz: PTZ
            • initial_transform: DAffine2
            • operation_count: usize
            • handle: DVec2
            • last_point: DVec2
            • grs_pen_handle: bool
            • ghost_outline: Vec<(Vec<ClickTargetType>, DAffine2)>
            • was_grabbing: bool
          • TransformLayerMessageContexttransform_layer_message_handler.rs
            • document: &'a DocumentMessageHandler
            • input: &'a InputPreprocessorMessageHandler
            • tool_data: &'a ToolData
            • shape_editor: &'a mut ShapeState
        • Select
          • SelectToolMessageselect_tool.rs
            • 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(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: SelectToolFsmState
            • tool_data: SelectToolData
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Artboard
          • ArtboardToolMessageartboard_tool.rs
            • 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(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: ArtboardToolFsmState
            • data: ArtboardToolData
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Navigate
          • NavigateToolMessagenavigate_tool.rs
            • Abort
            • PointerUp
              • zoom_in: bool
            • PointerMove
              • snap: Key
            • TiltCanvasBegin
            • ZoomCanvasBegin
            • End
          • NavigateToolnavigate_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: NavigateToolFsmState
            • tool_data: NavigateToolData
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Eyedropper
          • EyedropperToolMessageeyedropper_tool.rs
            • Abort
            • SamplePrimaryColorBegin
            • SamplePrimaryColorEnd
            • PointerMove
            • SampleSecondaryColorBegin
            • SampleSecondaryColorEnd
          • EyedropperTooleyedropper_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: EyedropperToolFsmState
            • data: EyedropperToolData
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Fill
          • FillToolMessagefill_tool.rs
            • Abort
            • WorkingColorChanged
            • Overlays
              • context: OverlayContext
            • PointerMove
            • PointerUp
            • FillPrimaryColor
            • FillSecondaryColor
          • FillToolfill_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: FillToolFsmState
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Gradient
          • GradientToolMessagegradient_tool.rs
            • Abort
            • Overlays
              • context: OverlayContext
            • DeleteStop
            • InsertStop
            • PointerDown
            • PointerMove
              • constrain_axis: Key
            • PointerOutsideViewport
              • constrain_axis: Key
            • PointerUp
            • UpdateOptions
              • options: GradientOptionsUpdate
          • GradientToolgradient_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: GradientToolFsmState
            • data: GradientToolData
            • options: GradientOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Path
          • PathToolMessagepath_tool.rs
            • Abort
            • SelectionChanged
            • Overlays
              • context: OverlayContext
            • BreakPath
            • DeselectAllPoints
            • Delete
            • DeleteAndBreakPath
            • DragStop
              • extend_selection: Key
              • shrink_selection: Key
            • Enter
              • extend_selection: Key
              • shrink_selection: Key
            • Escape
            • ClosePath
            • 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
            • SelectAllAnchors
            • 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(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: PathToolFsmState
            • tool_data: PathToolData
            • options: PathToolOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Pen
          • PenToolMessagepen_tool.rs
            • 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(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: PenToolFsmState
            • tool_data: PenToolData
            • options: PenOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Freehand
          • FreehandToolMessagefreehand_tool.rs
            • Overlays
              • context: OverlayContext
            • Abort
            • WorkingColorChanged
            • DragStart
              • append_to_selected: Key
            • DragStop
            • PointerMove
            • UpdateOptions
              • options: FreehandOptionsUpdate
          • FreehandToolfreehand_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: FreehandToolFsmState
            • data: FreehandToolData
            • options: FreehandOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Spline
          • SplineToolMessagespline_tool.rs
            • Overlays
              • context: OverlayContext
            • CanvasTransformed
            • Abort
            • WorkingColorChanged
            • Confirm
            • DragStart
              • append_to_selected: Key
            • DragStop
            • MergeEndpoints
            • PointerMove
            • PointerOutsideViewport
            • Undo
            • UpdateOptions
              • options: SplineOptionsUpdate
          • SplineToolspline_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: SplineToolFsmState
            • tool_data: SplineToolData
            • options: SplineOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Shape
          • ShapeToolMessageshape_tool.rs
            • Overlays
              • context: OverlayContext
            • Abort
            • WorkingColorChanged
            • DragStart
            • DragStop
            • HideShapeTypeWidget
              • hide: bool
            • PointerMove
              • modifier: ShapeToolModifierKey
            • PointerOutsideViewport
              • modifier: ShapeToolModifierKey
            • UpdateOptions
              • options: ShapeOptionsUpdate
            • SetShape
              • shape: ShapeType
            • IncreaseSides
            • DecreaseSides
            • NudgeSelectedLayers
              • delta_x: f64
              • delta_y: f64
              • resize: Key
              • resize_opposite_corner: Key
          • ShapeToolshape_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: ShapeToolFsmState
            • tool_data: ShapeToolData
            • options: ShapeToolOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Text
          • TextToolMessagetext_tool.rs
            • 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
          • TextTooltext_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: TextToolFsmState
            • tool_data: TextToolData
            • options: TextOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • Brush
          • BrushToolMessagebrush_tool.rs
            • Abort
            • WorkingColorChanged
            • DragStart
            • DragStop
            • PointerMove
            • UpdateOptions
              • options: BrushToolMessageOptionsUpdate
          • BrushToolbrush_tool.rs(violates naming convention — should end with 'Message', 'MessageHandler', or 'MessageContext')
            • fsm_state: BrushToolFsmState
            • data: BrushToolData
            • options: BrushOptions
          • &mut ToolActionMessageContext<'a>utility_types.rs
            • document: &'a mut DocumentMessageHandler
            • document_id: DocumentId
            • global_tool_data: &'a DocumentToolData
            • input: &'a InputPreprocessorMessageHandler
            • font_cache: &'a FontCache
            • shape_editor: &'a mut ShapeState
            • node_graph: &'a NodeGraphExecutor
            • preferences: &'a PreferencesMessageHandler
        • 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
        • ResetColors
        • SelectWorkingColor
          • color: Color
          • primary: bool
        • SelectRandomWorkingColor
          • primary: bool
        • ToggleSelectVsPath
        • SwapColors
        • Undo
        • UpdateCursor
        • UpdateHints
        • UpdateSelectionMode
          • selection_mode: SelectionMode
      • ToolMessageHandlertool_message_handler.rs
        • tool_state: ToolFsmState
        • transform_layer_handler: TransformLayerMessageHandler
        • shape_editor: ShapeState
        • tool_is_active: bool
      • ToolMessageContexttool_message_handler.rs
        • document_id: DocumentId
        • document: &'a mut DocumentMessageHandler
        • input: &'a InputPreprocessorMessageHandler
        • persistent_data: &'a PersistentData
        • node_graph: &'a NodeGraphExecutor
        • preferences: &'a PreferencesMessageHandler
    • 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 DocumentMessage definitions:

pub enum DocumentMessage {
	...
	// A message that carries one named 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 the #[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.