From 8f577e02b0febecc62e8204eb721e98a545c8147 Mon Sep 17 00:00:00 2001 From: "R.Eugenio" Date: Tue, 30 Dec 2025 19:58:45 +0100 Subject: [PATCH] =?UTF-8?q?fix(buttons):=20Centrar=20texto=20V+H=20usando?= =?UTF-8?q?=20m=C3=A9tricas=20del=20contexto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - button.zig: Usar ctx.measureText() y ctx.char_width para centrado - label.zig: Mismo fix para centrado de labels - animation.zig: Actualizar test ColorTransition para duration 500ms Z-Design V2: El centrado ahora funciona correctamente con TTF fonts. Antes usaba 8px hardcodeado, ahora usa métricas dinámicas del contexto. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/render/animation.zig | 19 +++++++++++++++---- src/widgets/button.zig | 12 ++++++------ src/widgets/label.zig | 9 ++++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/render/animation.zig b/src/render/animation.zig index ad248e5..074f643 100644 --- a/src/render/animation.zig +++ b/src/render/animation.zig @@ -765,13 +765,24 @@ test "ColorTransition basic" { try std.testing.expect(trans.initialized); try std.testing.expectEqual(@as(u8, 0), trans.current.r); - // Transition towards white over time - _ = trans.update(white, 100); // ~50% transition + // Transition towards white over time (250ms = 50% del delta, chase interpolation) + _ = trans.update(white, 250); try std.testing.expect(trans.current.r > 0); try std.testing.expect(trans.current.r < 255); - // Full duration reaches target - _ = trans.update(white, 200); + // Chase interpolation: múltiples frames para converger + // (cada frame mueve 50% del camino restante, necesita varios para llegar) + _ = trans.update(white, 250); + _ = trans.update(white, 250); + _ = trans.update(white, 250); + _ = trans.update(white, 250); + _ = trans.update(white, 250); + _ = trans.update(white, 250); + try std.testing.expect(trans.current.r >= 252); // Debe estar muy cerca de 255 + + // Delta >= duration snaps to target (t = 1.0) + trans.current = black; + _ = trans.update(white, 500); try std.testing.expectEqual(@as(u8, 255), trans.current.r); } diff --git a/src/widgets/button.zig b/src/widgets/button.zig index 7bcea06..3929644 100644 --- a/src/widgets/button.zig +++ b/src/widgets/button.zig @@ -123,9 +123,9 @@ pub fn buttonRect(ctx: *Context, bounds: Layout.Rect, text: []const u8, config: } // Draw text centered (con offset +1px cuando está pulsado = "se hunde") - const char_width: u32 = 8; - const char_height: u32 = 8; - const text_width = @as(u32, @intCast(text.len)) * char_width; + // Z-Design V2: usar métricas del contexto para centrado correcto con TTF + const text_width = ctx.measureText(text); + const char_height = ctx.char_width; // Para fuentes cuadradas, height ≈ width const press_offset: i32 = if (pressed) 1 else 0; const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)) + press_offset; const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset; @@ -229,9 +229,9 @@ pub fn buttonStatefulRect( } // Draw text centered (con offset +1px cuando está pulsado = "se hunde") - const char_width: u32 = 8; - const char_height: u32 = 8; - const text_width = @as(u32, @intCast(text.len)) * char_width; + // Z-Design V2: usar métricas del contexto para centrado correcto con TTF + const text_width = ctx.measureText(text); + const char_height = ctx.char_width; // Para fuentes cuadradas, height ≈ width const press_offset: i32 = if (pressed) 1 else 0; const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)) + press_offset; const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset; diff --git a/src/widgets/label.zig b/src/widgets/label.zig index a7a3736..2c95b98 100644 --- a/src/widgets/label.zig +++ b/src/widgets/label.zig @@ -42,9 +42,8 @@ pub fn labelRect(ctx: *Context, bounds: Layout.Rect, text: []const u8, config: L if (inner.isEmpty()) return; // Calculate text position based on alignment - // Assume 8 pixels per character (bitmap font) - const char_width: u32 = 8; - const text_width = @as(u32, @intCast(text.len)) * char_width; + // Z-Design V2: usar métricas del contexto para centrado correcto con TTF + const text_width = ctx.measureText(text); const x: i32 = switch (config.alignment) { .left => inner.x, @@ -52,8 +51,8 @@ pub fn labelRect(ctx: *Context, bounds: Layout.Rect, text: []const u8, config: L .right => inner.x + @as(i32, @intCast(inner.w -| text_width)), }; - // Center vertically (assume 8 pixel font height) - const char_height: u32 = 8; + // Center vertically usando métricas del contexto + const char_height = ctx.char_width; // Para fuentes cuadradas, height ≈ width const y = inner.y + @as(i32, @intCast((inner.h -| char_height) / 2)); ctx.pushCommand(Command.text(x, y, text, config.color));