use crate::datetime::DateTime;
use crate::event::{Event, EventType, WxEvtHandler};
use crate::geometry::{Point, Size};
use crate::id::Id;
use crate::window::{WindowHandle, WxWidget};
use std::ptr;
use wxdragon_sys as ffi;
widget_style_enum!(
name: CalendarCtrlStyle,
doc: "Style flags for Calendar control.",
variants: {
Default: 0, "Default style.",
SundayFirst: ffi::WXD_CAL_SUNDAY_FIRST, "Show Sunday as the first day in the week.",
MondayFirst: ffi::WXD_CAL_MONDAY_FIRST, "Show Monday as the first day in the week.",
ShowHolidays: ffi::WXD_CAL_SHOW_HOLIDAYS, "Highlight holidays in the calendar.",
NoYearChange: ffi::WXD_CAL_NO_YEAR_CHANGE, "Disable year changing.",
NoMonthChange: ffi::WXD_CAL_NO_MONTH_CHANGE, "Disable month changing.",
SequentialMonthSelection: ffi::WXD_CAL_SEQUENTIAL_MONTH_SELECTION, "Use alternative, more compact, style for the month and year selection controls.",
ShowSurroundingWeeks: ffi::WXD_CAL_SHOW_SURROUNDING_WEEKS, "Show the neighbouring weeks in the previous and next months."
},
default_variant: Default
);
#[derive(Clone, Copy)]
pub struct CalendarCtrl {
handle: WindowHandle,
}
impl CalendarCtrl {
pub fn builder(parent: &dyn WxWidget) -> CalendarCtrlBuilder<'_> {
CalendarCtrlBuilder::new(parent)
}
fn new_impl(parent_ptr: *mut ffi::wxd_Window_t, id: Id, date: Option<&DateTime>, pos: Point, size: Size, style: i64) -> Self {
assert!(!parent_ptr.is_null(), "CalendarCtrl requires a parent");
let c_date_ptr = date.map_or(ptr::null(), |d| d.as_const_ptr());
let ptr = unsafe {
ffi::wxd_CalendarCtrl_Create(parent_ptr, id, c_date_ptr, pos.into(), size.into(), style as ffi::wxd_Style_t)
};
if ptr.is_null() {
panic!("Failed to create CalendarCtrl widget");
}
CalendarCtrl {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
#[inline]
fn calendar_ptr(&self) -> *mut ffi::wxd_CalendarCtrl_t {
self.handle
.get_ptr()
.map(|p| p as *mut ffi::wxd_CalendarCtrl_t)
.unwrap_or(std::ptr::null_mut())
}
pub fn set_date(&self, date: &DateTime) -> bool {
let ptr = self.calendar_ptr();
if ptr.is_null() {
return false;
}
unsafe { ffi::wxd_CalendarCtrl_SetDate(ptr, date.as_const_ptr()) }
}
pub fn get_date(&self) -> Option<DateTime> {
let ptr = self.calendar_ptr();
if ptr.is_null() {
return None;
}
unsafe {
let raw_dt_ptr = ffi::wxd_CalendarCtrl_GetDate(ptr);
if raw_dt_ptr.is_null() {
None
} else {
Some(DateTime::from(raw_dt_ptr))
}
}
}
pub fn window_handle(&self) -> WindowHandle {
self.handle
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CalendarEvent {
SelectionChanged,
DoubleClicked,
MonthChanged,
YearChanged,
}
#[derive(Debug)]
pub struct CalendarEventData {
event: Event, }
impl CalendarEventData {
pub(crate) fn new(event: Event) -> Self {
Self { event }
}
pub fn get_id(&self) -> i32 {
unsafe {
let event_ptr = self.event._as_ptr();
if !event_ptr.is_null() {
return ffi::wxd_Event_GetId(event_ptr);
}
0
}
}
pub fn get_date(&self) -> Option<DateTime> {
let event_ptr = self.event._as_ptr();
if event_ptr.is_null() {
return None;
}
let date_ptr = unsafe { ffi::wxd_CalendarEvent_GetDate(event_ptr) };
if date_ptr.is_null() {
return None;
}
Some(DateTime::from(date_ptr))
}
}
impl WxWidget for CalendarCtrl {
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 CalendarCtrl {
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 CalendarCtrl {}
crate::implement_widget_local_event_handlers!(
CalendarCtrl, CalendarEvent, CalendarEventData,
SelectionChanged => selection_changed, EventType::CALENDAR_SEL_CHANGED,
DoubleClicked => double_clicked, EventType::CALENDAR_DOUBLECLICKED,
MonthChanged => month_changed, EventType::CALENDAR_MONTH_CHANGED,
YearChanged => year_changed, EventType::CALENDAR_YEAR_CHANGED
);
#[cfg(feature = "xrc")]
impl crate::xrc::XrcSupport for CalendarCtrl {
unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
CalendarCtrl {
handle: WindowHandle::new(ptr),
}
}
}
impl crate::window::FromWindowWithClassName for CalendarCtrl {
fn class_name() -> &'static str {
"wxCalendarCtrl"
}
unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
CalendarCtrl {
handle: WindowHandle::new(ptr),
}
}
}
widget_builder!(
name: CalendarCtrl,
parent_type: &'a dyn WxWidget,
style_type: CalendarCtrlStyle,
fields: {
initial_date: Option<DateTime> = None
},
build_impl: |slf| {
CalendarCtrl::new_impl(
slf.parent.handle_ptr(),
slf.id,
slf.initial_date.as_ref(),
slf.pos,
slf.size,
slf.style.bits(),
)
}
);