diff --git a/crates/benilla-app/src/ui_script/extract/text.rs b/crates/benilla-app/src/ui_script/extract/text.rs index acfbf53b..00d95d38 100644 --- a/crates/benilla-app/src/ui_script/extract/text.rs +++ b/crates/benilla-app/src/ui_script/extract/text.rs @@ -107,8 +107,13 @@ pub(super) fn emit( let (x0, top, cell_h) = crate::ui_text::line_origin(&mut atlas.lock(), drawn, host.rect, draw_justify, spec); ebox_geom = Some((x0, top, cell_h)); - text_clip = Some(host.clip.map_or(host.rect, |c| c.intersect(host.rect))); + // A single-line box shows only what fits its text region (`0x77d858` sets the window's + // substring), so the whole string drawn here is cut at the region. A multi-line region is + // only as tall as its text, and the reference clips neither it nor the caret texture + // (`E+0x368`), which after a trailing break stands a line below it: only a ScrollFrame's + // clip applies. if !ui.multi_line { + text_clip = Some(host.clip.map_or(host.rect, |c| c.intersect(host.rect))); draw_text = drawn; draw_rect = Rect::new(x0, host.rect.min.y, x0 + 100_000.0, host.rect.max.y); draw_justify = crate::ui_text::Justify { @@ -419,3 +424,133 @@ mod tests { assert_eq!(gaps, [1, 2].into_iter().collect()); } } + +/// The focused multi-line box's caret through the whole UI pass, on the client faces: the region +/// that draws its text is only as tall as that text, and the caret must not be cut to it. +#[cfg(test)] +mod caret_tests { + use bevy::prelude::*; + use bevy::window::PrimaryWindow; + + use benilla_ui::script::UiScript; + + use super::super::{paint_script, tick_script, UiQuad, UiQuads}; + use crate::portrait::PortraitImages; + use crate::ui_text::UiFontAtlas; + + /// A focused 270-wide multi-line box at 14 px on a 1024×768 window (`s = 1`), holding `text`. + fn app_with_focused_box(text: &str) -> App { + let script = UiScript::new().unwrap(); + script + .run(&format!( + r#" + E = CreateFrame("EditBox", "E") + E:SetPoint("TOPLEFT", 100, -100) + E:SetWidth(270); E:SetHeight(200) + E:SetFont("Fonts\\FRIZQT__.TTF", 14) + E:SetMultiLine(true) + E:SetFocus() + E:SetText({text:?}) + "# + )) + .unwrap(); + let mut app = App::new(); + app.insert_non_send_resource(script); + app.insert_resource(UiFontAtlas::for_test(1.0).expect("the client faces open")); + app.init_resource::(); + app.init_resource::(); + app.init_resource::>(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::