refactor(table_core): Unify EditKeyboardResult with NavigateDirection and handled flag

- Add NavigateDirection enum (none, next_cell, prev_cell, next_row, prev_row)
- Replace navigate_next/navigate_prev bools with single navigate field
- Add 'handled' flag to prevent double processing of Tab
- Add Up/Down arrow handling for row navigation
- Use getKeyEvents() loop instead of keyPressed() for consistency
This commit is contained in:
reugenio 2025-12-27 12:09:39 +01:00
parent e8b4c98d4a
commit 49cf12f7b9

View file

@ -210,24 +210,34 @@ pub fn detectDoubleClick(
// Manejo de teclado para edición // Manejo de teclado para edición
// ============================================================================= // =============================================================================
/// Dirección de navegación después de edición
pub const NavigateDirection = enum {
none,
next_cell, // Tab
prev_cell, // Shift+Tab
next_row, // Enter o
prev_row, //
};
/// Resultado de procesar teclado en modo edición /// Resultado de procesar teclado en modo edición
pub const EditKeyboardResult = struct { pub const EditKeyboardResult = struct {
/// Se confirmó la edición (Enter) /// Se confirmó la edición (Enter, Tab, flechas)
committed: bool = false, committed: bool = false,
/// Se canceló la edición (Escape) /// Se canceló la edición (Escape 2x)
cancelled: bool = false, cancelled: bool = false,
/// Se revirtió al valor original (primer Escape) /// Se revirtió al valor original (Escape 1x)
reverted: bool = false, reverted: bool = false,
/// Se debe navegar a siguiente celda (Tab) /// Dirección de navegación después de commit
navigate_next: bool = false, navigate: NavigateDirection = .none,
/// Se debe navegar a celda anterior (Shift+Tab)
navigate_prev: bool = false,
/// El buffer de edición cambió /// El buffer de edición cambió
text_changed: bool = false, text_changed: bool = false,
/// Indica que se procesó un evento de teclado (para evitar doble procesamiento)
handled: bool = false,
}; };
/// Procesa teclado en modo edición /// Procesa teclado en modo edición
/// Modifica edit_buffer, edit_len, edit_cursor según las teclas /// Modifica edit_buffer, edit_len, edit_cursor según las teclas
/// Retorna resultado con flags de navegación y si se procesó algún evento
pub fn handleEditingKeyboard( pub fn handleEditingKeyboard(
ctx: *Context, ctx: *Context,
edit_buffer: []u8, edit_buffer: []u8,
@ -238,8 +248,12 @@ pub fn handleEditingKeyboard(
) EditKeyboardResult { ) EditKeyboardResult {
var result = EditKeyboardResult{}; var result = EditKeyboardResult{};
// Escape: cancelar o revertir // Procesar eventos de tecla
if (ctx.input.keyPressed(.escape)) { for (ctx.input.getKeyEvents()) |event| {
if (!event.pressed) continue;
switch (event.key) {
.escape => {
escape_count.* += 1; escape_count.* += 1;
if (escape_count.* >= 2 or original_text == null) { if (escape_count.* >= 2 or original_text == null) {
result.cancelled = true; result.cancelled = true;
@ -253,52 +267,59 @@ pub fn handleEditingKeyboard(
result.reverted = true; result.reverted = true;
} }
} }
result.handled = true;
return result; return result;
} },
.enter => {
// Reset escape count en cualquier otra tecla
escape_count.* = 0;
// Enter: confirmar
if (ctx.input.keyPressed(.enter)) {
result.committed = true; result.committed = true;
result.navigate = .next_row;
result.handled = true;
return result; return result;
} },
.tab => {
// Tab: confirmar y navegar
if (ctx.input.keyPressed(.tab)) {
result.committed = true; result.committed = true;
if (ctx.input.modifiers.shift) { result.navigate = if (event.modifiers.shift) .prev_cell else .next_cell;
result.navigate_prev = true; result.handled = true;
} else {
result.navigate_next = true;
}
return result; return result;
} },
.up => {
// Movimiento del cursor result.committed = true;
if (ctx.input.keyPressed(.left)) { result.navigate = .prev_row;
result.handled = true;
return result;
},
.down => {
result.committed = true;
result.navigate = .next_row;
result.handled = true;
return result;
},
.left => {
if (edit_cursor.* > 0) edit_cursor.* -= 1; if (edit_cursor.* > 0) edit_cursor.* -= 1;
return result; result.handled = true;
} // Reset escape count
if (ctx.input.keyPressed(.right)) { escape_count.* = 0;
},
.right => {
if (edit_cursor.* < edit_len.*) edit_cursor.* += 1; if (edit_cursor.* < edit_len.*) edit_cursor.* += 1;
return result; result.handled = true;
} escape_count.* = 0;
if (ctx.input.keyPressed(.home)) { },
.home => {
edit_cursor.* = 0; edit_cursor.* = 0;
return result; result.handled = true;
} escape_count.* = 0;
if (ctx.input.keyPressed(.end)) { },
.end => {
edit_cursor.* = edit_len.*; edit_cursor.* = edit_len.*;
return result; result.handled = true;
} escape_count.* = 0;
},
// Backspace .backspace => {
if (ctx.input.keyPressed(.backspace)) { if (edit_cursor.* > 0 and edit_len.* > 0) {
if (edit_cursor.* > 0) {
// Shift characters left // Shift characters left
var i: usize = edit_cursor.* - 1; const pos = edit_cursor.* - 1;
var i: usize = pos;
while (i < edit_len.* - 1) : (i += 1) { while (i < edit_len.* - 1) : (i += 1) {
edit_buffer[i] = edit_buffer[i + 1]; edit_buffer[i] = edit_buffer[i + 1];
} }
@ -306,11 +327,10 @@ pub fn handleEditingKeyboard(
edit_cursor.* -= 1; edit_cursor.* -= 1;
result.text_changed = true; result.text_changed = true;
} }
return result; result.handled = true;
} escape_count.* = 0;
},
// Delete .delete => {
if (ctx.input.keyPressed(.delete)) {
if (edit_cursor.* < edit_len.*) { if (edit_cursor.* < edit_len.*) {
var i: usize = edit_cursor.*; var i: usize = edit_cursor.*;
while (i < edit_len.* - 1) : (i += 1) { while (i < edit_len.* - 1) : (i += 1) {
@ -319,27 +339,33 @@ pub fn handleEditingKeyboard(
edit_len.* -= 1; edit_len.* -= 1;
result.text_changed = true; result.text_changed = true;
} }
return result; result.handled = true;
escape_count.* = 0;
},
else => {},
}
} }
// Character input // Procesar texto ingresado (caracteres imprimibles)
if (ctx.input.text_input_len > 0) { const text_input = ctx.input.getTextInput();
const text = ctx.input.text_input[0..ctx.input.text_input_len]; if (text_input.len > 0) {
for (text) |ch| { for (text_input) |ch| {
if (ch >= 32 and ch < 127) {
if (edit_len.* < edit_buffer.len - 1) { if (edit_len.* < edit_buffer.len - 1) {
// Shift characters right // Hacer espacio moviendo caracteres hacia la derecha
var i: usize = edit_len.*; if (edit_cursor.* < edit_len.*) {
var i = edit_len.*;
while (i > edit_cursor.*) : (i -= 1) { while (i > edit_cursor.*) : (i -= 1) {
edit_buffer[i] = edit_buffer[i - 1]; edit_buffer[i] = edit_buffer[i - 1];
} }
}
edit_buffer[edit_cursor.*] = ch; edit_buffer[edit_cursor.*] = ch;
edit_len.* += 1; edit_len.* += 1;
edit_cursor.* += 1; edit_cursor.* += 1;
result.text_changed = true; result.text_changed = true;
result.handled = true;
} }
} }
} escape_count.* = 0;
} }
return result; return result;