From f7687257086d464cbf33fc26154c007f0debe2e1 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 7 Aug 2026 16:02:39 +0700 Subject: [PATCH] a chat link is one token now, and tooltips print true costs - a chat link edits as one atomic token: the caret can't land inside it, its colors survive, one keypress removes it whole - spell tooltips print the resolved mana cost through the reference's own table walk, and the "% of base mana" line dies - the spirit healer's confirm comes back after a cancel and wears its warning icon - the dressing room's pane is a live animating model, and a tried-on bow lands in the hand Co-Authored-By: Claude Fable 5 --- .../benilla-app/assets/ui/CharacterFrame.xml | 34 +- crates/benilla-app/assets/ui/DressUpFrame.xml | 18 +- crates/benilla-app/assets/ui/InspectFrame.xml | 6 +- .../assets/ui/PetPaperDollFrame.xml | 13 +- crates/benilla-app/assets/ui/SkillFrame.xml | 7 +- crates/benilla-app/assets/ui/UiPanels.xml | 32 +- crates/benilla-app/src/capture/probes.rs | 11 + crates/benilla-app/src/death.rs | 25 +- .../src/entities/attach/preview.rs | 108 +- crates/benilla-app/src/interact.rs | 941 ------------ crates/benilla-app/src/interact/inspect.rs | 380 +++++ crates/benilla-app/src/interact/journal.rs | 2 +- crates/benilla-app/src/interact/mod.rs | 174 +++ crates/benilla-app/src/interact/pick.rs | 546 +++++++ crates/benilla-app/src/net/apply/death.rs | 6 +- crates/benilla-app/src/portrait/dressup.rs | 40 +- crates/benilla-app/src/portrait/framing.rs | 174 ++- crates/benilla-app/src/portrait/glue_booth.rs | 6 +- crates/benilla-app/src/portrait/mod.rs | 115 +- crates/benilla-app/src/portrait/test_bake.rs | 3 +- crates/benilla-app/src/target/cursor_mode.rs | 6 +- crates/benilla-app/src/target/hover.rs | 110 +- crates/benilla-app/src/ui_action/usable.rs | 45 +- crates/benilla-app/src/ui_dressup.rs | 218 ++- crates/benilla-app/src/ui_pet/mod.rs | 14 +- crates/benilla-app/src/ui_pet_stats.rs | 101 +- .../src/ui_script/character_tests.rs | 103 ++ .../benilla-app/src/ui_script/death_tests.rs | 56 + .../benilla-app/src/ui_script/extract/mod.rs | 33 +- .../benilla-app/src/ui_script/extract/text.rs | 13 +- .../src/ui_script/pet_paperdoll_tests.rs | 45 + crates/benilla-app/src/ui_text/layout/mod.rs | 41 +- crates/benilla-app/src/ui_text/layout/wrap.rs | 313 ++-- crates/benilla-app/src/ui_text/markup.rs | 330 +++-- .../src/{ui_tooltip.rs => ui_tooltip/mod.rs} | 356 +---- crates/benilla-app/src/ui_tooltip/tests.rs | 346 +++++ .../src/spells/catalog_tests.rs | 103 ++ crates/benilla-formats/src/spells/display.rs | 31 +- crates/benilla-formats/src/spells/mod.rs | 13 + crates/benilla-ui/src/lib.rs | 5 +- crates/benilla-ui/src/markup.rs | 1308 +++++++++++++++++ crates/benilla-ui/src/script/editbox.rs | 7 +- .../benilla-ui/src/script/editbox/methods.rs | 8 +- crates/benilla-ui/src/script/editbox/tests.rs | 127 ++ crates/benilla-ui/src/script/tooltip_spell.rs | 8 +- crates/benilla-ui/src/widget/kinds/editbox.rs | 154 +- 46 files changed, 4840 insertions(+), 1695 deletions(-) delete mode 100644 crates/benilla-app/src/interact.rs create mode 100644 crates/benilla-app/src/interact/inspect.rs create mode 100644 crates/benilla-app/src/interact/mod.rs create mode 100644 crates/benilla-app/src/interact/pick.rs rename crates/benilla-app/src/{ui_tooltip.rs => ui_tooltip/mod.rs} (70%) create mode 100644 crates/benilla-app/src/ui_tooltip/tests.rs create mode 100644 crates/benilla-ui/src/markup.rs diff --git a/crates/benilla-app/assets/ui/CharacterFrame.xml b/crates/benilla-app/assets/ui/CharacterFrame.xml index 224853a4..22d45eda 100644 --- a/crates/benilla-app/assets/ui/CharacterFrame.xml +++ b/crates/benilla-app/assets/ui/CharacterFrame.xml @@ -276,6 +276,17 @@ return end local frame = getglobal("BenillaCharacterFrame") + -- ref CharacterFrame.lua:11, and the line whose absence desynced this window: the tab + -- row is selected HERE, from the page's own id, on EVERY path — including the one that + -- closes the window. Having it only on the tab-button OnClick meant a KEYBIND + -- (`C`/`SHIFT-P`, which call straight in here) switched the page and left the row + -- selecting the old tab; clicking that old tab then took the "already visible" branch + -- and shut the window instead of switching back (director, 2026-08-06). The id is the + -- page's own `id=` attribute — the loader really does apply it (loader/geometry.rs + -- SetID) — and `character_tests.rs` pins every page's id against its slot in + -- BENILLA_CHARACTERFRAME_SUBFRAMES, which is what keeps the two in step the day + -- Reputation lands between them. + PanelTemplates_SetTab(frame, subFrame:GetID()) if frame:IsVisible() then if subFrame:IsVisible() then HideUIPanel(frame) @@ -292,15 +303,14 @@ -- The tab row's own OnClick (ref CharacterFrameTab_OnClick, l.35-48), now id-based (decision -- 0437 phase 4 grows the row to 2) — the MerchantFrame.xml Merchant/Buyback pair's own shape -- for a >1-tab window: `id` indexes BOTH the tab button and BENILLA_CHARACTERFRAME_SUBFRAMES - -- 1:1. PanelTemplates_SetTab visually selects the clicked tab (the ref's own - -- PanelTemplates_SetTab(this, subFrame:GetID()) call, dropped by the original phase-1a - -- single-tab comment above — restored now that a second tab exists to disagree with the - -- first). l.47's trailing PlaySound is the ref's OWN redundant second igCharacterInfoTab — - -- ToggleCharacter already plays it on the "switch to this tab" path, so this second call only - -- matters when the window is ALREADY open on this same tab, i.e. the HideUIPanel branch — - -- transcribed verbatim rather than "fixed" since it's the ref's own behavior, not a bug of ours. + -- 1:1. It does NOT select the tab itself — the ref's own tab OnClick doesn't either, because + -- ToggleCharacter is the single place that does it (above), so the click path and the + -- keybind path cannot disagree. l.47's trailing PlaySound is the ref's OWN redundant second + -- igCharacterInfoTab — ToggleCharacter already plays it on the "switch to this tab" path, so + -- this second call only matters when the window is ALREADY open on this same tab, i.e. the + -- HideUIPanel branch — transcribed verbatim rather than "fixed" since it's the ref's own + -- behavior, not a bug of ours. function BenillaCharacterFrameTab_OnClick(id) - PanelTemplates_SetTab(getglobal("BenillaCharacterFrame"), id) ToggleCharacter(BENILLA_CHARACTERFRAME_SUBFRAMES[id]) PlaySound("igCharacterInfoTab") end @@ -1369,7 +1379,7 @@ exactly fill the parent instead of the ref's setAllPoints="true" — the same effect (see this file's header: frame-level setAllPoints was a no-op when this was written and is wired now; the explicit size is equivalent, so it stays). --> - + @@ -1409,7 +1419,11 @@ - + + diff --git a/crates/benilla-app/assets/ui/DressUpFrame.xml b/crates/benilla-app/assets/ui/DressUpFrame.xml index fe4d9973..27f0af84 100644 --- a/crates/benilla-app/assets/ui/DressUpFrame.xml +++ b/crates/benilla-app/assets/ui/DressUpFrame.xml @@ -24,9 +24,13 @@ player" and "put the player's own gear back on it" are the same effect. - The ref's `scale="2.0"` on the model widget is a 3D-widget zoom with no meaning for a baked pane — the booth frames the body from its own bounds (`framing::body_frame`), the - same law the paper doll is framed by. - - The pane animates in the ref (a live widget playing Stand); ours is the frozen bake the - paper doll beside it is (decision 0822 — the same look call, taken the same way). + same law the paper doll is framed by. The bake is framed at THIS pane's 316×351 aspect, + not square, or the UI's stretch would leave every character 11% too tall (decision 1069). + - The pane ANIMATES, as the ref's live widget does — Stand looping (decision 1069; the look + call 0822 §5 left open, made by the director). Its booth is TRANSPARENT for the same + reason a widget is: the dark room behind the character is the `DressUpBackground-` + art below, and Reset/Close sit on that art *inside* this pane's rect (both anchor sets + transcribed byte-identically from the ref, which is why the overlap is the ref's too). -->