Trait sixtyfps::Model [−]
pub trait Model {
type Data;
fn row_count(&self) -> usize;
fn row_data(&self, row: usize) -> Self::Data;
fn attach_peer(&self, peer: ModelPeer);
fn set_row_data(&self, _row: usize, _data: Self::Data) { ... }
fn iter(&self) -> ModelIterator<'_, Self::Data>ⓘ { ... }
fn as_any(&self) -> &(dyn Any + 'static) { ... }
}
Expand description
A Model is providing Data for the Repeater or ListView elements of the .60
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) -> Self::Data {
self.array.borrow()[row].clone()
}
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 attach_peer(&self, peer: ModelPeer) {
// simply forward to ModelNotify::attach
self.notify.attach(peer);
}
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)
}
}
Associated Types
type Data
type Data
The model data: A model is a set of row and each row has this data
Required methods
Returns the data for a particular row. This function should be called with row < row_count()
.
fn attach_peer(&self, peer: ModelPeer)
fn attach_peer(&self, peer: ModelPeer)
The implementation should forward to ModelNotify::attach
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 [ModelNofity::row_changed
] on its
internal ModelNotify
.
Returns an iterator visiting all elements of the model.
Return something that can be downcast’ed (typically self)
This is useful to get back to the actual model from a ModelHandle stored in a component.
let vec_model = Rc::new(VecModel::from(vec![1i32, 2, 3]));
let handle = ModelHandle::from(vec_model as Rc<dyn Model<Data = i32>>);
// later:
handle.as_any().downcast_ref::<VecModel<i32>>().unwrap().push(4);
assert_eq!(handle.row_data(3), 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 }