//! Mide cuánto tarda el ajuste blando del text-area y el hit-testing del mouse //! según el largo del texto. Diagnóstico de T11 (COLA-SHUMA): el input se cuelga //! al clickear con mucho texto. Evidencia en TEXTO (Regla 8 del repo), no en //! pantalla. //! //! Tres columnas, tres caminos distintos: //! - `wrap` — partir el texto en renglones visuales (`renglones_visuales`). //! - `click2d` — click en el text-area: wrap + mapear x→columna dentro del //! renglón (`place_caret_2d`). //! - `click1L` — click en el campo de **una línea**, donde el texto llega //! entero al mapeo x→columna (`Press`). No pasa por el wrap. Se mide con el //! caret **al final** —como queda tras tipear o pegar—, que es el caso caro: //! ahí el campo está desplazado (`scroll_x`) y el punto clickeado cae al //! fondo del texto, no en los primeros caracteres. //! //! Lo que se mira no es el número absoluto (depende de la máquina) sino cómo //! crece: duplicar el texto tiene que duplicar el costo, no cuadruplicarlo. use llimphi_widget_text_input::{MemClipboard, TextInputEvent, TextInputState}; use std::time::Instant; fn main() { let mut clip = MemClipboard::new(); // Ancho típico del input del cajón, y un texto de palabras normales. const ANCHO: f32 = 900.0; let palabra = "cargo "; // Calentar el typesetter: la primera medición de todo el proceso paga la // carga de la fuente (~150 ms) y, sin esto, se la come la primera fila de // la tabla y parece un costo del texto corto. { let mut st = TextInputState::new(); st.fijar_ancho_caja(ANCHO); st.set_text("cargo cargo cargo"); let _ = st.renglones_visuales(); st.pointer_click(100.0, 13.0); } println!( "{:>8} {:>10} {:>9} {:>9} {:>9}", "chars", "renglones", "wrap ms", "click2d ms", "click1L ms" ); for n in [200usize, 500, 1_000, 2_000, 4_000, 8_000, 16_000, 32_000] { let texto: String = palabra.repeat(n / palabra.len() + 1); let texto = &texto[..n]; let mut st = TextInputState::new(); st.fijar_ancho_caja(ANCHO); st.set_text(texto); let t0 = Instant::now(); let filas = st.renglones_visuales(); let ms = t0.elapsed().as_secs_f64() * 1000.0; // El gesto del bug: un click en una posición puntual del texto. let t1 = Instant::now(); st.place_caret_2d(430.0, 40.0); let ms_click = t1.elapsed().as_secs_f64() * 1000.0; // El mismo gesto en el campo de una línea: el texto no está envuelto, // así que el mapeo x→columna lo ve entero. Con el caret al final el // campo está desplazado y el click cae al fondo del texto. let mut una = TextInputState::new(); una.fijar_ancho_caja(ANCHO); una.set_text(texto); una.editor_mut().set_caret_at(0, n); let t2 = Instant::now(); una.handle(TextInputEvent::Press(430.0), &mut clip); let ms_1l = t2.elapsed().as_secs_f64() * 1000.0; println!("{n:>8} {filas:>10} {ms:>9.1} {ms_click:>10.1} {ms_1l:>10.1}"); if ms > 4_000.0 || ms_1l > 4_000.0 { println!(" (corto acá: ya es inusable)"); break; } } }