Skip to content

Commit

Permalink
Add request_compute_layout_recursive to let scrolling bypass layout (
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc authored Nov 10, 2023
1 parent bc60b60 commit 9d24307
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 31 deletions.
7 changes: 7 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ pub struct AppState {
pub(crate) view_states: HashMap<Id, ViewState>,
stale_view_state: ViewState,
pub(crate) scheduled_updates: Vec<FrameUpdate>,
pub(crate) request_compute_layout: bool,
pub(crate) request_paint: bool,
pub(crate) disabled: HashSet<Id>,
pub(crate) keyboard_navigable: HashSet<Id>,
Expand Down Expand Up @@ -270,6 +271,7 @@ impl AppState {
view_states: HashMap::new(),
scheduled_updates: Vec::new(),
request_paint: false,
request_compute_layout: false,
disabled: HashSet::new(),
keyboard_navigable: HashSet::new(),
draggable: HashSet::new(),
Expand Down Expand Up @@ -491,6 +493,11 @@ impl AppState {
self.request_changes(id, ChangeFlags::LAYOUT)
}

/// Requests that `compute_layout` will run for `_id` and all direct and indirect children.
pub fn request_compute_layout_recursive(&mut self, _id: Id) {
self.request_compute_layout = true;
}

// `Id` is unused currently, but could be used to calculate damage regions.
pub fn request_paint(&mut self, _id: Id) {
self.request_paint = true;
Expand Down
3 changes: 2 additions & 1 deletion src/views/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ impl Scroll {

if child_viewport != self.child_viewport {
app_state.set_viewport(self.child.id(), child_viewport);
app_state.request_layout(self.id);
app_state.request_compute_layout_recursive(self.id);
app_state.request_paint(self.id);
self.child_viewport = child_viewport;
if let Some(onscroll) = &self.onscroll {
onscroll(child_viewport);
Expand Down
64 changes: 34 additions & 30 deletions src/views/virtual_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ where

let (viewport, set_viewport) = create_signal(Rect::ZERO);

create_effect(move |prev_hash_run| {
create_effect(move |prev| {
let mut items_vector = each_fn();
let viewport = viewport.get();
let min = match direction {
Expand Down Expand Up @@ -148,35 +148,39 @@ where
};

let hashed_items = items.iter().map(&key_fn).collect::<FxIndexSet<_>>();
let diff = if let Some(HashRun(prev_hash_run)) = prev_hash_run {
let mut diff = diff(&prev_hash_run, &hashed_items);
let mut items = items
.into_iter()
.map(|i| Some(i))
.collect::<SmallVec<[Option<_>; 128]>>();
for added in &mut diff.added {
added.view = Some(items[added.at].take().unwrap());
}
diff
} else {
let mut diff = Diff::default();
for (i, item) in items.into_iter().enumerate() {
diff.added.push(DiffOpAdd {
at: i,
view: Some(item),
});
}
diff
};
id.update_state(
VirtualListState {
diff,
before_size,
after_size,
},
false,
);
HashRun(hashed_items)
let (prev_before_size, prev_after_size, diff) =
if let Some((prev_before_size, prev_after_size, HashRun(prev_hash_run))) = prev {
let mut diff = diff(&prev_hash_run, &hashed_items);
let mut items = items
.into_iter()
.map(|i| Some(i))
.collect::<SmallVec<[Option<_>; 128]>>();
for added in &mut diff.added {
added.view = Some(items[added.at].take().unwrap());
}
(prev_before_size, prev_after_size, diff)
} else {
let mut diff = Diff::default();
for (i, item) in items.into_iter().enumerate() {
diff.added.push(DiffOpAdd {
at: i,
view: Some(item),
});
}
(0.0, 0.0, diff)
};

if !diff.is_empty() || prev_before_size != before_size || prev_after_size != after_size {
id.update_state(
VirtualListState {
diff,
before_size,
after_size,
},
false,
);
}
(before_size, after_size, HashRun(hashed_items))
});

let view_fn = Box::new(as_child_of_current_scope(view_fn));
Expand Down
11 changes: 11 additions & 0 deletions src/window_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,10 +493,16 @@ impl WindowHandle {

cx.clear();
cx.compute_view_layout(&mut self.view);
self.app_state.request_compute_layout = false;

taffy_duration
}

fn compute_layout(&mut self) {
let mut cx = LayoutCx::new(&mut self.app_state);
cx.compute_view_layout(&mut self.view);
}

pub fn render_frame(&mut self) {
// Processes updates scheduled on this frame.
for update in mem::take(&mut self.app_state.scheduled_updates) {
Expand Down Expand Up @@ -636,6 +642,7 @@ impl WindowHandle {
&& !self.needs_style()
&& !self.has_deferred_update_messages()
&& !self.has_anim_update_messages()
&& !self.app_state.request_compute_layout
{
break;
}
Expand All @@ -650,6 +657,10 @@ impl WindowHandle {
self.layout();
}

if mem::take(&mut self.app_state.request_compute_layout) {
self.compute_layout();
}

self.process_deferred_update_messages();
self.process_anim_update_messages();
}
Expand Down

0 comments on commit 9d24307

Please sign in to comment.