use crate::bitmap::Bitmap;
use crate::event::{EventType, WxEvtHandler};
use crate::geometry::{Point, Size};
use crate::id::Id;
use crate::widgets::combobox::ComboBoxStyle;
use crate::window::{WindowHandle, WxWidget};
use std::ffi::{CStr, CString};
use wxdragon_sys as ffi;
#[derive(Clone, Copy)]
pub struct BitmapComboBox {
handle: WindowHandle,
}
impl BitmapComboBox {
pub fn builder(parent: &dyn WxWidget) -> BitmapComboBoxBuilder<'_> {
BitmapComboBoxBuilder::new(parent)
}
#[inline]
fn bitmap_combobox_ptr(&self) -> *mut ffi::wxd_BitmapComboBox_t {
self.handle
.get_ptr()
.map(|p| p as *mut ffi::wxd_BitmapComboBox_t)
.unwrap_or(std::ptr::null_mut())
}
pub fn append(&self, item: &str, bitmap: Option<&Bitmap>) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
let c_item = CString::new(item).expect("Invalid CString for BitmapComboBox item");
let b_ptr = bitmap.map(|b| b.as_const_ptr()).unwrap_or(std::ptr::null());
unsafe {
ffi::wxd_BitmapComboBox_Append(ptr, c_item.as_ptr(), b_ptr);
}
}
pub fn insert(&self, item: &str, bitmap: Option<&Bitmap>, pos: usize) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
let c_item = CString::new(item).expect("Invalid CString for BitmapComboBox item");
let b_ptr = bitmap.map(|b| b.as_const_ptr()).unwrap_or(std::ptr::null());
unsafe {
ffi::wxd_BitmapComboBox_Insert(ptr, c_item.as_ptr(), b_ptr, pos as u32);
}
}
pub fn clear(&self) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_BitmapComboBox_Clear(ptr) };
}
pub fn get_selection(&self) -> i32 {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return -1;
}
unsafe { ffi::wxd_BitmapComboBox_GetSelection(ptr) }
}
pub fn set_selection(&self, index: i32) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_BitmapComboBox_SetSelection(ptr, index) };
}
pub fn get_string(&self, index: u32) -> String {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return String::new();
}
let len = unsafe { ffi::wxd_BitmapComboBox_GetString(ptr, index as i32, std::ptr::null_mut(), 0) };
if len <= 0 {
return String::new();
}
let mut buf = vec![0; len as usize + 1];
unsafe { ffi::wxd_BitmapComboBox_GetString(ptr, index as i32, buf.as_mut_ptr(), buf.len()) };
unsafe { CStr::from_ptr(buf.as_ptr()).to_string_lossy().to_string() }
}
pub fn get_count(&self) -> u32 {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return 0;
}
unsafe { ffi::wxd_BitmapComboBox_GetCount(ptr) }
}
pub fn set_value(&self, value: &str) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
let c_value = CString::new(value).expect("CString::new failed for value");
unsafe { ffi::wxd_BitmapComboBox_SetValue(ptr, c_value.as_ptr()) };
}
pub fn get_value(&self) -> String {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return String::new();
}
let len = unsafe { ffi::wxd_BitmapComboBox_GetValue(ptr, std::ptr::null_mut(), 0) };
if len <= 0 {
return String::new();
}
let mut buf = vec![0; len as usize + 1];
unsafe { ffi::wxd_BitmapComboBox_GetValue(ptr, buf.as_mut_ptr(), buf.len()) };
unsafe { CStr::from_ptr(buf.as_ptr()).to_string_lossy().to_string() }
}
pub fn get_item_bitmap(&self, n: u32) -> Option<Bitmap> {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return None;
}
let bmp_ptr = unsafe { ffi::wxd_BitmapComboBox_GetItemBitmap(ptr, n) };
if bmp_ptr.is_null() {
None
} else {
Some(Bitmap::from(bmp_ptr))
}
}
pub fn set_item_bitmap(&self, n: u32, bitmap: &Bitmap) {
let ptr = self.bitmap_combobox_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_BitmapComboBox_SetItemBitmap(ptr, n, bitmap.as_const_ptr()) };
}
}
widget_builder!(
name: BitmapComboBox,
parent_type: &'a dyn WxWidget,
style_type: ComboBoxStyle,
fields: {
value: String = String::new()
},
build_impl: |slf| {
let parent_ptr = slf.parent.handle_ptr();
assert!(!parent_ptr.is_null(), "BitmapComboBox requires a parent");
let c_value = CString::new(slf.value.as_str()).expect("Invalid CString for BitmapComboBox value");
unsafe {
let ptr = ffi::wxd_BitmapComboBox_Create(
parent_ptr,
slf.id,
c_value.as_ptr(),
slf.pos.into(),
slf.size.into(),
slf.style.bits() as ffi::wxd_Style_t,
);
if ptr.is_null() {
panic!("Failed to create BitmapComboBox widget");
}
BitmapComboBox {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t)
}
}
}
);
impl WxWidget for BitmapComboBox {
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 BitmapComboBox {
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 BitmapComboBox {}
use crate::implement_widget_local_event_handlers;
use crate::widgets::combobox::{ComboBoxEvent, ComboBoxEventData};
implement_widget_local_event_handlers!(
BitmapComboBox,
ComboBoxEvent,
ComboBoxEventData,
Selected => selection_changed, EventType::COMMAND_COMBOBOX_SELECTED
);
use crate::event::TextEvents;
impl TextEvents for BitmapComboBox {}
#[cfg(feature = "xrc")]
impl crate::xrc::XrcSupport for BitmapComboBox {
unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
BitmapComboBox {
handle: WindowHandle::new(ptr),
}
}
}
impl crate::window::FromWindowWithClassName for BitmapComboBox {
fn class_name() -> &'static str {
"wxBitmapComboBox"
}
unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
BitmapComboBox {
handle: WindowHandle::new(ptr),
}
}
}