feat(vtank): slice 7 fix round B item 8 — Route tab collapses to VTank's 2-across grid
Transcribed VTank's own Route tab almost verbatim (docs/research/
vtank-kb/08-ui-views.md §1 "Tab: Route", 20 controls, +4px left margin for
our own convention): the waypoint list, a bottom row (nav-type menu +
insert-mode menu + three nav image buttons), and a right-hand 2-across
button grid in VTank's own row order (Add/Open Vendor; Add Portal-NPC/Add
NPC Talk; Add Recall+its recall-type menu; Add Pause+field+"seconds"
label; Add Chat+field).
- cmbNavInsertMode is now a real 3-option <menu> (RouteInsertMode.AddToEnd/
InsertAbove/InsertBelow, new enum in Navigation.cs) instead of the old
2-state ToggleRouteAddPosition button — InsertAbove/InsertBelow are now
genuinely distinct (before vs. after the selected waypoint), not both
collapsed into "not append".
- The three nav image buttons (advance/regress/nearest-point, DAT ids
0x060028FD/0x060028FC/0x060011F7) move from the waypoint-actions row to
the bottom row beside the nav-type menu, matching VTank's own layout.
- "Use NPC" is recaptioned "Add NPC Talk" (VTank's own cmdNavUseNPC text),
same AddRouteUseSelected binding.
- The pause duration is now a real editable field
(RoutePauseSecondsFieldText, default "5", parsed/clamped 0-3600 by
SetRoutePauseSecondsText) plus a "seconds" label, matching VTank's own
txtPauseWaypointTime/Label52 — replaces the RoutePauseDown/RoutePauseUp
stepper (removed).
- MossTank-only controls with no VTank Route-tab counterpart — Checkpoint,
Jump, Remove, Set Follow Target + its status label, Follow Corners, Open
Doors, Nav Priority (a real second copy of Options' own "Boost Nav.
Priority"), and the Follow/Nav Min Distance +/- stepper (a real
duplicate of Options' own editable field) — move to
mosstank-advanced.xml's new "MossTank Extras" section (popup height
300 -> 392 to fit them without touching the retail editor above).
New tests: RouteInsertModeControlsWhereANewWaypointLands (AddToEnd/
InsertAbove/InsertBelow each produce the correct insertion index),
RoutePauseSecondsFieldParsesAndClampsInput. Both mutation-checked:
hardcoding AddRouteWaypoint's insertion to always-append turned the first
red ("Point: (0N, 0E)" instead of containing "99"); removing the Math.Clamp
in SetRoutePauseSecondsText turned the second red ("99999" instead of the
clamped "3600"). Both restored to green.
EveryInteractiveControlDeclaresARealHandlerBinding: 166 -> 156 (mosstank.xml
Route tab 28 -> 18 controls; the 10 relocated/removed controls are either
gone or moved into mosstank-advanced.xml, a separate file this scan
doesn't cover).
SecondaryPopupPanelsFitTheirOwnBoundsAndEveryBindingResolves: mosstank-
advanced.xml's expected height 300 -> 392.
tests/AcDream.Plugins.MossTank.Tests: 668/668 (was 666/666, +2 new tests).
tests/AcDream.App.Tests --filter Markup|Plugin|UiMenu|Slider: 276/3 skipped/279 (unchanged).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e7ed603e6e
commit
95c93858a1
6 changed files with 224 additions and 93 deletions
|
|
@ -203,7 +203,7 @@ internal sealed partial class MossTankPanel
|
|||
private string _routeChatDraft = "/ls";
|
||||
private int _routePauseSeconds = 5;
|
||||
private RouteRecallKind _routeRecallKind = RouteRecallKind.PrimaryPortal;
|
||||
private bool _routeAddToEnd = true;
|
||||
private RouteInsertMode _routeInsertMode = RouteInsertMode.AddToEnd;
|
||||
private IReadOnlyList<string> _metaRows = Array.Empty<string>();
|
||||
private int _selectedMetaRule;
|
||||
private string _metaProfileNameDraft = string.Empty;
|
||||
|
|
@ -819,7 +819,16 @@ internal sealed partial class MossTankPanel
|
|||
public string RouteProfileNameDraft => _routeProfileNameDraft;
|
||||
public string RouteNotice => _routeNotice;
|
||||
public string RouteChatDraft => _routeChatDraft;
|
||||
public string RoutePauseText => $"{_routePauseSeconds} seconds";
|
||||
// Fix round B item 8: VTank's own txtPauseWaypointTime is a real
|
||||
// editable field defaulting to "5" (docs/research/vtank-kb/
|
||||
// 08-ui-views.md §1's Route table), not a "-"/"+" stepper.
|
||||
public string RoutePauseSecondsFieldText =>
|
||||
_routePauseSeconds.ToString(CultureInfo.InvariantCulture);
|
||||
public Action<string> SetRoutePauseSecondsText => value =>
|
||||
{
|
||||
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int seconds))
|
||||
_routePauseSeconds = Math.Clamp(seconds, 0, 3600);
|
||||
};
|
||||
public string RouteMinimumDistanceText => string.Create(
|
||||
CultureInfo.InvariantCulture,
|
||||
$"Follow/Nav Min Distance: {_navigationSettings.MinimumDistanceMeters:0.0}m");
|
||||
|
|
@ -827,9 +836,24 @@ internal sealed partial class MossTankPanel
|
|||
_navigationSettings.FollowTargetObjectId == 0u
|
||||
? "Follow target: [None]"
|
||||
: $"Follow target: {_navigationSettings.FollowTargetName}";
|
||||
public string RouteAddPositionText => _routeAddToEnd
|
||||
? "Add to End"
|
||||
: "Insert After Selection";
|
||||
// Fix round B item 8: VTank's own cmbNavInsertMode is a 3-option
|
||||
// <menu> (Add to End / Insert Above / Insert Below), not the old
|
||||
// 2-state toggle button.
|
||||
public IReadOnlyList<string> RouteInsertModeNames { get; } =
|
||||
["Add to End", "Insert Above", "Insert Below"];
|
||||
public string SelectedRouteInsertMode => _routeInsertMode switch
|
||||
{
|
||||
RouteInsertMode.InsertAbove => "Insert Above",
|
||||
RouteInsertMode.InsertBelow => "Insert Below",
|
||||
_ => "Add to End",
|
||||
};
|
||||
public Action<string> SelectRouteInsertMode => value =>
|
||||
_routeInsertMode = value switch
|
||||
{
|
||||
"Insert Above" => RouteInsertMode.InsertAbove,
|
||||
"Insert Below" => RouteInsertMode.InsertBelow,
|
||||
_ => RouteInsertMode.AddToEnd,
|
||||
};
|
||||
|
||||
public Action ToggleNavigation => () =>
|
||||
{
|
||||
|
|
@ -891,12 +915,6 @@ internal sealed partial class MossTankPanel
|
|||
public Action RemoveRouteWaypoint => RemoveRouteWaypointCore;
|
||||
public Action MoveRouteWaypointUp => () => MoveRouteWaypoint(-1);
|
||||
public Action MoveRouteWaypointDown => () => MoveRouteWaypoint(1);
|
||||
public Action ToggleRouteAddPosition => () =>
|
||||
_routeAddToEnd = !_routeAddToEnd;
|
||||
public Action RoutePauseDown => () =>
|
||||
_routePauseSeconds = Math.Max(0, _routePauseSeconds - 1);
|
||||
public Action RoutePauseUp => () =>
|
||||
_routePauseSeconds = Math.Min(3600, _routePauseSeconds + 1);
|
||||
public Action RouteMinimumDistanceDown => () =>
|
||||
{
|
||||
_navigationSettings.MinimumDistanceMeters = Math.Max(
|
||||
|
|
@ -2200,11 +2218,13 @@ internal sealed partial class MossTankPanel
|
|||
|
||||
private void AddRouteWaypoint(RouteWaypoint waypoint)
|
||||
{
|
||||
int insertion = _routeAddToEnd
|
||||
? _navigationSettings.Waypoints.Count
|
||||
: Math.Min(
|
||||
_navigationSettings.Waypoints.Count,
|
||||
_selectedRouteWaypoint + 1);
|
||||
int count = _navigationSettings.Waypoints.Count;
|
||||
int insertion = _routeInsertMode switch
|
||||
{
|
||||
RouteInsertMode.InsertAbove => Math.Clamp(_selectedRouteWaypoint, 0, count),
|
||||
RouteInsertMode.InsertBelow => Math.Min(count, _selectedRouteWaypoint + 1),
|
||||
_ => count,
|
||||
};
|
||||
_navigationSettings.Waypoints.Insert(insertion, waypoint);
|
||||
_selectedRouteWaypoint = insertion;
|
||||
_navigation.Reset();
|
||||
|
|
|
|||
|
|
@ -40,6 +40,21 @@ internal enum RouteJumpDirection
|
|||
StrafeRight,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VTank's own cmbNavInsertMode (docs/research/vtank-kb/08-ui-views.md §1
|
||||
/// "Tab: Route": "options: Add to End / Insert Above / Insert Below").
|
||||
/// Replaces the old two-state _routeAddToEnd bool (fix round B item 8) —
|
||||
/// InsertAbove/InsertBelow are both relative to the currently selected
|
||||
/// waypoint, distinguishing "before" from "after" rather than collapsing
|
||||
/// both non-append cases into one.
|
||||
/// </summary>
|
||||
internal enum RouteInsertMode
|
||||
{
|
||||
AddToEnd,
|
||||
InsertAbove,
|
||||
InsertBelow,
|
||||
}
|
||||
|
||||
internal sealed class RouteWaypoint
|
||||
{
|
||||
public RouteWaypointType Type { get; set; }
|
||||
|
|
|
|||
|
|
@ -30,8 +30,29 @@
|
|||
overlapped and read as garbled text on screen once this became a
|
||||
top-level window (live-verified, screenshot before the fix showed
|
||||
"AdvancedOptionsced Options — complete VTank settings table").
|
||||
-->
|
||||
<panel x="253" y="405" w="392" h="300" title="MossTank Advanced Options"
|
||||
|
||||
Fix round B item 8: below the retail key-value editor is a "MossTank
|
||||
Extras" section — controls with no VTank-tab counterpart, moved here per
|
||||
the owner's silhouette rule (VTank's own controls are never
|
||||
shrunk/moved/reordered to make room for MossTank extras) rather than
|
||||
crowding the Route tab: Checkpoint/Jump (AddRouteCheckpoint/
|
||||
AddRouteJump), Remove (RemoveRouteWaypoint), Set Follow Target +
|
||||
its status label, Follow Corners/Open Doors (navigation toggles with no
|
||||
Route-tab VTank equivalent), Nav Priority (a real second copy of
|
||||
Options' own "Boost Nav. Priority" — same NavigationPriorityEnabled/
|
||||
ToggleNavigationPriority binding, kept here too rather than assuming the
|
||||
user remembers Options has it), and the Follow/Nav Min Distance +/-
|
||||
stepper (a real duplicate of Options' own editable
|
||||
FollowNavMinimumValueText field — kept for symmetry with the other
|
||||
extras, not deleted, since both write the same
|
||||
NavigationSettings.MinimumDistanceMeters). Panel height grows 300->392
|
||||
to fit this section without touching the retail editor above it; item 9
|
||||
is expected to reshuffle the retail portion further (clVal column,
|
||||
lFilterList checklist, description readout) without moving this section.
|
||||
Bold text isn't representable in the plain retail UI font (0x40000000
|
||||
has no bold face) — the section header uses the same bright caption
|
||||
color other headers use instead. -->
|
||||
<panel x="253" y="405" w="392" h="392" title="MossTank Advanced Options"
|
||||
visible="{AdvancedOptionsVisible}" resize="none">
|
||||
<list x="4" y="22" w="260" h="160" rowheight="17"
|
||||
items="{AdvancedOptionNames}" selected="{SelectedAdvancedOptionIndex}"
|
||||
|
|
@ -47,4 +68,22 @@
|
|||
maxlength="160" clearonsubmit="false" background="#E6000000"
|
||||
tooltip="Edit the selected advanced-option value and press Enter or Apply." />
|
||||
<label x="4" y="216" w="384" h="16" text="{AdvancedOptionNotice}" color="#FFC7B98F" />
|
||||
|
||||
<label x="4" y="236" w="200" h="16" text="MossTank Extras" color="#FFE8DEC3" />
|
||||
<button x="4" y="254" w="90" h="18" text="Checkpoint" onclick="{AddRouteCheckpoint}" />
|
||||
<button x="100" y="254" w="90" h="18" text="Jump" onclick="{AddRouteJump}" />
|
||||
<button x="4" y="276" w="90" h="18" text="Remove" onclick="{RemoveRouteWaypoint}" />
|
||||
<button x="100" y="276" w="140" h="18" text="Set Follow Target" onclick="{SetFollowTarget}" />
|
||||
<label x="4" y="298" w="376" h="16" text="{RouteFollowTargetText}" color="#FFC7B98F" />
|
||||
<toggle x="4" y="318" w="140" h="18" text="Follow Corners"
|
||||
checked="{FollowAroundCornersEnabled}" onclick="{ToggleFollowAroundCorners}" />
|
||||
<toggle x="200" y="318" w="140" h="18" text="Open Doors"
|
||||
checked="{OpenDoorsEnabled}" onclick="{ToggleOpenDoors}" />
|
||||
<toggle x="4" y="340" w="140" h="18" text="Nav Priority"
|
||||
checked="{NavigationPriorityEnabled}" onclick="{ToggleNavigationPriority}" />
|
||||
<label x="4" y="362" w="180" h="16" text="{RouteMinimumDistanceText}" color="#FFC7B98F" />
|
||||
<button x="190" y="362" w="24" h="18" text="-"
|
||||
onclick="{RouteMinimumDistanceDown}" tooltip="Decrease the route arrival distance." />
|
||||
<button x="218" y="362" w="24" h="18" text="+"
|
||||
onclick="{RouteMinimumDistanceUp}" tooltip="Increase the route arrival distance." />
|
||||
</panel>
|
||||
|
|
|
|||
|
|
@ -553,29 +553,65 @@
|
|||
<label x="332" y="178" w="184" h="16" text="{Coverage}" color="#FF9B9072" />
|
||||
</group>
|
||||
|
||||
<!-- Route: VTank's navigation-waypoint editor and execution surface.
|
||||
The waypoint list is VTank's own clWP/clWPc 2-column grid (Campaign
|
||||
VT S7.5, docs/research/vtank-kb/08-ui-views.md §1 "Tab: Route";
|
||||
<!-- Route: VTank's own 2-across button grid, row order, and bottom
|
||||
nav-control row (fix round B item 8, docs/research/vtank-kb/
|
||||
08-ui-views.md §1 "Tab: Route" — 20 controls, transcribed almost
|
||||
verbatim, +4px left margin for our own convention). The waypoint
|
||||
list is VTank's own clWP/clWPc 2-column grid (Campaign VT S7.5;
|
||||
PluginCore.cs:3576-3599 — any cell click deletes the waypoint).
|
||||
PITCH: text 330+7=337, count (last column) auto. -->
|
||||
PITCH: text 330+7=337, count (last column) auto.
|
||||
|
||||
MossTank-only extras that have no VTank Route-tab counterpart moved
|
||||
to the Advanced Options popup's own "MossTank Extras" section:
|
||||
Checkpoint, Jump, Remove, Set Follow Target + its status label,
|
||||
Follow Corners, Open Doors, Nav Priority (also duplicates Options'
|
||||
own "Boost Nav. Priority"), and the Follow/Nav Min Distance +/-
|
||||
stepper (a real duplicate of Options' own editable field — kept for
|
||||
symmetry with the other extras rather than deleted, see
|
||||
mosstank-advanced.xml's own comment).
|
||||
|
||||
cmbNavInsertMode is now a real 3-option <menu> (RouteInsertMode:
|
||||
AddToEnd/InsertAbove/InsertBelow, Navigation.cs) replacing the old
|
||||
2-state toggle button; the three nav image buttons (advance/regress/
|
||||
nearest, DAT ids 0x060028FD/0x060028FC/0x060011F7) sit beside it on
|
||||
the same bottom row instead of the waypoint-actions row. "Use NPC"
|
||||
is recaptioned "Add NPC Talk" (VTank's own cmdNavUseNPC text) with
|
||||
the same AddRouteUseSelected binding. The pause duration is now a
|
||||
real editable field (RoutePauseSecondsFieldText, default "5") plus
|
||||
a "seconds" label, matching VTank's txtPauseWaypointTime/Label52
|
||||
instead of the old "-"/"+" stepper. -->
|
||||
<group x="8" y="42" w="848" h="194" visible="{RouteVisible}">
|
||||
<label x="4" y="0" text="Navigation Waypoints" color="#FFE8DEC3" />
|
||||
<list x="4" y="18" w="366" h="120" rowheight="17"
|
||||
<label x="4" y="0" w="370" h="16" text="Navigation Waypoints" color="#FFE8DEC3" />
|
||||
<list x="4" y="16" w="370" h="116" rowheight="17"
|
||||
selected="{SelectedRouteWaypointIndex}" onchange="{SelectRouteWaypoint}"
|
||||
tooltip="Click a waypoint to remove it.">
|
||||
<column type="text" width="337" items="{RouteWaypointTextColumn}" onclick="{DeleteRouteWaypointAt}" />
|
||||
<column type="text" width="30" items="{RouteWaypointCountColumn}" onclick="{DeleteRouteWaypointAt}" />
|
||||
</list>
|
||||
|
||||
<button x="380" y="18" w="92" h="21" text="Add"
|
||||
onclick="{AddRoutePoint}" />
|
||||
<button x="478" y="18" w="116" h="21" text="Open Vendor"
|
||||
onclick="{AddRouteOpenVendor}" />
|
||||
<button x="600" y="18" w="116" h="21" text="Add Portal/NPC"
|
||||
onclick="{AddRoutePortal}" />
|
||||
<menu x="4" y="136" w="80" h="16" items="{RouteModeNames}"
|
||||
selected="{SelectedRouteMode}" onchange="{SelectRouteMode}"
|
||||
rows="4" openupward="true" tooltip="Choose Circular, Linear, Follow, or Once route behavior." />
|
||||
<menu x="90" y="136" w="120" h="16" items="{RouteInsertModeNames}"
|
||||
selected="{SelectedRouteInsertMode}" onchange="{SelectRouteInsertMode}"
|
||||
rows="3" openupward="true" tooltip="Where Add buttons insert the new waypoint." />
|
||||
<button x="214" y="136" w="16" h="16" icon="0x060028FD" iconkind="did"
|
||||
onclick="{MoveRouteWaypointDown}" tooltip="Advance the current point." />
|
||||
<button x="230" y="136" w="16" h="16" icon="0x060028FC" iconkind="did"
|
||||
onclick="{MoveRouteWaypointUp}" tooltip="Regress the current point." />
|
||||
<!-- VTank's own btnNavResetPoint (icon 0x060011F7, "Select Nearest
|
||||
Point") reassigns the LIVE navigation cursor; MossTank has no
|
||||
mutable cursor to expose to a plugin, so this moves the tab's
|
||||
own edit selection to the closest waypoint instead — see
|
||||
SelectNearestRouteWaypoint's own doc comment. -->
|
||||
<button x="246" y="136" w="16" h="16" icon="0x060011F7" iconkind="did"
|
||||
onclick="{SelectNearestRouteWaypoint}" tooltip="Select the nearest waypoint." />
|
||||
|
||||
<button x="380" y="45" w="92" h="21" text="Add Recall"
|
||||
onclick="{AddRouteRecall}" />
|
||||
<button x="380" y="16" w="88" h="16" text="Add" onclick="{AddRoutePoint}" />
|
||||
<button x="474" y="16" w="88" h="16" text="Open Vendor" onclick="{AddRouteOpenVendor}" />
|
||||
<button x="380" y="38" w="88" h="16" text="Add Portal/NPC" onclick="{AddRoutePortal}" />
|
||||
<button x="474" y="38" w="88" h="16" text="Add NPC Talk" onclick="{AddRouteUseSelected}" />
|
||||
<button x="380" y="60" w="88" h="16" text="Add Recall" onclick="{AddRouteRecall}" />
|
||||
<!-- VTank's own cmbRecallType lists 27 named retail recalls
|
||||
(docs/research/vtank-kb/08-ui-views.md §1's Route table);
|
||||
MossTank's RouteRecallKind models 4 (Lifestone/Marketplace/
|
||||
|
|
@ -583,72 +619,24 @@
|
|||
spell-id data, out of this UI-parity slice's scope. scroll="true"
|
||||
is applied for grammar parity even though 4 items never need to
|
||||
scroll. -->
|
||||
<menu x="478" y="45" w="150" h="21" items="{RouteRecallNames}"
|
||||
<menu x="474" y="60" w="120" h="16" items="{RouteRecallNames}"
|
||||
selected="{SelectedRouteRecall}" onchange="{SelectRouteRecall}"
|
||||
rows="4" openupward="false" scroll="true"
|
||||
tooltip="Choose the recall type added by Add Recall." />
|
||||
<toggle x="636" y="47" w="142" h="20" text="Follow Corners"
|
||||
checked="{FollowAroundCornersEnabled}"
|
||||
onclick="{ToggleFollowAroundCorners}" />
|
||||
<toggle x="636" y="74" w="142" h="20" text="Open Doors"
|
||||
checked="{OpenDoorsEnabled}" onclick="{ToggleOpenDoors}" />
|
||||
|
||||
<button x="380" y="72" w="92" h="21" text="Add Pause"
|
||||
onclick="{AddRoutePause}" />
|
||||
<label x="478" y="76" text="{RoutePauseText}" color="#FFC7B98F" />
|
||||
<button x="570" y="72" w="28" h="21" text="-"
|
||||
onclick="{RoutePauseDown}" tooltip="Decrease the pause duration." />
|
||||
<button x="604" y="72" w="28" h="21" text="+"
|
||||
onclick="{RoutePauseUp}" tooltip="Increase the pause duration." />
|
||||
|
||||
<button x="380" y="99" w="92" h="21" text="Add Chat"
|
||||
onclick="{AddRouteChat}" />
|
||||
<field x="478" y="99" w="150" h="21" text="{RouteChatDraft}"
|
||||
<button x="380" y="82" w="88" h="16" text="Add Pause" onclick="{AddRoutePause}" />
|
||||
<field x="474" y="82" w="68" h="16" text="{RoutePauseSecondsFieldText}"
|
||||
onchange="{SetRoutePauseSecondsText}" onsubmit="{SetRoutePauseSecondsText}"
|
||||
maxlength="4" clearonsubmit="false" background="#E6000000"
|
||||
color="#FFE8DEC3" tooltip="Pause duration in seconds, added by Add Pause." />
|
||||
<label x="547" y="82" w="50" h="16" text="seconds" color="#FFE8DEC3" />
|
||||
<button x="380" y="104" w="88" h="16" text="Add Chat" onclick="{AddRouteChat}" />
|
||||
<field x="474" y="104" w="120" h="16" text="{RouteChatDraft}"
|
||||
onchange="{SetRouteChatDraft}" onsubmit="{SetRouteChatDraft}"
|
||||
maxlength="128" clearonsubmit="false" background="#E6000000"
|
||||
color="#FFE8DEC3" tooltip="Chat command added by Add Chat." />
|
||||
<button x="636" y="99" w="80" h="21" text="Use NPC"
|
||||
onclick="{AddRouteUseSelected}" />
|
||||
|
||||
<button x="380" y="126" w="92" h="21" text="Checkpoint"
|
||||
onclick="{AddRouteCheckpoint}" />
|
||||
<button x="478" y="126" w="72" h="21" text="Jump"
|
||||
onclick="{AddRouteJump}" />
|
||||
<button x="556" y="126" w="72" h="21" text="Remove"
|
||||
onclick="{RemoveRouteWaypoint}" />
|
||||
<button x="636" y="126" w="28" h="21" icon="0x060028FC" iconkind="did"
|
||||
onclick="{MoveRouteWaypointUp}" tooltip="Move the selected waypoint up." />
|
||||
<button x="670" y="126" w="28" h="21" icon="0x060028FD" iconkind="did"
|
||||
onclick="{MoveRouteWaypointDown}" tooltip="Move the selected waypoint down." />
|
||||
<!-- VTank's own btnNavResetPoint (icon 0x060011F7, "Select Nearest
|
||||
Point") reassigns the LIVE navigation cursor; MossTank has no
|
||||
mutable cursor to expose to a plugin, so this moves the tab's
|
||||
own edit selection to the closest waypoint instead — see
|
||||
SelectNearestRouteWaypoint's own doc comment. -->
|
||||
<button x="704" y="126" w="28" h="21" icon="0x060011F7" iconkind="did"
|
||||
onclick="{SelectNearestRouteWaypoint}" tooltip="Select the nearest waypoint." />
|
||||
|
||||
<menu x="4" y="148" w="90" h="22" items="{RouteModeNames}"
|
||||
selected="{SelectedRouteMode}" onchange="{SelectRouteMode}"
|
||||
rows="4" openupward="true" tooltip="Choose Circular, Linear, Follow, or Once route behavior." />
|
||||
<toggle x="102" y="150" w="132" h="20" text="Nav Priority"
|
||||
checked="{NavigationPriorityEnabled}"
|
||||
onclick="{ToggleNavigationPriority}" />
|
||||
<button x="242" y="148" w="136" h="22" text="{RouteAddPositionText}"
|
||||
onclick="{ToggleRouteAddPosition}" />
|
||||
<button x="386" y="148" w="112" h="22" text="Set Follow Target"
|
||||
onclick="{SetFollowTarget}" />
|
||||
<label x="506" y="152" text="{RouteFollowTargetText}"
|
||||
color="#FFC7B98F" />
|
||||
|
||||
<label x="4" y="174" text="{RouteMinimumDistanceText}"
|
||||
color="#FFC7B98F" />
|
||||
<button x="196" y="170" w="28" h="21" text="-"
|
||||
onclick="{RouteMinimumDistanceDown}" tooltip="Decrease the route arrival distance." />
|
||||
<button x="230" y="170" w="28" h="21" text="+"
|
||||
onclick="{RouteMinimumDistanceUp}" tooltip="Increase the route arrival distance." />
|
||||
<label x="270" y="174" text="{NavigationStatus}" color="#FF9B9072" />
|
||||
<label x="520" y="174" text="{RouteNotice}" color="#FF9B9072" />
|
||||
<label x="4" y="160" w="300" h="16" text="{NavigationStatus}" color="#FF9B9072" />
|
||||
<label x="310" y="160" w="300" h="16" text="{RouteNotice}" color="#FF9B9072" />
|
||||
</group>
|
||||
|
||||
<!-- Meta: ordered VTank state-machine rules. Rules fire once per state
|
||||
|
|
|
|||
|
|
@ -220,7 +220,19 @@ public sealed class MossTankMarkupContractTests
|
|||
// Apply/Remove/MoveUp/MoveDown, 14). "Add" is renamed "Create" and
|
||||
// stays in place (same slot, no count change). Added: the settable
|
||||
// cmbMetaCurrentState menu (+1). Net 186 -> 166 (-7 -14 +1).
|
||||
Assert.Equal(166, controls.Length);
|
||||
// Fix round B item 8: the Route tab collapses to VTank's own
|
||||
// 2-across button grid + bottom nav-control row (docs/research/
|
||||
// vtank-kb/08-ui-views.md §1 "Tab: Route"), 28 -> 18 interactive
|
||||
// controls within mosstank.xml. Checkpoint/Jump/Remove/Set Follow
|
||||
// Target/Follow Corners/Open Doors/Nav Priority/the Follow-Nav-Min-
|
||||
// Distance stepper (no VTank Route-tab counterpart) moved to
|
||||
// mosstank-advanced.xml's own new "MossTank Extras" section — a
|
||||
// separate file this scan doesn't cover. The 2-state
|
||||
// ToggleRouteAddPosition button became the real 3-option
|
||||
// cmbNavInsertMode <menu>, and the pause "-"/"+" stepper became one
|
||||
// editable field, matching VTank's own txtPauseWaypointTime. Net
|
||||
// 166 -> 156.
|
||||
Assert.Equal(156, controls.Length);
|
||||
|
||||
foreach (XElement control in controls)
|
||||
{
|
||||
|
|
@ -431,7 +443,7 @@ public sealed class MossTankMarkupContractTests
|
|||
/// give the main panel, now split across three files instead of one.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData("mosstank-advanced.xml", 392f, 300f)]
|
||||
[InlineData("mosstank-advanced.xml", 392f, 392f)]
|
||||
[InlineData("mosstank-loot-editor.xml", 268f, 300f)]
|
||||
[InlineData("mosstank-buffpicker.xml", 268f, 236f)]
|
||||
[InlineData("mosstank-metaeditor.xml", 630f, 160f)]
|
||||
|
|
|
|||
|
|
@ -2055,6 +2055,63 @@ public sealed class MossTankPanelTests
|
|||
Assert.Equal(["1"], panel.RouteWaypointCountColumn);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RouteInsertModeControlsWhereANewWaypointLands()
|
||||
{
|
||||
// Fix round B item 8: VTank's own cmbNavInsertMode is a real
|
||||
// 3-option <menu> (Add to End / Insert Above / Insert Below),
|
||||
// replacing the old 2-state ToggleRouteAddPosition button.
|
||||
var automation = new FakeAutomation { NavigationSnapshot = NavigationAt(0f) };
|
||||
var panel = new MossTankPanel(new FakeHost(automation));
|
||||
Assert.Equal("Add to End", panel.SelectedRouteInsertMode);
|
||||
|
||||
automation.NavigationSnapshot = automation.NavigationSnapshot with
|
||||
{ Position = automation.NavigationSnapshot.Position with { EastWest = 0d } };
|
||||
panel.AddRoutePoint(); // index 0 @ 0
|
||||
automation.NavigationSnapshot = automation.NavigationSnapshot with
|
||||
{ Position = automation.NavigationSnapshot.Position with { EastWest = 20d } };
|
||||
panel.AddRoutePoint(); // index 1 @ 20 (default Add to End)
|
||||
Assert.Equal(2, panel.RouteWaypointTextColumn.Count);
|
||||
Assert.Contains("20", panel.RouteWaypointTextColumn[1]);
|
||||
|
||||
panel.SelectRouteInsertMode("Insert Above");
|
||||
Assert.Equal("Insert Above", panel.SelectedRouteInsertMode);
|
||||
panel.SelectRouteWaypoint(0); // the @0 waypoint
|
||||
automation.NavigationSnapshot = automation.NavigationSnapshot with
|
||||
{ Position = automation.NavigationSnapshot.Position with { EastWest = 99d } };
|
||||
panel.AddRoutePoint(); // must land BEFORE index 0, not appended
|
||||
Assert.Equal(3, panel.RouteWaypointTextColumn.Count);
|
||||
Assert.Contains("99", panel.RouteWaypointTextColumn[0]);
|
||||
|
||||
panel.SelectRouteInsertMode("Insert Below");
|
||||
Assert.Equal("Insert Below", panel.SelectedRouteInsertMode);
|
||||
panel.SelectRouteWaypoint(0); // the @99 waypoint
|
||||
automation.NavigationSnapshot = automation.NavigationSnapshot with
|
||||
{ Position = automation.NavigationSnapshot.Position with { EastWest = 77d } };
|
||||
panel.AddRoutePoint(); // must land right AFTER index 0
|
||||
Assert.Equal(4, panel.RouteWaypointTextColumn.Count);
|
||||
Assert.Contains("77", panel.RouteWaypointTextColumn[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoutePauseSecondsFieldParsesAndClampsInput()
|
||||
{
|
||||
// Fix round B item 8: VTank's own txtPauseWaypointTime is a real
|
||||
// editable field defaulting to "5", replacing the old "-"/"+"
|
||||
// stepper (RoutePauseDown/RoutePauseUp, now removed).
|
||||
var panel = new MossTankPanel(new FakeHost(new FakeAutomation()));
|
||||
Assert.Equal("5", panel.RoutePauseSecondsFieldText);
|
||||
|
||||
panel.SetRoutePauseSecondsText("12");
|
||||
Assert.Equal("12", panel.RoutePauseSecondsFieldText);
|
||||
|
||||
panel.SetRoutePauseSecondsText("99999");
|
||||
Assert.Equal("3600", panel.RoutePauseSecondsFieldText);
|
||||
|
||||
panel.SetRoutePauseSecondsText("not a number");
|
||||
Assert.Equal("3600", panel.RoutePauseSecondsFieldText); // unchanged on bad input
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MetaTabEditsAndExecutesTheLiveStateMachine()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue