Package sc.fiji.snt

Class PathNodeEditor

java.lang.Object
sc.fiji.snt.PathNodeEditor

public final class PathNodeEditor extends Object
Viewer-agnostic node-editing operations on a single Path: the logic behind the 'Edit Mode' commands of InteractiveTracerCanvas (delete, insert, move, lock, radius, tag, re-root, split, undo), but free of any canvas/ImagePlus dependency so that it can be driven by other front-ends (e.g., Bdv/Bvv).

This class lives in sc.fiji.snt because several of the Path/PathAndFillManager members it relies on are package-scoped. It is a front-end helper: it holds no GUI state beyond the (optional) dialogs it is explicitly handed. All coordinates are calibrated (world) coordinates, i.e., the same space as Path.getNode(int).

Every operation returns a PathNodeEditor.Result: callers are expected to display PathNodeEditor.Result.message() (if any) and, when PathNodeEditor.Result.pathsChanged() is true, re-sync any rendering of the Path Manager.

Author:
Tiago Ferreira
  • Constructor Details

    • PathNodeEditor

      public PathNodeEditor(SNT snt)
  • Method Details

    • getPath

      public Path getPath()
      Returns:
      the path being edited (see SNT.getEditingPath()), or null
    • setActiveNode

      public void setActiveNode(int index)
      Tags a node of the editing path as 'active', i.e., the target of subsequent operations. Does nothing if the active node is locked.
      Parameters:
      index - the node index or -1 for none
    • getActiveNode

      public int getActiveNode()
      Returns:
      the index of the active node, or -1
    • isActiveNodeLocked

      public boolean isActiveNodeLocked()
      Returns:
      whether the active node is locked
    • canUndo

      public boolean canUndo()
      Returns:
      whether there are edits that can be undone
    • isFitted

      public boolean isFitted()
      Returns:
      whether the editing path is in fitted-display mode (structural edits are unsupported)
    • pushUndo

      public void pushUndo()
      Records the current state of the editing path so that the next edit can be undone. Operations of this class do it themselves. It is only needed by front-ends modifying the path directly, e.g., once for a whole gesture (a drag) made of many small changes
    • undo

      public PathNodeEditor.Result undo()
      Undoes the last node edit
    • toggleLock

      public PathNodeEditor.Result toggleLock()
      Toggles the locked state of the active node. A locked node remains active regardless of the cursor
    • deleteNode

      public PathNodeEditor.Result deleteNode()
      Deletes the active node. Single-node/two-node paths cannot be shortened: use deleteWholePath() if isTooShortToDeleteNode() is true (after confirming with the user)
    • deleteNodeOrPath

      public PathNodeEditor.Result deleteNodeOrPath(GuiUtils gui)
      Deletes the active node or, if the editing path is too short to lose nodes (see isTooShortToDeleteNode()), the entire path after asking for confirmation
      Parameters:
      gui - the GuiUtils instance used to display the confirmation prompt
    • isTooShortToDeleteNode

      public boolean isTooShortToDeleteNode()
      Returns:
      true if the editing path cannot lose further nodes (see deleteNode())
    • deleteWholePath

      public PathNodeEditor.Result deleteWholePath()
      Deletes the entire editing path from the Path Manager. Callers should confirm with the user first
    • insertNode

      public PathNodeEditor.Result insertNode(double x, double y, double z)
      Inserts a node at the specified position, immediately before the active node. The active node remains active.
    • moveNode

      public PathNodeEditor.Result moveNode(double x, double y, double z)
      Moves the active node to the specified position
    • moveNode

      public PathNodeEditor.Result moveNode(double x, double y, double z, boolean recordUndo)
      Moves the active node to the specified position
      Parameters:
      recordUndo - if false, the move is not recorded in the undo history (see pushUndo())
    • tagNode

      public PathNodeEditor.Result tagNode(Color color)
      Assigns (or removes, if null) a color tag to the active node
    • tagNode

      public PathNodeEditor.Result tagNode(Path target, int index, Color color)
      As tagNode(Color), for a node that was the active one when a color chooser was opened: the active node follows the cursor while a chooser is open, so it is restored first
      Parameters:
      target - the editing path the chooser was opened for. Nothing is done if it is no longer the editing path
      index - the index of the node the chooser was opened for
      color - the color, or null to remove the tag
    • promptAndSetRadius

      public PathNodeEditor.Result promptAndSetRadius(GuiUtils gui)
      Prompts for, and assigns, a radius to the active node (mirrors the dialog of the classic canvas)
      Parameters:
      gui - the GuiUtils instance used to display dialogs
    • setActiveNodeAsRoot

      public PathNodeEditor.Result setActiveNodeAsRoot(GuiUtils gui)
      Makes the active node the root of its tree. Asks for confirmation (the operation cannot be undone). On success the editing path is released: Callers must re-sync and leave edit mode.
    • splitTreeAtActiveNode

      public PathNodeEditor.Result splitTreeAtActiveNode(GuiUtils gui)
      Splits the tree at the active node. Asks for confirmation (the operation cannot be undone). On success the editing path is released: Callers must re-sync and leave edit mode.
    • getSecondaryPath

      public Path getSecondaryPath()
      Returns:
      the 'secondary' path, i.e., the path that was being edited before the current one, or null
    • hasSecondaryNode

      public boolean hasSecondaryNode()
      Returns:
      whether a secondary path with an active node exists, i.e., whether connectToSecondaryPath(GuiUtils, boolean) may be applicable
    • connectToSecondaryPath

      public PathNodeEditor.Result connectToSecondaryPath(GuiUtils gui, boolean showDialog)
      Connects the active node of the editing path to the active node of the secondary path (the one edited previously). By default the editing path becomes the child (branching from the secondary path), but a heuristic and the user may swap roles. Asks for confirmation (the operation cannot be undone). On success the editing path is released: Callers must re-sync and leave edit mode.
      Parameters:
      gui - used to display prompts and errors
      showDialog - whether the user should be prompted to confirm (and possibly swap) the parent and child
      Returns:
      the outcome. A failure with no message means the operation was canceled or reported to the user
    • connectToNode

      public PathNodeEditor.Result connectToNode(Path parent, int nodeIdx, GuiUtils gui)
      Connects the active node of the editing path to a node of another path (e.g., the node snapped to by a 'magnetic' cursor). The editing path is always the child, i.e., it branches from parent. Unlike connectToSecondaryPath(GuiUtils, boolean), no confirmation is asked. On success the editing path is released: Callers must re-sync and leave edit mode.
      Parameters:
      parent - the path to branch from
      nodeIdx - the index of the node of parent to branch from
      gui - used to display errors
      Returns:
      the outcome. A failure with no message means the operation was reported to the user
      See Also:
    • resolveNode

      public PathAndFillManager.NodeRef resolveNode(Path displayed, int index)
      Resolves a node of a displayed path to the node that connections must refer to. The paths displayed in the viewers are the versions in use: A path displayed as its fitted version is a copy that does not hold the topology, so it is resolved to its un-fitted original (see PathAndFillManager.getVersionInUse(Path))
      Parameters:
      displayed - the displayed path
      index - the index of a node of displayed
      Returns:
      the equivalent node of the path holding the topology. It is the same node if displayed is not a fitted copy
    • resolvePath

      public Path resolvePath(Path displayed)
      Parameters:
      displayed - the displayed path
      Returns:
      the path holding the topology: the un-fitted original if displayed is a fitted copy, otherwise displayed
    • canConnectTo

      public boolean canConnectTo(Path other)
      Parameters:
      other - the path to be tested
      Returns:
      whether the editing path could branch from other without creating a loop