use cxx::let_cxx_string;
use crate::ffi;
use crate::signal::{self, SignalHandle};
pub struct Action {
ptr: *mut ffi::QAction,
signal_handles: Vec<SignalHandle>,
}
impl Action {
pub fn new(text: impl Into<String>) -> Builder {
Builder::new(text.into())
}
pub fn set_text(&self, text: &str) {
debug_assert!(!self.ptr.is_null());
let_cxx_string!(c_text = text);
unsafe { ffi::QAction_setText(self.ptr, &c_text); }
}
pub fn text(&self) -> String {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_text(self.ptr) }
}
pub fn set_icon(&self, icon_path: &str) {
debug_assert!(!self.ptr.is_null());
let_cxx_string!(c_path = icon_path);
unsafe { ffi::QAction_setIcon(self.ptr, &c_path); }
}
pub fn set_checkable(&self, checkable: bool) {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_setCheckable(self.ptr, checkable); }
}
pub fn set_checked(&self, checked: bool) {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_setChecked(self.ptr, checked); }
}
pub fn is_checked(&self) -> bool {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_isChecked(self.ptr) }
}
pub fn set_shortcut(&self, key: &str) {
debug_assert!(!self.ptr.is_null());
let_cxx_string!(c_key = key);
unsafe { ffi::QAction_setShortcut(self.ptr, &c_key); }
}
pub fn set_enabled(&self, enabled: bool) {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_setEnabled(self.ptr, enabled); }
}
pub fn is_enabled(&self) -> bool {
debug_assert!(!self.ptr.is_null());
unsafe { ffi::QAction_isEnabled(self.ptr) }
}
pub fn set_tool_tip(&self, tip: &str) {
debug_assert!(!self.ptr.is_null());
let_cxx_string!(c_tip = tip);
unsafe { ffi::QAction_setToolTip(self.ptr, &c_tip); }
}
pub fn connect_triggered<F: Fn(bool) + 'static>(&mut self, f: F) {
debug_assert!(!self.ptr.is_null());
let handle = signal::leak_bool(f);
unsafe { ffi::QAction_onTriggered(self.ptr, handle.token); }
self.signal_handles.push(handle);
}
pub fn connect_toggled<F: Fn(bool) + 'static>(&mut self, f: F) {
debug_assert!(!self.ptr.is_null());
let handle = signal::leak_bool(f);
unsafe { ffi::QAction_onToggled(self.ptr, handle.token); }
self.signal_handles.push(handle);
}
}
impl Drop for Action {
fn drop(&mut self) {
if self.ptr.is_null() { return; }
for h in self.signal_handles.drain(..) {
unsafe { h.reclaim(); }
}
unsafe { ffi::QAction_delete(self.ptr); }
self.ptr = std::ptr::null_mut();
}
}
pub struct Builder {
text: String,
on_triggered: Option<Box<dyn Fn(bool)>>,
on_toggled: Option<Box<dyn Fn(bool)>>,
}
impl Builder {
fn new(text: String) -> Self {
Self {
text,
on_triggered: None,
on_toggled: None,
}
}
pub fn on_triggered<F: Fn(bool) + 'static>(mut self, f: F) -> Self {
self.on_triggered = Some(Box::new(f));
self
}
pub fn on_toggled<F: Fn(bool) + 'static>(mut self, f: F) -> Self {
self.on_toggled = Some(Box::new(f));
self
}
pub fn build(self) -> Action {
let_cxx_string!(c_text = &self.text);
let ptr = unsafe {
ffi::QAction_new(&c_text, std::ptr::null_mut())
};
debug_assert!(!ptr.is_null());
let mut signal_handles = Vec::new();
if let Some(cb) = self.on_triggered {
let handle = signal::leak_bool(cb);
unsafe { ffi::QAction_onTriggered(ptr, handle.token); }
signal_handles.push(handle);
}
if let Some(cb) = self.on_toggled {
let handle = signal::leak_bool(cb);
unsafe { ffi::QAction_onToggled(ptr, handle.token); }
signal_handles.push(handle);
}
Action { ptr, signal_handles }
}
}