From b5073dcbe306af8f803653f3ebd0b90f0be1d725 Mon Sep 17 00:00:00 2001 From: "R.Eugenio" Date: Tue, 30 Dec 2025 15:38:02 +0100 Subject: [PATCH] =?UTF-8?q?feat(button):=20Micro-interacciones=20al=20puls?= =?UTF-8?q?ar=20bot=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acabado Espectacular mejora #5: - Bisel invertido cuando pressed (oscuro arriba = "hundido") - Texto desplazado +1px abajo/derecha cuando pressed - Aplicado a buttonRect y buttonStatefulRect - Botones se sienten "físicos" al pulsarlos 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/widgets/button.zig | 56 +++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/widgets/button.zig b/src/widgets/button.zig index 4b23d49..7bcea06 100644 --- a/src/widgets/button.zig +++ b/src/widgets/button.zig @@ -105,22 +105,30 @@ pub fn buttonRect(ctx: *Context, bounds: Layout.Rect, text: []const u8, config: ctx.pushCommand(Command.rectOutline(bounds.x, bounds.y, bounds.w, bounds.h, theme.border)); } - // Bisel 3D sutil: línea clara arriba, línea oscura abajo (inside) + // Bisel 3D sutil: invierte cuando está pulsado (micro-interacción) if (bounds.h >= 4 and bounds.w >= 4 and !config.disabled) { - // Línea superior interna (highlight) - const bevel_light = bg_color.lighten(15); - ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_light)); - // Línea inferior interna (shadow) - const bevel_dark = bg_color.darken(15); - ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_dark)); + if (pressed) { + // Pressed: bisel invertido (oscuro arriba, claro abajo) = "hundido" + const bevel_dark = bg_color.darken(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_dark)); + const bevel_light = bg_color.lighten(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_light)); + } else { + // Normal: bisel claro arriba, oscuro abajo = "elevado" + const bevel_light = bg_color.lighten(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_light)); + const bevel_dark = bg_color.darken(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_dark)); + } } - // Draw text centered + // 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; - const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)); - const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)); + 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; ctx.pushCommand(Command.text(text_x, text_y, text, fg_color)); @@ -203,22 +211,30 @@ pub fn buttonStatefulRect( ctx.pushCommand(Command.rectOutline(bounds.x, bounds.y, bounds.w, bounds.h, theme.border)); } - // Bisel 3D sutil: línea clara arriba, línea oscura abajo (inside) + // Bisel 3D sutil: invierte cuando está pulsado (micro-interacción) if (bounds.h >= 4 and bounds.w >= 4 and !config.disabled) { - // Línea superior interna (highlight) - const bevel_light = bg_color.lighten(15); - ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_light)); - // Línea inferior interna (shadow) - const bevel_dark = bg_color.darken(15); - ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_dark)); + if (pressed) { + // Pressed: bisel invertido (oscuro arriba, claro abajo) = "hundido" + const bevel_dark = bg_color.darken(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_dark)); + const bevel_light = bg_color.lighten(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_light)); + } else { + // Normal: bisel claro arriba, oscuro abajo = "elevado" + const bevel_light = bg_color.lighten(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + 1, bounds.w - 2, 1, bevel_light)); + const bevel_dark = bg_color.darken(15); + ctx.pushCommand(Command.rect(bounds.x + 1, bounds.y + @as(i32, @intCast(bounds.h)) - 2, bounds.w - 2, 1, bevel_dark)); + } } - // Draw text centered + // 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; - const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)); - const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)); + 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; ctx.pushCommand(Command.text(text_x, text_y, text, fg_color));