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:
parent
e8b4c98d4a
commit
49cf12f7b9
1 changed files with 126 additions and 100 deletions
|
|
@ -210,24 +210,34 @@ pub fn detectDoubleClick(
|
|||
// 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
|
||||
pub const EditKeyboardResult = struct {
|
||||
/// Se confirmó la edición (Enter)
|
||||
/// Se confirmó la edición (Enter, Tab, flechas)
|
||||
committed: bool = false,
|
||||
/// Se canceló la edición (Escape)
|
||||
/// Se canceló la edición (Escape 2x)
|
||||
cancelled: bool = false,
|
||||
/// Se revirtió al valor original (primer Escape)
|
||||
/// Se revirtió al valor original (Escape 1x)
|
||||
reverted: bool = false,
|
||||
/// Se debe navegar a siguiente celda (Tab)
|
||||
navigate_next: bool = false,
|
||||
/// Se debe navegar a celda anterior (Shift+Tab)
|
||||
navigate_prev: bool = false,
|
||||
/// Dirección de navegación después de commit
|
||||
navigate: NavigateDirection = .none,
|
||||
/// El buffer de edición cambió
|
||||
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
|
||||
/// 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(
|
||||
ctx: *Context,
|
||||
edit_buffer: []u8,
|
||||
|
|
@ -238,8 +248,12 @@ pub fn handleEditingKeyboard(
|
|||
) EditKeyboardResult {
|
||||
var result = EditKeyboardResult{};
|
||||
|
||||
// Escape: cancelar o revertir
|
||||
if (ctx.input.keyPressed(.escape)) {
|
||||
// Procesar eventos de tecla
|
||||
for (ctx.input.getKeyEvents()) |event| {
|
||||
if (!event.pressed) continue;
|
||||
|
||||
switch (event.key) {
|
||||
.escape => {
|
||||
escape_count.* += 1;
|
||||
if (escape_count.* >= 2 or original_text == null) {
|
||||
result.cancelled = true;
|
||||
|
|
@ -253,52 +267,59 @@ pub fn handleEditingKeyboard(
|
|||
result.reverted = true;
|
||||
}
|
||||
}
|
||||
result.handled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Reset escape count en cualquier otra tecla
|
||||
escape_count.* = 0;
|
||||
|
||||
// Enter: confirmar
|
||||
if (ctx.input.keyPressed(.enter)) {
|
||||
},
|
||||
.enter => {
|
||||
result.committed = true;
|
||||
result.navigate = .next_row;
|
||||
result.handled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Tab: confirmar y navegar
|
||||
if (ctx.input.keyPressed(.tab)) {
|
||||
},
|
||||
.tab => {
|
||||
result.committed = true;
|
||||
if (ctx.input.modifiers.shift) {
|
||||
result.navigate_prev = true;
|
||||
} else {
|
||||
result.navigate_next = true;
|
||||
}
|
||||
result.navigate = if (event.modifiers.shift) .prev_cell else .next_cell;
|
||||
result.handled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Movimiento del cursor
|
||||
if (ctx.input.keyPressed(.left)) {
|
||||
},
|
||||
.up => {
|
||||
result.committed = true;
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
if (ctx.input.keyPressed(.right)) {
|
||||
result.handled = true;
|
||||
// Reset escape count
|
||||
escape_count.* = 0;
|
||||
},
|
||||
.right => {
|
||||
if (edit_cursor.* < edit_len.*) edit_cursor.* += 1;
|
||||
return result;
|
||||
}
|
||||
if (ctx.input.keyPressed(.home)) {
|
||||
result.handled = true;
|
||||
escape_count.* = 0;
|
||||
},
|
||||
.home => {
|
||||
edit_cursor.* = 0;
|
||||
return result;
|
||||
}
|
||||
if (ctx.input.keyPressed(.end)) {
|
||||
result.handled = true;
|
||||
escape_count.* = 0;
|
||||
},
|
||||
.end => {
|
||||
edit_cursor.* = edit_len.*;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Backspace
|
||||
if (ctx.input.keyPressed(.backspace)) {
|
||||
if (edit_cursor.* > 0) {
|
||||
result.handled = true;
|
||||
escape_count.* = 0;
|
||||
},
|
||||
.backspace => {
|
||||
if (edit_cursor.* > 0 and edit_len.* > 0) {
|
||||
// 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) {
|
||||
edit_buffer[i] = edit_buffer[i + 1];
|
||||
}
|
||||
|
|
@ -306,11 +327,10 @@ pub fn handleEditingKeyboard(
|
|||
edit_cursor.* -= 1;
|
||||
result.text_changed = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Delete
|
||||
if (ctx.input.keyPressed(.delete)) {
|
||||
result.handled = true;
|
||||
escape_count.* = 0;
|
||||
},
|
||||
.delete => {
|
||||
if (edit_cursor.* < edit_len.*) {
|
||||
var i: usize = edit_cursor.*;
|
||||
while (i < edit_len.* - 1) : (i += 1) {
|
||||
|
|
@ -319,27 +339,33 @@ pub fn handleEditingKeyboard(
|
|||
edit_len.* -= 1;
|
||||
result.text_changed = true;
|
||||
}
|
||||
return result;
|
||||
result.handled = true;
|
||||
escape_count.* = 0;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
// Character input
|
||||
if (ctx.input.text_input_len > 0) {
|
||||
const text = ctx.input.text_input[0..ctx.input.text_input_len];
|
||||
for (text) |ch| {
|
||||
if (ch >= 32 and ch < 127) {
|
||||
// Procesar texto ingresado (caracteres imprimibles)
|
||||
const text_input = ctx.input.getTextInput();
|
||||
if (text_input.len > 0) {
|
||||
for (text_input) |ch| {
|
||||
if (edit_len.* < edit_buffer.len - 1) {
|
||||
// Shift characters right
|
||||
var i: usize = edit_len.*;
|
||||
// Hacer espacio moviendo caracteres hacia la derecha
|
||||
if (edit_cursor.* < edit_len.*) {
|
||||
var i = edit_len.*;
|
||||
while (i > edit_cursor.*) : (i -= 1) {
|
||||
edit_buffer[i] = edit_buffer[i - 1];
|
||||
}
|
||||
}
|
||||
edit_buffer[edit_cursor.*] = ch;
|
||||
edit_len.* += 1;
|
||||
edit_cursor.* += 1;
|
||||
result.text_changed = true;
|
||||
result.handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
escape_count.* = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Reference in a new issue