Skip to main content

winio_ui_winui/widgets/
list_box.rs

1use std::rc::Rc;
2
3use inherit_methods_macro::inherit_methods;
4use send_wrapper::SendWrapper;
5use windows::{
6    Foundation::IReference,
7    core::{HSTRING, IInspectable, Interface},
8};
9use winio_callback::Callback;
10use winio_handle::AsContainer;
11use winio_primitive::{Point, Size};
12use winui3::Microsoft::UI::Xaml::Controls::{
13    self as MUXC, SelectionChangedEventHandler, SelectionMode,
14};
15
16use crate::{GlobalRuntime, Result, Widget, widgets::ToIReference};
17
18#[derive(Debug)]
19pub struct ListBox {
20    on_select: SendWrapper<Rc<Callback<()>>>,
21    handle: Widget,
22    list_box: MUXC::ListBox,
23}
24
25#[inherit_methods(from = "self.handle")]
26impl ListBox {
27    pub fn new(parent: impl AsContainer) -> Result<Self> {
28        let list_box = MUXC::ListBox::new()?;
29        let on_select = SendWrapper::new(Rc::new(Callback::new()));
30        {
31            let on_select = on_select.clone();
32            list_box.SelectionChanged(&SelectionChangedEventHandler::new(move |_, _| {
33                on_select.signal::<GlobalRuntime>(());
34                Ok(())
35            }))?;
36        }
37        Ok(Self {
38            on_select,
39            handle: Widget::new(parent, list_box.cast()?)?,
40            list_box,
41        })
42    }
43
44    pub fn is_visible(&self) -> Result<bool>;
45
46    pub fn set_visible(&mut self, v: bool) -> Result<()>;
47
48    pub fn is_enabled(&self) -> Result<bool>;
49
50    pub fn set_enabled(&mut self, v: bool) -> Result<()>;
51
52    pub fn preferred_size(&self) -> Result<Size>;
53
54    pub fn min_size(&self) -> Result<Size>;
55
56    pub fn loc(&self) -> Result<Point>;
57
58    pub fn set_loc(&mut self, p: Point) -> Result<()>;
59
60    pub fn size(&self) -> Result<Size>;
61
62    pub fn set_size(&mut self, v: Size) -> Result<()>;
63
64    pub fn tooltip(&self) -> Result<String>;
65
66    pub fn set_tooltip(&mut self, s: impl AsRef<str>) -> Result<()>;
67
68    pub fn is_multiple(&self) -> Result<bool> {
69        Ok(self.list_box.SelectionMode()? != SelectionMode::Single)
70    }
71
72    pub fn set_multiple(&mut self, v: bool) -> Result<()> {
73        self.list_box.SetSelectionMode(if v {
74            SelectionMode::Multiple
75        } else {
76            SelectionMode::Single
77        })?;
78        Ok(())
79    }
80
81    pub fn is_selected(&self, i: usize) -> Result<bool> {
82        self.list_box
83            .Items()?
84            .GetAt(i as _)?
85            .cast::<MUXC::ListBoxItem>()?
86            .IsSelected()
87    }
88
89    pub fn set_selected(&mut self, i: usize, v: bool) -> Result<()> {
90        self.list_box
91            .Items()?
92            .GetAt(i as _)?
93            .cast::<MUXC::ListBoxItem>()?
94            .SetIsSelected(v)?;
95        Ok(())
96    }
97
98    pub async fn wait_select(&self) {
99        self.on_select.wait().await;
100    }
101
102    pub fn insert(&mut self, i: usize, s: impl AsRef<str>) -> Result<()> {
103        let item = MUXC::ListBoxItem::new()?;
104        item.SetContent(&HSTRING::from(s.as_ref()).to_reference()?)?;
105        self.list_box
106            .Items()?
107            .InsertAt(i as _, &item.cast::<IInspectable>()?)?;
108        Ok(())
109    }
110
111    pub fn remove(&mut self, i: usize) -> Result<()> {
112        self.list_box.Items()?.RemoveAt(i as _)?;
113        Ok(())
114    }
115
116    pub fn get(&self, i: usize) -> Result<String> {
117        let item = self.list_box.Items()?.GetAt(i as _)?;
118        Ok(item
119            .cast::<MUXC::ListBoxItem>()?
120            .Content()?
121            .cast::<IReference<HSTRING>>()?
122            .Value()?
123            .to_string_lossy())
124    }
125
126    pub fn set(&mut self, i: usize, s: impl AsRef<str>) -> Result<()> {
127        let item = self.list_box.Items()?.GetAt(i as _)?;
128        item.cast::<MUXC::ListBoxItem>()?
129            .SetContent(&HSTRING::from(s.as_ref()).to_reference()?)?;
130        Ok(())
131    }
132
133    pub fn len(&self) -> Result<usize> {
134        Ok(self.list_box.Items()?.Size()? as usize)
135    }
136
137    pub fn is_empty(&self) -> Result<bool> {
138        Ok(self.len()? == 0)
139    }
140
141    pub fn clear(&mut self) -> Result<()> {
142        self.list_box.Items()?.Clear()?;
143        Ok(())
144    }
145}
146
147winio_handle::impl_as_widget!(ListBox, handle);