El menú y el frontend, sincronizados
Un menú que vive en el core y una interfaz que vive en la webview tienen que estar de acuerdo. Cómo se mantiene el estado sincronizado sin duplicar la verdad.
El error
El caso que hace perder trabajo es «Guardar» desactivado con cambios pendientes, porque el usuario confía en el menú: si dice que no hay nada que guardar, cierra.
Actualizar sin reconstruir
Reconstruir el menú entero en cada cambio funciona y tiene dos problemas: es más caro de lo que parece, y en algunos sistemas produce un parpadeo visible de la barra.
Lo correcto es cambiar solo lo que cambia:
// guardar la referencia a los elementos que cambian de estadostruct MenuVivo { guardar: MenuItem<Wry>, deshacer: MenuItem<Wry>, cerrar_proyecto: MenuItem<Wry>,}pub fn actualizar(menu: &MenuVivo, estado: &Estado) -> Result<(), Error> { menu.guardar.set_enabled(estado.hay_cambios)?; menu.deshacer.set_enabled(estado.puede_deshacer)?; menu.cerrar_proyecto.set_enabled(estado.proyecto.is_some())?; Ok(())}Y llamar a eso desde un solo sitio: la función que cambia el estado de la aplicación, no desde cada comando que lo toca. Es el mismo argumento del nivel 47.1.
Cuándo actualizar
Tres momentos, y solo tres:
- Cuando cambia el estado que la disponibilidad usa. Nada más.
- Al cambiar de ventana activa, si el estado es por ventana. Ver abajo.
- Y al construir el menú, para que el estado inicial sea correcto — que se olvida, y produce un menú donde todo está activo hasta el primer cambio.
No hace falta actualizar en un temporizador ni al abrir el menú. Si el estado es la fuente única, ya está al día.
Varias ventanas
El caso que complica, y tiene dos formas según el sistema:
Y el frontend
La otra mitad: los botones de la interfaz leen la misma verdad.
- Un comando que devuelve el estado de las acciones, llamado al arrancar.
- Y un evento cuando cambia, con el mismo contenido.
- El frontend no calcula disponibilidad, la recibe. Si un botón necesita saber si algo se puede hacer, pregunta.
Con eso, menú y botones no pueden divergir, porque los dos son proyecciones del mismo dato.