use std::ffi::CString;
use crate::{color::Colour, dialogs::Dialog, window::WxWidget};
use wxdragon_sys as ffi;
#[derive(Clone, Copy)]
pub struct ColourDialog {
dialog_base: Dialog,
}
pub struct ColourDialogBuilder<'a, W: WxWidget> {
parent: &'a W,
title: String,
initial_colour: Option<Colour>,
choose_full: bool,
custom_colours: std::collections::HashMap<i32, Colour>,
}
impl ColourDialog {
pub fn builder<'a, W: WxWidget>(parent: &'a W) -> ColourDialogBuilder<'a, W> {
ColourDialogBuilder {
parent,
title: "Choose a colour".to_string(),
initial_colour: None,
choose_full: false,
custom_colours: std::collections::HashMap::new(),
}
}
pub(crate) unsafe fn from_ptr(ptr: *mut ffi::wxd_ColourDialog_t) -> Self {
ColourDialog {
dialog_base: unsafe { Dialog::from_ptr(ptr as *mut ffi::wxd_Dialog_t) },
}
}
fn as_ptr(&self) -> *mut ffi::wxd_ColourDialog_t {
self.dialog_base.as_ptr() as *mut ffi::wxd_ColourDialog_t
}
pub fn show_modal(&self) -> i32 {
self.dialog_base.show_modal()
}
pub fn get_colour(&self) -> Option<Colour> {
let data_ptr = unsafe { ffi::wxd_ColourDialog_GetColourData(self.as_ptr()) };
if data_ptr.is_null() {
None
} else {
let colour = unsafe { ffi::wxd_ColourData_GetColour(data_ptr) };
Some(Colour::from(colour))
}
}
}
impl<'a, W: WxWidget> ColourDialogBuilder<'a, W> {
pub fn with_title(mut self, title: &str) -> Self {
self.title = title.to_string();
self
}
pub fn with_initial_colour(mut self, colour: Colour) -> Self {
self.initial_colour = Some(colour);
self
}
pub fn with_choose_full(mut self, choose_full: bool) -> Self {
self.choose_full = choose_full;
self
}
pub fn with_custom_colour(mut self, index: i32, colour: Colour) -> Self {
self.custom_colours.insert(index, colour);
self
}
pub fn build(self) -> ColourDialog {
let c_title = CString::new(self.title).expect("CString::new failed for title");
let has_custom_data = self.initial_colour.is_some() || self.choose_full || !self.custom_colours.is_empty();
let colour_data_ptr = if has_custom_data {
let data_ptr = unsafe { ffi::wxd_ColourData_Create() };
if !data_ptr.is_null() {
if let Some(colour) = self.initial_colour {
unsafe { ffi::wxd_ColourData_SetColour(data_ptr, colour.into()) };
}
if self.choose_full {
unsafe { ffi::wxd_ColourData_SetChooseFull(data_ptr, true) };
}
for (index, colour) in self.custom_colours {
unsafe { ffi::wxd_ColourData_SetCustomColour(data_ptr, index, colour.into()) };
}
}
data_ptr
} else {
std::ptr::null_mut()
};
let parent_ptr = self.parent.handle_ptr();
assert!(!parent_ptr.is_null(), "ColourDialog requires a valid parent window pointer.");
let ptr = unsafe { ffi::wxd_ColourDialog_Create(parent_ptr, c_title.as_ptr(), colour_data_ptr) };
if !colour_data_ptr.is_null() {
unsafe { ffi::wxd_ColourData_Destroy(colour_data_ptr) };
}
if ptr.is_null() {
panic!("Failed to create wxColourDialog");
}
unsafe { ColourDialog::from_ptr(ptr) }
}
}
impl WxWidget for ColourDialog {
fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
self.dialog_base.handle_ptr()
}
}