Nodify.Avalonia

repository·avalonia_port·Indexed 43 days ago

https://github.com/bandysc/nodify-avalonia

A node-based editor framework for Avalonia that provides infrastructure for creating visual node graphs, including support for nodes, connections, zooming, panning, and minimaps.

Tokens
29K
Snippets
92
Records
151
Agent score
54%

What's inside Nodify.Avalonia

  1. What is Nodify?

    avalonia_port

    Nodify is a WPF node-based editor control designed to simplify building node-based tools. It provides a collection of components for managing nodes, connections, and connectors.

    Key features include:

    • An infinite canvas for placing and moving nodes.
    • Support for selecting and dragging groups of nodes.
    • Connecting and disconnecting nodes or connectors.
    • Zooming and panning capabilities.
    • Automatic screen movement when dragging elements near edges.
    • High performance optimized for hundreds of nodes.
    • Built from the ground up to work with the MVVM pattern.
  2. How the EditorState system works

    avalonia_port

    Nodify uses a state machine pattern to manage editor behavior. The EditorState is an abstract base class that defines how the editor responds to user input (mouse, keyboard, wheel) depending on the current context (e.g., panning, selecting, or cutting).

    States are managed via a stack on the NodifyEditor. When a new state is pushed, Enter(EditorState from) is called; when the current state is popped, Exit() is called and the previous state's ReEnter(EditorState from) is invoked. This allows for complex, layered interactions where a user can transition from a default state into a specialized interaction mode and back again.

  3. Configure Zooming in NodifyEditor

    avalonia_port

    Zooming is performed via the mouse wheel or keyboard shortcuts (CTRL + to zoom in, CTRL - to zoom out).

    Key Properties:

    • DisableZooming: Set to true to disable zooming.
    • ViewportZoom: Programmatically set the zoom level. Must be between MinViewportZoom and MaxViewportZoom.
    • MinViewportZoom: The minimum allowed zoom level (default: 0.1).
    • MaxViewportZoom: The maximum allowed zoom level (default: 2).
    • ViewportSize, ViewportTransform: Updated during zooming operations.
  4. Use the CuttingLine control to remove intersecting connections

    avalonia_port

    The CuttingLine control allows users to perform a 'cutting' gesture to remove multiple intersecting connections at once.

    Default Gestures

    • Start Cutting: SHIFT+ALT+LeftClick (configurable via EditorGestures.Editor.Cutting).
    • Cancel Cutting: Escape key or Right Mouse Button (configurable via EditorGestures.Editor.CancelAction).

    Available Commands

    You can intercept or react to the cutting lifecycle using these commands in NodifyEditor:

    • CuttingStartedCommand
    • CuttingCompletedCommand
    • RemoveConnectionCommand: Triggered for every connection that intersects the cutting line when the operation completes.
  5. Understand the Nodify content layers

    avalonia_port

    The NodifyEditor uses three distinct layers to manage the rendering and interaction of graph elements. This separation allows for asynchronous loading and complex control behaviors:

    1. Items Layer (NodifyEditor.ItemsSource): Contains the actual content. Each item is wrapped in an ItemContainer to provide selection and dragging capabilities. This layer can render any control, including connectors or text blocks.
    2. Connections Layer (NodifyEditor.Connections): Renders all active connections. By default, this layer is rendered behind the items layer.
    3. Decorators Layer (NodifyEditor.Decorators): Manages the positioning of controls, assigning each control a specific location within the graph.
  6. How pending connections work

    avalonia_port

    A pending connection is created when a user drags a connection from a connector. It can be dropped onto an ItemContainer (if AllowOnlyConnectors is false) or another Connector.

    Key Behaviors:

    • Completion: The Target property is updated when the connection is completed. The CompletedCommand is fired, passing the Target as a parameter.
    • Cancellation: Releasing the right mouse button cancels the pending connection.
    • Previewing: If EnablePreview is true, the PreviewTarget updates to show the element currently under the mouse cursor (or null).
    • Snapping: Connection snapping to connectors can be toggled via the EnableSnapping property.
    • Customization: The visual content of a pending connection can be customized using the ContentTemplate property.
    • Commands:
      • StartedCommand: Fired when the drag begins, passing the Source as a parameter.
      • CompletedCommand: Fired when the connection is successfully made, passing the Target as a parameter.
  7. Understand the EditorState lifecycle and transitions

    avalonia_port

    Nodify uses a state machine pattern via EditorState to handle user interactions. Different states (like EditorDefaultState, EditorPanningState, or EditorCuttingState) manage specific input behaviors (mouse and keyboard).

    // The editor transitions between states based on input. 
    // For example, in EditorDefaultState:
    // - mouse left down  -> Selecting State
    // - mouse right down  -> Panning State
    // 
    // In Selecting State:
    // - mouse left up    -> Default State
    // - mouse right down  -> Panning State
    //
    // In Panning State:
    // - mouse right up   -> previous state (Selecting State or Default State)
    // - mouse left up    -> Panning State
  8. Understand the Nodify hierarchy and terminology

    avalonia_port

    To work effectively with Nodify, you must understand the relationship between its core components:

    • Editor: The root component that manages the visual tree, including nodes, connections, selection rectangles, and pending connections.
    • Nodes: Containers within the editor that hold content. A node can contain Connectors, or the node itself can act as a connector (e.g., a StateNode).
    • Connectors: Elements within nodes that facilitate creating connections. A connector can initiate a Pending Connection, which becomes a real Connection once the interaction is completed.
  9. Extend or use ContainerState for custom container behavior

    avalonia_port

    The ContainerState class is the base class for managing states within an ItemContainer. It allows you to implement custom logic for how a container responds to user input (keyboard, mouse, wheel) and how it transitions between different states.

    When implementing a custom ContainerState, you can override lifecycle methods like Enter (called when pushing a new state), Exit (called when popping a state), and ReEnter (called when returning to a state via PopState). You can also override input handlers such as HandleKeyDown, HandleMouseDown, and HandleMouseMove to provide specialized interaction models for specific container modes.

    // Example of how a state might be pushed onto a container
    // (Conceptual usage based on ContainerState methods)
    public void ChangeMode(ItemContainer container, ContainerState newState)
    {
        container.PushState(newState);
    }
  10. Use the Pushing Items feature

    avalonia_port

    Pushing items allows users to move items via a drag gesture.

    Interaction:

    • Initiate: Hold CTRL+SHIFT and click with the Left Mouse Button.
    • Cancel: Press Escape or hold CTRL+SHIFT and click the Right Mouse Button.

    Key Properties:

    • IsPushingItems: Becomes true during the operation.
    • PushOrientation: Initialized with the direction of the drag.
    • PushedArea: Updates in real-time to reflect the interaction state.
    • PushedAreaStyle: Used to customize the visual appearance of the push area.
    • AllowPushItemsCancellation: Set to false to prevent users from canceling the operation.
  11. Configure Snapping to Grid

    avalonia_port

    When moving selected items, they can snap to a grid based on the GridCellSize property. Snapping is relative to the position of the selected item, not the virtual grid.

    Key Properties:

    • GridCellSize: The size of the grid cells (default: 1).
    • EnableSnappingCorrection: If true, the final position of items is corrected after a move if they were not initially snapped or if GridCellSize changed at runtime.