the addon arc: the AddOns folder opens
- benilla loads real 1.12 addons from Interface/AddOns — TOC, XML and Lua through one loader, with per-addon saved variables, Bindings.xml and the lifecycle events addons expect - both AddOns screens are in: the character-select list with per-addon enable state, and the ESC menu's in-game list - the API surface is measured, not guessed — a corpus harness runs hundreds of real 1.12 addons and ranks exactly which globals, templates and verbs they demand - the Lua dialect is the client's own, read off the binary — 5.0 semantics with the 1.12 additions, and UI source files are bytes, not UTF-8 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,11 @@ pub(super) fn tip_mut(model: &mut Model, h: FrameHandle) -> mlua::Result<&mut To
|
||||
/// hover).
|
||||
fn apply_font(d: &mut RegionData, name: &str, fo: Option<&FontObject>) {
|
||||
d.font_object = Some(name.to_string());
|
||||
// The severance mask is left standing — a re-point does NOT restore inheritance in the
|
||||
// reference (see `super::font`'s module doc on the `+0x2c` inheritMask). A freshly created
|
||||
// line has a clean mask anyway; an adopted XML-declared line keeps whatever its own attributes
|
||||
// severed. Either way the line inherits the object LIVE from here: a later
|
||||
// `GameTooltipText:SetFont(…)` re-paints every tooltip line through `font::propagate`.
|
||||
if let Some(f) = fo {
|
||||
d.font_path = f.font.clone();
|
||||
d.font_height = f.height;
|
||||
@@ -263,6 +268,11 @@ fn write_cell(model: &mut Model, rh: crate::widget::RegionHandle, text: &str, co
|
||||
let d = model.region_data.entry(rh).or_default();
|
||||
d.text = Some(text.to_string());
|
||||
d.vertex_color = Some(color);
|
||||
// `AddLine("…", r, g, b)`'s colour is this line's OWN colour, exactly as if Lua had called
|
||||
// `SetTextColor` on the cell — so it must survive a later mutation of the font object the
|
||||
// line inherits ([`super::types::FontExplicit`]). Without the mark, one
|
||||
// `GameTooltipText:SetTextColor(…)` would repaint every red/green line in the tooltip.
|
||||
d.font_explicit.color = true;
|
||||
d.hidden = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ use mlua::{Lua, Table, Value, Variadic};
|
||||
|
||||
use crate::layout::{Anchor, Point};
|
||||
use crate::script::object::{frame_handle_of, frame_wrapper};
|
||||
use crate::script::region::region_handle_of;
|
||||
use crate::script::Model;
|
||||
use crate::widget::{KindState, TOOLTIP_LINE_GAP, TOOLTIP_PAD};
|
||||
|
||||
use super::{
|
||||
append_line, bool_arg, cancel_fade, clear_content, fire_cleared, hide_tooltip, now,
|
||||
@@ -209,6 +211,70 @@ pub(in crate::script) fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
"NumLines",
|
||||
lua.create_function(|lua, this: Table| with_tip(lua, &this, |t| t.num_lines as i64))?,
|
||||
)?;
|
||||
// AddFontStrings(left, right) — adopt two caller-made FontStrings as the next line pair
|
||||
// (`0x530c40`, wow-re `system/ui/scratch/bindings.md`; the parent module's doc already names it
|
||||
// as how the real class grows past its template's 30 declared pairs).
|
||||
//
|
||||
// The scan-tooltip idiom, and the reason this landed with the font-object work rather than
|
||||
// separately: `Gratuity-2.0.lua:56-59` builds its whole 30-line hidden tooltip out of
|
||||
// `tt:CreateFontString()` + `:SetFontObject(GameFontNormal)` + `tt:AddFontStrings(l, r)`, so
|
||||
// publishing the font globals only moved that library's death one line down. Five corpus addons
|
||||
// sit behind those four lines.
|
||||
//
|
||||
// The pair is placed exactly as an engine-grown one (hidden, left/right justified, hung off the
|
||||
// previous line) — the layout pass owns line geometry either way — but the regions' FONTS are
|
||||
// left alone, since choosing them is the entire point of the caller doing this by hand.
|
||||
m.set(
|
||||
"AddFontStrings",
|
||||
lua.create_function(|lua, (this, left, right): (Table, Table, Table)| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let lh = region_handle_of(lua, &left)?;
|
||||
let rh = region_handle_of(lua, &right)?;
|
||||
let mut model = lua.app_data_mut::<Model>().expect("model app_data");
|
||||
let frame_id = model.frame_id(h);
|
||||
let prev_left = match model.arena.frame(h).map(|f| &f.kind_state) {
|
||||
Some(KindState::Tooltip(t)) => t.left_lines.last().copied(),
|
||||
_ => return Err(mlua::Error::runtime("not a GameTooltip")),
|
||||
};
|
||||
let anchor = match prev_left {
|
||||
None => Anchor::new(
|
||||
Point::TopLeft,
|
||||
frame_id,
|
||||
Point::TopLeft,
|
||||
TOOLTIP_PAD,
|
||||
-TOOLTIP_PAD,
|
||||
),
|
||||
Some(prev) => {
|
||||
let prev_id = model.region_id(prev);
|
||||
Anchor::new(
|
||||
Point::TopLeft,
|
||||
prev_id,
|
||||
Point::BottomLeft,
|
||||
0.0,
|
||||
-TOOLTIP_LINE_GAP,
|
||||
)
|
||||
}
|
||||
};
|
||||
let left_id = model.region_id(lh);
|
||||
{
|
||||
let d = model.region_data.entry(lh).or_default();
|
||||
d.hidden = true;
|
||||
d.justify_h = crate::script::JustifyH::Left;
|
||||
d.anchors = vec![anchor];
|
||||
}
|
||||
{
|
||||
let d = model.region_data.entry(rh).or_default();
|
||||
d.hidden = true;
|
||||
d.justify_h = crate::script::JustifyH::Right;
|
||||
d.anchors = vec![Anchor::new(Point::Right, left_id, Point::Right, 0.0, 0.0)];
|
||||
}
|
||||
model.touch_layout(); // two line rows entered the layout graph (decision 0740)
|
||||
let t = tip_mut(&mut model, h)?;
|
||||
t.left_lines.push(lh);
|
||||
t.right_lines.push(rh);
|
||||
Ok(())
|
||||
})?,
|
||||
)?;
|
||||
// SetMinimumWidth(w) — a floor on the auto-sized width (the ref's SetTooltipMoney calls it
|
||||
// with the money row's width so coins never overhang the plate).
|
||||
m.set(
|
||||
|
||||
Reference in New Issue
Block a user