relm4_components/
simple_adw_combo_row.rs1use std::fmt::Debug;
5
6use relm4::{Component, ComponentParts, ComponentSender, adw};
7
8use adw::gtk::StringList;
9use adw::prelude::ComboRowExt;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct SimpleComboRow<E: ToString> {
21 pub variants: Vec<E>,
23 pub active_index: Option<usize>,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum SimpleComboRowMsg<E: ToString> {
30 UpdateData(SimpleComboRow<E>),
32 SetActiveIdx(usize),
34 #[doc(hidden)]
35 UpdateIndex(usize),
36}
37
38impl<E> Component for SimpleComboRow<E>
39where
40 E: ToString + 'static + Debug,
41{
42 type CommandOutput = ();
43 type Input = SimpleComboRowMsg<E>;
44 type Output = usize;
45 type Init = Self;
46 type Root = adw::ComboRow;
47 type Widgets = adw::ComboRow;
48
49 fn init_root() -> Self::Root {
50 adw::ComboRow::default()
51 }
52
53 fn init(
54 model: Self::Init,
55 widgets: Self::Root,
56 sender: ComponentSender<Self>,
57 ) -> ComponentParts<Self> {
58 model.render(&widgets);
59
60 widgets.connect_selected_notify(move |combo_box| {
61 sender.input(Self::Input::UpdateIndex(combo_box.selected() as _));
62 });
63
64 ComponentParts { model, widgets }
65 }
66
67 fn update_with_view(
68 &mut self,
69 widgets: &mut Self::Widgets,
70 input: Self::Input,
71 sender: ComponentSender<Self>,
72 _root: &Self::Root,
73 ) {
74 match input {
75 SimpleComboRowMsg::UpdateIndex(idx) => {
76 sender.output(idx).ok();
79 self.active_index = Some(idx);
80 }
81 SimpleComboRowMsg::SetActiveIdx(idx) => {
82 if idx < self.variants.len() {
83 self.active_index = Some(idx);
84 widgets.set_selected(idx as u32);
85 }
86 }
87 SimpleComboRowMsg::UpdateData(data) => {
88 *self = data;
89 self.render(widgets);
90 }
91 }
92 }
93}
94
95impl<E> SimpleComboRow<E>
96where
97 E: ToString,
98{
99 fn render(&self, combo_box: &adw::ComboRow) {
100 let model: StringList = self.variants.iter().map(ToString::to_string).collect();
101 combo_box.set_model(Some(&model));
102
103 if let Some(idx) = self.active_index {
104 combo_box.set_selected(idx as u32);
105 }
106 }
107
108 #[must_use]
110 pub fn get_active_elem(&self) -> Option<&E> {
111 self.active_index.map(|idx| &self.variants[idx])
112 }
113}