pub trait Model {
type Data;
// Required methods
fn row_count(&self) -> usize;
fn row_data(&self, row: usize) -> Option<Self::Data>;
fn model_tracker(&self) -> &dyn ModelTracker;
// Provided methods
fn set_row_data(&self, _row: usize, _data: Self::Data) { ... }
fn iter(&self) -> ModelIterator<'_, Self::Data> โ
where Self: Sized { ... }
fn as_any(&self) -> &(dyn Any + 'static) { ... }
}
Expand description
A Model is providing Data for the Repeater or ListView elements of the .slint
language
If the model can be changed, the type implementing the Model trait should holds
a ModelNotify
, and is responsible to call functions on it to let the UI know that
something has changed.
Example
As an example, letโs see the implementation of VecModel
.
pub struct VecModel<T> {
// the backing data, stored in a `RefCell` as this model can be modified
array: std::cell::RefCell<Vec<T>>,
// the ModelNotify will allow to notify the UI that the model changes
notify: ModelNotify,
}
impl<T: Clone + 'static> Model for VecModel<T> {
type Data = T;
fn row_count(&self) -> usize {
self.array.borrow().len()
}
fn row_data(&self, row: usize) -> Option<Self::Data> {
self.array.borrow().get(row).cloned()
}
fn set_row_data(&self, row: usize, data: Self::Data) {
self.array.borrow_mut()[row] = data;
// don't forget to call row_changed
self.notify.row_changed(row);
}
fn model_tracker(&self) -> &dyn ModelTracker {
&self.notify
}
fn as_any(&self) -> &dyn core::any::Any {
// a typical implementation just return `self`
self
}
}
// when modifying the model, we call the corresponding function in
// the ModelNotify
impl<T> VecModel<T> {
/// Add a row at the end of the model
pub fn push(&self, value: T) {
self.array.borrow_mut().push(value);
self.notify.row_added(self.array.borrow().len() - 1, 1)
}
/// Remove the row at the given index from the model
pub fn remove(&self, index: usize) {
self.array.borrow_mut().remove(index);
self.notify.row_removed(index, 1)
}
}
Required Associated Typesยง
type Data
type Data
The model data: A model is a set of row and each row has this data
Required Methodsยง
fn row_data(&self, row: usize) -> Option<Self::Data>
fn row_data(&self, row: usize) -> Option<Self::Data>
Returns the data for a particular row. This function should be called with row < row_count()
.
This function does not register dependencies on the current binding. For an equivalent
function that tracks dependencies, see ModelExt::row_data_tracked
fn model_tracker(&self) -> &dyn ModelTracker
fn model_tracker(&self) -> &dyn ModelTracker
The implementation should return a reference to its ModelNotify
field.
You can return &()
if you your Model
is constant and does not have a ModelNotify field.
Provided Methodsยง
fn set_row_data(&self, _row: usize, _data: Self::Data)
fn set_row_data(&self, _row: usize, _data: Self::Data)
Sets the data for a particular row.
This function should be called with row < row_count()
, otherwise the implementation can panic.
If the model cannot support data changes, then it is ok to do nothing. The default implementation will print a warning to stderr.
If the model can update the data, it should also call ModelNotify::row_changed
on its
internal ModelNotify
.
fn iter(&self) -> ModelIterator<'_, Self::Data> โwhere
Self: Sized,
fn iter(&self) -> ModelIterator<'_, Self::Data> โwhere Self: Sized,
Returns an iterator visiting all elements of the model.
fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Return something that can be downcastโed (typically self)
This is useful to get back to the actual model from a ModelRc
stored
in a component.
let handle = ModelRc::new(VecModel::from(vec![1i32, 2, 3]));
// later:
handle.as_any().downcast_ref::<VecModel<i32>>().unwrap().push(4);
assert_eq!(handle.row_data(3).unwrap(), 4);
Note: the default implementation returns nothing interesting. this method should be implemented by model implementation to return something useful. For example:
fn as_any(&self) -> &dyn core::any::Any { self }