Construisez un espace de travail plus riche
Réunissez mises en page avancées, vues de données, superpositions, graphiques, éditeur, fichiers et couches de terminal sans perdre de vue leurs vraies frontières de features.
Résultat : vous pouvez concevoir un espace de travail compact et choisir ses features Cargo optionnelles en connaissance de cause.
01
Donnez un rôle à chaque panneau
Commencez par un rail défilable et une zone de travail flexible. SplitPane possède la poignée de redimensionnement, tandis que chaque ScrollView garde le débordement dans son panneau.
Faites défiler avec intention
Choisissez l'axe vertical, horizontal ou les deux. Les barres sont actives par défaut et follow_end convient aux flux qui doivent rester près du dernier élément.
Redimensionnez sans deviner
SplitPane::columns et SplitPane::rows acceptent deux vues. Les tailles minimales protègent le contenu utile et bind_position permet à l'application de conserver la position du séparateur.
Mini application 3 : un espace redimensionnable
SplitPane place deux vues autour d'un séparateur déplaçable et impose une taille minimale à chaque côté.
let workspace = SplitPane::columns(navigation, content)
.initial_position(230.0)
.min_start(180.0)
.min_end(420.0);02
Transformez les lignes en décisions
TableView garde son en-tête fixe pendant que le corps défile. Les identifiants typés rendent la sélection utile au reste de l'application.
Sélection typée
Construisez d'abord les colonnes, puis les lignes. bind_selected écrit l'identifiant activé dans une valeur State, tandis que on_select peut émettre une action applicative.
Cellules riches
Une cellule peut afficher un texte normal, un texte discret, un badge sémantique ou une progression. L'alignement des colonnes et des cellules reste explicite.
Clavier inclus
Les lignes actives participent au focus et à la navigation clavier. Les lignes désactivées restent visibles mais sont ignorées par la sélection.
Mini application 1 : un tableau sélectionnable
Les colonnes définissent les tailles, les lignes gardent des clés stables et bind_selected écrit la clé choisie dans State.
fn task_table(selected: State<u8>) -> TableView<u8> {
TableView::new()
.column(TableColumn::new("Task").flex(2.0))
.column(TableColumn::new("Status"))
.column(TableColumn::new("Progress").width(120.0))
.row(
TableRow::new(1)
.leading_icon(IconId::Check)
.cell(TableCell::text("Polish the workspace"))
.cell(TableCell::badge("Active", BadgeTone::Success))
.cell(TableCell::progress(0.75)),
)
.row(
TableRow::new(2)
.cell(TableCell::text("Invite a teammate"))
.cell(TableCell::muted("Next"))
.cell(TableCell::progress(0.25)),
)
.bind_selected(selected)
.max_body_height(180.0)
}Compilé avec Rust 1.88 sur beta.2. Les quatre extraits viennent d'une fixture qui utilise les features Ailloli UI par défaut.
03
Ajoutez de l'aide sans accaparer tout l'écran
Donnez un objectif clair à chaque superposition. Sa visibilité peut être interne, contrôlée ou liée à un signal modifiable selon le propriétaire de l'état.
Dialog
Dialog peut peindre une confirmation au-dessus de son enfant. Le mode lié se ferme en écrivant false après confirmation, annulation, Échap ou clic sur l'arrière-plan.
Menu contextuel
ContextMenu s'ouvre au clic droit et accepte icônes, raccourcis, séparateurs, entrées désactivées et un niveau interactif de sous-menu.
Hôte de notifications
ToastHost empile des notifications légères au-dessus d'un enfant. Une liste liée peut retirer les identifiants correspondants quand le contrôle de fermeture est activé.
Mini application 4 : des superpositions autour du contenu
ToastHost possède les notifications et Dialog enveloppe le contenu qu'il peut recouvrir. L'ouverture demande encore un déclencheur ou un état lié explicite.
ToastHost::<()>::new()
.position(ToastPosition::BottomRight)
.toast(
Toast::new("ready", "Workspace ready")
.description("Right-click the navigation for more options.")
.tone(ToastTone::Success)
.leading_icon(IconId::Check),
)
.child(
Dialog::<()>::new()
.title("Ready for a focused session?")
.body("Your panels, table, and charts are prepared.")
.confirm_label("Let's go")
.cancel_label("Not yet")
.default_open(false)
.child(
Container::new()
.fill()
.background(palette.background)
.child(workspace),
),
)04
Rendez d'abord les données visibles
Les graphiques sont volontairement non interactifs. Ils transforment des valeurs finies en réponse visuelle rapide, tandis que votre application conserve la propriété des données.
BarChart
Utilisez des libellés pour une comparaison courte. Plusieurs séries partagent chaque groupe et parcourent la palette du thème.
LineChart
Fournissez des points x et y explicites pour une tendance. Les marqueurs sont optionnels et tous les points activés doivent avoir des coordonnées finies.
RadialGauge
Projetez une valeur dans un intervalle, puis ajoutez un pourcentage et un libellé optionnels pour une carte d'état compacte.
Mini application 2 : trois graphiques compacts
BarChart compare des catégories, LineChart suit une tendance numérique et RadialGauge montre une progression unique.
Row::new()
.gap(16.0)
.child(
BarChart::new()
.series("Completed", [3.0, 5.0, 4.0, 7.0])
.labels(["Mon", "Tue", "Wed", "Thu"]),
)
.child(
LineChart::new()
.series(
"Focus",
[(0.0, 42.0), (1.0, 61.0), (2.0, 54.0)],
)
.range(0.0, 100.0)
.show_points(true)
.tone(ChartTone::Info),
),
)
.child(
RadialGauge::new()
.value(75.0)
.range(0.0, 100.0)
.show_value(true)
.label("Weekly goal"),
),05
Quelques outils de plus à connaître
Vous n'avez pas besoin de tout aujourd'hui. Retenez le nom de la famille, puis revenez-y lorsque votre application en aura l'usage.
Trouver et naviguer
Sidebar et ListView conviennent aux petits menus familiers et disposent tous les éléments. TreeView gère les données imbriquées et peut utiliser un TreeModelHandle virtualisé pour les grands arbres. CommandPalette filtre des commandes pensées pour le clavier.
Choisir une valeur
Select et ComboBox gèrent les listes. DatePicker, TimePicker et ColorPicker se lient à une valeur ciblée et présentent le choix dans une superposition.
Montrer la progression et l'état
ProgressBar, CircularProgress et StatusIndicator rendent le travail en cours visible. Toast et Dialog communiquent un résultat court ou une décision.
Construire des parcours plus riches
UploadDropzone émet l'intention de déposer un fichier sans effectuer les entrées-sorties. ChatWidget fournit la présentation et des gestionnaires typés, tandis que votre application possède le service.
06
Activez seulement la capacité nécessaire
Les widgets de présentation de l'éditeur et du terminal appartiennent à l'ensemble par défaut. L'accès aux fichiers, l'analyse enrichie et les entrées-sorties PTY sont des capacités optionnelles distinctes.
Éditeur par défaut
Editor et CodeEditor sont exportés sans feature supplémentaire. La feature tree_sitter enrichit l'analyse Rust, les symboles, les replis et le travail syntaxique.
Fichiers indépendants du fournisseur
La feature files expose FileExplorer et des modèles d'instantané. Elle émet des intentions et ne modifie pas seule un système de fichiers.
Système de fichiers local
files_local ajoute LocalFileExplorer et les fournisseurs natifs locaux. Elle peut démarrer des workers et lire le système de fichiers visible du processus.
Limite actuelle du résolveur avec Rust 1.88
Une résolution neuve de tree_sitter sélectionne actuellement tree-sitter-language 0.1.8, qui exige Rust 1.90. Verrouillez la version 0.1.7 dans le lockfile de l'application jusqu'au resserrement de la plage de dépendance.
Choisissez la plus petite feature
Six configurations ont été vérifiées : cinq compilent directement, tandis que tree_sitter compile avec Rust 1.88 après avoir verrouillé tree-sitter-language en version 0.1.7 dans le lockfile du projet utilisateur.
Widgets riches
Features par défautMises en page, tableaux, superpositions, graphiques, éditeurs, Terminal et TerminalView
CompiléAnalyse Rust enrichie
tree_sitterSyntaxe Tree-sitter, symboles, appels et régions repliables pour Rust
Compilé avec verrouillageInstantanés de fichiers
filesFileExplorer indépendant du fournisseur et modèles de fichiers
CompiléFichiers locaux
files_localLocalFileExplorer, fournisseurs locaux et chargement en arrière-plan
CompiléContrats PTY
terminal_ptyTrait de backend, handle de session, événements, regroupement et backend simulé
CompiléBackend PTY natif
terminal_pty_portablePortablePtyBackend et entrées-sorties natives du processus enfant
Compilé sur Linux
| Couche | Feature Cargo | Ce qu'elle ajoute | Vérification |
|---|---|---|---|
| Widgets riches | Features par défaut | Mises en page, tableaux, superpositions, graphiques, éditeurs, Terminal et TerminalView | Compilé |
| Analyse Rust enrichie | tree_sitter | Syntaxe Tree-sitter, symboles, appels et régions repliables pour Rust | Compilé avec verrouillage |
| Instantanés de fichiers | files | FileExplorer indépendant du fournisseur et modèles de fichiers | Compilé |
| Fichiers locaux | files_local | LocalFileExplorer, fournisseurs locaux et chargement en arrière-plan | Compilé |
| Contrats PTY | terminal_pty | Trait de backend, handle de session, événements, regroupement et backend simulé | Compilé |
| Backend PTY natif | terminal_pty_portable | PortablePtyBackend et entrées-sorties natives du processus enfant | Compilé sur Linux |
Disponible par défaut ne veut pas dire connecté
Terminal et TerminalView peuvent effectuer leur rendu sans support PTY. Activer terminal_pty expose les contrats d'entrées-sorties de processus sans les relier automatiquement à votre application.
Écrivez le contrat des features dans Cargo.toml
Gardez beta.2 épinglée, puis ajoutez seulement les noms des features nécessaires à la prochaine couche de votre application.
[package]
name = "ailloli_ui_book_feature_matrix"
version = "0.1.0"
edition = "2021"
rust-version = "1.88"
publish = false
[features]
tree-sitter = ["ailloli_ui/tree_sitter"]
files = ["ailloli_ui/files"]
files-local = ["files", "ailloli_ui/files_local"]
terminal-pty = ["ailloli_ui/terminal_pty"]
terminal-pty-portable = ["terminal-pty", "ailloli_ui/terminal_pty_portable"]
[dependencies]
ailloli_ui = "=0.1.0-beta.2"use ailloli_ui::prelude::*;
#[cfg(feature = "terminal-pty-portable")]
use ailloli_ui::PortablePtyBackend;
#[cfg(feature = "terminal-pty")]
use ailloli_ui::{MockPtyBackend, PtyBackend, PtySpawnConfig};
fn main() {
let _editor = Editor::new(State::new(TextBuffer::from_string(
"A friendly note".to_owned(),
)));
let _code_editor: CodeEditor<()> = CodeEditor::new(State::new(Document::new(
DocumentId(1),
TextBuffer::from_string("fn main() {}".to_owned()),
)))
.language(EditorLanguage::Rust);
let _log = TerminalView::new()
.line(TerminalLine::prompt("$ cargo check"))
.line(TerminalLine::success("Finished"));
#[cfg(feature = "files")]
{
let root = FileUri::parse("file:///project").expect("valid URI");
let node =
FileExplorerNode::directory(root.clone(), "project").child(FileExplorerNode::file(
root.join_child("main.rs").expect("valid child URI"),
"main.rs",
));
let _files = FileExplorer::<()>::new([node]).default_expanded(root);
}
#[cfg(feature = "files-local")]
let _local_files = LocalFileExplorer::<()>::new(".").lazy_cached();
#[cfg(feature = "terminal-pty")]
{
let backend = MockPtyBackend::default();
let handle = backend
.spawn(PtySpawnConfig::default())
.expect("mock PTY spawn");
handle.shutdown().expect("mock PTY shutdown");
}
#[cfg(feature = "terminal-pty-portable")]
let _portable_backend = PortablePtyBackend::new();
}Verrouillage temporaire pour Rust 1.88
Exécutez cette commande uniquement avec tree_sitter sur Rust 1.88, puis enregistrez le Cargo.lock obtenu dans l'application et revérifiez-le quand les dépendances de beta.2 changent.
cargo update -p tree-sitter-language --precise 0.1.707
Un terminal possède trois couches distinctes
Séparer présentation, émulation et entrées-sorties du processus évite de transformer discrètement un journal en lanceur de shell.
TerminalView
Un journal défilable pour des lignes statiques ou des événements en flux. Ce n'est pas un PTY et il n'analyse pas les séquences ANSI.
Terminal
Une vue interactive de TerminalState. Elle peut émettre des octets de protocole, mais votre application reste propriétaire du transport et de la synchronisation.
terminal_pty
Ajoute les contrats de backend, les handles, le regroupement et un simulateur sûr en mémoire. terminal_pty_portable ajoute le backend natif portable-pty.
Traitez le lancement de processus comme une frontière de sécurité
Le backend portable n'isole pas les programmes, ne valide ni les chemins ni l'environnement, ne masque pas les sorties et ne borne pas ses files. Validez chaque entrée avant tout lancement.
À vous de jouer
Exercice : observez un panneau redimensionnable
Transformez un comportement de mise en page riche en une petite expérience visible.
- 1Liez la position d'un SplitPane à un State initialisé à 280.
- 2Affichez la position courante dans un Text pendant le déplacement du séparateur.
Gardez le contenu des deux panneaux très simple. Une étiquette de chaque côté suffit.
Faire glisser le séparateur change les tailles des panneaux et le nombre affiché.