Table of Contents

List Command Panel

A ListCommand is the container command: an optional title plus a list of enable-wrapped commands. Running one walks CommandEntryList top-down and skips a disabled entry together with everything nested under it — the wrapper yields nothing while its flag is clear. The mission's own command is always a list, so the Mission branch root is a list, and every nested one is the same shape one level down.

List is an ordinary catalog kind — category Flow — so a list is added the way any command is, and adding one grows a sub-tree: the node's children are its own entries, and its panel embeds the same entry-list editor the branch root uses, scoped to the nested list.

This page covers what a list is, how its title reads, and what moving commands in and out of one costs. The entry-list editor itself — Add Command, the row actions, the three drag landings — is documented once, on Mission Root Panel.

Key Models

The Panel of a List Entry

Selecting a list command in the Control Tree opens, top to bottom:

  • List Entry Panel
    • Control Bar
      • Up / Down / Duplicate / Delete — labelled buttons for the operations that rewrite the parent list. Delete asks for confirmation in a dialog naming the command.
      • At the bar's left, a caption while the command is disabled: skipped during play, still editable.
    • Title (optional) Input
    • Embedded Entry-List Editor
      • This list's own entries, scoped to the node's path.

The Title input holds the raw title — empty when unset — while the label the row and the tree show is composed by the engine: List when the title is blank, List [title] when it is not. A titled list still says what it is. A whitespace-only title counts as unset and is never written into the project file, so it cannot come back as a changed title on the next load.

Keystrokes debounce into one title save. The pending save is flushed before anything that shifts the entry paths — a structural operation, a duplicate, a selection change — and cancelled on delete and on unmount, so a late write cannot land on whichever command slid into the old path. Once it is saved the tree label refreshes in place rather than by rebuilding the branch, which would remount the open editor mid-edit.

The root list is the one list without a title input: the branch root reads Mission.

Enabling, and What a Disabled List Skips

The enable switch is the checkbox on the command's own Control Tree item, not a control in the entry row. It decides only whether the command runs: while it is clear the row and the tree node dim, and the editor stays open and fully editable. Unticking a list dims its whole sub-tree — the dim rides ancestor propagation in the tree while each nested entry keeps its own flag, which is exactly what the run does: a disabled entry is skipped with everything under it.

Paths

A command node's key is its Mission API path — "0", "1", nested "0.2" for entry 2 inside the list at index 0. Every structural change re-mints them: deleting entry 2 slides the next command into path "2". Each branch build therefore stamps its nodes, so the editor panel remounts onto the new path instead of going on showing the command that used to live there.

Moving Commands In and Out

  • Into a list — drag a row onto the middle band of a list row; that row's outer quarters still reorder around it.
  • Out of a list — drag onto the drop-out zone of a nested list's editor, which is visible only while a row inside that editor is being dragged. The entry lands right after the list command itself in the owning list.

Both are the same reparent call. The server resolves the source list and the target list to object references before it mutates either, so the index shift the removal causes cannot misroute the insert, and it refuses to move a list into itself or into one of its own descendants. That guard compares identity rather than path-string prefixes, because "02", "+2" and " 2" all parse to index 2.

Two more properties of a list follow from the same API:

  • A new command lands at the end of the list it was added to, root or nested. Nothing is pinned; the order is entirely the user's, changed with the row's up / down buttons or by dragging.
  • Duplicate is a deep copy. The entry is cloned through the same XML round-trip the project file uses, so a nested list copies with its whole sub-tree, and the clone lands right after the source.

Dragging serves rearrangement only: a drag carrying text or files is ignored, because the row's drag handling returns as soon as the drag did not start on a row. To bring several program files in at once, open a Program File command's picker and pick them together — the first pick lands on that command and each further pick becomes another Program File command right after it, in pick order, inside the same list at any depth.

Which Commands a List Can Hold

The addable set is the server's command catalog: every engine command carrying [CommandCatalog], reflected into the picker Add Command opens, which searches by display label, kind key and alias. List is one of those commands, which is what makes nesting an ordinary act rather than a special case. The frontend contributes an icon per kind, and its own label where it has one; the server supplies the localized label otherwise, so a newly attributed engine command becomes addable with no frontend change.

A command without that attribute stays loadable from a project file but is never offered for creation. General Config is the one such command with an editor of its own: it is the legacy settings bundle, so a project file storing one loads as the individual setting commands it stands for and saving never writes the bundle back — editable when a project still constructs one through the API, and absent from the catalog.

Selecting an entry row selects that command's tree node, and the command's editor opens on that node — the kind's own panel when one exists, otherwise a generic editor built from the scalar fields the command declares. Selection is one row at a time: there is no multi-selection here, and every action acts on the row that carries it. Because the server composes every entry label, a command carrying no title of its own still reads as its localized display name.

There is no second column inside this editor: the entry list is a single column in the tree's editor pane. The draggable vertical divider on screen belongs to the Execution page, between the left dock — the Control Tree over the editor panel — and the central area; a second divider inside that dock drags the height between the tree and the editor.

Source Code Path

See HiNC App Anatomy for git repository links.

Web Application

  • wwwroot-src/src/components/controlTree/MissionCommandSlavePanel.vue — a list entry's panel: the control bar, the optional Title input with its debounce / flush / cancel discipline, the embedded entry-list editor of a list entry, and the bespoke-or-generic editor choice for every other kind.
  • wwwroot-src/src/components/controlTree/MissionRootPanel.vue — the entry-list editor embedded here and serving the branch root: the rows and their actions, the three drag landings, and the drop-out zone shown only during a drag inside a nested editor.
  • wwwroot-src/src/components/controlTree/missionItemTypes.ts — the child builders that recurse into a list's own entries, the per-kind editor override map, the kind and category icons, and the per-build stamp that forces the panel remount.
  • wwwroot-src/src/components/controlTree/useControlTreeHost.ts — which nodes show a checkbox, the dim that flows down a disabled command's sub-tree, the enable write, and the in-place label refresh after a title edit or a language switch.
  • wwwroot-src/src/api/mission.ts — the typed wrapper over the Mission API and the path convention (root or empty = the root list, 0.2 = a nested entry).
  • wwwroot-src/src/components/mission/GenericCommandPanel.vue — the editor a catalog kind gets when it ships no bespoke panel, built from the command's declared scalar fields.
  • wwwroot-src/src/components/mission/NcFileCommandPanel.vue — the multi-pick file dialog: the first pick lands on the command, each further pick becomes another Program File command right after it.
  • wwwroot-src/src/pages/ExecutionPage.vue — the page-level splitter between the left dock and the central area.
  • wwwroot-src/src/i18n/en/tree.ts — the tree.mission.* strings: the kind names, the drop-out zone, the run-order hint, the disabled hint and the operation labels.
  • Missions/MissionController.cs — the entry lifecycle: GET list-command/entries (recursive), POST list-command/entries and POST list-command/entries/{path} (append at the tail of the root or of a nested list), DELETE list-command/entries/{path}, POST list-command/entries/{path}/move, PUT list-command/reorder, POST list-command/entries/{path}/duplicate (the XML-round-trip deep clone), POST list-command/entries/{path}/reparent (drag-into-list and drop-out, with the self/descendant guard), PUT commands/{path}/listcommand for the title, and PUT commands/{path}/enabled for an entry's enable flag. GetCommandTitle composes every entry label the tree shows.
  • Missions/MissionCommandCatalog.cs — reflects the [CommandCatalog] commands into the addable set and constructs the picked kind.

HiAPI Engine

  • HiNc/SessionCommands/ListCommand.cs — the container: the optional title, the entry list a run walks top-down, the whitespace-only-title-is-unset XML rule, the Flow catalog attribute, and the List / List [title] composition.
  • HiNc/SessionCommands/EnablingWrapper.cs — the enable flag plus the wrapped command that together make one entry.
  • HiNc/SessionCommands/ITitleCommand.cs — the interface a command implements to compose its own title from the caller's vocabulary.
  • HiNc/SessionCommands/CommandCatalogAttribute.csCommandCategory and the attribute (category, order, kind key, aliases) that makes the addable set backend-owned.
  • HiNc/SessionCommands/PreSettingCommand.cs — the General Config bundle: no catalog attribute, and a loaded project expands a stored one into the split setting commands.
  • HiNc/MachiningProcs/MachiningProject.cs — declares the mission's command and keeps it a list.

See Also

  • Mission Root Panel — the entry-list editor this command embeds, documented once
  • Building a Mission — the task this command serves: grouping a mission and moving entries between groups
  • Mission — the rest of the command panels