feat(vtank): slice 7 S7.6 — Meta tab's real 6-column rules grid
VTank's own lstMetaRules grid (delete/move-up/move-down icon-ish cells + State/Condition/Action text cells, docs/research/vtank-kb/08-ui-views.md §1 "Tab: Meta"; PluginCore.cs:2218-2247) replaces the padded single-column rules list: any State/Condition/Action cell click opens the rule editor below (reusing the existing SelectMetaRule), the up/down cells reorder using the same 0x060028FC/FD DAT icons the Monsters and Route grids already established, and the delete cell is a plain text "X" — no retail DAT delete-glyph id is confirmed anywhere in this codebase (unlike the already-established move icons), and "X" is ASCII the default retail font renders without the unrenderable-glyph risk NoButtonAnywhereUsesTheUnrenderableArrowGlyphs guards against. The new pin (contract control count 180->186) and the new panel test were shown to fail against a targeted mutation before being confirmed green. MossTank suite 659 -> 660; App markup/plugin filter holds 192/192. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
6118062a7a
commit
cc323f6a59
4 changed files with 91 additions and 4 deletions
|
|
@ -921,6 +921,44 @@ internal sealed partial class MossTankPanel
|
|||
public string MetaStatus => _meta.Status;
|
||||
public IReadOnlyList<string> MetaRows => _metaRows;
|
||||
public int SelectedMetaRuleIndex => _selectedMetaRule;
|
||||
|
||||
// ── Meta grid (Campaign VT S7.6: VTank's own lstMetaRules 6-column
|
||||
// grid, docs/research/vtank-kb/08-ui-views.md §1 "Tab: Meta";
|
||||
// PluginCore.cs:2218-2247 — col 0 delete, col 1 move up, col 2 move
|
||||
// down, cols 3-5 (State/Condition/Action text) open the rule editor).
|
||||
// Delete uses a text "X" cell rather than an icon: no retail DAT
|
||||
// delete-glyph id is confirmed anywhere in this codebase (unlike the
|
||||
// move-up/move-down 0x060028FC/FD pair, already established by the
|
||||
// Monsters/Route grids), and "X" is plain ASCII the default retail
|
||||
// font already renders — see NoButtonAnywhereUsesTheUnrenderableArrowGlyphs
|
||||
// for why an unconfirmed glyph id is worse than a text fallback. ──
|
||||
public IReadOnlyList<string> MetaDeleteColumn =>
|
||||
Enumerable.Repeat("X", _metaProfile.Rules.Count).ToArray();
|
||||
public IReadOnlyList<uint> MetaMoveUpIcons =>
|
||||
Enumerable.Repeat(0x060028FCu, _metaProfile.Rules.Count).ToArray();
|
||||
public IReadOnlyList<uint> MetaMoveDownIcons =>
|
||||
Enumerable.Repeat(0x060028FDu, _metaProfile.Rules.Count).ToArray();
|
||||
public IReadOnlyList<string> MetaStateColumn =>
|
||||
_metaProfile.Rules.Select(static rule => rule.State).ToArray();
|
||||
public IReadOnlyList<string> MetaConditionColumn =>
|
||||
_metaProfile.Rules.Select(static rule => DescribeMetaCondition(rule.Condition)).ToArray();
|
||||
public IReadOnlyList<string> MetaActionColumn =>
|
||||
_metaProfile.Rules.Select(static rule => DescribeMetaAction(rule.Action)).ToArray();
|
||||
public Action<int> DeleteMetaRuleAt => row =>
|
||||
{
|
||||
SelectMetaRuleCore(row);
|
||||
RemoveMetaRuleCore();
|
||||
};
|
||||
public Action<int> MoveMetaRuleUpAt => row =>
|
||||
{
|
||||
SelectMetaRuleCore(row);
|
||||
MoveMetaRule(-1);
|
||||
};
|
||||
public Action<int> MoveMetaRuleDownAt => row =>
|
||||
{
|
||||
SelectMetaRuleCore(row);
|
||||
MoveMetaRule(1);
|
||||
};
|
||||
public IReadOnlyList<string> MetaConditionNames =>
|
||||
Enum.GetNames<MetaConditionKind>();
|
||||
public IReadOnlyList<string> MetaActionNames => Enum.GetNames<MetaActionKind>();
|
||||
|
|
|
|||
|
|
@ -609,7 +609,13 @@
|
|||
</group>
|
||||
|
||||
<!-- Meta: ordered VTank state-machine rules. Rules fire once per state
|
||||
entry; transitions/call/return use the live MetaEngine. -->
|
||||
entry; transitions/call/return use the live MetaEngine. The rules
|
||||
list is VTank's own 6-column lstMetaRules grid (Campaign VT S7.6,
|
||||
docs/research/vtank-kb/08-ui-views.md §1 "Tab: Meta";
|
||||
PluginCore.cs:2218-2247 — col 0 delete, cols 1/2 move up/down, cols
|
||||
3-5 State/Condition/Action open the rule editor below). PITCH:
|
||||
delete/move 16+7=23 each, State 150+7=157, Condition/Action share
|
||||
the remainder ("*"). -->
|
||||
<group x="8" y="42" w="848" h="194" visible="{MetaVisible}">
|
||||
<menu x="4" y="0" w="132" h="21" items="{MetaProfileNames}"
|
||||
selected="{SelectedMetaProfile}" onchange="{SelectMetaProfile}"
|
||||
|
|
@ -633,8 +639,15 @@
|
|||
<label x="620" y="4" text="{MetaStateText}" color="#FFE8DEC3" />
|
||||
|
||||
<list x="4" y="26" w="776" h="68" rowheight="17"
|
||||
items="{MetaRows}" selected="{SelectedMetaRuleIndex}"
|
||||
onchange="{SelectMetaRule}" tooltip="Select an ordered meta rule to edit." />
|
||||
selected="{SelectedMetaRuleIndex}" onchange="{SelectMetaRule}"
|
||||
tooltip="Click State/Condition/Action to edit; delete/move-up/move-down cells act immediately.">
|
||||
<column type="text" width="23" items="{MetaDeleteColumn}" onclick="{DeleteMetaRuleAt}" />
|
||||
<column type="icon" width="23" iconkind="did" values="{MetaMoveUpIcons}" onclick="{MoveMetaRuleUpAt}" />
|
||||
<column type="icon" width="23" iconkind="did" values="{MetaMoveDownIcons}" onclick="{MoveMetaRuleDownAt}" />
|
||||
<column type="text" width="157" items="{MetaStateColumn}" onclick="{SelectMetaRule}" />
|
||||
<column type="text" width="*" items="{MetaConditionColumn}" onclick="{SelectMetaRule}" />
|
||||
<column type="text" width="*" items="{MetaActionColumn}" onclick="{SelectMetaRule}" />
|
||||
</list>
|
||||
|
||||
<field x="4" y="100" w="118" h="21" text="{MetaStateDraft}"
|
||||
onchange="{SetMetaStateDraft}" onsubmit="{SetMetaStateDraft}"
|
||||
|
|
|
|||
|
|
@ -205,7 +205,10 @@ public sealed class MossTankMarkupContractTests
|
|||
// S7.5 replaced the Route tab's single-column waypoint list with
|
||||
// VTank's own clWP/clWPc 2-column grid (+2) and added the
|
||||
// "Select Nearest Point" button (+1) — net 177 -> 180.
|
||||
Assert.Equal(180, controls.Length);
|
||||
// S7.6 replaced the Meta tab's single-column rules list with
|
||||
// VTank's own 6-column lstMetaRules grid (+6: the list itself was
|
||||
// already counted, now 6 <column> children) — net 180 -> 186.
|
||||
Assert.Equal(186, controls.Length);
|
||||
|
||||
foreach (XElement control in controls)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2049,6 +2049,39 @@ public sealed class MossTankPanelTests
|
|||
Assert.Equal("Hunt", panel.MetaState);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MetaGridColumnsMatchTheRulesAndDeleteMoveActOnTheClickedRow()
|
||||
{
|
||||
// Campaign VT S7.6: VTank's own 6-column lstMetaRules grid
|
||||
// (PluginCore.cs:2218-2247) — col 0 delete, cols 1/2 move up/down,
|
||||
// cols 3-5 open the editor for that row (SelectMetaRule, already
|
||||
// covered by MetaTabEditsAndExecutesTheLiveStateMachine).
|
||||
var panel = new MossTankPanel(new FakeHost(new FakeAutomation()));
|
||||
|
||||
panel.SetMetaStateDraft("Idle");
|
||||
panel.SelectMetaAction(nameof(MetaActionKind.ChatCommand));
|
||||
panel.SetMetaActionTextDraft("/mt one");
|
||||
panel.AddMetaRule();
|
||||
panel.SetMetaStateDraft("Hunt");
|
||||
panel.SetMetaActionTextDraft("/mt two");
|
||||
panel.AddMetaRule();
|
||||
|
||||
Assert.Equal(["Idle", "Hunt"], panel.MetaStateColumn);
|
||||
Assert.Contains("/mt one", panel.MetaActionColumn[0], StringComparison.Ordinal);
|
||||
Assert.Contains("/mt two", panel.MetaActionColumn[1], StringComparison.Ordinal);
|
||||
Assert.Equal(["X", "X"], panel.MetaDeleteColumn);
|
||||
Assert.All(panel.MetaMoveUpIcons, id => Assert.Equal(0x060028FCu, id));
|
||||
Assert.All(panel.MetaMoveDownIcons, id => Assert.Equal(0x060028FDu, id));
|
||||
|
||||
panel.MoveMetaRuleDownAt(0); // "Idle" <-> "Hunt"
|
||||
Assert.Equal(["Hunt", "Idle"], panel.MetaStateColumn);
|
||||
panel.MoveMetaRuleUpAt(1); // back
|
||||
Assert.Equal(["Idle", "Hunt"], panel.MetaStateColumn);
|
||||
|
||||
panel.DeleteMetaRuleAt(0); // "Idle"
|
||||
Assert.Equal(["Hunt"], panel.MetaStateColumn);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MetaProfilesAreIndependentDurableDocuments()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue