floui/widgets/
button.rs

1use crate::{enums, prelude::*};
2use floui_sys;
3use std::sync::Arc;
4
5/// A Button widget
6#[derive(Clone)]
7pub struct Button {
8    inner: Arc<*mut floui_sys::CButton>,
9}
10
11unsafe impl Sync for Button {}
12unsafe impl Send for Button {}
13
14unsafe impl WidgetExt for Button {
15    fn inner(&self) -> *mut floui_sys::CWidget {
16        *self.inner as _
17    }
18    fn from_widget_ptr(ptr: *mut floui_sys::CWidget) -> Self {
19        Self {
20            inner: Arc::new(ptr as _),
21        }
22    }
23}
24
25impl Button {
26    /// Constructs a new widget
27    pub fn new(label: &str) -> Self {
28        let label = std::ffi::CString::new(label).unwrap();
29        let inner = unsafe { Arc::new(floui_sys::CButton_new(label.as_ptr())) };
30        Self { inner }
31    }
32
33    /// Sets the action of the widget
34    pub fn action<F: 'static + FnMut(&Self)>(self, cb: F) -> Self {
35        unsafe {
36            unsafe extern "C" fn shim(
37                wid: *mut floui_sys::CWidget,
38                data: *mut std::os::raw::c_void,
39            ) {
40                let wid = Button::from_widget_ptr(wid as *mut _);
41                let a = data as *mut Box<dyn FnMut(&Button)>;
42                let f: &mut (dyn FnMut(&Button)) = &mut **a;
43                let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f(&wid)));
44            }
45            let a: *mut Box<dyn FnMut(&Self)> = Box::into_raw(Box::new(Box::new(cb)));
46            let data: *mut std::os::raw::c_void = a as *mut std::os::raw::c_void;
47            let callback: floui_sys::CFlouiCallback = Some(shim);
48            floui_sys::CButton_action(*self.inner, callback, data);
49        }
50        self
51    }
52
53    /// Set the button to be filled
54    pub fn filled(self) -> Self {
55        unsafe { floui_sys::CButton_filled(*self.inner) }
56        self
57    }
58
59    /// Sets the foreground color
60    pub fn foreground(self, col: enums::Color) -> Self {
61        unsafe { floui_sys::CButton_foreground(*self.inner, col.0) }
62        self
63    }
64}
65
66/// A Toggle widget
67#[derive(Clone)]
68pub struct Toggle {
69    inner: Arc<*mut floui_sys::CToggle>,
70}
71
72unsafe impl Sync for Toggle {}
73unsafe impl Send for Toggle {}
74
75unsafe impl WidgetExt for Toggle {
76    fn inner(&self) -> *mut floui_sys::CWidget {
77        *self.inner as _
78    }
79    fn from_widget_ptr(ptr: *mut floui_sys::CWidget) -> Self {
80        Self {
81            inner: Arc::new(ptr as _),
82        }
83    }
84}
85
86impl Toggle {
87    /// Constructs a new widget
88    pub fn new(label: &str) -> Self {
89        let label = std::ffi::CString::new(label).unwrap();
90        let inner = unsafe { Arc::new(floui_sys::CToggle_new(label.as_ptr())) };
91        Self { inner }
92    }
93
94    /// Sets the action of the widget
95    pub fn action<F: 'static + FnMut(&Self)>(self, cb: F) -> Self {
96        unsafe {
97            unsafe extern "C" fn shim(
98                wid: *mut floui_sys::CWidget,
99                data: *mut std::os::raw::c_void,
100            ) {
101                let wid = Toggle::from_widget_ptr(wid as *mut _);
102                let a = data as *mut Box<dyn FnMut(&Toggle)>;
103                let f: &mut (dyn FnMut(&Toggle)) = &mut **a;
104                let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f(&wid)));
105            }
106            let a: *mut Box<dyn FnMut(&Self)> = Box::into_raw(Box::new(Box::new(cb)));
107            let data: *mut std::os::raw::c_void = a as *mut std::os::raw::c_void;
108            let callback: floui_sys::CFlouiCallback = Some(shim);
109            floui_sys::CToggle_action(*self.inner, callback, data);
110        }
111        self
112    }
113
114    /// Sets the foreground color
115    pub fn foreground(self, col: enums::Color) -> Self {
116        unsafe { floui_sys::CToggle_foreground(*self.inner, col.0) }
117        self
118    }
119
120    /// Sets whether the Toggle is set
121    pub fn set_value(&self, val: bool) {
122        unsafe { floui_sys::CToggle_set_value(*self.inner, val as i32) }
123    }
124
125    /// Constructs a toggle that is set depending on val
126    pub fn with_value(self, val: bool) -> Self {
127        self.set_value(val);
128        self
129    }
130
131    /// Returs whether the toggle is set
132    pub fn value(&self) -> bool {
133        unsafe { floui_sys::CToggle_value(*self.inner) != 0 }
134    }
135}
136
137/// A checkbox widget
138#[derive(Clone)]
139pub struct Check {
140    inner: Arc<*mut floui_sys::CCheck>,
141}
142
143unsafe impl Sync for Check {}
144unsafe impl Send for Check {}
145
146unsafe impl WidgetExt for Check {
147    fn inner(&self) -> *mut floui_sys::CWidget {
148        *self.inner as _
149    }
150    fn from_widget_ptr(ptr: *mut floui_sys::CWidget) -> Self {
151        Self {
152            inner: Arc::new(ptr as _),
153        }
154    }
155}
156
157impl Check {
158    /// Constructs a new widget
159    pub fn new(label: &str) -> Self {
160        let label = std::ffi::CString::new(label).unwrap();
161        let inner = unsafe { Arc::new(floui_sys::CCheck_new(label.as_ptr())) };
162        Self { inner }
163    }
164
165    /// Sets the action of the widget
166    pub fn action<F: 'static + FnMut(&Self)>(self, cb: F) -> Self {
167        unsafe {
168            unsafe extern "C" fn shim(
169                wid: *mut floui_sys::CWidget,
170                data: *mut std::os::raw::c_void,
171            ) {
172                let wid = Check::from_widget_ptr(wid as *mut _);
173                let a = data as *mut Box<dyn FnMut(&Check)>;
174                let f: &mut (dyn FnMut(&Check)) = &mut **a;
175                let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f(&wid)));
176            }
177            let a: *mut Box<dyn FnMut(&Self)> = Box::into_raw(Box::new(Box::new(cb)));
178            let data: *mut std::os::raw::c_void = a as *mut std::os::raw::c_void;
179            let callback: floui_sys::CFlouiCallback = Some(shim);
180            floui_sys::CCheck_action(*self.inner, callback, data);
181        }
182        self
183    }
184
185    /// Sets the foreground color
186    pub fn foreground(self, col: enums::Color) -> Self {
187        unsafe { floui_sys::CCheck_foreground(*self.inner, col.0) }
188        self
189    }
190
191    /// Sets whether the Check is set
192    pub fn set_value(&self, val: bool) {
193        unsafe { floui_sys::CCheck_set_value(*self.inner, val as i32) }
194    }
195
196    /// Constructs a check that is set depending on val
197    pub fn with_value(self, val: bool) -> Self {
198        self.set_value(val);
199        self
200    }
201
202    /// Returs whether the check is set
203    pub fn value(&self) -> bool {
204        unsafe { floui_sys::CCheck_value(*self.inner) != 0 }
205    }
206}