truce_iced/widgets/
toggle.rs1use std::fmt::Debug;
4use std::marker::PhantomData;
5
6use iced::Element;
7use iced::widget::{column, text, toggler};
8
9use crate::param_cache::ParamCache;
10use crate::param_message::{Message, ParamMessage};
11use crate::theme;
12use truce_params::Params;
13
14pub struct ToggleWidget<'a, M> {
16 id: u32,
17 value: bool,
18 label: Option<&'a str>,
19 _phantom: PhantomData<M>,
20}
21
22impl<'a, M: Clone + Debug + 'static> ToggleWidget<'a, M> {
23 pub fn new(id: impl Into<u32>, params: &'a ParamCache<impl Params>) -> Self {
24 let id = id.into();
25 Self {
26 id,
27 value: params.get(id) >= 0.5,
28 label: None,
29 _phantom: PhantomData,
30 }
31 }
32
33 #[must_use]
34 pub fn label(mut self, label: &'a str) -> Self {
35 self.label = Some(label);
36 self
37 }
38
39 #[must_use]
40 pub fn into_element(self) -> Element<'a, Message<M>> {
41 let id = self.id;
42
43 let t = toggler(self.value)
44 .on_toggle(move |on| {
45 Message::Param(ParamMessage::SetNormalized(id, if on { 1.0 } else { 0.0 }))
46 })
47 .size(18.0);
48
49 let mut col = column![t].spacing(4).align_x(iced::Alignment::Center);
50
51 if let Some(label) = self.label {
52 col = col.push(text(label).size(10).color(theme::TEXT_DIM));
53 }
54
55 col.into()
56 }
57}
58
59impl<'a, M: Clone + Debug + 'static> From<ToggleWidget<'a, M>> for Element<'a, Message<M>> {
60 fn from(t: ToggleWidget<'a, M>) -> Self {
61 t.into_element()
62 }
63}