widget: list: impl ListIter for VecDeque
//! Simple list view widget.
use std::cmp::Ordering;
+use std::collections::VecDeque;
use std::f64;
use std::sync::Arc;
@@ -216,6 +217,77 @@ impl<S: Data, T: Data> ListIter<(S, T)> for (S, Arc<Vec<T>>) {
}
}
+impl<T: Data> ListIter<T> for Arc<VecDeque<T>> {
+ fn for_each(&self, mut cb: impl FnMut(&T, usize)) {
+ for (i, item) in self.iter().enumerate() {
+ cb(item, i);
+ }
+ }
+
+ fn for_each_mut(&mut self, mut cb: impl FnMut(&mut T, usize)) {
+ let mut new_data = VecDeque::with_capacity(self.data_len());
+ let mut any_changed = false;
+
+ for (i, item) in self.iter().enumerate() {
+ let mut d = item.to_owned();
+ cb(&mut d, i);
+
+ if !any_changed && !item.same(&d) {
+ any_changed = true;
+ }
+ new_data.push_back(d);
+ }
+
+ if any_changed {
+ *self = Arc::new(new_data);
+ }
+ }
+
+ fn data_len(&self) -> usize {
+ self.len()
+ }
+}
+
+// S == shared data type
+impl<S: Data, T: Data> ListIter<(S, T)> for (S, Arc<VecDeque<T>>) {
+ fn for_each(&self, mut cb: impl FnMut(&(S, T), usize)) {
+ for (i, item) in self.1.iter().enumerate() {
+ let d = (self.0.clone(), item.to_owned());
+ cb(&d, i);
+ }
+ }
+
+ fn for_each_mut(&mut self, mut cb: impl FnMut(&mut (S, T), usize)) {
+ let mut new_data = VecDeque::with_capacity(self.1.len());
+ let mut any_shared_changed = false;
+ let mut any_el_changed = false;
+
+ for (i, item) in self.1.iter().enumerate() {
+ let mut d = (self.0.clone(), item.to_owned());
+ cb(&mut d, i);
+
+ if !any_shared_changed && !self.0.same(&d.0) {
+ any_shared_changed = true;
+ }
+ if any_shared_changed {
+ self.0 = d.0;
+ }
+ if !any_el_changed && !item.same(&d.1) {
+ any_el_changed = true;
+ }
+ new_data.push_back(d.1);
+ }
+
+ if any_el_changed {
+ self.1 = Arc::new(new_data);
+ }
+ }
+
+ fn data_len(&self) -> usize {
+ self.1.len()
+ }
+}
+
impl<C: Data, T: ListIter<C>> Widget<T> for List<C> {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
let mut children = self.children.iter_mut();
