Skip to main content

winio_ui_win32/widgets/
check_box.rs

1use inherit_methods_macro::inherit_methods;
2use windows_sys::Win32::UI::{
3    Controls::{BST_CHECKED, BST_UNCHECKED, WC_BUTTONW},
4    WindowsAndMessaging::{
5        BM_GETCHECK, BM_SETCHECK, BN_CLICKED, BS_CHECKBOX, WM_COMMAND, WS_CHILD, WS_TABSTOP,
6        WS_VISIBLE,
7    },
8};
9use winio_handle::{AsContainer, AsWidget};
10use winio_primitive::{Point, Size};
11
12use crate::{Result, runtime::WindowMessageCommand, widgets::Widget};
13
14#[derive(Debug)]
15pub struct CheckBox {
16    handle: Widget,
17}
18
19#[inherit_methods(from = "self.handle")]
20impl CheckBox {
21    pub fn new(parent: impl AsContainer) -> Result<Self> {
22        let handle = Widget::new(
23            WC_BUTTONW,
24            WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_CHECKBOX as u32,
25            0,
26            parent.as_container().as_win32(),
27        )?;
28        Ok(Self { handle })
29    }
30
31    pub fn is_visible(&self) -> Result<bool>;
32
33    pub fn set_visible(&mut self, v: bool) -> Result<()>;
34
35    pub fn is_enabled(&self) -> Result<bool>;
36
37    pub fn set_enabled(&mut self, v: bool) -> Result<()>;
38
39    pub fn preferred_size(&self) -> Result<Size> {
40        let s = self.handle.measure_text()?;
41        Ok(Size::new(s.width + 18.0, s.height + 2.0))
42    }
43
44    pub fn loc(&self) -> Result<Point>;
45
46    pub fn set_loc(&mut self, p: Point) -> Result<()>;
47
48    pub fn size(&self) -> Result<Size>;
49
50    pub fn set_size(&mut self, v: Size) -> Result<()>;
51
52    pub fn tooltip(&self) -> Result<String>;
53
54    pub fn set_tooltip(&mut self, s: impl AsRef<str>) -> Result<()>;
55
56    pub fn text(&self) -> Result<String>;
57
58    pub fn set_text(&mut self, s: impl AsRef<str>) -> Result<()>;
59
60    fn is_checked_impl(&self) -> bool {
61        self.handle.send_message(BM_GETCHECK, 0, 0) == BST_CHECKED as _
62    }
63
64    pub fn is_checked(&self) -> Result<bool> {
65        Ok(self.is_checked_impl())
66    }
67
68    fn set_checked_impl(&self, v: bool) {
69        self.handle.send_message(
70            BM_SETCHECK,
71            if v { BST_CHECKED } else { BST_UNCHECKED } as _,
72            0,
73        );
74    }
75
76    pub fn set_checked(&self, v: bool) -> Result<()> {
77        self.set_checked_impl(v);
78        Ok(())
79    }
80
81    pub async fn wait_click(&self) {
82        loop {
83            let WindowMessageCommand {
84                message, handle, ..
85            } = self.handle.wait_parent(WM_COMMAND).await.command();
86            if std::ptr::eq(handle, self.handle.as_widget().as_win32()) && (message == BN_CLICKED) {
87                self.set_checked_impl(!self.is_checked_impl());
88                break;
89            }
90        }
91    }
92}
93
94winio_handle::impl_as_widget!(CheckBox, handle);