# TLabel  (guide pp. 465–467)

Rust module(s): src/widgets/static_text.rs   |   magiblot: include/tvision/dialogs.h / source/tvision/tlabel.cpp

> TLabel has two own fields (`Light`, `Link`), four methods documented by the guide
> (`Init`, `Draw`, `GetPalette`, `HandleEvent`), plus `Load`/`Store`/`shutDown`
> lifecycle methods visible in the header. The magiblot C++ source also exposes
> `shutDown` and the private helper `focusLink`.

| Guide entry | Pg | Bucket | Corr | Rust symbol / mapping | Doc | Notes |
|---|---|---|---|---|---|---|
| `Light` (field) | 465 | PORTED | OK | `Label.light: bool` | 3 | Guide: `Boolean`, read-only. Rust: `light: bool` (private, readable via `is_light()`). Initialised `false`; toggled by focus broadcasts. `is_light()` rustdoc now explains the broadcast mechanism: set `true` on `RECEIVED_FOCUS` from `source == link`, back to `false` on `RELEASED_FOCUS`, and the role-pair it selects. |
| `Link` (field) | 465 | EQUIVALENT | OK | `Label.link: Option<ViewId>` | 3 | Guide: `PView` raw pointer (read-only). Rust: `Option<ViewId>` — resolvable handle, never a raw pointer. Idiomatic mapping: `infoPtr`/raw pointers → `ViewId` (D3, documented in struct doc). `link()` accessor rustdoc now covers: `None` = bare caption (click/hotkey clears event but requests no focus), and that the id is resolved by the event loop so the label never holds a raw reference to its peer. |
| `Init` (constructor) | 466 | PORTED | OK | `tv::Label::new(bounds: Rect, text: impl Into<String>, link: Option<ViewId>) -> Label` | 3 | Guide: calls `TStaticText::Init`, sets `Link = ALink`, sets `Options |= ofPreProcess | ofPostProcess`, sets `EventMask |= evBroadcast`. Rust: sets `pre_process: true`, `post_process: true`; broadcasts are received unconditionally by the event loop (no explicit `evBroadcast` mask needed). `new` rustdoc now explains when to use, the `~`-marked hotkey convention, the `None`-link rationale (bare caption is a valid use case contra the C++ guide warning), and why both pre/post-process phases are required for hotkey delivery to a non-selectable view. |
| `Load` (constructor) | 466 | NOT-PORTED | — | — | — | `TStreamable` / stream persistence dropped project-wide. |
| `Draw` (method) | 466 | PORTED | OK | `tv::Label::draw` (impl `View::draw`) | 3 | magiblot draws a marker glyph at column 0 via `showMarkers`/`specialChars[scOff]`; Rust fills row + draws `~`-marked text at column 1 and leaves column 0 as fill — `showMarkers` decoration intentionally not modeled (commented at `static_text.rs:304`). It IS a visible behavioral difference (column-0 marker never appears) — tracked as a secondary observation in `gap-report.md` §2b — but documented, so OK on the correctness axis. |
| `GetPalette` (method) | 466 | EQUIVALENT | OK | `(Role::LabelNormal, Role::LabelNormalShortcut)` / `(Role::LabelLight, Role::LabelLightShortcut)` via `state_roles()` in `draw` | N/A | C++ returns `CLabel` (4 entries: normal text, selected text, normal shortcut, selected shortcut — indices 7–9 of dialog palette). Rust expands to two explicit `(lo, hi)` role pairs selected by `light`. Known idiomatic mapping: class Palette → `tv::Theme` (D7). `state_roles()` is private; N/A. |
| `HandleEvent` (method) | 466 | PORTED | OK | `tv::Label::handle_event` (impl `View::handle_event`) | 3 | All three C++ diffs are real but functionally equivalent and documented — (2) light-update via `source == link` transition tracking and (3) no inline `drawView` (D9 whole-tree redraw) are noted in the struct doc; (1) the `focusLink` selectable-gate is stated in `focus_link`'s rustdoc (`static_text.rs:377-379`: the gate is applied by the owning group via `focus_descendant`, which silently no-ops on non-selectable). No undocumented divergence remains. |
| `shutDown` (method) | — | NOT-PORTED | — | — | — | magiblot `shutDown` nulls `link` then calls `TStaticText::shutDown`. In Rust, `Option<ViewId>` is naturally nullable (None) and `Drop` handles cleanup; no explicit shutdown needed. The "Known limitation" in the struct doc covers the stale-highlight case when a link is removed at runtime (analogous to the race `shutDown` guards against in C++). |
| `Store` (method) | 466 | NOT-PORTED | — | — | — | `TStreamable` / stream persistence dropped project-wide. |
| `CLabel` palette (4 entries) | 467 | EQUIVALENT | OK | `tv::theme::Role::LabelNormal`, `LabelLight`, `LabelNormalShortcut`, `LabelLightShortcut` | 3 | Guide: `CLabel` maps 4 entries (indices 7–9 of dialog palette): text normal, text selected, shortcut normal, shortcut selected. Rust uses 4 named `Role` variants split into two (lo, hi) pairs for normal and lit states. The mapping is correct; documented in struct doc. The `Role` variants themselves score 2 — they explain what color family they belong to but not how the lit/normal switch drives them. |

## Summary

- PORTED: 4   EQUIVALENT: 3   NOT-PORTED: 3   MISSING: 0   UNSURE: 0
- SUSPECT: 0   |   doc<3 (public): 0   |   → concept: 0
- Notable findings: `Draw` omits the `showMarkers`/`specialChars` column-0 glyph decoration (intentional, commented at `static_text.rs:304`; visible behavioral difference tracked in gap-report §2b). `HandleEvent`'s `focus_link` selectable-guard is delegated to `Group::focus_descendant` — documented in `focus_link`'s rustdoc but not in the method's own entry — a minor clarity gap. The NOT-PORTED count (4) is fully accounted for: stream persistence (2) + `shutDown` + `DataSize`-equivalent absence. `Light`/`is_light()`, `Link`/`link()`, and `Init`/`new` all raised to score 3 this session.
