Input handling is split between InteractionHelper (the state machine that interprets pointer events) and SelectionManager (the selection model). The manager wires them together and turns their results into undoable DrawingActions.

Input Flow

  1. The host receives a native pointer event and converts the coordinates into world space (subtract PanOffset, divide by Zoom).
  2. It forwards the event to the manager: HandleMouseDown(point, modifiers, button), HandleMouseMove(point, modifiers), HandleMouseUp(...) and HandleMouseWheel(point, delta).
  3. InteractionHelper hit-tests ports, resize handles, components and lines in that priority order and enters a drag state.
  4. On completion it either mutates the model directly (with a matching DrawingAction pushed onto HistoryManager) or raises an event for the host (for example ComponentDropped).
// What the host does on a mouse-down (world coordinates)
float zoom = drawingManager.Zoom == 0 ? 1f : drawingManager.Zoom;
var world = new SKPoint(
    (screen.X - drawingManager.PanOffset.X) / zoom,
    (screen.Y - drawingManager.PanOffset.Y) / zoom);

drawingManager.HandleMouseDown(world, SKKeyModifiers.None, mouseButton: 0);

Drag States

InteractionHelper exposes its live state so hosts can render cursors, ghosts and previews:

MemberTypeMeaning
IsDraggingboolA component drag is in progress.
DraggingComponentSkiaComponentThe component being dragged.
IsDraggingLineboolA line is being re-routed or re-attached.
DraggingLineIConnectionLineThe line being dragged.
IsDrawingLineboolA new connection is being drawn from a port.
IsSelecting / SelectionRectbool / SKRectMarquee selection in progress and its world-space rectangle.

When a component drag ends, the helper builds a ComponentDropEventArgs (component, canvas and screen position, final bounds) and the manager raises ComponentDropped.

Selection Model

SelectionManager owns three independent selections — components, lines and connection points — and is reachable as drawingManager.SelectionManager:

MemberDescription
SelectComponent(component, addToSelection)Replaces or extends the component selection.
AddToSelection(component) / RemoveFromSelection(...)Incremental changes for all three selection kinds.
SelectComponentsInRect(rect, components, addToSelection)Marquee selection; the helper calls this on mouse-up.
SelectLine(line, ...) / SelectConnectionPoint(point, ...)Line and port selection.
SelectedComponents / SelectedLines / SelectedConnectionPointsRead-only views of the current selection.
IsSelected(...), SelectionCount, SelectAll(), SelectNext(forward), ClearSelection()Query and navigation helpers.
SelectionChangedEvent raised on any change; the manager re-raises it for hosts.

Selection is a model concern, not a rendering concern: components expose IsSelected for drawing, but the truth lives in the manager.

Keyboard and Clipboard

The host forwards key events; the manager implements the standard editor set and exposes clipboard operations that use the same DTO serializer as files:

ActionManager API
Select allSelectAllComponents()
CopyCopySelectedComponents() (serializes to a clipboard DTO string)
PastePasteComponents(position) (deserializes, offsets, pushes PasteComponentsAction)
DeleteDeleteSelectedComponents() (components plus attached lines as one action)
Undo / RedoUndo() / Redo(), with CanUndo/CanRedo for menu state
Move selectionMoveSelectedComponents(offset)
ArrangeBringToFront() / SendToBack() and the align helpers

Escape cancels an in-progress drag or connection draw; the preview line is discarded and no action is recorded.

Undo Integration

Every mutation that goes through the manager pushes a DrawingAction onto HistoryManager. Drags are recorded once, on mouse-up, with the original positions captured at mouse-down — so a 200-pixel drag is a single undo step, not 200.

// The manager records actions itself; hosts only push custom ones
drawingManager.MoveSelectedComponents(new SKPoint(20, 0));   // recorded

// Custom operations use the same history
drawingManager.HistoryManager.ExecuteAction(new AlignComponentsAction(...));

HistoryChanged fires on every push, undo and redo, which is what menu commands bind to. The full action catalog is listed on the Undo/Redo System page; the events raised by input are cataloged on the Event Catalog page.