2 个版本
0.1.1 | 2022 年 5 月 13 日 |
---|---|
0.1.0 | 2022 年 5 月 13 日 |
#1089 在 GUI
58KB
415 行
Douglas 是一个基于 Elm 架构构建的微型终端 UI 框架。它深受 Elm 架构 影响,并受到了 bubbletea 和 iced 的启发。
使用方法
使用 Douglas 构建 UI 非常简单!
use douglas::{Config, Program};
struct App;
impl Program for App {
type Message = ();
fn view(&self) -> String {
"Hello, world!\n".into()
}
}
fn main() {
App.run(&mut Config::default()).unwrap();
}
当然,这并不令人兴奋。Douglas 应用程序只需要三个要素
init
初始化你的状态模型,并执行任何设置update
处理消息和用户输入view
渲染你的 UI(你已见过这个!)
use douglas::{Command, Config, Mailbox, Program};
// declare your state model
struct App {
counter: usize,
}
// setup a constructor
impl App {
fn new() -> Self {
Self {
counter: 0,
}
}
}
// declare message type
enum Message {
Increment,
Decrement,
}
impl Program for App {
type Message = Message;
fn init(&mut self, _: Mailbox<Self::Message>) -> Command<Self::Message> {
// send an Increment message right away
Command::send(Message::Increment)
}
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
// you can pattern match on incoming messages
match message {
Message::Increment => self.counter += 1,
Message::Decrement => self.counter -= 1,
}
Command::none()
}
fn view(&self) -> String {
format!("count: {}\n", self.counter)
}
}
fn main() {
let app = App::new();
let config = Config::default();
app.run(&mut config).unwrap();
}
最后,如果你需要执行任何清理工作,你可以实现 exit
use douglas::Program;
impl Program for App {
// (...snip...)
fn exit(self) {
println!("Goodbye, cruel world!");
}
}
处理事件
除了 update
,应用程序还可以实现 on_event
来响应用户在终端上的按键等事件,并发送消息
use douglas::{Command, Program};
use crossterm::event::{Event, KeyCode, KeyEvent};
impl Program for App {
// (...snip...)
fn on_event(event: Event) -> Command<Self::Message> {
match event {
Event::Key(KeyEvent { code: KeyCode::Up, .. }) =>
Command::send(Message::Increment),
_ => Command::none()
}
}
}
外部交互
有时,响应发生在程序生命周期之外的事件很有用,比如当数据在网络中可用时响应,或者每隔一段时间发送消息。你可以使用程序的信箱
use douglas::{Command, Mailbox, Program, Timer};
use crossterm::event::{Event, KeyCode, KeyEvent};
use std::time::Duration;
struct App {
timer: Timer,
}
#[derive(Clone)]
enum Message {
Tick,
}
impl App {
fn new() -> Self {
Self {
timer: Timer::new(Duration::from_millis(1_000), Message::Tick),
}
}
}
impl Program for App {
// (...snip...)
fn init(&mut self, mailbox: Mailbox<Self::Message>) -> Command<Self::Message> {
self.timer.start(mailbox);
Command::none()
}
// make sure to clean up!
fn exit(mut self) {
self.timer.stop();
}
}
示例
你可以查看 examples
目录,以查看一些实际项目的操作。你还可以直接运行一个示例
cargo run --package hello_world
贡献
此项目正在开发中。所有贡献都欢迎!
此项目遵循 贡献者公约。请互相友好相处 :)
许可协议
此项目根据 MIT 许可协议 发布。版权所有 2022 Aaron Ross,保留所有权利。
依赖项
~2.5MB
~41K SLoC