Druid es un framework para crear aplicaciones gráficas simples. Se podía decir que es un Java Swing para el lenguaje Rust.
La documentación oficial dice:
"El framework está orientado a datos. Comparte muchas ideas (y se inspira directamente) en frameworks de interfaz de usuario declarativos contemporáneos como Flutter, Jetpack Compose y SwiftUI, a la vez que intenta ser conceptualmente simple y, en gran medida, no mágico".
Druid permite crear aplicaciones gráficas interactivas sencillas que se pueden implementar en Windows, macOS, Linux, OpenBSD, FreeBSD y la web.
Druid se basa en druid-shell, que implementa todo el código de nivel inferior específico de la plataforma, proporcionando una abstracción común para funciones como eventos de teclado y ratón, la creación de ventanas y el lanzamiento de aplicaciones. Por debajo de druid-shell se encuentra piet, una biblioteca de gráficos 2D multiplataforma que proporciona una API de dibujo sencilla y familiar que se puede implementar en diversas plataformas.
Druid es un framework declarativo basado en datos. Describes el modelo de tu aplicación en términos del rasgo "Datos" y luego construyes un árbol de widgets que pueden mostrar y modificar tus datos.
Tus widgets gestionan eventos, como el movimiento del ratón, y pueden modificar los datos; estos cambios se envían a los widgets correspondientes, que pueden actualizar su estado y redibujarlos.
A medida que su aplicación crece, puede usar Lenses para exponer solo ciertos subconjuntos de su modelo de datos a ciertos subconjuntos de su árbol de widgets.
Requisitos:
- Tener instalado Rust.
- Tener instalado Cargo.
Creando una aplicación con Cargo
Crear proyecto y ubicarse en el directorio creado:
$ cargo new hola_mundo_gui $ cd hola_mundo_gui
Editar el archivo Cargo.toml para agregar dependencia:
[package] name = "hola_mundo_gui" version = "0.1.0" edition = "2021" [dependencies] druid = "0.8.3"
También podemos usar esta forma para agregar la dependencia:
$ cargo add druid
Editar el programa main.rs
use druid::widget::{Align, Flex, Label, TextBox}; use druid::{AppLauncher, Data, Env, Lens, LocalizedString, Widget, WindowDesc, WidgetExt}; const VERTICAL_WIDGET_SPACING: f64 = 20.0; const TEXT_BOX_WIDTH: f64 = 200.0; const WINDOW_TITLE: LocalizedString<HelloState> = LocalizedString::new("GUI con Druid y Rust"); #[derive(Clone, Data, Lens)] struct HelloState { name: String, } fn main() { // describe the main window let main_window = WindowDesc::new(build_root_widget()) .title(WINDOW_TITLE) .window_size((400.0, 400.0)); // create the initial app state let initial_state = HelloState { name: "Mundo".into(), }; // start the application AppLauncher::with_window(main_window) .launch(initial_state) .expect("Failed to launch application"); } fn build_root_widget() -> impl Widget<HelloState> { // a label that will determine its text based on the current app data. let label = Label::new(|data: &HelloState, _env: &Env| format!("Hola {}!", data.name)); // a textbox that modifies `name`. let textbox = TextBox::new() .with_placeholder("Cual es tu nombre?") .fix_width(TEXT_BOX_WIDTH) .lens(HelloState::name); // arrange the two widgets vertically, with some padding let layout = Flex::column() .with_child(label) .with_spacer(VERTICAL_WIDGET_SPACING) .with_child(textbox); // center the two widgets in the available space Align::centered(layout) }
Construir y ejecutar:
$ cargo build $ cargo run
Se mostrará una ventana con la leyenda "Hola Mundo!" junto con un textbox con el texto de "Cual es tu nombre?". Podrás introducir tu nombre o cualquier texto y la leyenda cambiará a "Hola TEXTO_INTRODUCIDO".
Quienes hayan usado Java Swing algunas cosas les parecerán familiares. La GUI es muy sencilla, solo contiene un layout y una caja de texto o textbox que cambiará la leyenda con el texto introducido. El método main se encargará de ejecutar la ventana.
Modificaremos el programa para crear un incrementador o decrementador. Tendrá los botones para incrementar o decrementar un contador y se mostrará en el layout cuando el usuario de clic a alguno de los dos botones.
main.rs
use druid::widget::{Button, Flex, Label}; use druid::{AppLauncher, Data, Lens, LocalizedString, Widget, WidgetExt, WindowDesc}; #[derive(Clone, Data, Lens)] struct AppState { count: i32, } fn build_ui() -> impl Widget<AppState> { // Etiqueta que muestra el contador let label = Label::new(|data: &AppState, _env: &_| format!("Contador: {}", data.count)) .padding(5.0) .center(); // Botones para incrementar y decrementar let increment = Button::new("Incrementar") .on_click(|_ctx, data: &mut AppState, _env| data.count += 1) .padding(5.0); let decrement = Button::new("Decrementar") .on_click(|_ctx, data: &mut AppState, _env| data.count -= 1) .padding(5.0); // Organiza los widgets en una columna Flex::column() .with_child(label) .with_child(Flex::row().with_child(increment).with_child(decrement)) .padding(10.0) } fn main() { // Configura la ventana principal let main_window = WindowDesc::new(build_ui()) .title(LocalizedString::new("Contador Simple")) .window_size((400.0, 200.0)); // Estado inicial let initial_state = AppState { count: 0 }; // Lanza la aplicación AppLauncher::with_window(main_window) .launch(initial_state) .expect("Fallo al lanzar la aplicación"); }
Construimos y ejecutamos:
$ cargo build $ cargo run
Se ejecutará el programa y mostrará una ventana con dos botones, uno para incrementar y el otro para decrementar un contador.
¡Hemos creado nuestras primeras aplicaciones GUI con Druid Framework!
Continuaremos con esta serie sobre Rust en próximas entregas.
Enlaces:
https://areweguiyet.com/https://github.com/linebender/druid/tree/master/druid/examples
https://docs.rs/druid/latest/druid/
https://linebender.org/druid/
Comentarios
Publicar un comentario