diff --git a/druid/examples/menu.rs b/druid/examples/menu.rs index 815283299b..910e24d0bf 100644 --- a/druid/examples/menu.rs +++ b/druid/examples/menu.rs @@ -74,15 +74,16 @@ fn build_menu() -> Menu { ) .entry( MenuItem::new("1 Selected") - .on_activate(|_, data: &mut AppState, _|if data.value == 1 {data.value = 0} else {data.value = 1}) - .selected_if(|data: &AppState, _|data.value == 1) + .radio_item(1, Some(0)) + .lens(AppState::value) ) .entry( MenuItem::new("2 Selected") - .on_activate(|_, data: &mut AppState, _|if data.value == 2 {data.value = 0} else {data.value = 2}) - .selected_if(|data: &AppState, _|data.value == 2) + .radio_item(2, Some(0)) + .lens(AppState::value) ) .entry( + // Implementing the radio item from hand MenuItem::new("3 Selected") .on_activate(|_, data: &mut AppState, _|if data.value == 3 {data.value = 0} else {data.value = 3}) .selected_if(|data: &AppState, _|data.value == 3) @@ -90,6 +91,12 @@ fn build_menu() -> Menu { .separator() .entry( MenuItem::new("CheckBox") + .toggle_data() + .lens(AppState::option) + ) + .entry( + // Implementing the CheckBox from hand + MenuItem::new("Manual CheckBox") .on_activate(|_, data: &mut AppState, _|data.option = !data.option) .selected_if(|data: &AppState, _|data.option) ) diff --git a/druid/src/menu/mod.rs b/druid/src/menu/mod.rs index 0624623664..44c5832c76 100644 --- a/druid/src/menu/mod.rs +++ b/druid/src/menu/mod.rs @@ -638,6 +638,23 @@ impl MenuItem { self.on_activate(move |ctx, _data, _env| ctx.submit_command(cmd.clone())) } + /// Turns this `MenuItem` into a `RadioButton` + /// + /// When selected this MenuItem will set the provided value as data. + /// If data is equal to the provided value the Item is selected otherwise not. + pub fn radio_item(self, value: T, unselect: Option) -> Self where T: PartialEq { + let value2 = value.clone(); + self + .on_activate(move |_, data: &mut T, _|{ + if data != value { + *data = value.clone(); + } else if let Some(value) = unselect.clone() { + *data = value; + } + }) + .selected_if(move |data, _|data == value2) + } + /// Provide a hotkey for activating this menu item. /// /// This is equivalent to @@ -723,6 +740,18 @@ impl MenuItem { } } +impl MenuItem { + /// Turns the MenuItem into a CheckBox. + /// + /// this is a convenience method which sets the `on_activate` and `selected_if` callbacks + /// to behave like a `CheckBox`. + pub fn toggle_data(self) -> Self { + self + .on_activate(|_, data, _|*data = !*data) + .selected_if(|data, _|*data) + } +} + impl MenuVisitor for Menu { fn activate(&mut self, ctx: &mut MenuEventCtx, id: MenuItemId, data: &mut T, env: &Env) { for child in &mut self.children {