Compare commits
3 commits
f17104c08b
...
63daca0827
| Author | SHA1 | Date | |
|---|---|---|---|
| 63daca0827 | |||
| 4cdc8c44e2 | |||
| cc7c2a00c6 |
6 changed files with 56 additions and 65 deletions
|
|
@ -728,6 +728,9 @@ pub const Context = struct {
|
||||||
animating: bool,
|
animating: bool,
|
||||||
/// False if panel was suppressed - caller should return immediately
|
/// False if panel was suppressed - caller should return immediately
|
||||||
should_draw: bool,
|
should_draw: bool,
|
||||||
|
/// The actual background color being drawn (for table mimetism)
|
||||||
|
/// Tables should use this as row_normal to blend seamlessly with panel
|
||||||
|
derived_bg: Style.Color,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Draw a complete panel frame with focus transition and 3D effects.
|
/// Draw a complete panel frame with focus transition and 3D effects.
|
||||||
|
|
@ -832,7 +835,12 @@ pub const Context = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// should_draw = false indica que el panel debe saltar operaciones costosas (BD, widgets)
|
// should_draw = false indica que el panel debe saltar operaciones costosas (BD, widgets)
|
||||||
return .{ .animating = animating, .should_draw = !burst_suppressed };
|
// derived_bg = color actual del fondo (para mimetismo de tablas)
|
||||||
|
return .{
|
||||||
|
.animating = animating,
|
||||||
|
.should_draw = !burst_suppressed,
|
||||||
|
.derived_bg = transition.current,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the context
|
/// Resize the context
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,6 @@
|
||||||
// Types - Enums, structs, constantes
|
// Types - Enums, structs, constantes
|
||||||
pub const types = @import("types.zig");
|
pub const types = @import("types.zig");
|
||||||
// Re-exports de types
|
// Re-exports de types
|
||||||
pub const table_tips = types.table_tips;
|
|
||||||
pub const TIP_ROTATION_FRAMES = types.TIP_ROTATION_FRAMES;
|
|
||||||
pub const MAX_EDIT_BUFFER_SIZE = types.MAX_EDIT_BUFFER_SIZE;
|
pub const MAX_EDIT_BUFFER_SIZE = types.MAX_EDIT_BUFFER_SIZE;
|
||||||
pub const MAX_PENDING_COLUMNS = types.MAX_PENDING_COLUMNS;
|
pub const MAX_PENDING_COLUMNS = types.MAX_PENDING_COLUMNS;
|
||||||
pub const MAX_CELL_VALUE_LEN = types.MAX_CELL_VALUE_LEN;
|
pub const MAX_CELL_VALUE_LEN = types.MAX_CELL_VALUE_LEN;
|
||||||
|
|
|
||||||
|
|
@ -4,31 +4,10 @@
|
||||||
//! - Enums de estado y dirección
|
//! - Enums de estado y dirección
|
||||||
//! - Structs de configuración y colores
|
//! - Structs de configuración y colores
|
||||||
//! - Constantes globales
|
//! - Constantes globales
|
||||||
//! - Tips proactivos
|
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Style = @import("../../core/style.zig");
|
const Style = @import("../../core/style.zig");
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Tips Proactivos (FASE I)
|
|
||||||
// =============================================================================
|
|
||||||
|
|
||||||
/// Tips de atajos de teclado para mostrar en StatusLine
|
|
||||||
/// Rotan cada ~10 segundos para enseñar atajos al usuario
|
|
||||||
pub const table_tips = [_][]const u8{
|
|
||||||
"Tip: F2 o Space para editar celda",
|
|
||||||
"Tip: Tab/Shift+Tab navega entre celdas",
|
|
||||||
"Tip: Ctrl+N crea nuevo registro",
|
|
||||||
"Tip: Ctrl+Delete o Ctrl+B borra registro",
|
|
||||||
"Tip: Ctrl+Shift+1..9 ordena por columna",
|
|
||||||
"Tip: Ctrl+Home/End va al inicio/fin",
|
|
||||||
"Tip: Enter confirma y baja, Escape cancela",
|
|
||||||
"Tip: Al editar, tecla directa reemplaza todo",
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Frames entre rotación de tips (~10s @ 60fps)
|
|
||||||
pub const TIP_ROTATION_FRAMES: u32 = 600;
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Constantes globales
|
// Constantes globales
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
|
||||||
|
|
@ -247,9 +247,53 @@ pub fn tabsRect(
|
||||||
total_width += width;
|
total_width += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw tabs
|
// ==========================================================================
|
||||||
|
// PASS 1: Process input events BEFORE drawing (fix visual lag on click)
|
||||||
|
// ==========================================================================
|
||||||
var tab_x = bar_rect.x;
|
var tab_x = bar_rect.x;
|
||||||
|
|
||||||
|
for (tab_list, 0..) |tab, i| {
|
||||||
|
if (i >= tab_widths.len) break;
|
||||||
|
|
||||||
|
const tab_width = tab_widths[i];
|
||||||
|
const tab_rect = Layout.Rect.init(tab_x, bar_rect.y, tab_width, config.tab_height);
|
||||||
|
const is_hovered_input = tab_rect.contains(mouse.x, mouse.y) and !tab.disabled;
|
||||||
|
|
||||||
|
// Handle close button click (pass 1)
|
||||||
|
if (config.show_close and tab.closable) {
|
||||||
|
const close_x = tab_x + @as(i32, @intCast(tab_width - config.close_size - 8));
|
||||||
|
const close_y = bar_rect.y + @as(i32, @intCast((config.tab_height - config.close_size) / 2));
|
||||||
|
const close_rect = Layout.Rect.init(close_x, close_y, config.close_size, config.close_size);
|
||||||
|
const close_hovered = close_rect.contains(mouse.x, mouse.y);
|
||||||
|
|
||||||
|
if (close_hovered) {
|
||||||
|
state.close_hovered = @intCast(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse_pressed and close_hovered) {
|
||||||
|
result.closed = true;
|
||||||
|
result.closed_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle tab click (pass 1) - update state BEFORE drawing
|
||||||
|
if (mouse_pressed and is_hovered_input and state.close_hovered != @as(i32, @intCast(i))) {
|
||||||
|
ctx.requestFocus(widget_id);
|
||||||
|
if (state.selected != i) {
|
||||||
|
state.selected = i;
|
||||||
|
result.changed = true;
|
||||||
|
result.selected = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tab_x += @as(i32, @intCast(tab_width));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================================================
|
||||||
|
// PASS 2: Draw tabs with UPDATED state
|
||||||
|
// ==========================================================================
|
||||||
|
tab_x = bar_rect.x;
|
||||||
|
|
||||||
for (tab_list, 0..) |tab, i| {
|
for (tab_list, 0..) |tab, i| {
|
||||||
if (i >= tab_widths.len) break;
|
if (i >= tab_widths.len) break;
|
||||||
|
|
||||||
|
|
@ -328,38 +372,20 @@ pub fn tabsRect(
|
||||||
const text_y = bar_rect.y + @as(i32, @intCast((config.tab_height - 8) / 2));
|
const text_y = bar_rect.y + @as(i32, @intCast((config.tab_height - 8) / 2));
|
||||||
ctx.pushCommand(Command.text(tab_x + @as(i32, @intCast(config.padding_h)), text_y, tab.label, text_color));
|
ctx.pushCommand(Command.text(tab_x + @as(i32, @intCast(config.padding_h)), text_y, tab.label, text_color));
|
||||||
|
|
||||||
// Draw close button
|
// Draw close button (events already handled in Pass 1)
|
||||||
if (config.show_close and tab.closable) {
|
if (config.show_close and tab.closable) {
|
||||||
const close_x = tab_x + @as(i32, @intCast(tab_width - config.close_size - 8));
|
const close_x = tab_x + @as(i32, @intCast(tab_width - config.close_size - 8));
|
||||||
const close_y = bar_rect.y + @as(i32, @intCast((config.tab_height - config.close_size) / 2));
|
const close_y = bar_rect.y + @as(i32, @intCast((config.tab_height - config.close_size) / 2));
|
||||||
const close_rect = Layout.Rect.init(close_x, close_y, config.close_size, config.close_size);
|
const close_rect = Layout.Rect.init(close_x, close_y, config.close_size, config.close_size);
|
||||||
|
|
||||||
const close_hovered = close_rect.contains(mouse.x, mouse.y);
|
const close_hovered = close_rect.contains(mouse.x, mouse.y);
|
||||||
if (close_hovered) {
|
|
||||||
state.close_hovered = @intCast(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const close_color = if (close_hovered) colors.close_hover else colors.close_color;
|
const close_color = if (close_hovered) colors.close_hover else colors.close_color;
|
||||||
|
|
||||||
// Draw X
|
// Draw X
|
||||||
ctx.pushCommand(Command.text(close_x + 3, close_y + 2, "x", close_color));
|
ctx.pushCommand(Command.text(close_x + 3, close_y + 2, "x", close_color));
|
||||||
|
|
||||||
// Handle close click
|
|
||||||
if (mouse_pressed and close_hovered) {
|
|
||||||
result.closed = true;
|
|
||||||
result.closed_index = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle tab click
|
// Note: Tab click handling moved to Pass 1 (before drawing)
|
||||||
if (mouse_pressed and is_hovered and state.close_hovered != @as(i32, @intCast(i))) {
|
|
||||||
ctx.requestFocus(widget_id);
|
|
||||||
if (state.selected != i) {
|
|
||||||
state.selected = i;
|
|
||||||
result.changed = true;
|
|
||||||
result.selected = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tab_x += @as(i32, @intCast(tab_width));
|
tab_x += @as(i32, @intCast(tab_width));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,12 +123,6 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
/// Indica si hubo doble click este frame
|
/// Indica si hubo doble click este frame
|
||||||
double_clicked: bool = false,
|
double_clicked: bool = false,
|
||||||
|
|
||||||
/// Frame counter para animaciones
|
|
||||||
frame_count: u32 = 0,
|
|
||||||
|
|
||||||
/// Índice del tip actual (para tips proactivos rotativos)
|
|
||||||
tip_index: u8 = 0,
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Buffers persistentes para texto formateado (evitar stack buffer escape)
|
// Buffers persistentes para texto formateado (evitar stack buffer escape)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
@ -281,7 +275,6 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
self.filter_text_changed = false;
|
self.filter_text_changed = false;
|
||||||
self.chip_changed = false;
|
self.chip_changed = false;
|
||||||
self.changed_chip_index = null;
|
self.changed_chip_index = null;
|
||||||
self.frame_count +%= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
|
||||||
|
|
@ -106,9 +106,6 @@ pub const VirtualAdvancedTableResult = struct {
|
||||||
edited_value: ?[]const u8 = null,
|
edited_value: ?[]const u8 = null,
|
||||||
previous_row: ?usize = null,
|
previous_row: ?usize = null,
|
||||||
|
|
||||||
// Tips
|
|
||||||
current_tip: ?[]const u8 = null,
|
|
||||||
|
|
||||||
pub fn getRowChanges(self: *const VirtualAdvancedTableResult) []const table_core.PendingCellChange {
|
pub fn getRowChanges(self: *const VirtualAdvancedTableResult) []const table_core.PendingCellChange {
|
||||||
return self.row_changes[0..self.row_changes_count];
|
return self.row_changes[0..self.row_changes_count];
|
||||||
}
|
}
|
||||||
|
|
@ -428,16 +425,6 @@ pub fn virtualAdvancedTableRect(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tips
|
|
||||||
list_state.frame_count +%= 1;
|
|
||||||
|
|
||||||
if (has_focus and !list_state.isEditing()) {
|
|
||||||
if (list_state.frame_count % table_core.TIP_ROTATION_FRAMES == 0) {
|
|
||||||
list_state.tip_index = @intCast((list_state.tip_index + 1) % table_core.table_tips.len);
|
|
||||||
}
|
|
||||||
result.current_tip = table_core.table_tips[list_state.tip_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue