refactor(states): Embed CellEditState in AdvancedTableState and VirtualAdvancedTableState
FASE 2 del refactor de tablas: - AdvancedTableState: Embed cell_edit, delegate editing methods - VirtualAdvancedTableState: Embed cell_edit, replace editing_cell/edit_buffer - Update advanced_table.zig to use isEditing() and cell_edit.* - Update virtual_advanced_table.zig to use getEditingCell() - Update cell_editor.zig to use cell_edit.* Reduces code duplication, centralizes editing logic in table_core
This commit is contained in:
parent
6819919060
commit
37e3b61aca
5 changed files with 96 additions and 144 deletions
|
|
@ -175,7 +175,7 @@ pub fn advancedTableRect(
|
||||||
|
|
||||||
// Handle keyboard
|
// Handle keyboard
|
||||||
if (has_focus) {
|
if (has_focus) {
|
||||||
if (table_state.editing) {
|
if (table_state.isEditing()) {
|
||||||
// Handle editing keyboard
|
// Handle editing keyboard
|
||||||
handleEditingKeyboard(ctx, table_state, table_schema, &result);
|
handleEditingKeyboard(ctx, table_state, table_schema, &result);
|
||||||
|
|
||||||
|
|
@ -444,7 +444,7 @@ fn drawRow(
|
||||||
const time_diff = current_time -| table_state.last_click_time;
|
const time_diff = current_time -| table_state.last_click_time;
|
||||||
const is_double_click = same_cell and time_diff < table_state.double_click_threshold_ms;
|
const is_double_click = same_cell and time_diff < table_state.double_click_threshold_ms;
|
||||||
|
|
||||||
if (is_double_click and config.allow_edit and col.editable and !table_state.editing) {
|
if (is_double_click and config.allow_edit and col.editable and !table_state.isEditing()) {
|
||||||
// Double-click: start editing
|
// Double-click: start editing
|
||||||
if (table_state.getRow(row_idx)) |row| {
|
if (table_state.getRow(row_idx)) |row| {
|
||||||
const value = row.get(col.name);
|
const value = row.get(col.name);
|
||||||
|
|
@ -594,7 +594,7 @@ fn drawEditingOverlay(
|
||||||
ctx.pushCommand(Command.text(col_x + 4, text_y, edit_text, colors.text_selected));
|
ctx.pushCommand(Command.text(col_x + 4, text_y, edit_text, colors.text_selected));
|
||||||
|
|
||||||
// Draw cursor
|
// Draw cursor
|
||||||
const cursor_x = col_x + 4 + @as(i32, @intCast(table_state.edit_cursor * 8));
|
const cursor_x = col_x + 4 + @as(i32, @intCast(table_state.cell_edit.edit_cursor * 8));
|
||||||
ctx.pushCommand(Command.rect(cursor_x, text_y, 1, 8, colors.text_selected));
|
ctx.pushCommand(Command.rect(cursor_x, text_y, 1, 8, colors.text_selected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -933,10 +933,10 @@ fn handleEditingKeyboard(
|
||||||
// Usar table_core para procesamiento de teclado (DRY)
|
// Usar table_core para procesamiento de teclado (DRY)
|
||||||
const kb_result = table_core.handleEditingKeyboard(
|
const kb_result = table_core.handleEditingKeyboard(
|
||||||
ctx,
|
ctx,
|
||||||
&table_state.edit_buffer,
|
&table_state.cell_edit.edit_buffer,
|
||||||
&table_state.edit_len,
|
&table_state.cell_edit.edit_len,
|
||||||
&table_state.edit_cursor,
|
&table_state.cell_edit.edit_cursor,
|
||||||
&table_state.escape_count,
|
&table_state.cell_edit.escape_count,
|
||||||
original_text,
|
original_text,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,27 +90,16 @@ pub const AdvancedTableState = struct {
|
||||||
last_validation_message_len: usize = 0,
|
last_validation_message_len: usize = 0,
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Editing
|
// Editing (usa CellEditState de table_core para composición)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
/// Is currently editing a cell
|
/// Estado de edición embebido (Fase 2 refactor)
|
||||||
editing: bool = false,
|
cell_edit: table_core.CellEditState = .{},
|
||||||
|
|
||||||
/// Edit buffer for current edit
|
|
||||||
edit_buffer: [MAX_EDIT_BUFFER]u8 = undefined,
|
|
||||||
|
|
||||||
/// Length of text in edit buffer
|
|
||||||
edit_len: usize = 0,
|
|
||||||
|
|
||||||
/// Cursor position in edit buffer
|
|
||||||
edit_cursor: usize = 0,
|
|
||||||
|
|
||||||
/// Original value before editing (for revert on Escape)
|
/// Original value before editing (for revert on Escape)
|
||||||
|
/// NOTA: Mantenemos esto porque CellValue es más rico que buffer crudo
|
||||||
original_value: ?CellValue = null,
|
original_value: ?CellValue = null,
|
||||||
|
|
||||||
/// Escape count (1 = revert, 2 = cancel)
|
|
||||||
escape_count: u8 = 0,
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Double-click detection
|
// Double-click detection
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
@ -303,9 +292,7 @@ pub const AdvancedTableState = struct {
|
||||||
self.prev_selected_col = -1;
|
self.prev_selected_col = -1;
|
||||||
|
|
||||||
// Clear editing
|
// Clear editing
|
||||||
self.editing = false;
|
self.cell_edit.stopEditing();
|
||||||
self.edit_len = 0;
|
|
||||||
self.escape_count = 0;
|
|
||||||
|
|
||||||
// Clear sorting
|
// Clear sorting
|
||||||
self.sort_column = -1;
|
self.sort_column = -1;
|
||||||
|
|
@ -689,76 +676,81 @@ pub const AdvancedTableState = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Editing
|
// Editing (delega a cell_edit embebido)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
/// Start editing current cell
|
/// Start editing current cell
|
||||||
|
/// Usa la celda seleccionada (selected_row, selected_col)
|
||||||
pub fn startEditing(self: *AdvancedTableState, initial_value: []const u8) void {
|
pub fn startEditing(self: *AdvancedTableState, initial_value: []const u8) void {
|
||||||
self.editing = true;
|
const row: usize = if (self.selected_row >= 0) @intCast(self.selected_row) else 0;
|
||||||
self.escape_count = 0;
|
const col: usize = if (self.selected_col >= 0) @intCast(self.selected_col) else 0;
|
||||||
|
self.cell_edit.startEditing(row, col, initial_value, null);
|
||||||
// Copy initial value to edit buffer
|
|
||||||
const len = @min(initial_value.len, MAX_EDIT_BUFFER);
|
|
||||||
@memcpy(self.edit_buffer[0..len], initial_value[0..len]);
|
|
||||||
self.edit_len = len;
|
|
||||||
self.edit_cursor = len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop editing
|
/// Stop editing
|
||||||
pub fn stopEditing(self: *AdvancedTableState) void {
|
pub fn stopEditing(self: *AdvancedTableState) void {
|
||||||
self.editing = false;
|
self.cell_edit.stopEditing();
|
||||||
self.edit_len = 0;
|
|
||||||
self.edit_cursor = 0;
|
|
||||||
self.escape_count = 0;
|
|
||||||
self.original_value = null;
|
self.original_value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current edit text
|
/// Get current edit text
|
||||||
pub fn getEditText(self: *const AdvancedTableState) []const u8 {
|
pub fn getEditText(self: *const AdvancedTableState) []const u8 {
|
||||||
return self.edit_buffer[0..self.edit_len];
|
return self.cell_edit.getEditText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if currently editing
|
||||||
|
pub fn isEditing(self: *const AdvancedTableState) bool {
|
||||||
|
return self.cell_edit.editing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert text at cursor position
|
/// Insert text at cursor position
|
||||||
pub fn insertText(self: *AdvancedTableState, text: []const u8) void {
|
pub fn insertText(self: *AdvancedTableState, text: []const u8) void {
|
||||||
for (text) |c| {
|
for (text) |c| {
|
||||||
if (self.edit_len < MAX_EDIT_BUFFER) {
|
if (self.cell_edit.edit_len < table_core.MAX_EDIT_BUFFER_SIZE) {
|
||||||
// Shift text after cursor
|
// Shift text after cursor
|
||||||
var i = self.edit_len;
|
var i = self.cell_edit.edit_len;
|
||||||
while (i > self.edit_cursor) : (i -= 1) {
|
while (i > self.cell_edit.edit_cursor) : (i -= 1) {
|
||||||
self.edit_buffer[i] = self.edit_buffer[i - 1];
|
self.cell_edit.edit_buffer[i] = self.cell_edit.edit_buffer[i - 1];
|
||||||
}
|
}
|
||||||
self.edit_buffer[self.edit_cursor] = c;
|
self.cell_edit.edit_buffer[self.cell_edit.edit_cursor] = c;
|
||||||
self.edit_len += 1;
|
self.cell_edit.edit_len += 1;
|
||||||
self.edit_cursor += 1;
|
self.cell_edit.edit_cursor += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete character before cursor (backspace)
|
/// Delete character before cursor (backspace)
|
||||||
pub fn deleteBackward(self: *AdvancedTableState) void {
|
pub fn deleteBackward(self: *AdvancedTableState) void {
|
||||||
if (self.edit_cursor > 0) {
|
if (self.cell_edit.edit_cursor > 0) {
|
||||||
// Shift text after cursor
|
var i = self.cell_edit.edit_cursor - 1;
|
||||||
var i = self.edit_cursor - 1;
|
while (i < self.cell_edit.edit_len - 1) : (i += 1) {
|
||||||
while (i < self.edit_len - 1) : (i += 1) {
|
self.cell_edit.edit_buffer[i] = self.cell_edit.edit_buffer[i + 1];
|
||||||
self.edit_buffer[i] = self.edit_buffer[i + 1];
|
|
||||||
}
|
}
|
||||||
self.edit_len -= 1;
|
self.cell_edit.edit_len -= 1;
|
||||||
self.edit_cursor -= 1;
|
self.cell_edit.edit_cursor -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete character at cursor (delete)
|
/// Delete character at cursor (delete)
|
||||||
pub fn deleteForward(self: *AdvancedTableState) void {
|
pub fn deleteForward(self: *AdvancedTableState) void {
|
||||||
if (self.edit_cursor < self.edit_len) {
|
if (self.cell_edit.edit_cursor < self.cell_edit.edit_len) {
|
||||||
// Shift text after cursor
|
var i = self.cell_edit.edit_cursor;
|
||||||
var i = self.edit_cursor;
|
while (i < self.cell_edit.edit_len - 1) : (i += 1) {
|
||||||
while (i < self.edit_len - 1) : (i += 1) {
|
self.cell_edit.edit_buffer[i] = self.cell_edit.edit_buffer[i + 1];
|
||||||
self.edit_buffer[i] = self.edit_buffer[i + 1];
|
|
||||||
}
|
}
|
||||||
self.edit_len -= 1;
|
self.cell_edit.edit_len -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle Escape key (revert or cancel)
|
||||||
|
pub fn handleEditEscape(self: *AdvancedTableState) table_core.CellEditState.EscapeAction {
|
||||||
|
const action = self.cell_edit.handleEscape();
|
||||||
|
if (action == .cancelled) {
|
||||||
|
self.original_value = null;
|
||||||
|
}
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Snapshots (for Auto-CRUD)
|
// Snapshots (for Auto-CRUD)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
@ -1037,10 +1029,10 @@ test "AdvancedTableState editing" {
|
||||||
var state = AdvancedTableState.init(std.testing.allocator);
|
var state = AdvancedTableState.init(std.testing.allocator);
|
||||||
defer state.deinit();
|
defer state.deinit();
|
||||||
|
|
||||||
try std.testing.expect(!state.editing);
|
try std.testing.expect(!state.isEditing());
|
||||||
|
|
||||||
state.startEditing("Hello");
|
state.startEditing("Hello");
|
||||||
try std.testing.expect(state.editing);
|
try std.testing.expect(state.isEditing());
|
||||||
try std.testing.expectEqualStrings("Hello", state.getEditText());
|
try std.testing.expectEqualStrings("Hello", state.getEditText());
|
||||||
|
|
||||||
state.insertText(" World");
|
state.insertText(" World");
|
||||||
|
|
@ -1050,7 +1042,7 @@ test "AdvancedTableState editing" {
|
||||||
try std.testing.expectEqualStrings("Hello Worl", state.getEditText());
|
try std.testing.expectEqualStrings("Hello Worl", state.getEditText());
|
||||||
|
|
||||||
state.stopEditing();
|
state.stopEditing();
|
||||||
try std.testing.expect(!state.editing);
|
try std.testing.expect(!state.isEditing());
|
||||||
}
|
}
|
||||||
|
|
||||||
test "AdvancedTableState sorting" {
|
test "AdvancedTableState sorting" {
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ pub fn drawCellEditor(
|
||||||
));
|
));
|
||||||
|
|
||||||
// Cursor: posición calculada con measureTextToCursor (TTF-aware)
|
// Cursor: posición calculada con measureTextToCursor (TTF-aware)
|
||||||
const cursor_offset = ctx.measureTextToCursor(text, state.edit_cursor);
|
const cursor_offset = ctx.measureTextToCursor(text, state.cell_edit.edit_cursor);
|
||||||
const cursor_x = geom.x + padding + @as(i32, @intCast(cursor_offset));
|
const cursor_x = geom.x + padding + @as(i32, @intCast(cursor_offset));
|
||||||
|
|
||||||
// Visibilidad del cursor usando función compartida de Context
|
// Visibilidad del cursor usando función compartida de Context
|
||||||
|
|
@ -109,10 +109,10 @@ pub fn drawCellEditor(
|
||||||
const original_text = state.getOriginalValue();
|
const original_text = state.getOriginalValue();
|
||||||
const kb_result = table_core.handleEditingKeyboard(
|
const kb_result = table_core.handleEditingKeyboard(
|
||||||
ctx,
|
ctx,
|
||||||
&state.edit_buffer,
|
&state.cell_edit.edit_buffer,
|
||||||
&state.edit_buffer_len,
|
&state.cell_edit.edit_len,
|
||||||
&state.edit_cursor,
|
&state.cell_edit.edit_cursor,
|
||||||
&state.escape_count,
|
&state.cell_edit.escape_count,
|
||||||
if (original_text.len > 0) original_text else null,
|
if (original_text.len > 0) original_text else null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,18 +147,11 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
footer_display_len: usize = 0,
|
footer_display_len: usize = 0,
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Estado de edición CRUD Excel-style
|
// Estado de edición CRUD Excel-style (usa CellEditState de table_core)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
/// Celda actualmente en edición (null = no editando)
|
/// Estado de edición embebido (Fase 2 refactor)
|
||||||
editing_cell: ?CellId = null,
|
cell_edit: table_core.CellEditState = .{},
|
||||||
|
|
||||||
/// Valor original de la celda (para Escape revertir)
|
|
||||||
original_value: [256]u8 = undefined,
|
|
||||||
original_value_len: usize = 0,
|
|
||||||
|
|
||||||
/// Contador de Escapes (1 = revertir celda, 2 = descartar fila)
|
|
||||||
escape_count: u8 = 0,
|
|
||||||
|
|
||||||
/// Fila actual tiene cambios sin guardar en BD
|
/// Fila actual tiene cambios sin guardar en BD
|
||||||
row_dirty: bool = false,
|
row_dirty: bool = false,
|
||||||
|
|
@ -166,11 +159,6 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
/// Última fila editada (para detectar cambio de fila)
|
/// Última fila editada (para detectar cambio de fila)
|
||||||
last_edited_row: ?usize = null,
|
last_edited_row: ?usize = null,
|
||||||
|
|
||||||
/// Buffer de edición (texto actual en el editor)
|
|
||||||
edit_buffer: [256]u8 = undefined,
|
|
||||||
edit_buffer_len: usize = 0,
|
|
||||||
edit_cursor: usize = 0,
|
|
||||||
|
|
||||||
/// Tiempo de última edición (para parpadeo cursor)
|
/// Tiempo de última edición (para parpadeo cursor)
|
||||||
last_edit_time_ms: u64 = 0,
|
last_edit_time_ms: u64 = 0,
|
||||||
|
|
||||||
|
|
@ -579,96 +567,76 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Métodos de edición CRUD Excel-style
|
// Métodos de edición CRUD Excel-style (delega a cell_edit embebido)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
/// Verifica si hay una celda en edición
|
/// Verifica si hay una celda en edición
|
||||||
pub fn isEditing(self: *const Self) bool {
|
pub fn isEditing(self: *const Self) bool {
|
||||||
return self.editing_cell != null;
|
return self.cell_edit.editing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtiene la celda actualmente en edición
|
||||||
|
pub fn getEditingCell(self: *const Self) ?CellId {
|
||||||
|
if (!self.cell_edit.editing) return null;
|
||||||
|
return .{ .row = self.cell_edit.edit_row, .col = self.cell_edit.edit_col };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inicia edición de una celda
|
/// Inicia edición de una celda
|
||||||
/// initial_char: si viene de tecla alfanumérica, el caracter inicial (null = mostrar valor actual)
|
/// initial_char: si viene de tecla alfanumérica, el caracter inicial (null = mostrar valor actual)
|
||||||
pub fn startEditing(self: *Self, cell: CellId, current_value: []const u8, initial_char: ?u8, current_time_ms: u64) void {
|
pub fn startEditing(self: *Self, cell: CellId, current_value: []const u8, initial_char: ?u8, current_time_ms: u64) void {
|
||||||
// Guardar valor original (para Escape)
|
self.cell_edit.startEditing(cell.row, cell.col, current_value, initial_char);
|
||||||
const len = @min(current_value.len, self.original_value.len);
|
|
||||||
@memcpy(self.original_value[0..len], current_value[0..len]);
|
|
||||||
self.original_value_len = len;
|
|
||||||
|
|
||||||
// Inicializar buffer de edición
|
|
||||||
if (initial_char) |c| {
|
|
||||||
// Tecla alfanumérica: empezar con ese caracter
|
|
||||||
self.edit_buffer[0] = c;
|
|
||||||
self.edit_buffer_len = 1;
|
|
||||||
self.edit_cursor = 1;
|
|
||||||
} else {
|
|
||||||
// Doble-click/Space: mostrar valor actual
|
|
||||||
@memcpy(self.edit_buffer[0..len], current_value[0..len]);
|
|
||||||
self.edit_buffer_len = len;
|
|
||||||
self.edit_cursor = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.editing_cell = cell;
|
|
||||||
self.escape_count = 0;
|
|
||||||
self.last_edit_time_ms = current_time_ms;
|
self.last_edit_time_ms = current_time_ms;
|
||||||
self.cell_value_changed = false;
|
self.cell_value_changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtiene el texto actual del editor
|
/// Obtiene el texto actual del editor
|
||||||
pub fn getEditText(self: *const Self) []const u8 {
|
pub fn getEditText(self: *const Self) []const u8 {
|
||||||
return self.edit_buffer[0..self.edit_buffer_len];
|
return self.cell_edit.getEditText();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Establece el texto del editor
|
/// Establece el texto del editor
|
||||||
pub fn setEditText(self: *Self, text: []const u8) void {
|
pub fn setEditText(self: *Self, text: []const u8) void {
|
||||||
const len = @min(text.len, self.edit_buffer.len);
|
const len = @min(text.len, table_core.MAX_EDIT_BUFFER_SIZE);
|
||||||
@memcpy(self.edit_buffer[0..len], text[0..len]);
|
@memcpy(self.cell_edit.edit_buffer[0..len], text[0..len]);
|
||||||
self.edit_buffer_len = len;
|
self.cell_edit.edit_len = len;
|
||||||
self.edit_cursor = len;
|
self.cell_edit.edit_cursor = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtiene el valor original (antes de editar)
|
/// Obtiene el valor original (antes de editar)
|
||||||
pub fn getOriginalValue(self: *const Self) []const u8 {
|
pub fn getOriginalValue(self: *const Self) []const u8 {
|
||||||
return self.original_value[0..self.original_value_len];
|
return self.cell_edit.getOriginalValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifica si el valor ha cambiado respecto al original
|
/// Verifica si el valor ha cambiado respecto al original
|
||||||
pub fn hasValueChanged(self: *const Self) bool {
|
pub fn hasValueChanged(self: *const Self) bool {
|
||||||
const current = self.getEditText();
|
return self.cell_edit.hasChanged();
|
||||||
const original = self.getOriginalValue();
|
|
||||||
return !std.mem.eql(u8, current, original);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finaliza edición guardando cambios (retorna true si hubo cambios)
|
/// Finaliza edición guardando cambios (retorna true si hubo cambios)
|
||||||
pub fn commitEdit(self: *Self) bool {
|
pub fn commitEdit(self: *Self) bool {
|
||||||
if (self.editing_cell == null) return false;
|
if (!self.cell_edit.editing) return false;
|
||||||
|
|
||||||
const changed = self.hasValueChanged();
|
const changed = self.cell_edit.hasChanged();
|
||||||
if (changed) {
|
if (changed) {
|
||||||
self.row_dirty = true;
|
self.row_dirty = true;
|
||||||
self.cell_value_changed = true;
|
self.cell_value_changed = true;
|
||||||
// Solo actualizar última fila editada si hubo cambios reales
|
// Solo actualizar última fila editada si hubo cambios reales
|
||||||
self.last_edited_row = self.editing_cell.?.row;
|
self.last_edited_row = self.cell_edit.edit_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.editing_cell = null;
|
self.cell_edit.stopEditing();
|
||||||
self.escape_count = 0;
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finaliza edición descartando cambios
|
/// Finaliza edición descartando cambios
|
||||||
pub fn cancelEdit(self: *Self) void {
|
pub fn cancelEdit(self: *Self) void {
|
||||||
self.editing_cell = null;
|
self.cell_edit.stopEditing();
|
||||||
self.escape_count = 0;
|
|
||||||
self.cell_value_changed = false;
|
self.cell_value_changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Revierte el texto de la celda al valor original (Escape 1)
|
/// Revierte el texto de la celda al valor original (Escape 1)
|
||||||
pub fn revertCellText(self: *Self) void {
|
pub fn revertCellText(self: *Self) void {
|
||||||
const original = self.getOriginalValue();
|
self.cell_edit.revertToOriginal();
|
||||||
@memcpy(self.edit_buffer[0..original.len], original);
|
|
||||||
self.edit_buffer_len = original.len;
|
|
||||||
self.edit_cursor = original.len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maneja la tecla Escape (retorna acción a tomar)
|
/// Maneja la tecla Escape (retorna acción a tomar)
|
||||||
|
|
@ -682,20 +650,15 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn handleEscape(self: *Self) EscapeAction {
|
pub fn handleEscape(self: *Self) EscapeAction {
|
||||||
if (self.editing_cell == null) return .none;
|
const action = self.cell_edit.handleEscape();
|
||||||
|
return switch (action) {
|
||||||
self.escape_count += 1;
|
.reverted => .reverted,
|
||||||
|
.cancelled => blk: {
|
||||||
if (self.escape_count == 1) {
|
self.row_dirty = false;
|
||||||
// Escape 1: Revertir texto a valor original
|
break :blk .discard_row;
|
||||||
self.revertCellText();
|
},
|
||||||
return .reverted;
|
.none => .none,
|
||||||
} else {
|
};
|
||||||
// Escape 2+: Descartar cambios de fila
|
|
||||||
self.cancelEdit();
|
|
||||||
self.row_dirty = false;
|
|
||||||
return .discard_row;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifica si cambió de fila (para auto-save)
|
/// Verifica si cambió de fila (para auto-save)
|
||||||
|
|
@ -713,12 +676,9 @@ pub const VirtualAdvancedTableState = struct {
|
||||||
|
|
||||||
/// Resetea el estado de edición completamente
|
/// Resetea el estado de edición completamente
|
||||||
pub fn resetEditState(self: *Self) void {
|
pub fn resetEditState(self: *Self) void {
|
||||||
self.editing_cell = null;
|
self.cell_edit.stopEditing();
|
||||||
self.escape_count = 0;
|
|
||||||
self.row_dirty = false;
|
self.row_dirty = false;
|
||||||
self.last_edited_row = null;
|
self.last_edited_row = null;
|
||||||
self.edit_buffer_len = 0;
|
|
||||||
self.edit_cursor = 0;
|
|
||||||
self.cell_value_changed = false;
|
self.cell_value_changed = false;
|
||||||
self.row_edit_buffer.clear();
|
self.row_edit_buffer.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ pub fn virtualAdvancedTableRect(
|
||||||
|
|
||||||
// Draw CellEditor overlay if editing
|
// Draw CellEditor overlay if editing
|
||||||
if (list_state.isEditing()) {
|
if (list_state.isEditing()) {
|
||||||
const editing = list_state.editing_cell.?;
|
const editing = list_state.getEditingCell().?;
|
||||||
|
|
||||||
// Calculate cell geometry for the editing cell
|
// Calculate cell geometry for the editing cell
|
||||||
if (list_state.getCellGeometry(
|
if (list_state.getCellGeometry(
|
||||||
|
|
@ -306,7 +306,7 @@ pub fn virtualAdvancedTableRect(
|
||||||
|
|
||||||
// Handle editor results
|
// Handle editor results
|
||||||
if (editor_result.committed) {
|
if (editor_result.committed) {
|
||||||
const edited_cell = list_state.editing_cell.?;
|
const edited_cell = list_state.getEditingCell().?;
|
||||||
const new_value = list_state.getEditText();
|
const new_value = list_state.getEditText();
|
||||||
|
|
||||||
// Añadir cambio al buffer de fila (NO commit inmediato)
|
// Añadir cambio al buffer de fila (NO commit inmediato)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue