- Notifications
You must be signed in to change notification settings - Fork80
Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust
License
antoyo/relm
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Since relm is based on GTK+, you need this library on your system in order to use it.
Seethis page for information on how to install GTK+.
First, add this to yourCargo.toml
:
gtk ="^0.16.0"relm ="^0.24.0"relm-derive ="^0.24.0"
Next, add this to your crate:
use relm::{connect,Relm,Update,Widget};use gtk::prelude::*;use gtk::{Window,Inhibit,WindowType};use relm_derive::Msg;
Then, create your model:
structModel{// …}
The model contains the data related to aWidget
. It may be updated by theWidget::update
function.
Create your messageenum
:
#[derive(Msg)]enumMsg{// …Quit,}
Messages are sent toWidget::update
to indicate that an event happened. The model can be updated when an event is received.
Create astruct
which represents aWidget
which contains the GTK+ widgets (in this case, the main window of the application) and the model:
structWin{// …model:Model,window:Window,}
To make thisstruct
a relmWidget
that can be shown by the library, implement theUpdate
andWidget
traits:
implUpdateforWin{// Specify the model used for this widget.typeModel =Model;// Specify the model parameter used to init the model.typeModelParam =();// Specify the type of the messages sent to the update function.typeMsg =Msg;// Return the initial model.fnmodel(_:&Relm<Self>, _:()) ->Model{Model{}}// The model may be updated when a message is received.// Widgets may also be updated in this function.fnupdate(&mutself,event:Msg){match event{Msg::Quit => gtk::main_quit(),}}}implWidgetforWin{// Specify the type of the root widget.typeRoot =Window;// Return the root widget.fnroot(&self) ->Self::Root{self.window.clone()}// Create the widgets.fnview(relm:&Relm<Self>,model:Self::Model) ->Self{// GTK+ widgets are used normally within a `Widget`.let window =Window::new(WindowType::Toplevel);// Connect the signal `delete_event` to send the `Quit` message.connect!(relm, window, connect_delete_event(_, _),return(Some(Msg::Quit),Inhibit(false)));// There is also a `connect!()` macro for GTK+ events that do not need a// value to be returned in the callback. window.show_all();Win{ model, window,}}}
Finally, show thisWidget
by callingWin::run()
:
fnmain(){Win::run(()).unwrap();}
A#[widget]
attribute is provided to simplify the creation of a widget.
This attribute does the following:
Provide a
view!
macro to create the widget with a declarative syntax.Automatically create the
fn root()
,type Msg
,type Model
,type ModelParam
andtype Root
items.Automatically insert the call to
Widget::set_property()
in theupdate()
function when assigning to an attribute of the model.Automatically create the
Widget
struct
.Update
andWidget
traits can be implemented at once.
To use this attribute, add the following code:
use relm_derive::widget;
Here is an example using this attribute:
#[derive(Msg)]pubenumMsg{Decrement,Increment,Quit,}pubstructModel{counter:u32,}#[widget]implWidgetforWin{fnmodel() ->Model{Model{counter:0,}}fnupdate(&mutself,event:Msg){match event{// A call to self.label1.set_text() is automatically inserted by the// attribute every time the model.counter attribute is updated.Msg::Decrement =>self.model.counter -=1,Msg::Increment =>self.model.counter +=1,Msg::Quit => gtk::main_quit(),}}view!{ gtk::Window{ gtk::Box{ orientation:Vertical, gtk::Button{// By default, an event with one paramater is assumed. clicked =>Msg::Increment,// Hence, the previous line is equivalent to:// clicked(_) => Increment, label:"+",}, gtk::Label{// Bind the text property of this Label to the counter attribute// of the model.// Every time the counter attribute is updated, the text property// will be updated too. text:&self.model.counter.to_string(),}, gtk::Button{ clicked =>Msg::Decrement, label:"-",},},// Use a tuple when you want to both send a message and return a value to// the GTK+ callback. delete_event(_, _) =>(Msg::Quit,Inhibit(false)),}}}
Note | Thestruct Win is now automatically created by the attribute, as are the functionroot() and the associated typesModel ,ModelParam ,Msg andContainer .You can still provide the method and the associated types if needed, but you cannot create thestruct . |
Warning | The#[widget] makes the generatedstruct public: hence, the corresponding model and message types must be public too. |
Warning | Your program might be slower when using this attribute because the code generation is simple.For instance, the following code fnupdate(&mutself,event:Msg){for _in0..100{self.model.counter +=1;}} will generate this function: fnupdate(&mutself,event:Msg){for _in0..100{self.model.counter +=1;self.label1.set_text(&self.model.counter.to_string());}} |
Warning | Also, the fnupdate(&mutself,event:Msg){self.model.text.push_str("Text");} will not work as expected. Please use the following variation if needed. fnupdate(&mutself,event:Msg){self.model.text +="Text";} |
For more information about how you can use relm, you can take a look at theexamples.
Yellow Pitaya: A desktop interface for the redpitaya hardware oscilloscope.
Game of Life: Conway’s Game of Life Simulator
Country Parser: Parses Google location history and displays timeline of countries visited
Chessground: An experimental chessboard widget
Effitask: Graphical task manager, based on the todo.txt format
KS Curve Tracer: A companion app for AD2 curve tracer
Cigale: Tool to prepare the timesheet of the tasks you did at work
Projectpad: Manage secret credentials and server information as a software developer or sysadmin.
TimezoneRS: A GUI application to visually see the time in different time zones
Tubefeeder /Pipeline: Watch YouTube, LBRY, and PeerTube videos in one place.
Hotwire: Study network traffic of a few popular protocols in a simple way
gue: GUI for controlling phillips hue lights
MyCitadel Wallet: MyCitadel Cryptocurrency Wallet app
If you want to add your project to this list, pleasecreate a pull request.
About
Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust