diff --git a/docs/research/vtank-kb/08-ui-views.md b/docs/research/vtank-kb/08-ui-views.md index 41962188..c442fe37 100644 --- a/docs/research/vtank-kb/08-ui-views.md +++ b/docs/research/vtank-kb/08-ui-views.md @@ -11,7 +11,10 @@ Primary sources: the file; matches the brief's "156 controls"). - `refs/vtank/uTank2.ViewXML.AdvancedOptionsView.xml`, `SelfBuffChoiceView.xml`, `FriendlyLootEditorView.xml` — secondary popup - views. + views (the last is a vestigial resource nothing loads, see §6). +- `refs/vtank/dc.xml` — a fourth secondary view the first draft missed: + 268×300, icon 8241, "Virindi Tank Debug", an `lRefcounts` list view loaded + at `dc.cs:52` (citation pass 2026-09-06). - `refs/vtank/uTank2.Resources.defaultsettings.usd` — VTank's serialized default-settings catalog (setting name / type / default / description / category-bitmask). This is the authoritative cross-reference for what @@ -27,7 +30,10 @@ Primary sources: `ViewProperties.cs`, `ACImage.cs` — window chrome, icon-id resolution, `StoredViewInfo` persistence. - `refs/vvs/decompiled/VirindiViewService.Themes/Float_Theme.cs` — default - theme pixel constants (`TabHeight`, `SliderNubWidth`, etc.). + theme pixel constants (`TabHeight`, `SliderNubWidth`, etc.) — the default + because `HudViewDrawStyle.a()` registers it at index 1 and the registry + value `HKLM\SOFTWARE\Decal\Services\{DBAC9286-…}\Theme` defaults to 1 + (`HudViewDrawStyle.cs:118-167`; `Theme2` is a string-name override). - `refs/vtank/decompiled/uTank2/PluginCore.cs` — the class that loads `mainView.xml`, casts every named control to a typed wrapper interface, and wires `Click`/`Change`/`Change_Old` handlers. **Heavily obfuscated** @@ -157,14 +163,14 @@ by both the initializer and every change handler: | slOtherStam | Slider | 96,128,144,16 | "Restam others at:" | `Recharge-Helper-Stam` | `:4573` | | slOtherMana | Slider | 96,144,144,16 | "Infuse others at:" | `Recharge-Helper-Mana` | `:4574` | -Each slider has a matching `min="0" max="100"` (`mainView.xml:81-83` etc.) +Each slider has a matching `minimum="0" maximum="100"` (`mainView.xml:81-83` etc.) percent readout label (`lblVitals_H_Self`, `_S_Self`, `_M_Self`, `_H_Idle`, `_S_Idle`, `_M_Idle`, `_H_Help`, `_S_Help`, `_M_Help` — 9 `StaticText` controls at 248,0 / 248,16 / … / 248,144, each `80×16`, default text `"0%"`) updated from the slider's `.Position` on every `Change` (e.g. `cx.Text = co.Position + "%";` — `PluginCore.cs:4560-4561`). Plus the 9 "Heal at:"/"Restam at:"/… `Label1`/`Label2`/`Label3`/`Label11`/`Label21`/ -`Label31`/`Label111`/`Label211`/`Label311` captions (8×16 each). +`Label31`/`Label111`/`Label211`/`Label311` captions (all at left=8, 80×16). ### Tab: Monsters (26 controls: 25 leaf + 1 container, **23 list columns**) @@ -276,15 +282,15 @@ Data tables (confirmed by name): `ExtraBuffSpells` and | cmdNewRecall | PushButton | 376,60,88,16 | "Add Recall" | | | cmbRecallType | Choice | 470,60,120,16 | selected=0 | 27 options: Primary/Secondary/LS/LS Sending/Portal/Aphus/Sanctuary/Caul/GW/Aerlinthe/Mt. Lethe/Ulgrim's/Bur/PtOIA/Graveyard/Colosseum/Fac. Hub/Gear K. Camp/Neftet/Candeth/FacHub/Rynthid/VR Rocks/VR Tree/Soc. CH/Soc. RB/Soc. EW (note: "Fac. Hub" and "FacHub" both present — another authoring duplicate) | | cmdNewWaypointPause | PushButton | 376,82,88,16 | "Add Pause" | | -| txtPauseWaypointTime | Edit | 470,82,68,16 | "5" | only Edit control in the whole file with a non-empty default `text` | +| txtPauseWaypointTime | Edit | 470,82,68,16 | "5" | one of only two Edit controls in the file with a non-empty default `text` (the other is `txtChatWaypoint`, `"/ls"`) | | Label52 | StaticText | 543,82,50,16 | "seconds" | | | cmdNewWaypointChat | PushButton | 376,104,88,16 | "Add Chat" | | | txtChatWaypoint | Edit | 470,104,120,16 | "/ls" | | The `100673789`/`100673788`/`100667895` background image ids assigned to the three nav image-buttons decode (subtracting VVS's `0x6000000` DAT -block prefix) to portal.dat indices `0x0A47FD`, `0x0A47FC`, -`0x0A2BF7` — retail DAT icon glyphs, not synthesized art. +block prefix) to portal.dat indices `0x28FD`, `0x28FC`, `0x11F7` (full ids `0x060028FD`, +`0x060028FC`, `0x060011F7`; the first draft mis-decoded the decimals) — retail DAT icon glyphs, not synthesized art. ### Tab: Meta (5 controls, 6 list columns) @@ -346,9 +352,11 @@ Two-tab `Notebook1`: **The "Rules" page is a stub in retail VTank itself** — its own XML literally reads "This page not yet completed." (`FriendlyLootEditorView.xml:10`). Only the "Names" (name-match) editor is functional. This is the one place -where our `mosstank.xml`'s loot editor (§5) is **more complete than VTank's -own shipped UI**, since it implements a full rule list with action/priority -editing that VTank never finished. +where our `mosstank.xml`'s loot editor (§5) is **more complete than this +resource** — but note (§6) that VTank never loads `FriendlyLootEditorView.xml`; +the editor a VTank user actually sees belongs to the external loot plugin +(VTClassic), outside `refs/vtank/`, so this is not a comparison against +what ships. --- @@ -356,13 +364,13 @@ editing that VTank never finished. | VVS control | Key semantics | Source | |---|---|---| -| `HudList` | Vertically scrolling grid; every row has the same ordered column set (`cColInfo`: `ControlType`/`Width`/`Name`), each cell is a live child control (`HudStaticText`/`HudCheckBox`/`HudPictureBox`/`HudButton`/`HudTextBox`/nested `HudList`/`HudFixedLayout`/`HudTabView`). **No built-in header row** — the header glyphs seen in `mainView.xml` (F/B/G/I/…) are ordinary `StaticText` controls placed manually above the list at `top=0`, with the list itself starting at `top=16`. Row height defaults to `ControlHeight=16px`; `Padding=1px` (vertical), `WPadding=7px` (horizontal gap between columns), `WPaddingOuter=3px` (left/right list margin). A `0`-width text/button/edit/list/fixedlayout/notebook column auto-sizes: all such columns in one list share the remaining width equally after fixed-width and icon (fixed at declared width) and check (fixed 13px) columns are subtracted. Selection is not built in as a highlighted-row concept — `Click` is a **per-cell** event `delClickedControl(sender, row, col)`, fired from `MouseUp` when the press and release land in the same cell; callers implement "selected row" state themselves. Scrolling is a `HudVScrollBar` child, width from the theme's `VScrollBarButtonSize` (16px in `Float_Theme`), driven by mouse-wheel or drag. | `HudList.cs:14-609` (whole file); `Float_Theme.cs:58` | +| `HudList` | Vertically scrolling grid; every row has the same ordered column set (`cColInfo`: `ControlType`/`Width`/`Name`), each cell is a live child control (`HudStaticText`/`HudCheckBox`/`HudPictureBox`/`HudButton`/`HudTextBox`/nested `HudList`/`HudFixedLayout`/`HudTabView`). **No built-in header row** — the header glyphs seen in `mainView.xml` (F/B/G/I/…) are ordinary `StaticText` controls placed manually above the list at `top=0`, with the list itself starting at `top=16`. Row height defaults to `ControlHeight=16px`; `Padding=1px` (vertical), `WPadding=7px` (horizontal gap between columns), `WPaddingOuter=3px` (left/right list margin). A `0`-width text/button/edit/list/fixedlayout/notebook column auto-sizes: all such columns in one list share the remaining width equally after fixed-width and icon (fixed at declared width) and check (fixed 13px) columns are subtracted. Selection is not built in as a highlighted-row concept — `Click` is a **per-cell** event `delClickedControl(sender, row, col)`, fired from `MouseUp` for the cell containing the **press** point (`HudList.cs:482` tests `orig` only — the release point is never checked against the cell, so press-in-A/release-in-B still reports cell A); callers implement "selected row" state themselves. Scrolling is a `HudVScrollBar` child, width from the theme's `VScrollBarButtonSize` (16px in `Float_Theme`), driven by mouse-wheel or drag. | `HudList.cs:14-609` (whole file); `Float_Theme.cs:58` | | `HudList` column mapping (from progid) | `IconColumn`→`HudPictureBox` (default 16px), `TextColumn`→`HudStaticText`, `CheckColumn`→`HudCheckBox` (fixed 13px regardless of declared width), plus (less commonly used) `FixedLayout`→`HudFixedLayout`, `Notebook`→`HudTabView`, `PushButton`→`HudButton`, `Checkbox`→`HudCheckBox`, `Edit`→`HudTextBox`, `StaticText`→`HudStaticText`, `List`→`HudList` (nested) | `Decal3XMLParser.cs:257-424` | | `HudCombo` (`Choice`) | A dropdown: closed state shows the selected item's control (usually a `HudStaticText`) in a `ComboBackground_Unselected` box with a themed up/down arrow (16px square, `arrowrect`). Opening spawns a **separate top-level popup surface** (`DxHud`, its own device/texture, `+1` z-priority above the owning view) sized to `min(item count, 10) * 16px` rows (`m_j=10` fixed max-visible, `dropdownamt`), with its own `HudVScrollBar` if the item count exceeds 10. Selecting an item raises `Change`; closing happens on any click outside the drop rect, or via `FireLostFocus`. `AddItem`/`InsertItem` accept either a raw string (wrapped in a `HudStaticText`) or an arbitrary `HudControl` + opaque tag object — so combo items are not restricted to plain text. | `HudCombo.cs:15-744` | | `HudTabView` (`Notebook`) | Tab strip height is themed (`TabHeight=16px` in `Float_Theme`). Each tab's width auto-sizes to its caption's rendered text width (capped at 280px) plus themed left/right border sizes (`TabLeftBorder_Size`/`TabRightBorder_Size`, both `0` in `Float_Theme`) plus a themed horizontal padding (`TabTextHPadding=6px`). Selected vs. deselected tabs use **separate font options** (`TabTextFontName/Size/Weight/Color/Shadow*_Selected` vs `_Deselected`). Mouse wheel over the tab strip cycles tabs; over the body it's forwarded to the active child. Only one tab's content control is ever `CanDraw=true` at a time — switching tabs disposes no state, it just flips visibility/draw flags on the existing child controls (so per-tab state survives switching, which matters for MossTank/acdream parity: switching tabs must not reset in-progress edits). | `HudTabView.cs:12-455`; `Float_Theme.cs:91-93` | | `HudHSlider` (`Slider`) | Backed by `LinearPositionControl` (`Min`/`Max`/`Position`, `Changed(min,max,pos)` event, `Percentage` helper = `100*Position/(Max-Min)`). Draws as a 3px-tall two-tone bar (`SliderBarOuter`/`SliderBarInner`) plus a themed nub (`SliderNubWidth=7px`, `SliderNubHeight=12px` in `Float_Theme`) whose X position is `GetPositionProportionalPixels`. Drag-to-set, click-to-jump-to-position, and mouse-wheel (±1 unit per notch, accumulator-smoothed via `v.a`) are all supported; `UserChangeable=false` disables all three without hiding the control. | `HudHSlider.cs:9-131`, `LinearPositionControl.cs:6-186`, `Float_Theme.cs:54-55` | | `HudTextBox` (`Edit`) | Single-line text input with a blinking caret (500ms toggle via an internal timer `r`), left/right/Home/End/Backspace/Delete/Ctrl+V (paste from the Windows clipboard) key handling, and an optional numeric-only input mode (`eTextBoxInputType.Int_Numeric`/`Float_Numeric`) that rejects any edit that doesn't `TryParse`. Background is themed (`TextBoxBackground`/`_MouseOver`) with a 1px `ButtonHighlight`/`ButtonShadow` bevel. **The `imageportalsrc="4726"` attribute present on every `Edit` control in `mainView.xml` is never read by `Decal3XMLParser.cs`'s `"decalcontrols.edit"` case** — only `text` is consumed; the parser never sets `HudPictureBox.Image` for an Edit control, and a repo-wide grep of VTank's own source found no other code path assigning it either. This is a **dead/vestigial XML attribute**, likely copy-pasted from an older Decal 3.0 view-XML dialect; acdream's markup does not need to reproduce it. | `HudTextBox.cs:11-417` (esp. `RawKeyAction`/`KeyDown` `260-350`, `DrawNow` `371-416`); parser evidence `Decal3XMLParser.cs:205-212`; dead-attribute confirmed by grep across `refs/vtank/decompiled/` (only hits are the literal XML strings and one string-builder-generated XML fragment in `h8.cs:104`) | -| `HudButton` (`PushButton`) vs. `HudImageButton` (`Button`) | **These are two different progids mapping to two different classes.** `PushButton` → `HudButton`: text-only push button, themed `ButtonBackground`/`_MouseOver`/`_Down`/`_Down_MouseOver` fills with a 1px bevel, optional `ImagePressed`/`OverlayImage` override. `Button` → `HudImageButton`: an image-only button taking `iconlibrary` (a portal-dat "icon library" grouping id), `background`/`icon`/`pressedicon` (each resolved via `ACImage.FromIconLibrary` unless the numeric value already looks like a raw image id, per `global::b.d`), and `matte` (a background color override, with `Color.Cyan` specifically mapped to fully transparent). Neither VTank's `mainView.xml` uses `Button` directly (only the three Route-tab nav arrows use it, via VTank's own C# code assigning `.Background` post-construction rather than XML `icon=`/`background=` attributes — see the Route-tab table above) nor does `AdvancedOptionsView.xml`/`FriendlyLootEditorView.xml`. | `HudButton.cs:9-226`; parser `Decal3XMLParser.cs:157-195` (`PushButton`), `:165-195` (`Button`) | +| `HudButton` (`PushButton`) vs. `HudImageButton` (`Button`) | **These are two different progids mapping to two different classes.** `PushButton` → `HudButton`: text-only push button, themed `ButtonBackground`/`_MouseOver`/`_Down`/`_Down_MouseOver` fills with a 1px bevel, optional `ImagePressed`/`OverlayImage` override. `Button` → `HudImageButton`: an image-only button taking `iconlibrary` (a portal-dat "icon library" grouping id), `background`/`icon`/`pressedicon` (each resolved via `ACImage.FromIconLibrary` unless the numeric value already looks like a raw image id, per `global::b.d`), and `matte` (a background color override, with `Color.Cyan` specifically mapped to fully transparent). Neither VTank's `mainView.xml` uses `Button` directly (only the three Route-tab nav arrows use it, via VTank's own C# code assigning `.Background` post-construction rather than XML `icon=`/`background=` attributes — see the Route-tab table above) nor does `AdvancedOptionsView.xml`/`FriendlyLootEditorView.xml`. | `HudButton.cs:9-226`; parser `Decal3XMLParser.cs:157-164` (`PushButton`), `:165-193` (`Button`) | | `HudCheckBox` (`Checkbox`) | Fixed **13×13px** glyph box regardless of the declared control width/height (only the optional trailing label text uses the extra width). Three visual states: unchecked/checked (each with a `_MouseOver` variant) plus a transient "partial" press-feedback state while the mouse is down inside the box. `UserChangeable=false` disables toggling without hiding it. Label text (when present) starts at a fixed `+17px` offset from the left edge. | `HudCheckBox.cs:10-267` | | `HudControl` (base) | Only left-button `MouseDown`/`MouseUp`/`MouseMove`/`MouseWheel` are wired; there is no right-click or double-click concept anywhere in the base class or in any of the concrete controls surveyed. A `Hit` event fires once per press-then-release-inside-the-same-control. Focus is a single static `HudView.FocusControl` — only one control across the *entire* VVS runtime (all views, all plugins) can have keyboard focus at a time. | `HudControl.cs:13-712` | @@ -380,7 +388,7 @@ editing that VTank never finished. | `StaticText` | `