Skip to content

Commit 263bfb0

Browse files
committed
Allow adding custom methods in the #[widget] trait
1 parent a5364c9 commit 263bfb0

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

examples/communication-attribute.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl Widget for Counter {
103103
fn update(&mut self, event: CounterMsg) {
104104
match event {
105105
Decrement => self.model.counter -= 1,
106-
Increment => self.model.counter += 1,
106+
Increment => self.increment(),
107107
}
108108
}
109109

@@ -123,6 +123,10 @@ impl Widget for Counter {
123123
},
124124
}
125125
}
126+
127+
fn increment(&mut self) {
128+
self.model.counter += 1;
129+
}
126130
}
127131

128132
#[derive(Clone)]

relm-gen-widget/src/lib.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub struct Driver {
7676
model_type: Option<ImplItem>,
7777
model_param_type: Option<ImplItem>,
7878
msg_type: Option<ImplItem>,
79+
other_methods: Vec<ImplItem>,
7980
properties_model_map: Option<PropertyModelMap>,
8081
root_method: Option<ImplItem>,
8182
root_type: Option<ImplItem>,
@@ -103,12 +104,13 @@ impl Driver {
103104
Driver {
104105
data_method: None,
105106
generic_types: None,
106-
root_method: None,
107-
root_type: None,
108107
model_type: None,
109108
model_param_type: None,
110109
msg_type: None,
110+
other_methods: vec![],
111111
properties_model_map: None,
112+
root_method: None,
113+
root_type: None,
112114
root_widget: None,
113115
root_widget_expr: None,
114116
root_widget_type: None,
@@ -121,6 +123,13 @@ impl Driver {
121123
}
122124
}
123125

126+
fn add_set_property_to_method(&self, func: &mut ImplItem) {
127+
if let Method(_, ref mut block) = func.node {
128+
let mut adder = Adder::new(self.properties_model_map.as_ref().expect("update method"));
129+
*block = adder.fold_block(block.clone());
130+
}
131+
}
132+
124133
fn add_widgets(&mut self, widget: &Widget, map: &PropertyModelMap) {
125134
// Only add widgets that are needed by the update() function.
126135
let mut to_add = false;
@@ -186,7 +195,7 @@ impl Driver {
186195
self.widget_msg_type = Some(get_second_param_type(&sig));
187196
self.update_method = Some(i)
188197
},
189-
method_name => panic!("Unexpected method {}", method_name),
198+
_ => self.other_methods.push(i),
190199
}
191200
},
192201
Type(_) => {
@@ -218,13 +227,16 @@ impl Driver {
218227
}
219228
new_items.push(self.get_update());
220229
new_items.push(self.get_root());
230+
let other_methods = self.get_other_methods(&typ);
221231
let item = Impl(unsafety, polarity, generics, path, typ, new_items);
222232
ast.node = item;
223233
let container_impl = view.container_impl;
224234
quote! {
225235
#widget_struct
226236
#ast
227237
#container_impl
238+
239+
#other_methods
228240
}
229241
}
230242
else {
@@ -273,6 +285,18 @@ impl Driver {
273285
})
274286
}
275287

288+
fn get_other_methods(&mut self, typ: &Ty) -> Tokens {
289+
let mut other_methods: Vec<_> = self.other_methods.drain(..).collect();
290+
for method in &mut other_methods {
291+
self.add_set_property_to_method(method);
292+
}
293+
quote! {
294+
impl #typ {
295+
#(#other_methods)*
296+
}
297+
}
298+
}
299+
276300
fn get_root(&mut self) -> ImplItem {
277301
self.root_method.take().unwrap_or_else(|| {
278302
let root_widget_expr = self.root_widget_expr.take().expect("root widget expr");
@@ -299,10 +323,7 @@ impl Driver {
299323
*/
300324
fn get_update(&mut self) -> ImplItem {
301325
let mut func = self.update_method.take().expect("update method");
302-
if let Method(_, ref mut block) = func.node {
303-
let mut adder = Adder::new(self.properties_model_map.as_ref().expect("update method"));
304-
*block = adder.fold_block(block.clone());
305-
}
326+
self.add_set_property_to_method(&mut func);
306327
// TODO: consider gtk::main_quit() as return.
307328
func
308329
}

0 commit comments

Comments
 (0)