use std::ops::Range;
use teksilo_core::ObserverHandle;
use crate::data_change::DataChange;
use crate::dnd_types::{
DragEligibility, DragSource, DropCommit, DropPosition, DropQuery, DropResponse, ItemKey,
RowState,
};
pub trait ListDataSource: 'static {
type Item: 'static;
type Key: ItemKey;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn with_item<R>(&self, index: usize, f: impl FnOnce(&Self::Item) -> R) -> Option<R>;
fn key_at(&self, _index: usize) -> Option<Self::Key> {
None
}
fn index_of(&self, _key: &Self::Key) -> Option<usize> {
None
}
fn observe_changes(&self, f: impl Fn(&DataChange) + 'static) -> ObserverHandle;
fn first_changed_index(&self) -> Option<usize> {
None
}
fn drag(&self, _key: &Self::Key) -> DragEligibility {
DragEligibility::NoDrag
}
fn can_accept(&self, _query: &DropQuery<'_, Self::Key>) -> DropResponse {
DropResponse::Reject
}
fn accept_drop(&self, _commit: DropCommit<'_, Self::Key>) -> bool {
false
}
fn reorder_within(
&self,
sources: &[Self::Key],
target: &Self::Key,
position: DropPosition,
) -> bool {
let mut anchor = target.clone();
let mut pos = position;
let mut moved = false;
for key in sources {
if key == &anchor {
continue;
}
if self.accept_drop(DropCommit {
source: DragSource::SameView { key: key.clone() },
target: anchor.clone(),
position: pos,
}) {
moved = true;
anchor = key.clone();
pos = DropPosition::After;
}
}
moved
}
fn on_drag_out(&self, _key: &Self::Key) {}
fn row_state(&self, _index: usize) -> RowState {
RowState::Ready
}
fn request_window(&self, _range: Range<usize>) {}
fn can_fetch_more(&self) -> bool {
false
}
fn fetch_more(&self) {}
}