use crate::event::WxEvtHandler;
use crate::window::{WindowHandle, WxWidget};
use crate::{Id, Point, Size};
use std::ffi::{CStr, CString};
use wxdragon_sys as ffi;
use super::enums::DataViewColumnFlags;
use super::item::DataViewItem;
use super::variant::Variant;
use super::{
DataViewAlign, DataViewCellMode, DataViewColumn, DataViewProgressRenderer, DataViewStyle, DataViewTextRenderer,
DataViewToggleRenderer, VariantType,
};
#[derive(Clone, Copy)]
pub struct DataViewListCtrl {
handle: WindowHandle,
}
impl DataViewListCtrl {
pub fn builder(parent: &dyn WxWidget) -> DataViewListCtrlBuilder<'_> {
DataViewListCtrlBuilder::new(parent)
}
fn new_impl(parent_ptr: *mut ffi::wxd_Window_t, id: i32, pos: Point, size: Size, style: i64) -> Self {
let ptr = unsafe {
ffi::wxd_DataViewListCtrl_Create(
parent_ptr,
id as i64,
&pos as *const Point as *const ffi::wxd_Point,
&size as *const Size as *const ffi::wxd_Size,
style,
)
};
if ptr.is_null() {
panic!("Failed to create DataViewListCtrl widget");
}
DataViewListCtrl {
handle: WindowHandle::new(ptr),
}
}
#[inline]
fn dvlc_ptr(&self) -> *mut ffi::wxd_Window_t {
self.handle.get_ptr().unwrap_or(std::ptr::null_mut())
}
pub fn window_handle(&self) -> WindowHandle {
self.handle
}
pub fn append_text_column(
&self,
label: &str,
model_column: usize,
align: DataViewAlign,
width: i32,
flags: DataViewColumnFlags,
) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let renderer = DataViewTextRenderer::new(VariantType::String, DataViewCellMode::Inert, align);
let column = DataViewColumn::new(label, &renderer, model_column, width, align, flags);
unsafe { ffi::wxd_DataViewCtrl_AppendColumn(ptr, column.as_raw()) }
}
pub fn append_toggle_column(
&self,
label: &str,
model_column: usize,
align: DataViewAlign,
width: i32,
flags: DataViewColumnFlags,
) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let renderer = DataViewToggleRenderer::new(VariantType::Bool, DataViewCellMode::Activatable, align);
let column = DataViewColumn::new(label, &renderer, model_column, width, align, flags);
unsafe { ffi::wxd_DataViewCtrl_AppendColumn(ptr, column.as_raw()) }
}
pub fn append_progress_column(&self, label: &str, model_column: usize, width: i32, flags: DataViewColumnFlags) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let renderer = DataViewProgressRenderer::new(VariantType::Int32, DataViewCellMode::Inert);
let column = DataViewColumn::new(label, &renderer, model_column, width, DataViewAlign::Center, flags);
unsafe { ffi::wxd_DataViewCtrl_AppendColumn(ptr, column.as_raw()) }
}
pub fn select_row(&self, row: usize) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
unsafe { ffi::wxd_DataViewCtrl_SelectRow(ptr, row as i64) }
}
pub fn get_selected_row(&self) -> Option<usize> {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return None;
}
let row = unsafe { ffi::wxd_DataViewCtrl_GetSelectedRow(ptr) };
if row >= 0 { Some(row as usize) } else { None }
}
pub fn unselect_all(&self) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DataViewCtrl_UnselectAll(ptr) }
}
pub fn get_item_count(&self) -> usize {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return 0;
}
unsafe { ffi::wxd_DataViewListCtrl_GetItemCount(ptr) as usize }
}
pub fn append_item(&self, values: &[Variant]) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let ptrs: Vec<*const ffi::wxd_Variant_t> = values.iter().map(|v| v.as_const_ptr()).collect();
unsafe { ffi::wxd_DataViewListCtrl_AppendItem(ptr, ptrs.as_ptr(), ptrs.len() as u32, 0) }
}
pub fn prepend_item(&self, values: &[Variant]) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let ptrs: Vec<*const ffi::wxd_Variant_t> = values.iter().map(|v| v.as_const_ptr()).collect();
unsafe { ffi::wxd_DataViewListCtrl_PrependItem(ptr, ptrs.as_ptr(), ptrs.len() as u32, 0) }
}
pub fn insert_item(&self, row: usize, values: &[Variant]) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
let ptrs: Vec<*const ffi::wxd_Variant_t> = values.iter().map(|v| v.as_const_ptr()).collect();
unsafe { ffi::wxd_DataViewListCtrl_InsertItem(ptr, row as u32, ptrs.as_ptr(), ptrs.len() as u32, 0) }
}
pub fn delete_item(&self, row: usize) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
unsafe { ffi::wxd_DataViewListCtrl_DeleteItem(ptr, row as u32) }
}
pub fn delete_all_items(&self) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DataViewListCtrl_DeleteAllItems(ptr) }
}
pub fn set_value<T: Into<Variant>>(&self, row: usize, col: usize, value: T) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
let v: Variant = value.into();
unsafe { ffi::wxd_DataViewListCtrl_SetValue(ptr, row as u32, col as u32, v.as_const_ptr()) }
}
pub fn get_value(&self, row: usize, col: usize) -> Option<Variant> {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return None;
}
let v_ptr = unsafe { ffi::wxd_DataViewListCtrl_GetValue(ptr, row as u32, col as u32) };
if v_ptr.is_null() { None } else { Some(Variant::from(v_ptr)) }
}
pub fn set_text_value(&self, row: usize, col: usize, value: &str) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
let c_str = CString::new(value).unwrap_or_default();
unsafe { ffi::wxd_DataViewListCtrl_SetTextValue(ptr, row as u32, col as u32, c_str.as_ptr()) }
}
pub fn get_text_value(&self, row: usize, col: usize) -> String {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return String::new();
}
let c_str = unsafe { ffi::wxd_DataViewListCtrl_GetTextValue(ptr, row as u32, col as u32) };
if c_str.is_null() {
String::new()
} else {
unsafe { CStr::from_ptr(c_str).to_string_lossy().into_owned() }
}
}
pub fn set_toggle_value(&self, row: usize, col: usize, value: bool) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DataViewListCtrl_SetToggleValue(ptr, row as u32, col as u32, value) }
}
pub fn get_toggle_value(&self, row: usize, col: usize) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
unsafe { ffi::wxd_DataViewListCtrl_GetToggleValue(ptr, row as u32, col as u32) }
}
pub fn item_to_row(&self, item: &DataViewItem) -> Option<usize> {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return None;
}
let row = unsafe { ffi::wxd_DataViewListCtrl_ItemToRow(ptr, **item) };
if row >= 0 { Some(row as usize) } else { None }
}
pub fn row_to_item(&self, row: usize) -> Option<DataViewItem> {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return None;
}
let item_ptr = unsafe { ffi::wxd_DataViewListCtrl_RowToItem(ptr, row as i32) };
if item_ptr.is_null() {
None
} else {
Some(DataViewItem::from(item_ptr as *const _))
}
}
pub fn unselect_row(&self, row: usize) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DataViewListCtrl_UnselectRow(ptr, row as u32) }
}
pub fn is_row_selected(&self, row: usize) -> bool {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return false;
}
unsafe { ffi::wxd_DataViewListCtrl_IsRowSelected(ptr, row as u32) }
}
pub fn set_item_data(&self, item: &DataViewItem, data: usize) {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_DataViewListCtrl_SetItemData(ptr, **item, data) }
}
pub fn get_item_data(&self, item: &DataViewItem) -> usize {
let ptr = self.dvlc_ptr();
if ptr.is_null() {
return 0;
}
unsafe { ffi::wxd_DataViewListCtrl_GetItemData(ptr, **item) }
}
}
impl WxWidget for DataViewListCtrl {
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 DataViewListCtrl {
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 DataViewListCtrl {}
widget_builder!(
name: DataViewListCtrl,
parent_type: &'a dyn WxWidget,
style_type: DataViewStyle,
fields: {},
build_impl: |slf| {
DataViewListCtrl::new_impl(
slf.parent.handle_ptr(),
slf.id,
slf.pos,
slf.size,
slf.style.bits(),
)
}
);
impl crate::widgets::dataview::DataViewEventHandler for DataViewListCtrl {}