Glyph User Interface
Not your typical GUI library: Glyph UI is actually for implementing text-based interfaces. In particular, its usage is designed to result in maintainable applications even at large numbers of components by leveraging the Elm architecture.
Examples
Glyph UI's hello world isn't the most succinct, but that's a non-goal. With that understanding, let's get started by setting up our imports:
use ;
// We'll use this later for detecting specific keypresses
use Key;
Next, let's define our model:
Now we can implement the Gui trait for our model, which
describes what our view will look like, how to handle messages, and when to
exit the application:
# use ;
# use Key;
#
Nearly there! The final piece is to create and start the
Runtime, which we'll do now:
# use glyph_ui::{
# prelude::*,
# event::Event,
# view::{
# prelude::*,
# text,
# },
# };
# use keyboard_types::Key;
# struct HelloWorld {
# shutdown: bool,
# }
# impl Gui for HelloWorld {
# type Message = bool;
# type Event = ();
# fn view(&mut self) -> element::View<Self::Event, Self::Message> {
# text::new("Hello, world!")
# .on_event(|e, _f| {
# if let Event::Key(k) = e {
# if let Key::Character(c) = &k.key {
# if c == "q" {
# return Box::new(std::iter::once(true));
# }
# }
# }
# Box::new(std::iter::empty())
# })
# .into_element()
# }
# fn update(&mut self, m: Self::Message) {
# self.shutdown = m;
# }
# fn control_flow(&self) -> ControlFlow {
# if self.shutdown {
# ControlFlow::Exit
# } else {
# ControlFlow::Wait
# }
# }
# }
#[tokio::main]
async fn main() {
// Instantiate our model
let gui = HelloWorld {
shutdown: false,
};
// Create and start the runtime
Runtime::new(gui, |task| tokio::spawn(task)).run().await;
}
Now if we compile and run our code, we'll see Hello, world! in the top
left corner of our terminal, and we'll get our shell back if we press the
q key. For more examples that demonstrate more complex applications, see
here.