Skip to content

Commit fbf842c

Browse files
committed
Add support for generic widget
1 parent 0d511e8 commit fbf842c

7 files changed

Lines changed: 488 additions & 64 deletions

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
#![feature(proc_macro)]
23+
24+
extern crate gtk;
25+
#[macro_use]
26+
extern crate relm;
27+
extern crate relm_attributes;
28+
#[macro_use]
29+
extern crate relm_derive;
30+
31+
use std::fmt::Display;
32+
33+
use gtk::{
34+
ButtonExt,
35+
Inhibit,
36+
OrientableExt,
37+
WidgetExt,
38+
};
39+
use gtk::Orientation::{Horizontal, Vertical};
40+
use relm::Widget;
41+
use relm_attributes::widget;
42+
43+
use self::CounterMsg::*;
44+
use self::Msg::*;
45+
46+
pub trait IncDec {
47+
fn dec(&self) -> Self;
48+
fn inc(&self) -> Self;
49+
}
50+
51+
impl IncDec for i32 {
52+
fn dec(&self) -> Self {
53+
*self - 1
54+
}
55+
56+
fn inc(&self) -> Self {
57+
*self + 1
58+
}
59+
}
60+
61+
#[derive(Clone)]
62+
pub struct Model<T> {
63+
counter: T,
64+
}
65+
66+
#[derive(Msg)]
67+
pub enum CounterMsg {
68+
Decrement,
69+
Increment,
70+
}
71+
72+
#[widget]
73+
impl<T: Clone + IncDec + Display> Widget for Counter<T> {
74+
fn model(value: T) -> Model<T> {
75+
Model {
76+
counter: value,
77+
}
78+
}
79+
80+
fn update(&mut self, event: CounterMsg, model: &mut Self::Model) {
81+
match event {
82+
Decrement => {
83+
model.counter = model.counter.dec();
84+
},
85+
Increment => {
86+
model.counter = model.counter.inc();
87+
},
88+
}
89+
}
90+
91+
view! {
92+
gtk::Box {
93+
orientation: Vertical,
94+
gtk::Button {
95+
label: "+",
96+
clicked => Increment,
97+
},
98+
gtk::Label {
99+
text: &model.counter.to_string(),
100+
//let counter_label = Label::new(Some(model.counter.to_string().as_ref()));
101+
},
102+
gtk::Button {
103+
label: "-",
104+
clicked => Decrement,
105+
},
106+
}
107+
}
108+
}
109+
110+
#[derive(Msg)]
111+
pub enum Msg {
112+
Quit,
113+
}
114+
115+
#[widget]
116+
impl Widget for Win {
117+
fn model(_: ()) -> () {
118+
()
119+
}
120+
121+
fn update(&mut self, event: Msg, _model: &mut ()) {
122+
match event {
123+
Quit => gtk::main_quit(),
124+
}
125+
}
126+
127+
view! {
128+
gtk::Window {
129+
gtk::Box {
130+
orientation: Horizontal,
131+
Counter<i32>(2),
132+
Counter<i32>(3),
133+
},
134+
delete_event(_, _) => (Quit, Inhibit(false)),
135+
}
136+
}
137+
}
138+
139+
fn main() {
140+
Win::run(()).unwrap();
141+
}

examples/generic-widget.rs

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
* Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
extern crate gtk;
23+
#[macro_use]
24+
extern crate relm;
25+
#[macro_use]
26+
extern crate relm_derive;
27+
28+
use std::fmt::Display;
29+
use std::marker::PhantomData;
30+
31+
use gtk::{
32+
Button,
33+
ButtonExt,
34+
ContainerExt,
35+
Inhibit,
36+
Label,
37+
WidgetExt,
38+
Window,
39+
WindowType,
40+
};
41+
use gtk::Orientation::{Horizontal, Vertical};
42+
use relm::{Component, ContainerWidget, RemoteRelm, Widget};
43+
44+
use self::CounterMsg::*;
45+
use self::Msg::*;
46+
47+
trait IncDec {
48+
fn dec(&mut self);
49+
fn inc(&mut self);
50+
}
51+
52+
impl IncDec for i32 {
53+
fn dec(&mut self) {
54+
*self -= 1;
55+
}
56+
57+
fn inc(&mut self) {
58+
*self += 1;
59+
}
60+
}
61+
62+
#[derive(Clone)]
63+
struct Model<T> {
64+
counter: T,
65+
}
66+
67+
#[derive(Msg)]
68+
enum CounterMsg {
69+
Decrement,
70+
Increment,
71+
}
72+
73+
#[derive(Clone)]
74+
struct Counter<T> {
75+
counter_label: Label,
76+
vbox: gtk::Box,
77+
_phantom: PhantomData<T>,
78+
}
79+
80+
impl<T: Clone + IncDec + Display> Widget for Counter<T> {
81+
type Model = Model<T>;
82+
type ModelParam = T;
83+
type Msg = CounterMsg;
84+
type Root = gtk::Box;
85+
86+
fn model(value: T) -> Self::Model {
87+
Model {
88+
counter: value,
89+
}
90+
}
91+
92+
fn root(&self) -> &Self::Root {
93+
&self.vbox
94+
}
95+
96+
fn update(&mut self, event: CounterMsg, model: &mut Self::Model) {
97+
let label = &self.counter_label;
98+
99+
match event {
100+
Decrement => {
101+
model.counter.dec();
102+
label.set_text(&model.counter.to_string());
103+
},
104+
Increment => {
105+
model.counter.inc();
106+
label.set_text(&model.counter.to_string());
107+
},
108+
}
109+
}
110+
111+
fn view(relm: &RemoteRelm<Self>, model: &Self::Model) -> Self {
112+
let vbox = gtk::Box::new(Vertical, 0);
113+
114+
let plus_button = Button::new_with_label("+");
115+
vbox.add(&plus_button);
116+
117+
let counter_label = Label::new(Some(model.counter.to_string().as_ref()));
118+
vbox.add(&counter_label);
119+
120+
let minus_button = Button::new_with_label("-");
121+
vbox.add(&minus_button);
122+
123+
connect!(relm, plus_button, connect_clicked(_), Increment);
124+
connect!(relm, minus_button, connect_clicked(_), Decrement);
125+
126+
Counter {
127+
counter_label: counter_label,
128+
vbox: vbox,
129+
_phantom: PhantomData,
130+
}
131+
}
132+
}
133+
134+
#[derive(Msg)]
135+
enum Msg {
136+
Quit,
137+
}
138+
139+
#[derive(Clone)]
140+
struct Win {
141+
_counter1: Component<Counter<i32>>,
142+
_counter2: Component<Counter<i32>>,
143+
window: Window,
144+
}
145+
146+
impl Widget for Win {
147+
type Model = ();
148+
type ModelParam = ();
149+
type Msg = Msg;
150+
type Root = Window;
151+
152+
fn model(_: ()) -> () {
153+
()
154+
}
155+
156+
fn root(&self) -> &Self::Root {
157+
&self.window
158+
}
159+
160+
fn update(&mut self, event: Msg, _model: &mut ()) {
161+
match event {
162+
Quit => gtk::main_quit(),
163+
}
164+
}
165+
166+
fn view(relm: &RemoteRelm<Self>, _model: &()) -> Win {
167+
let window = Window::new(WindowType::Toplevel);
168+
169+
let hbox = gtk::Box::new(Horizontal, 0);
170+
171+
let counter1 = hbox.add_widget::<Counter<i32>, _>(&relm, 2);
172+
let counter2 = hbox.add_widget::<Counter<i32>, _>(&relm, 3);
173+
window.add(&hbox);
174+
175+
window.show_all();
176+
177+
connect!(relm, window, connect_delete_event(_, _) (Some(Quit), Inhibit(false)));
178+
179+
Win {
180+
_counter1: counter1,
181+
_counter2: counter2,
182+
window: window,
183+
}
184+
}
185+
}
186+
187+
fn main() {
188+
Win::run(()).unwrap();
189+
}

relm-gen-widget/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ documentation = "https://docs.rs/relm-gen-widget/"
55
license = "MIT"
66
name = "relm-gen-widget"
77
repository = "https://github.com/antoyo/relm"
8-
version = "0.9.0"
8+
version = "0.9.1"
99

1010
[dependencies]
1111
lazy_static = "^0.2.4"

0 commit comments

Comments
 (0)