feat(paged_datasource): Handle injected rows in data access

When an injected row exists (Ctrl+N between lines):
- getRowCount(): adds 1 to total count
- getCellValueInto(): returns edit buffer values for injected row,
  shifts indices for rows after injection
- getRowId(): returns injected_row_id for injected row,
  shifts indices for rows after injection

This enables transparent rendering of injected rows without
modifying the drawing code.
This commit is contained in:
reugenio 2025-12-28 02:24:14 +01:00
parent 712466adc8
commit 5800d01a67

View file

@ -51,24 +51,57 @@ pub const PagedDataSource = struct {
// Implementación de TableDataSource
// =========================================================================
/// Retorna el número total de filas (filtered count)
/// Retorna el número total de filas (filtered count + inyección)
pub fn getRowCount(self: *Self) usize {
// Usar conteo filtrado si está disponible
const count_info = self.state.getDisplayCount();
return count_info.value;
var count = count_info.value;
// Si hay una fila inyectada, sumar 1 al conteo visual
if (self.state.injected_row_idx != null) {
count += 1;
}
return count;
}
/// Escribe el valor de una celda en el buffer proporcionado.
/// El row es índice global, se convierte a índice de ventana.
/// Maneja filas inyectadas (Ctrl+N entre líneas).
/// Retorna slice del buffer con el contenido.
pub fn getCellValueInto(self: *Self, row: usize, col: usize, buf: []u8) []const u8 {
// Validar columna
if (col >= self.columns.len) return "";
// =====================================================================
// Manejo de fila inyectada
// =====================================================================
if (self.state.injected_row_idx) |inj_idx| {
if (row == inj_idx) {
// Esta es la fila inyectada - leer del edit buffer
if (self.state.row_edit_buffer.getPendingValue(col)) |pending| {
const copy_len = @min(pending.len, buf.len);
@memcpy(buf[0..copy_len], pending[0..copy_len]);
return buf[0..copy_len];
}
// Sin valor pendiente - retornar vacío (celda nueva)
return "";
} else if (row > inj_idx) {
// Fila después de la inyección - ajustar índice (-1)
return self.getCellValueFromProvider(row - 1, col, buf);
}
// row < inj_idx: continuar normal
}
// Flujo normal (sin inyección o row < inj_idx)
return self.getCellValueFromProvider(row, col, buf);
}
/// Helper interno: obtiene valor de celda del provider (sin ajuste por inyección)
fn getCellValueFromProvider(self: *Self, row: usize, col: usize, buf: []u8) []const u8 {
// Convertir índice global a índice de ventana
const window_idx = self.state.globalToWindowIndex(row) orelse {
// Fila fuera de ventana actual - retornar vacío
// (el caller debería asegurarse de pedir solo filas visibles)
return "";
};
@ -88,7 +121,25 @@ pub const PagedDataSource = struct {
/// Retorna el ID único de una fila.
/// Si está en ventana, usa window data. Si no, consulta al provider.
/// Maneja filas inyectadas (Ctrl+N entre líneas).
pub fn getRowId(self: *Self, row: usize) i64 {
// Manejo de fila inyectada
if (self.state.injected_row_idx) |inj_idx| {
if (row == inj_idx) {
// Esta es la fila inyectada
return self.state.injected_row_id;
} else if (row > inj_idx) {
// Fila después de la inyección - ajustar índice
return self.getRowIdFromProvider(row - 1);
}
}
// Flujo normal
return self.getRowIdFromProvider(row);
}
/// Helper interno: obtiene ID de fila del provider (sin ajuste por inyección)
fn getRowIdFromProvider(self: *Self, row: usize) i64 {
// Intentar obtener de la ventana
if (self.state.globalToWindowIndex(row)) |window_idx| {
if (window_idx < self.state.current_window.len) {