97 lines
No EOL
2.2 KiB
Markdown
97 lines
No EOL
2.2 KiB
Markdown
# COSMIC Component System
|
|
|
|
This library is a prototyping area for a rewrite of Relm4's component system.
|
|
|
|
## Using a Macro to Define a Component
|
|
|
|
The simplest way to define a component is to use the `component!()` macro.
|
|
|
|
```rs
|
|
pub enum MyCustomInputMessage {
|
|
Variant1,
|
|
Variant2,
|
|
}
|
|
|
|
pub enum MyCustomCommand {
|
|
Action
|
|
}
|
|
|
|
component! {
|
|
// The model stores the state of this component.
|
|
pub struct MyCustomModel {
|
|
pub state: String,
|
|
}
|
|
|
|
// Widgets managed by the view are stored here.
|
|
pub struct MyCustomWidgets {
|
|
description: gtk::Label,
|
|
}
|
|
|
|
// The type of the input sender
|
|
type Input = MyCustomInputMessage;
|
|
|
|
// The type of the output sender
|
|
type Output = ();
|
|
|
|
// Declares the root widget and how it should be constructed.
|
|
type Root = gtk::Box {
|
|
ccs::view! {
|
|
root = gtk::Box {
|
|
set_orientation: gtk::Orientation::Vertical,
|
|
}
|
|
}
|
|
|
|
root
|
|
};
|
|
|
|
// Constructs the inner component's model and widgets, using the
|
|
// initial parameter given by `args`.
|
|
fn init(args: (), root, input, output) {
|
|
let description = gtk::Label::new();
|
|
|
|
root.append(&description);
|
|
|
|
Fuselage {
|
|
model: MyCustomModel { state: String::new() },
|
|
widgets: MyCustomWidgets { description },
|
|
}
|
|
}
|
|
|
|
// Updates the model and view. `self` is the model.
|
|
fn update(&mut self, widgets, event, input, output) {
|
|
match event {
|
|
MyCustomInputMessage::Variant1 => {
|
|
|
|
}
|
|
|
|
MyCustomInputMessage::Variant2 => {
|
|
|
|
}
|
|
}
|
|
|
|
Some(MyCustomCommand::Action)
|
|
}
|
|
|
|
async fn command(command: MyCustomCommand, input) {
|
|
|
|
}
|
|
}
|
|
```
|
|
|
|
Components can be created and have their output events forwarded:
|
|
|
|
```rs
|
|
let counter = InfoButton::init()
|
|
.launch("Clicked 0 times".into(), "Click".into())
|
|
.forward(input.clone(), |event| match event {
|
|
InfoButtonOutput::Clicked => AppEvent::Increment
|
|
});
|
|
```
|
|
|
|
The handle returned can be used to emit inputs to it, and to get the root widget.
|
|
|
|
```rs
|
|
counter.emit(InfoButtonInput::SetDescription(format!("Clicked {} times", count)));
|
|
|
|
box.append(&counter.widget);
|
|
``` |