use crate::geometry::{Point, Size};
use crate::window::WxWidget;
use std::ffi::{CStr, CString};
use wxdragon_sys as ffi;
crate::widget_style_enum!(
name: DirDialogStyle,
doc: "Style flags for directory dialog.",
variants: {
Default: ffi::WXD_DEFAULT_DIALOG_STYLE, "Default style.",
MustExist: ffi::WXD_DD_DIR_MUST_EXIST, "The dialog will allow the user to choose only an existing directory.",
ChangeDir: ffi::WXD_DD_CHANGE_DIR, "Change the current working directory to the directory chosen by the user."
},
default_variant: Default
);
pub type DirDialogPtr = *mut ffi::wxd_DirDialog_t;
pub struct DirDialog {
ptr: DirDialogPtr,
}
impl DirDialog {
pub fn builder<'a>(parent: &'a dyn WxWidget, message: &str, default_path: &str) -> DirDialogBuilder<'a> {
DirDialogBuilder::new(parent, message, default_path)
}
pub fn show_modal(&self) -> i32 {
unsafe { ffi::wxd_Dialog_ShowModal(self.ptr as *mut ffi::wxd_Dialog_t) }
}
pub fn get_path(&self) -> Option<String> {
let len = unsafe { ffi::wxd_DirDialog_GetPath(self.ptr, std::ptr::null_mut(), 0) };
if len < 0 {
return None;
}
let mut buf = vec![0; len as usize + 1];
unsafe { ffi::wxd_DirDialog_GetPath(self.ptr, buf.as_mut_ptr(), buf.len()) };
Some(unsafe { CStr::from_ptr(buf.as_ptr()).to_string_lossy().to_string() })
}
pub fn set_path(&self, path: &str) {
unsafe {
let c_path = CString::new(path).unwrap();
ffi::wxd_DirDialog_SetPath(self.ptr, c_path.as_ptr());
}
}
pub fn get_message(&self) -> Option<String> {
let mut buffer = vec![0; 1024];
let len = unsafe { ffi::wxd_DirDialog_GetMessage(self.ptr, buffer.as_mut_ptr(), buffer.len()) };
if len < 0 {
return None;
}
Some(unsafe { CStr::from_ptr(buffer.as_ptr()).to_string_lossy().to_string() })
}
pub fn set_message(&self, message: &str) {
unsafe {
let c_message = CString::new(message).unwrap();
ffi::wxd_DirDialog_SetMessage(self.ptr, c_message.as_ptr());
}
}
}
impl WxWidget for DirDialog {
fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
self.ptr as *mut ffi::wxd_Window_t
}
}
impl Drop for DirDialog {
fn drop(&mut self) {
if !self.ptr.is_null() {
self.ptr = std::ptr::null_mut();
}
}
}
pub struct DirDialogBuilder<'a> {
parent: &'a dyn WxWidget,
message: String,
default_path: String,
style: i64,
pos: Point,
size: Size,
}
impl<'a> DirDialogBuilder<'a> {
pub fn new(parent: &'a dyn WxWidget, message: &str, default_path: &str) -> Self {
DirDialogBuilder {
parent,
message: message.to_string(),
default_path: default_path.to_string(),
style: DirDialogStyle::default().bits(),
pos: Point::DEFAULT_POSITION,
size: Size::DEFAULT_SIZE,
}
}
pub fn with_style(mut self, style: i64) -> Self {
self.style = style;
self
}
pub fn with_position(mut self, pos: Point) -> Self {
self.pos = pos;
self
}
pub fn with_size(mut self, size: Size) -> Self {
self.size = size;
self
}
pub fn build(self) -> DirDialog {
let c_message = CString::new(self.message).unwrap();
let c_default_path = CString::new(self.default_path).unwrap();
let ptr = unsafe {
ffi::wxd_DirDialog_Create(
self.parent.handle_ptr(),
c_message.as_ptr(),
c_default_path.as_ptr(),
self.style,
self.pos.x,
self.pos.y,
self.size.width,
self.size.height,
)
};
DirDialog { ptr }
}
}