use std::ptr;
use wxdragon_sys as ffi;
use crate::datetime::DateTime;
use crate::event::{Event, EventType, WxEvtHandler};
use crate::prelude::*;
use crate::window::{WindowHandle, WxWidget};
use std::default::Default;
widget_style_enum!(
name: DatePickerCtrlStyle,
doc: "Style flags for DatePickerCtrl widgets.",
variants: {
Default: ffi::WXD_DP_DEFAULT, "Default style.",
Spin: ffi::WXD_DP_SPIN, "Uses a spin control to change the date.",
Dropdown: ffi::WXD_DP_DROPDOWN, "Uses a dropdown control to select the date.",
AllowNone: ffi::WXD_DP_ALLOWNONE, "Allow the user to select 'None' (no date).",
ShowCentury: ffi::WXD_DP_SHOWCENTURY, "Shows the century in the default date format."
},
default_variant: Default
);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DatePickerCtrlEvent {
DateChanged,
}
#[derive(Debug)]
pub struct DatePickerCtrlEventData {
event: Event,
}
impl DatePickerCtrlEventData {
pub fn new(event: Event) -> Self {
Self { event }
}
pub fn get_date(&self) -> Option<DateTime> {
if self.event.is_null() {
return None;
}
let date_ptr = unsafe { ffi::wxd_CalendarEvent_GetDate(self.event.0) };
if date_ptr.is_null() {
return None;
}
Some(DateTime::from(date_ptr))
}
}
#[derive(Clone, Copy)]
pub struct DatePickerCtrl {
handle: WindowHandle,
}
impl DatePickerCtrl {
pub fn builder(parent: &dyn WxWidget) -> DatePickerCtrlBuilder<'_> {
DatePickerCtrlBuilder::new(parent)
}
#[inline]
fn date_picker_ptr(&self) -> *mut ffi::wxd_DatePickerCtrl_t {
self.handle
.get_ptr()
.map(|p| p as *mut ffi::wxd_DatePickerCtrl_t)
.unwrap_or(std::ptr::null_mut())
}
pub fn get_value(&self) -> DateTime {
let ptr = self.date_picker_ptr();
if ptr.is_null() {
return DateTime::default();
}
let ffi_dt = unsafe { ffi::wxd_DatePickerCtrl_GetValue(ptr) };
DateTime::from(ffi_dt)
}
pub fn set_value(&self, dt: &DateTime) {
let ptr = self.date_picker_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DatePickerCtrl_SetValue(ptr, dt.as_const_ptr()) };
}
pub fn get_range(&self) -> Result<(Option<DateTime>, Option<DateTime>), String> {
let ptr = self.date_picker_ptr();
if ptr.is_null() {
return Err("DatePickerCtrl has been destroyed".to_string());
}
let mut p1: *mut ffi::wxd_DateTime_t = std::ptr::null_mut();
let mut p2: *mut ffi::wxd_DateTime_t = std::ptr::null_mut();
let _has_range = unsafe { ffi::wxd_DatePickerCtrl_GetRange(ptr, &mut p1, &mut p2) };
let opt_dt1 = if p1.is_null() { None } else { Some(DateTime::from(p1)) };
let opt_dt2 = if p2.is_null() { None } else { Some(DateTime::from(p2)) };
Ok((opt_dt1, opt_dt2))
}
pub fn set_range(&self, dt_start: Option<&DateTime>, dt_end: Option<&DateTime>) {
let ptr = self.date_picker_ptr();
if ptr.is_null() {
return;
}
let ptr_dt1 = dt_start.map_or(ptr::null(), |dt| dt.as_const_ptr());
let ptr_dt2 = dt_end.map_or(ptr::null(), |dt| dt.as_const_ptr());
unsafe { ffi::wxd_DatePickerCtrl_SetRange(ptr, ptr_dt1, ptr_dt2) };
}
#[allow(dead_code)]
pub(crate) fn from_ptr(ptr: *mut ffi::wxd_DatePickerCtrl_t) -> Self {
Self {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
pub fn window_handle(&self) -> WindowHandle {
self.handle
}
}
impl WxWidget for DatePickerCtrl {
fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
self.handle.get_ptr().unwrap_or(std::ptr::null_mut())
}
fn is_valid(&self) -> bool {
self.handle.is_valid()
}
}
impl WxEvtHandler for DatePickerCtrl {
unsafe fn get_event_handler_ptr(&self) -> *mut ffi::wxd_EvtHandler_t {
self.handle.get_ptr().unwrap_or(std::ptr::null_mut()) as *mut ffi::wxd_EvtHandler_t
}
}
impl crate::event::WindowEvents for DatePickerCtrl {}
crate::implement_widget_local_event_handlers!(
DatePickerCtrl,
DatePickerCtrlEvent,
DatePickerCtrlEventData,
DateChanged => date_changed, EventType::DATE_CHANGED
);
widget_builder!(
name: DatePickerCtrl,
parent_type: &'a dyn WxWidget,
style_type: DatePickerCtrlStyle,
fields: {
value: Option<DateTime> = None
},
build_impl: |slf| {
assert!(!slf.parent.handle_ptr().is_null(), "DatePickerCtrl requires a parent");
let ffi_dt_ptr = slf.value.as_ref().map_or(ptr::null(), |dt_val| dt_val.as_const_ptr());
let ptr = unsafe {
ffi::wxd_DatePickerCtrl_Create(
slf.parent.handle_ptr(),
slf.id,
ffi_dt_ptr,
slf.pos.into(),
slf.size.into(),
slf.style.bits(),
)
};
if ptr.is_null() {
panic!("Failed to create DatePickerCtrl: FFI returned null pointer.");
}
DatePickerCtrl {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
);
#[cfg(feature = "xrc")]
impl crate::xrc::XrcSupport for DatePickerCtrl {
unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
DatePickerCtrl {
handle: WindowHandle::new(ptr),
}
}
}
impl crate::window::FromWindowWithClassName for DatePickerCtrl {
fn class_name() -> &'static str {
"wxDatePickerCtrl"
}
unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
DatePickerCtrl {
handle: WindowHandle::new(ptr),
}
}
}