fix(editor-ui): make text_input honor its authored box style
paint_text_field used to paint an unconditional white fill, a default grey border and a 6px radius floor, with near-black value text — a model embedding an input in its own styled wrapper zeroes all of that out (fill:[], stroke thickness 0, cornerRadius 0) and got a glaring white pill with a duplicate icon on a dark themed search bar. No authored fill now paints no box, no authored stroke draws no border, radius is taken as-is, and the value text color adapts to the authored fill's luminance.
This commit is contained in:
parent
4065364f3b
commit
4dcbb57c19
|
|
@ -50,6 +50,11 @@ pub fn widget_text_inset_left(w: &SceneWidget) -> f32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Perceived luminance (0..1) of an opaque scene color.
|
||||
fn color_luminance(c: Color) -> f32 {
|
||||
0.299 * c.r + 0.587 * c.g + 0.114 * c.b
|
||||
}
|
||||
|
||||
/// Paint the static visual for a widget scene node, in world coords.
|
||||
///
|
||||
/// `world_rect` is the node's already-zoom-scaled screen rect; `zoom`
|
||||
|
|
@ -249,14 +254,22 @@ fn paint_radio_group(cx: &mut PaintCx<'_>, w: &SceneWidget, r: Rect, zoom: f32)
|
|||
/// (near-black) or, when empty, the placeholder (muted).
|
||||
fn paint_text_field(cx: &mut PaintCx<'_>, node: &SceneNode, w: &SceneWidget, r: Rect, zoom: f32) {
|
||||
let (x, y, ww, h) = rect_parts(r);
|
||||
let radius = (node.corner_radius * zoom).max(6.0 * zoom);
|
||||
// Respect the AUTHORED box style. A model embedding an input into its own
|
||||
// styled wrapper zeroes everything out (`fill: []`, `stroke.thickness: 0`,
|
||||
// `cornerRadius: 0`) — the old unconditional white fill + grey border +
|
||||
// 6px-radius floor painted a glaring white pill on top of a dark themed
|
||||
// wrapper (measured on a dark dashboard's search bar). No fill → paint no
|
||||
// box; no stroke → draw no border; radius as authored.
|
||||
let radius = node.corner_radius * zoom;
|
||||
if let Some(fill) = node.fill {
|
||||
cx.backend.fill_round_rect(r, radius, fill);
|
||||
} else {
|
||||
cx.backend.fill_round_rect(r, radius, KNOB);
|
||||
}
|
||||
let stroke_w = node.stroke.map(|s| s.width).unwrap_or(1.0) * zoom;
|
||||
cx.backend.stroke_round_rect(r, radius, TRACK_OFF, stroke_w);
|
||||
if let Some(stroke) = node.stroke {
|
||||
if stroke.width > 0.0 {
|
||||
cx.backend
|
||||
.stroke_round_rect(r, radius, stroke.color, stroke.width * zoom);
|
||||
}
|
||||
}
|
||||
|
||||
// Leading / trailing lucide glyphs at the content edges, vertically
|
||||
// centred. The text inset (`widget_text_inset_left`) reserves room
|
||||
|
|
@ -288,6 +301,19 @@ fn paint_text_field(cx: &mut PaintCx<'_>, node: &SceneNode, w: &SceneWidget, r:
|
|||
}
|
||||
|
||||
if let Some((text, color)) = text_field_display_text(w) {
|
||||
// The default value color (#111) assumed the old white box. On an
|
||||
// authored DARK fill — or no box at all (transparent, blending into a
|
||||
// dark wrapper) — flip it light; the muted placeholder grey reads on
|
||||
// both. Only the VALUE color adapts.
|
||||
let color = if color == TEXT_VALUE {
|
||||
match node.fill {
|
||||
Some(bg) if color_luminance(bg) >= 0.5 => TEXT_VALUE,
|
||||
Some(_) => Color::rgb_u8(0xF5, 0xF5, 0xF5),
|
||||
None => Color::rgb_u8(0x9C, 0xA3, 0xAF),
|
||||
}
|
||||
} else {
|
||||
color
|
||||
};
|
||||
let fs = 14.0 * zoom;
|
||||
// text_area top-aligns; single-line inputs vertically centre.
|
||||
let ty = if w.kind == "text_area" {
|
||||
|
|
|
|||
Loading…
Reference in a new issue