Componentes principales
El contenedor se implementará inicialmente como una aplicación Rust organizada en módulos. No se necesita separar cada componente en un crate.
flowchart TD
P[Arranque por plataforma] --> C[Configuración efectiva]
C --> A[ShellApp]
A --> S[ShellState]
A --> L[Layout y componentes]
L --> H[Header y menús]
L --> N[Sidebar y toolbar]
L --> T[Pestañas]
L --> V[ContentHost y panel contextual]
L --> F[Footer y capas comunes]
V --> R[Registro de vistas]
A --> D[Adaptadores de plataforma]
| Componente | Responsabilidad |
|---|---|
ShellApp | Integrar eframe, componer las regiones y aplicar eventos |
ShellState | Mantener el estado del contenedor entre repintados |
LayoutController | Resolver distribución y modo compacto según el espacio |
ScreenRegistry | Registrar vistas y sus políticas de apertura |
TabManager | Abrir, activar y cerrar instancias de vistas |
CommandRegistry | Centralizar acciones de menú, botones y atajos |
OverlayManager | Administrar diálogos, búsqueda y notificaciones |
ThemeTokens | Proporcionar estilos compartidos |
PlatformServices | Adaptar ventana, preferencias y capacidades del host |
Los nombres son contratos de diseño. La implementación podrá combinar componentes pequeños, conservando sus responsabilidades.
Estructura de archivos propuesta
contenedor/
├── Cargo.toml
├── Cargo.lock
├── rust-toolchain.toml
├── Trunk.toml
├── index.html # Host del canvas y mensajes de arranque web
├── config/
│ ├── common.json
│ ├── desktop.json
│ └── web.json
├── assets/
│ ├── fonts/
│ └── icons/
└── src/
├── main.rs # Selección del arranque según el target
├── app.rs # ShellApp
├── config.rs # Tipos, composición y validación
├── platform/
│ ├── mod.rs
│ ├── desktop.rs
│ └── web.rs
├── shell/
│ ├── mod.rs
│ ├── state.rs
│ ├── events.rs
│ ├── header.rs
│ ├── menu.rs
│ ├── sidebar.rs
│ ├── toolbar.rs
│ ├── tabs.rs
│ ├── content.rs
│ ├── context_panel.rs
│ ├── footer.rs
│ ├── overlays.rs
│ └── theme.rs
└── screens/
├── mod.rs
├── home.rs
└── demo_editor.rs
Esta estructura no se ha creado todavía. home y demo_editor serán vistas genéricas para probar el contenedor.
Estado compartido
ShellState conserva, al menos, las pestañas abiertas, la pestaña activa, el estado de cada vista, los paneles visibles, las preferencias y los overlays activos.
La identidad de una pantalla y la identidad de su instancia son distintas:
| Identificador | Ejemplo | Propósito |
|---|---|---|
ScreenId | demo-editor | Identifica el tipo de pantalla |
TabId | tab-001 y tab-002 | Identifica cada instancia abierta |
WidgetId | Derivado de TabId más el control | Evita compartir foco y estado de controles por accidente |
Dos pestañas pueden compartir ScreenId, pero deben tener distintos TabId y estados independientes. Los controles egui se identificarán dentro de un ámbito basado en el TabId.
El estado se almacena fuera de las funciones que dibujan la interfaz. Repintar o cambiar de pestaña no recrea los datos de una vista.
Contrato de una vista
Una vista registrada proporciona:
- Identificador, título e icono.
- Política de apertura: única o con múltiples instancias.
- Límite de instancias, si corresponde.
- Constructor de su estado inicial.
- Contenido central y contenido contextual opcional.
- Indicador de cambios pendientes y respuesta a una solicitud de cierre.
La vista recibe un contexto controlado para emitir comandos. No controla el tamaño de la ventana ni dibuja el header, sidebar o footer de la aplicación.
Flujo de interacción
sequenceDiagram
participant U as Usuario
participant C as Componente visual
participant A as ShellApp
participant S as ShellState
U->>C: Selecciona una acción
C->>A: Emite un evento
A->>S: Valida y aplica la transición
S-->>A: Estado actualizado
A-->>C: Dibuja la siguiente vista
Los componentes emiten eventos como OpenView, ActivateTab, RequestCloseTab, ConfirmCloseTab, ToggleSidebar, ToggleContextPanel y SetTheme. Un punto central aplica las transiciones para evitar que varias regiones modifiquen simultáneamente la colección de pestañas.
Los botones de menú y sus atajos ejecutan el mismo comando. Los atajos del contenedor respetan el foco de los campos de texto y las restricciones del navegador.
Orden de composición
Se reserva primero el espacio del header, menú superior y footer. Después, el sidebar ocupa el lateral del espacio de trabajo. Dentro del espacio restante se distribuyen toolbar, pestañas, panel contextual y contenido central. Finalmente se dibujan overlays.
El orden importa en egui: los paneles consumen espacio disponible y el panel central se incorpora al final de su nivel. La implementación debe respetar los límites de los paneles y no abrir un panel raíz dentro de otro. Referencia de paneles.
Cierre y persistencia
El cierre de una pestaña es una operación del contenedor y ofrece el mismo diálogo en web y escritorio. El cierre de la ventana completa depende del host; no se promete un diálogo personalizado al cerrar o recargar el navegador.
La primera implementación persistirá preferencias de interfaz. El contenido de las vistas de ejemplo se conserva en memoria mientras la aplicación está abierta. La restauración de borradores de módulos reales se definirá cuando se aborde su contrato de datos.
El prototipo HTML actual sí guarda borradores de ejemplo en el navegador. Esa decisión del prototipo no impone una política de almacenamiento a los futuros módulos.
Límites de esta arquitectura
El contenedor puede mostrar una pantalla vacía, de carga o de error, pero no define cómo se resuelve un proceso bancario. Un módulo futuro se registra en el host y aporta su propia vista y estado sin modificar la estructura base del contenedor.