diff --git a/src/widgets/advanced_table/advanced_table.zig b/src/widgets/advanced_table/advanced_table.zig index 6175ad2..9ec26aa 100644 --- a/src/widgets/advanced_table/advanced_table.zig +++ b/src/widgets/advanced_table/advanced_table.zig @@ -505,27 +505,18 @@ fn drawScrollbar( const header_h: u32 = if (config.show_headers) config.header_height else 0; const scrollbar_h = bounds.h -| header_h; - const scrollbar_x = bounds.x + @as(i32, @intCast(bounds.w -| scrollbar_w)); - const scrollbar_y = bounds.y + @as(i32, @intCast(header_h)); - - // Background - ctx.pushCommand(Command.rect(scrollbar_x, scrollbar_y, scrollbar_w, scrollbar_h, colors.border)); - - // Thumb - const thumb_ratio = @as(f32, @floatFromInt(visible_rows)) / @as(f32, @floatFromInt(total_rows)); - const thumb_h = @max(20, @as(u32, @intFromFloat(@as(f32, @floatFromInt(scrollbar_h)) * thumb_ratio))); - - const scroll_ratio = @as(f32, @floatFromInt(table_state.nav.scroll_row)) / - @as(f32, @floatFromInt(@max(1, total_rows - visible_rows))); - const thumb_y_offset = @as(u32, @intFromFloat(scroll_ratio * @as(f32, @floatFromInt(scrollbar_h - thumb_h)))); - - ctx.pushCommand(Command.rect( - scrollbar_x + 2, - scrollbar_y + @as(i32, @intCast(thumb_y_offset)), - scrollbar_w - 4, - thumb_h, - colors.header_bg, - )); + // Usar función unificada de table_core + table_core.drawVerticalScrollbar(ctx, .{ + .track_x = bounds.x + @as(i32, @intCast(bounds.w -| scrollbar_w)), + .track_y = bounds.y + @as(i32, @intCast(header_h)), + .width = scrollbar_w, + .height = scrollbar_h, + .visible_count = visible_rows, + .total_count = total_rows, + .scroll_pos = table_state.nav.scroll_row, + .track_color = colors.border, + .thumb_color = colors.header_bg, + }); } fn drawEditingOverlay( diff --git a/src/widgets/table_core.zig b/src/widgets/table_core.zig index d15c000..117bc15 100644 --- a/src/widgets/table_core.zig +++ b/src/widgets/table_core.zig @@ -1332,6 +1332,125 @@ pub fn makeTableDataSource(comptime T: type, impl: *T) TableDataSource { }; } +// ============================================================================= +// Renderizado de Scrollbars (FASE 6) +// ============================================================================= + +/// Parámetros para dibujar scrollbar vertical +pub const VerticalScrollbarParams = struct { + /// Posición X del track + track_x: i32, + /// Posición Y del track + track_y: i32, + /// Ancho del scrollbar + width: u32 = 12, + /// Altura del track + height: u32, + /// Número de elementos visibles + visible_count: usize, + /// Número total de elementos + total_count: usize, + /// Posición actual del scroll (0-based) + scroll_pos: usize, + /// Color del track (fondo) + track_color: Style.Color, + /// Color del thumb (control deslizante) + thumb_color: Style.Color, +}; + +/// Dibuja un scrollbar vertical. +/// Función genérica usada por AdvancedTable y VirtualAdvancedTable. +pub fn drawVerticalScrollbar(ctx: *Context, params: VerticalScrollbarParams) void { + if (params.total_count == 0 or params.visible_count >= params.total_count) return; + + // Track (fondo) + ctx.pushCommand(Command.rect( + params.track_x, + params.track_y, + params.width, + params.height, + params.track_color, + )); + + // Calcular tamaño del thumb + const visible_ratio = @as(f32, @floatFromInt(params.visible_count)) / + @as(f32, @floatFromInt(params.total_count)); + const thumb_h = @max(20, @as(u32, @intFromFloat(visible_ratio * @as(f32, @floatFromInt(params.height))))); + + // Calcular posición del thumb + const max_scroll = params.total_count - params.visible_count; + const scroll_ratio = @as(f32, @floatFromInt(params.scroll_pos)) / + @as(f32, @floatFromInt(@max(1, max_scroll))); + const thumb_y_offset = @as(u32, @intFromFloat(scroll_ratio * @as(f32, @floatFromInt(params.height - thumb_h)))); + + // Thumb (control deslizante) + ctx.pushCommand(Command.rect( + params.track_x + 2, + params.track_y + @as(i32, @intCast(thumb_y_offset)), + params.width - 4, + thumb_h, + params.thumb_color, + )); +} + +/// Parámetros para dibujar scrollbar horizontal +pub const HorizontalScrollbarParams = struct { + /// Posición X del track + track_x: i32, + /// Posición Y del track + track_y: i32, + /// Ancho del track + width: u32, + /// Altura del scrollbar + height: u32 = 12, + /// Ancho visible del contenido + visible_width: u32, + /// Ancho total del contenido + total_width: u32, + /// Posición actual del scroll horizontal (pixels) + scroll_x: i32, + /// Máximo scroll horizontal (pixels) + max_scroll_x: i32, + /// Color del track (fondo) + track_color: Style.Color, + /// Color del thumb (control deslizante) + thumb_color: Style.Color, +}; + +/// Dibuja un scrollbar horizontal. +/// Función genérica usada por VirtualAdvancedTable. +pub fn drawHorizontalScrollbar(ctx: *Context, params: HorizontalScrollbarParams) void { + if (params.max_scroll_x <= 0) return; + + // Track (fondo) + ctx.pushCommand(Command.rect( + params.track_x, + params.track_y, + params.width, + params.height, + params.track_color, + )); + + // Calcular tamaño del thumb + const visible_ratio = @as(f32, @floatFromInt(params.visible_width)) / + @as(f32, @floatFromInt(params.total_width)); + const thumb_w = @max(20, @as(u32, @intFromFloat(visible_ratio * @as(f32, @floatFromInt(params.width))))); + + // Calcular posición del thumb + const scroll_ratio = @as(f32, @floatFromInt(params.scroll_x)) / + @as(f32, @floatFromInt(params.max_scroll_x)); + const thumb_x_offset = @as(u32, @intFromFloat(scroll_ratio * @as(f32, @floatFromInt(params.width - thumb_w)))); + + // Thumb (control deslizante) + ctx.pushCommand(Command.rect( + params.track_x + @as(i32, @intCast(thumb_x_offset)), + params.track_y + 2, + thumb_w, + params.height - 4, + params.thumb_color, + )); +} + // ============================================================================= // Tests // ============================================================================= diff --git a/src/widgets/virtual_advanced_table/virtual_advanced_table.zig b/src/widgets/virtual_advanced_table/virtual_advanced_table.zig index be9e565..f8f113d 100644 --- a/src/widgets/virtual_advanced_table/virtual_advanced_table.zig +++ b/src/widgets/virtual_advanced_table/virtual_advanced_table.zig @@ -914,21 +914,18 @@ fn drawScrollbar( const scrollbar_w: u32 = 12; const content_h = bounds.h -| header_h -| footer_h; - // Scrollbar track - const track_x = bounds.x + @as(i32, @intCast(bounds.w - scrollbar_w)); - const track_y = bounds.y + @as(i32, @intCast(header_h)); - ctx.pushCommand(Command.rect(track_x, track_y, scrollbar_w, content_h, colors.row_alternate)); - - // Thumb size and position - const visible_ratio = @as(f32, @floatFromInt(visible_rows)) / @as(f32, @floatFromInt(total_rows)); - const thumb_h = @max(20, @as(u32, @intFromFloat(visible_ratio * @as(f32, @floatFromInt(content_h))))); - - const scroll_ratio = @as(f32, @floatFromInt(list_state.nav.scroll_row)) / - @as(f32, @floatFromInt(@max(1, total_rows - visible_rows))); - const thumb_y = track_y + @as(i32, @intFromFloat(scroll_ratio * @as(f32, @floatFromInt(content_h - thumb_h)))); - - // Draw thumb - ctx.pushCommand(Command.rect(track_x + 2, thumb_y, scrollbar_w - 4, thumb_h, colors.border)); + // Usar función unificada de table_core + table_core.drawVerticalScrollbar(ctx, .{ + .track_x = bounds.x + @as(i32, @intCast(bounds.w - scrollbar_w)), + .track_y = bounds.y + @as(i32, @intCast(header_h)), + .width = scrollbar_w, + .height = content_h, + .visible_count = visible_rows, + .total_count = total_rows, + .scroll_pos = list_state.nav.scroll_row, + .track_color = colors.row_alternate, + .thumb_color = colors.border, + }); } // ============================================================================= @@ -946,27 +943,22 @@ fn drawScrollbarH( colors: *const VirtualAdvancedTableConfig.Colors, ) void { const scrollbar_v_w: u32 = 12; // Width of vertical scrollbar area - - // Scrollbar track position (at the bottom, above footer) - const track_x = bounds.x; - const track_y = bounds.y + @as(i32, @intCast(bounds.h - footer_h - scrollbar_h)); const track_w = bounds.w -| scrollbar_v_w; + const total_width = available_width + @as(u32, @intCast(@max(0, max_scroll_x))); - // Track background - ctx.pushCommand(Command.rect(track_x, track_y, track_w, scrollbar_h, colors.row_alternate)); - - // Calculate thumb size and position - if (max_scroll_x <= 0) return; - - const total_width = available_width + @as(u32, @intCast(max_scroll_x)); - const visible_ratio = @as(f32, @floatFromInt(available_width)) / @as(f32, @floatFromInt(total_width)); - const thumb_w = @max(20, @as(u32, @intFromFloat(visible_ratio * @as(f32, @floatFromInt(track_w))))); - - const scroll_ratio = @as(f32, @floatFromInt(scroll_offset_x)) / @as(f32, @floatFromInt(max_scroll_x)); - const thumb_x = track_x + @as(i32, @intFromFloat(scroll_ratio * @as(f32, @floatFromInt(track_w - thumb_w)))); - - // Draw thumb - ctx.pushCommand(Command.rect(thumb_x, track_y + 2, thumb_w, scrollbar_h - 4, colors.border)); + // Usar función unificada de table_core + table_core.drawHorizontalScrollbar(ctx, .{ + .track_x = bounds.x, + .track_y = bounds.y + @as(i32, @intCast(bounds.h - footer_h - scrollbar_h)), + .width = track_w, + .height = scrollbar_h, + .visible_width = available_width, + .total_width = total_width, + .scroll_x = scroll_offset_x, + .max_scroll_x = max_scroll_x, + .track_color = colors.row_alternate, + .thumb_color = colors.border, + }); } // =============================================================================