Skip to content

Instantly share code, notes, and snippets.

@zzeroo
Created November 22, 2017 16:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zzeroo/07155d47bf97876dcdc4c11bed731ba9 to your computer and use it in GitHub Desktop.
Save zzeroo/07155d47bf97876dcdc4c11bed731ba9 to your computer and use it in GitHub Desktop.
Second part of the relm README example code
#![feature(proc_macro)]
/// # `#[widget] attribute`
///
/// For the nightly users, 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 and type Root items.
/// * Automatically insert the call to Widget::set_property() in the update() function when assigning to an attribute of the model.
/// * Automatically create the Widget struct.
/// * Both traits can be implemented at once.
///
/// To be able to use this attribute, you need to add the `relm-attributes` crate in your `Cargo.toml`:
/// ```
/// relm-attributes = "^0.10.0"
/// ```
/// Add the following code on top of your code:
// #![feature(proc_macro)]
/// and add `relm_attributes` crate.
// extern crate relm_attributes;
/// The modified imports sould look like these:
extern crate gtk;
#[macro_use]
extern crate relm;
#[macro_use]
extern crate relm_derive;
extern crate relm_attributes;
use gtk::Orientation::Vertical;
use gtk::prelude::*;
use Msg::*;
use relm_attributes::widget;
use relm::Widget;
/// Add a `counter` member to your `Model` struct.
pub struct Model {
counter: i32,
}
/// And `Increment` and `Decrement` messages to the `Msg` enum.
#[derive(Msg)]
pub enum Msg {
Increment,
Decrement,
Quit,
}
/// Next delete the window struct (`struct Win {}`), plus the `impl Update for Win {}` and the `impl Widget for Win {}` blocks.
/// Here is an example using the `#[widget]` attribute. This code combines the previous deleted elements:
#[widget]
impl Widget for Win {
fn model() -> Model {
Model {
counter: 0,
}
}
fn update(&mut self, event: Msg) {
match event {
// A call to self.label1.set_text() is automatically inserted by the
// attribute every time the model.counter attribute is updateed.
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 parameter is assumed.
clicked => 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 => Decrement,
label: "-",
},
},
// Use a tupple when you want to both send a message and return a value to
// the GTK+ backend.
delete_event(_, _) => (Quit, gtk::Inhibit(false)),
}
}
}
fn main() {
Win::run(()).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment