use super::read_only_selection_list_base::IReadOnlySelectionList;
use super::selection_model_indexes_changed_event_args::SelectionModelIndexesChangedEventArgs;
use super::selection_model_selection_changed_event_args::SelectionModelSelectionChangedEventArgs;
use crate::items_source::ItemsSource;
use ferroui_base::data::model::INotifyPropertyChanged;
use ferroui_base::reactive::IDisposable;
use ferroui_base::BoxedValue;
use std::cell::Cell;
use std::rc::Rc;
pub trait ISelectionModel: INotifyPropertyChanged {
fn source(&self) -> Option<ItemsSource>;
fn set_source(&self, value: Option<ItemsSource>);
fn single_select(&self) -> bool;
fn set_single_select(&self, value: bool);
fn selected_index(&self) -> i32;
fn set_selected_index(&self, value: i32);
fn selected_indexes(&self) -> Rc<dyn IReadOnlySelectionList<i32>>;
fn selected_item(&self) -> Option<BoxedValue>;
fn set_selected_item(&self, value: Option<BoxedValue>);
fn selected_items(&self) -> Rc<dyn IReadOnlySelectionList<Option<BoxedValue>>>;
fn anchor_index(&self) -> i32;
fn set_anchor_index(&self, value: i32);
fn count(&self) -> usize;
fn indexes_changed(&self, handler: Rc<dyn Fn(&SelectionModelIndexesChangedEventArgs)>) -> Rc<dyn IDisposable>;
fn selection_changed(
&self,
handler: Rc<dyn Fn(&dyn SelectionModelSelectionChangedEventArgs)>,
) -> Rc<dyn IDisposable>;
fn lost_selection(&self, handler: Rc<dyn Fn()>) -> Rc<dyn IDisposable>;
fn source_reset(&self, handler: Rc<dyn Fn()>) -> Rc<dyn IDisposable>;
fn begin_batch_update(&self);
fn end_batch_update(&self);
fn is_selected(&self, index: i32) -> bool;
fn select(&self, index: i32);
fn deselect(&self, index: i32);
fn select_range(&self, start: i32, end: i32);
fn deselect_range(&self, start: i32, end: i32);
fn select_all(&self);
fn clear(&self);
fn as_internal_selection_model(&self) -> Option<&super::InternalSelectionModel> {
None
}
}
impl PartialEq for dyn ISelectionModel {
fn eq(&self, other: &Self) -> bool {
std::ptr::addr_eq(self as *const Self, other as *const Self)
}
}
pub fn selection_model_ptr_eq(a: &Rc<dyn ISelectionModel>, b: &Rc<dyn ISelectionModel>) -> bool {
std::ptr::addr_eq(Rc::as_ptr(a), Rc::as_ptr(b))
}
pub struct SelectionModelExtensions;
impl SelectionModelExtensions {
pub fn batch_update(model: &Rc<dyn ISelectionModel>) -> BatchUpdateOperation {
BatchUpdateOperation::new(model.clone())
}
}
pub struct BatchUpdateOperation {
owner: Rc<dyn ISelectionModel>,
is_disposed: Cell<bool>,
}
impl BatchUpdateOperation {
pub fn new(owner: Rc<dyn ISelectionModel>) -> Self {
owner.begin_batch_update();
Self { owner, is_disposed: Cell::new(false) }
}
}
impl IDisposable for BatchUpdateOperation {
fn dispose(&self) {
if !self.is_disposed.get() {
self.owner.end_batch_update();
self.is_disposed.set(true);
}
}
}