This commit is contained in:
2026-09-09 18:06:21 +08:00
parent 161af68fe3
commit 45b9f9ed5d
79 changed files with 1167 additions and 1532 deletions
@@ -105,9 +105,8 @@
<p>In the web application the status text moved out of the tool bar and onto the Execution tree item, which carries the run-state badge. The two single-advance buttons there share one <code>skip_next</code> icon and are separated by a letter drawn into the button's corner — <code>L</code> for the line button, <code>S</code> for the step button — rather than by colour; the tool-tips carry the key names.</p>
<h2 id="behavior">Behavior</h2>
<ul>
<li>Both the webservice and the win-desktop application watch <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events to track <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> status changes.</li>
<li>The webservice watches <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events to track <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html#Hi_MachiningProcs_LocalProjectService_PacePlayer">PacePlayer</a> status changes.</li>
<li>In the webservice, <code>ExecutionStatusService</code> subscribes to those events and broadcasts status changes over SignalR through <code>ExecutionStatusHub</code>.</li>
<li>The win-desktop application subscribes to the same <a class="xref" href="../../api/Hi.MachiningProcs.LocalProjectService.html">LocalProjectService</a> events directly.</li>
<li>The frequently used buttons carry hotkeys: Start / Resume, Pause, Run One Line and Run One Step. The app's tool-tips are the only place those key bindings are written down.</li>
<li>The background color of the <code>Status Text Field</code> follows the status:
<ul>
@@ -154,7 +153,7 @@
<p>The F5–F8 handler applies the same predicates before acting, and declines in two more cases: when the event target is an <code>input</code>, a <code>textarea</code> or a contenteditable element, and when the hosting page is deactivated. The second matters because the shell keep-alives the routed pages, so leaving the Execution route deactivates rather than unmounts this component; without the detach, F5 elsewhere in the app would drive the transport instead of reloading the browser. Every declined key falls through to the browser.</p>
<div class="TIP">
<h5>Tip</h5>
<p>Use icons rather than text on the tool-bar buttons. Run One Line and Run One Step share an icon, so they need a second mark to tell them apart — the win-desktop application seasons the icon green and blue, the web application draws an <code>L</code> and an <code>S</code> in the button corner. Either works; the default colour is enough for the rest.</p>
<p>Use icons rather than text on the tool-bar buttons. Run One Line and Run One Step share an icon, so they need a second mark to tell them apart — this bar draws an <code>L</code> and an <code>S</code> in the button corner. The default colour is enough for the rest.</p>
</div>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../index.html">HiNC App Anatomy</a> for git repository links.</p>
@@ -89,7 +89,6 @@
<h2 id="shipped-surface">Shipped Surface</h2>
<p>The panel has no route and no Control-Tree node of its own. It is chrome on the Execution page (<code>/execution</code>): the canvas panel's expansion header carries the <code>Meshed Geom ▾</code> dropdown — titled <em>Workpiece rendering cache and geometry-diff settings</em> — whose <code>Graphic Cache</code> row opens this panel in a nested menu. It hangs there because it acts on the workpiece meshed geometry's rendering cache, and its sibling row in the same dropdown is <code>Diff Visual Radius</code>. It is therefore only reachable while the Execution page's canvas column is shown.</p>
<p>In the WPF application the same submenu lives on the <a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a>.</p>
<p>The panel is self-contained: it takes no parent-supplied model. It holds local lower / upper / current values, loads them on mount, and commits each edit to <code>GET</code>/<code>POST /api/preference/graphic-cache</code>. <code>UserService</code> / <code>UserConfig</code> is the server-side model behind that endpoint.</p>
<h2 id="layout">Layout</h2>
<p>Titled <strong>Graphic Cache (MB)</strong>, with the caption &ldquo;Memory budget for rendering cache. Lower &amp; upper bound the slider.&rdquo;</p>
@@ -125,7 +124,7 @@
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a> — the dropdown that hosts this entry in the WPF client</li>
<li><a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a> — the sibling entries of the same dropdown</li>
</ul>
</article>
@@ -205,36 +205,6 @@ carrying no title of its own still reads as its localized display name.</p>
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.</p>
<h2 id="the-wpf-clients-list-panel">The WPF Client's List Panel</h2>
<p>The WPF panel edits the <strong>root</strong> list only. It binds the project's player command as a list, its Add
menu offers no List item, and its content switch has no List arm, so a nested list entry selected
there renders the literal text &ldquo;No editor available for ListCommand&rdquo;. Nesting is a web surface.</p>
<ul>
<li>Two columns: a 400px entry column, a <code>GridSplitter</code>, and the selected command's content column,
both columns floored at 300px.</li>
<li>One toolbar over the list — Add, Remove, Move Up, Move Down — acting on the list selection. There
is no duplicate.</li>
<li>Add is a plain button that pops a fixed six-item context menu built in its click handler:
&ldquo;Pre-Setting Command&rdquo;, &ldquo;NC Opt Option Command&rdquo;, &ldquo;NC File Command&rdquo;, &ldquo;NC Code Command&rdquo;,
&ldquo;Script Command&rdquo; and &ldquo;Post Execution Command&rdquo;.</li>
<li>The list box is extended-select. Remove takes every selected entry, prompting with a count when
more than one is selected, and a drag can carry a whole selection; Move Up and Move Down stay
disabled unless exactly one entry is selected.</li>
<li>Each entry box carries a labelled Enable checkbox at its left, the command's title in bold, and a
pin icon with a &ldquo;Pin at beginning&rdquo; / &ldquo;Pin at end&rdquo; label — shown on the first entry when it is a
General Config command, and on the last when it is a Post-Execution command.</li>
<li>Insertion works around the ends: a new entry lands before a trailing Post-Execution when that is
the list's only one, and a General Config lands at the top unless the list already starts with
one. A drag that would move a pinned entry — or drop another entry onto it — is refused, the guard
testing that the entry is the only command of its kind and sits at that end. The Move Up / Move
Down buttons are not covered by that guard.</li>
<li>The content panel is greyed and made read-only while the selected entry's Enable box is clear.</li>
<li>Files dropped from the file explorer onto the entry list create one enabled NC File command per
file, taking a project-relative path when the file sits under the project directory.</li>
<li>The entry label falls back to the raw class name for a command that composes no title of its
own — <code>GeomDiffCommand</code>, <code>OptimizeToFilesCommand</code>, <code>WriteStepFilesCommand</code> and
<code>WriteShotFilesCommand</code>.</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
@@ -118,9 +118,8 @@ mission row.</li>
<li>NC Code Editor Area
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcCodeCommand.html#Hi_SessionCommands_NcCodeCommand_NcText">NcText</a>.</li>
<li>A plain monospace text area: on the web an 18-row field with a 360 px floor, on WPF a Consolas
text box in an NC Code group box that takes the panel's remaining height.</li>
<li>No line-number gutter and no syntax highlighting on either client. The rich editor in this
<li>A plain monospace text area: an 18-row field with a 360 px floor.</li>
<li>No line-number gutter and no syntax highlighting. The rich editor in this
folder is the <a class="xref" href="script-command-panel.html">Script command</a>'s — that command ships
CodeMirror with a C# grammar, this one ships a text area.</li>
</ul>
@@ -97,9 +97,8 @@ into the project itself.</p>
and an absolute path on the server is accepted just as well. No base directory is stored with the
command: at play time <a class="xref" href="../../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_RunNcFile_">RunNcFile</a> hands the stored path
together with the project's own base directory to the local project service, and that is where a
relative path acquires its root. The WPF panel's <code>BaseDirectory</code> is the code-behind assistant
property the <a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a> asks a file-assigning GUI to carry,
assigned to the panel by its parent — a panel member, not a model member.</p>
relative path acquires its root; the convention behind it is the
<a class="xref" href="../../conventions/gui-file-path-assignment.html">Load Pattern</a>.</p>
<p>The panel renders on the command's own node in the Mission branch of the Execution page's Control
Tree, below the move / duplicate / delete control bar. This command has no title of its own, so the
row and tree label read <code>Program File [path]</code>, the path being the detail the label brackets.</p>
@@ -124,8 +123,7 @@ as CSV, and every other extension as brand NC).</p>
the project folder.</li>
<li>Every keystroke saves the path. Leaving the field or pressing Enter additionally refreshes
the file-info banner.</li>
<li>The web field flexes to fill the row beside the Browse button at any panel width; the WPF
field is a fixed 200 px column carrying its own label.</li>
<li>The field flexes to fill the row beside the Browse button at any panel width.</li>
</ul>
</li>
<li>Browse Button
@@ -140,8 +138,6 @@ field is a fixed 200 px column carrying its own label.</li>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.NcFileCommand.html#Hi_SessionCommands_NcFileCommand_NcKind">NcKind</a>.</li>
<li>Four choices: Auto (by extension), Brand NC, CL (CLSF) and CSV. The hint restates what Auto
detects, so the runner can be pinned when the extension would route the file elsewhere.</li>
<li>This control is the web client's. The WPF panel ships no kind control, so a project edited
there keeps the kind it already holds — Auto until something else sets it.</li>
</ul>
</li>
<li>File Info Banner
@@ -180,9 +176,6 @@ browser to preserve. It is the backstop for a brand extension the NC group does
</ul>
<p>CL and CSV are split out because they are closed extension sets: those are exactly the extensions
Auto routes to the CL and CSV runners, and everything else falls through to brand NC.</p>
<p>The WPF Browse button opens an <code>OpenFileDialog</code> with the panel's file-filter resource, starting at
the project directory or at the current file's own directory. A pick under the project directory is
stored as a relative path, and a pick outside it as an absolute one.</p>
<h2 id="multi-pick-fan-out">Multi-Pick Fan-Out</h2>
<p>The dialog is multi-select, and this is the one command editor that grows the mission. The first
picked file lands on this command. Each further pick becomes a <strong>new</strong> Program File command, added
@@ -191,18 +184,9 @@ list, so a command inside a nested list fans out inside that nested list. The pa
structure change, which rebuilds the owning list's branch around the new rows and leaves the
selection on this command.</p>
<h2 id="where-the-program-text-is-edited">Where the Program Text Is Edited</h2>
<p>The two clients part company here, and the command is the same either way: it stores a path.</p>
<ul>
<li><strong>Web</strong> — the panel does not edit the file. It assigns the path, picks the runner, reports what
the server knows about the file, and previews its first 100 lines read-only. Nothing in the
browser writes NC bytes back; the two file endpoints this panel calls are both reads.</li>
<li><strong>WPF</strong> — the panel opens the file. A non-text file, or one the panel cannot find, disables the
editor and states why in the Head Message Place above it. A text file within 20000 lines opens for
editing, with its line count in the group-box header; a longer one shows its first 20000 lines
read-only and warns in the Head Message Place. Two seconds after the last keystroke the editor
writes the file back, and reports the save in that same message place. The editor is AvalonEdit
with line numbers where that assembly resolves, and a plain Consolas text box otherwise.</li>
</ul>
<p>The command stores a path, and the panel does not edit the file. It assigns the path, picks the
runner, reports what the server knows about the file, and previews its first 100 lines read-only.
Nothing in the browser writes NC bytes back; the two file endpoints this panel calls are both reads.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
@@ -94,7 +94,7 @@ preference. <code>Run</code> assigns the command's option object onto the sessio
<code>sessionShell.NcOptOption = NcOptOption</code> — so the settings take effect at the point the entry sits
in the list. Everything played below it optimizes under them, and a second NC Optimization Config
further down the list re-points them mid-mission.</p>
<p>The command carries no title on either client. Its row and its tree label always read
<p>The command carries no title. Its row and its tree label always read
<code>NC Optimization Config</code>: <code>GetCommandTitle</code> returns that fixed name and takes nothing from the user.</p>
<h2 id="where-it-renders">Where It Renders</h2>
<p>The web client has one editor component for this command and mounts it once per tree node, each
@@ -126,7 +126,6 @@ command — a disabled command is skipped during play and stays fully editable.<
<li>Enable Depth Splition CheckBox
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.NcOpt.NcOptOption.html#Hi_NcOpt_NcOptOption_EnableDepthSplition">EnableDepthSplition</a>.</li>
<li>The desktop client labels the same switch &ldquo;Enable Depth Splitting&rdquo;.</li>
</ul>
</li>
<li>Enable Interpolation CheckBox
@@ -327,11 +326,6 @@ feed per tooth or preferred force survives a project save and reload.</p>
</tr>
</tbody>
</table>
<h2 id="the-two-clients">The Two Clients</h2>
<p>The desktop client edits the same command in one scrolling panel of six group boxes, and it names 17
of the model's options — the four enable switches, the two distances, the three feedrates,
acceleration and jerk, Preferred Force with the two spindle safety factors, and the three
compensation switches.</p>
<p>The web client edits five more, and that is the whole difference between the two editors: Min Feed
Per Tooth, Max Feed Per Tooth and Feedrate Assignment Ratio in the Feedrate section, and Yielding
Safety Factor and Thermal Yield Safety Factor in Force &amp; Safety.</p>
@@ -87,8 +87,7 @@
<article data-uid="Anatomy-PostExecutionCommandPanel">
<h1 id="postexecutioncommand-panel-post-execution">PostExecutionCommand Panel (Post-Execution)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html">PostExecutionCommand</a>, the command both clients label
<strong>Post-Execution</strong>. It is the Output category's first catalog entry, and it carries five outputs
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PostExecutionCommand.html">PostExecutionCommand</a>, labelled <strong>Post-Execution</strong>. It is the Output category's first catalog entry, and it carries five outputs
derived from what the session has played: step files, shot files, optimization files, a CL → NC
writeback, and a geometry-difference detection.</p>
<h2 id="when-it-runs-and-what-it-covers">When It Runs, and What It Covers</h2>
@@ -103,9 +102,7 @@ command before this command — and it re-serializes every control file the sess
play is written back too. Read this together with
<a class="xref" href="PreSettingCommand-panel.html">General Config</a>, the other half of the pair: those settings
apply from their position forward, these outputs cover everything up to this position.</p>
<p>The web client places the command anywhere in the list, like any other. The WPF client pins it to
the end: a new command is inserted before a trailing Post-Execution while that is the list's only
one, and the drag guard refuses to move it off the last position.</p>
<p>The command sits anywhere in the list, like any other; nothing pins it to the end.</p>
<p><code>Run</code> executes the enabled outputs in an order of its own, which is <strong>not</strong> the order the tree and
the list below show them in: shot files, then step files, then optimization, then the CL → NC
writeback, then the geometry difference. Output timestamps follow that order rather than the layout.</p>
@@ -218,14 +215,6 @@ carries the catalog attribute, so they load from a project file but are not offe
Command dialog. Post-Execution is the catalogued carrier of these outputs, which is why they are
edited as its sections.</p>
</div>
<h2 id="the-wpf-clients-panel">The WPF Client's Panel</h2>
<p>There four of the outputs are group boxes on one panel, each an enable checkbox over a grid that is
disabled until the box is ticked: Step Files Output, Shot Files Output, Optimization Output and
Geometry Difference Detection. The physics condition collapses the Shot Files and Optimization group
boxes rather than omitting tree nodes.</p>
<p>CL → NC Writeback is the one output the web client has and this panel does not. Its two properties
live on the same engine command, and the web section and its two endpoints are where they are
edited.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
@@ -251,7 +240,7 @@ overview caption and the writeback paragraph.</li>
<li><code>wwwroot-src/src/stores/appState.ts</code> — the physics preference and licence flags the tree builder
reads.</li>
<li><code>Environments/PreferenceController.cs</code> — serves the physics preference already combined with the
advanced-physics licence, the same condition the WPF panel evaluates.</li>
advanced-physics licence.</li>
<li><code>Missions/MissionController.cs</code> — the <code>commands/{path}/postexecution/*</code> endpoints: the five enable
flags, the four templates, the shot-file time resolution and the geom-diff detect radius.</li>
</ul>
@@ -87,18 +87,12 @@
<article data-uid="Anatomy-PreSettingCommandPanel">
<h1 id="presettingcommand-panel-general-config">PreSettingCommand Panel (General Config)</h1>
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html">PreSettingCommand</a>, the command both clients label
<strong>General Config</strong>. It is one command carrying a bundle of session settings — the machining
<p>The key model is <a class="xref" href="../../../api/Hi.SessionCommands.PreSettingCommand.html">PreSettingCommand</a>, labelled <strong>General Config</strong>. It is one command carrying a bundle of session settings — the machining
resolution, the machining motion resolution, collision detection, pause on failure, physics — plus
an optional read of a meshed-geometry file.</p>
<h2 id="where-a-general-config-comes-from">Where a General Config Comes From</h2>
<p>The two clients differ on how a mission acquires these settings, and that difference is the first
thing to know about this panel.</p>
<p>The WPF client creates the bundle. Its Add menu carries a hard-coded item that constructs a
<code>PreSettingCommand</code>, and the insert rule pins it to the top of the list: a new General Config lands
at index 0 unless the list already starts with one, and while it is the list's only General Config
the drag guard refuses to move it off that position.</p>
<p>The web client's Add Command dialog is served by the server's command catalog, which reflects every
<p>How a mission acquires these settings is the first thing to know about this panel.</p>
<p>The Add Command dialog is served by the server's command catalog, which reflects every
engine command carrying <code>[CommandCatalog]</code>. <code>PreSettingCommand</code> carries no such attribute, so the
dialog cannot produce one — the catalog keeps <code>presetting</code> only as a readable kind key, and creating
a command looks the kind up in the addable set alone. What the web offers instead is the same
@@ -212,21 +206,6 @@ project is loaded or assigned — not on a runtime reset and not when the workpi
an explicit setting survives both. This command carries its own value, and overwrites the
session's with it at the moment the command runs.</p>
</div>
<h2 id="the-wpf-clients-panel">The WPF Client's Panel</h2>
<p>There the whole bundle is one panel, in two group boxes.</p>
<ul>
<li><strong>Meshed Geometry Settings</strong> — an Enable Read Meshed Geometry checkbox over a Geometry File text
box and a Browse button; the grid beneath the checkbox is disabled until it is ticked. Browse is
an <code>OpenFileDialog</code> filtered to <code>*.wct;*.stl</code>, storing a pick under the project directory as a
relative path and one outside it as an absolute path.</li>
<li><strong>Machining Settings</strong> — the Machining Resolution control is an editable ComboBox pre-filled with
fifteen powers of two, from 0.0009765625 up to 16 in doublings, and a typed value outside that
list is accepted. Beside the Motion Resolution ComboBox a content presenter holds the fixed
fields, built at runtime and labelled Linear Resolution (mm) and Angle Resolution (deg) — Angle
Resolution being this client's wording for the same <code>RotaryResolution_deg</code> the web labels Rotary
Resolution. The three checkboxes sit loose in the same grid, and the Enable Physics one carries no
licence gate.</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
@@ -108,7 +108,7 @@ fully usable.</p>
<li>Script Title Text Field
<ul>
<li>The model is <a class="xref" href="../../../api/Hi.SessionCommands.ScriptCommand.html#Hi_SessionCommands_ScriptCommand_ScriptTitle">ScriptTitle</a>.</li>
<li>Labelled &ldquo;Title (optional)&rdquo; on the web, &ldquo;Script Title&rdquo; on WPF.</li>
<li>Labelled &quot;Title (optional)&quot;.</li>
</ul>
</li>
<li>Autosave Indicator (web)
@@ -183,11 +183,6 @@ the evaluator uses — and refuses to start when any of them has an error, namin
title, path, diagnostic id, message and line. The SPA's Start sends nothing to bypass that check, so
the refusal is what a user sees. The same check is also an endpoint of its own, per command and for
the whole mission.</p>
<h2 id="the-two-clients">The Two Clients</h2>
<p>The desktop client edits the same command in AvalonEdit: a bold Script Title label with its text
box, a Script Text label, and the editor with C# syntax highlighting and a line-number gutter,
bound to the command through an attached behaviour. There is no completion popup and no autosave —
the binding writes straight into the command as the text changes.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
@@ -89,7 +89,6 @@
<h2 id="shipped-surface">Shipped Surface</h2>
<p>The dialog has no route and no Control-Tree node. It is a modal on the Execution page (<code>/execution</code>), opened by the <code>tune</code> icon button on the Step Properties panel's title bar in the Step Info column — so it is reachable only while that column and that panel are shown. The button sits next to the list it configures.</p>
<p>In the WPF application the same editor is a window opened from the <a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a>.</p>
<p>The dialog's own view models are the two fetched values, <code>categories</code> and <code>displayedKeys</code>. The server models they mirror are <code>UserService.CandidateStepPresentKeyList</code> plus <code>UserService.StepPresentAccessDictionary</code> (the candidates) and <code>UserConfig.DisplayedStepPresentKeyList</code> (the ordered displayed list). The dialog's only prop is its open/closed flag.</p>
<h2 id="layout">Layout</h2>
<ul>
@@ -144,10 +143,9 @@
<li><code>custom</code> — &ldquo;Custom&rdquo;, the catch-all for every key the mapping does not place, including the keys registered at run time through <code>UserService.AdditionalStepPresentAccess</code>.</li>
</ol>
<p>All seven are always returned; nothing gates any of them, and the candidate list is read from <code>UserService.CandidateStepPresentKeyList</code> rather than from <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a> directly, so runtime-registered keys are included.</p>
<p>Each client carries its own copy of the key → category mapping: <code>ResolveStepPresentCategory</code> on the webservice, <code>GetKeyCategory</code> in the WPF window. The two are kept in step by hand, with the seven category codes as the shared contract — adding a property means editing both.</p>
<p>The key → category mapping is <code>ResolveStepPresentCategory</code> on the webservice, with the seven category codes as its contract.</p>
<h3 id="labels-and-localization">Labels and Localization</h3>
<p>The web app resolves <code>name</code> and <code>shortName</code> server-side for the requested language from the shipped step-present catalog, laid over the live <a class="xref" href="../../api/Hi.MachiningSteps.PresentAttribute.html">PresentAttribute</a>.<a class="xref" href="../../api/Hi.MachiningSteps.PresentAttribute.html#Hi_MachiningSteps_PresentAttribute_Name">Name</a> and <a class="xref" href="../../api/Hi.MachiningSteps.PresentAttribute.html#Hi_MachiningSteps_PresentAttribute_ShortName">ShortName</a> values — those are the English truth and the fallback for a missing catalog file or key. <a class="xref" href="../../api/Hi.MachiningSteps.PresentAttribute.html#Hi_MachiningSteps_PresentAttribute_Unit">Unit</a> is sent as-is and does not localize. The dialog pins the language with a <code>?lang=</code> argument on the request and re-pulls when the UI locale changes.</p>
<p>The WPF window resolves the same labels locally, through a resource manager over <a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html">MachiningStep</a>; a key with no translation keeps its original value.</p>
<p>Refer to the code to apply <a class="xref" href="../../api/Hi.MachiningSteps.PresentAttribute.html">PresentAttribute</a>:</p>
<pre><code class="lang-csharp" name="SampleCode-ShowStepPresent">internal static void ShowStepPresent(
UserService userEnv, MachiningStep machiningStep)
@@ -162,7 +160,7 @@
</code></pre><h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="selected-step-info-panel.html">Selected-Step Info Panel</a> — the panel whose property list this page configures</li>
<li><a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a> — the dropdown that hosts this entry in the WPF client</li>
<li><a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a> — the preference surface this editor sits beside</li>
<li><a href="../../manual/run/inspecting-a-step.html">Inspecting a Step</a> — the task this dialog serves, as a procedure</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>