use crate::dialogs::Dialog;
use crate::geometry::{Point, Size};
use crate::window::WxWidget;
use std::ffi::{CStr, CString};
use wxdragon_sys as ffi;
crate::widget_style_enum!(
name: TextEntryDialogStyle,
doc: "Style flags for text entry dialog.",
variants: {
Default: ffi::WXD_OK | ffi::WXD_CANCEL | ffi::WXD_CENTRE, "Default style with OK, Cancel buttons and centered dialog.",
Ok: ffi::WXD_OK, "Style flag for OK button.",
Cancel: ffi::WXD_CANCEL, "Style flag for Cancel button.",
Centre: ffi::WXD_CENTRE, "Style flag to center the dialog.",
Password: ffi::WXD_TE_PASSWORD, "Style flag for password text entry.",
ProcessEnter: ffi::WXD_TE_PROCESS_ENTER, "Style flag to process Enter key in the text control."
},
default_variant: Default
);
pub type TextEntryDialogPtr = *mut ffi::wxd_TextEntryDialog_t;
#[derive(Clone)]
pub struct TextEntryDialog {
dialog_base: Dialog,
}
impl TextEntryDialog {
pub fn builder<'a>(parent: &'a dyn WxWidget, message: &str, caption: &str) -> TextEntryDialogBuilder<'a> {
TextEntryDialogBuilder::new(parent, message, caption)
}
pub(crate) unsafe fn from_ptr(ptr: *mut ffi::wxd_TextEntryDialog_t) -> Self {
TextEntryDialog {
dialog_base: unsafe { Dialog::from_ptr(ptr as *mut ffi::wxd_Dialog_t) },
}
}
fn as_ptr(&self) -> TextEntryDialogPtr {
self.dialog_base.as_ptr() as TextEntryDialogPtr
}
pub fn show_modal(&self) -> i32 {
self.dialog_base.show_modal()
}
pub fn get_value(&self) -> Option<String> {
let mut buffer = [0; 1024]; let len = unsafe { ffi::wxd_TextEntryDialog_GetValue(self.as_ptr(), buffer.as_mut_ptr(), buffer.len()) };
if len < 0 {
return None; }
if len < buffer.len() as i32 {
Some(unsafe { CStr::from_ptr(buffer.as_ptr()).to_string_lossy().into_owned() })
} else {
let mut buf = vec![0; len as usize + 1];
let len_copied = unsafe { ffi::wxd_TextEntryDialog_GetValue(self.as_ptr(), buf.as_mut_ptr(), buf.len()) };
if len_copied == len {
Some(unsafe { CStr::from_ptr(buf.as_ptr()).to_string_lossy().to_string() })
} else {
None }
}
}
}
impl WxWidget for TextEntryDialog {
fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
self.dialog_base.handle_ptr()
}
}
impl Drop for TextEntryDialog {
fn drop(&mut self) {
}
}
pub struct TextEntryDialogBuilder<'a> {
parent: &'a dyn WxWidget,
message: String,
caption: String,
default_value: String,
style: TextEntryDialogStyle,
pos: Point,
size: Size, }
impl<'a> TextEntryDialogBuilder<'a> {
pub fn new(parent: &'a dyn WxWidget, message: &str, caption: &str) -> Self {
TextEntryDialogBuilder {
parent,
message: message.to_string(),
caption: caption.to_string(),
default_value: String::new(),
style: TextEntryDialogStyle::Default,
pos: Point::DEFAULT_POSITION,
size: Size::DEFAULT_SIZE,
}
}
pub fn with_default_value(mut self, value: &str) -> Self {
self.default_value = value.to_string();
self
}
pub fn with_style(mut self, style: TextEntryDialogStyle) -> Self {
self.style = style;
self
}
pub fn password(mut self) -> Self {
self.style |= TextEntryDialogStyle::Password;
self
}
pub fn with_pos(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) -> TextEntryDialog {
let c_message = CString::new(self.message).expect("CString::new failed for message");
let c_caption = CString::new(self.caption).expect("CString::new failed for caption");
let c_default_value = CString::new(self.default_value).expect("CString::new failed for default_value");
let parent_ptr = self.parent.handle_ptr();
assert!(
!parent_ptr.is_null(),
"TextEntryDialog requires a valid parent window pointer."
);
let ptr = unsafe {
ffi::wxd_TextEntryDialog_Create(
parent_ptr,
c_message.as_ptr(),
c_caption.as_ptr(),
c_default_value.as_ptr(),
self.style.bits() as ffi::wxd_Style_t,
self.pos.x,
self.pos.y,
self.size.width,
self.size.height,
)
};
if ptr.is_null() {
panic!("Failed to create wxTextEntryDialog");
}
unsafe { TextEntryDialog::from_ptr(ptr) }
}
}