WIFVLV376GIMVTGVXBFWIPU7FR5O3SGIQ343KIJEBWB6UURTJZJQC tasks.push(scrollable_height_task(id.clone()).map(move |height| {Msg::GotScrollableHeight { height, generation }}));// To be computed from sizes once tasks completelet section_offsets = vec![0.0; section_heights.len()];// 1 task to get the scrollable heightlet pending_tasks = Some(contents_count + 1);
pub fn update(nav: &mut NavScrollable, msg: Msg) -> Task<Msg> {
pub fn update<Message, MapFn, OnReady>(nav: &mut NavScrollable,msg: Msg,map_msg: MapFn,on_ready: OnReady,) -> Task<Message>whereMessage: MaybeSend + 'static,MapFn: Fn(Msg) -> Message + MaybeSend + 'static,OnReady: Fn(NeedsScrolling) -> Message,{
Task::batch(nav.sections.keys().map(|id| {let id_clone = id.clone();height_task(id.clone()).map(move |height| Msg::GotHeight {id: id_clone.clone(),height,})}))
let generation = nav.generation;// 1 task to get the scrollable heightnav.pending_tasks = Some(nav.section_heights.len() + 1);Task::batch(nav.section_heights.keys().map(|id| {let id_clone = id.clone();container_height_task(id.clone()).map(move |height| {Msg::GotSectionHeight {id: id_clone.clone(),height,generation,}})}).chain([scrollable_height_task(nav.id.clone()).map(move |height| Msg::GotScrollableHeight {height,generation,},)]),).map(map_msg)}Msg::GotScrollableHeight { height, generation } => {if generation == nav.generation {nav.height = height;if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);if nav.pending_tasks.is_none() {return Task::done(on_ready(nav.needs_scrolling));}}}Task::none()
Msg::GotHeight { id, height } => {reset_offsets(nav);nav.sections.insert(id, height);
Msg::GotSectionHeight {id,height,generation,} => {if generation == nav.generation {nav.section_heights.insert(id, height);if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);if nav.pending_tasks.is_none() {return Task::done(on_ready(nav.needs_scrolling));}}}
debug_assert_eq!(nav.sections.len(), children.len(), "The `NavScrollable` was most likely initialized with a count different from the number of actual children given to the the view function. Count is {}, but got {} children", nav.sections.len(), children.len());
debug_assert_eq!(nav.section_heights.len(), children.len(), "The `NavScrollable` was most likely initialized with a count different from the number of actual children given to the the view function. Count is {}, but got {} children", nav.section_heights.len(), children.len());
fn update_offsets(nav: &mut NavScrollable) {if !nav.offsets_ready {debug_assert_eq!(nav.sections.len(), nav.offsets.len());
fn update_offsets_if_ready(nav: &mut NavScrollable) {if nav.pending_tasks == Some(0) {debug_assert_eq!(nav.section_heights.len(), nav.section_offsets.len());
nav.sections.values().enumerate().for_each(|(i, height)| {// The current offset is the value of the accnav.offsets[i] = acc;// Increment the acc with the height of this sectionacc += *height;});nav.offsets_ready = true;
nav.section_heights.values().enumerate().for_each(|(i, height)| {// The current offset is the value of the accnav.section_offsets[i] = acc;// Increment the acc with the height of this sectionacc += *height;});nav.needs_scrolling = if acc > nav.height {NeedsScrolling::Yes} else {NeedsScrolling::No};nav.pending_tasks = None;}}/// Produces a [`Task`] that queries the height of the contents of [`Scrollable`] with the/// given [`Id`].fn scrollable_height_task(id: impl Into<scrollable::Id>) -> Task<f32> {let id = id.into();struct SizeOp {target: advanced::widget::Id,height: Option<f32>,}impl advanced::widget::Operation<f32> for SizeOp {fn scrollable(&mut self,id: Option<&advanced::widget::Id>,_bounds: Rectangle,content_bounds: Rectangle,_translation: iced::Vector,_state: &mut dyn advanced::widget::operation::Scrollable,) {if id == Some(&self.target) {dbg!(&_bounds, &content_bounds);self.height = Some(content_bounds.height);return;}}fn container(&mut self,_id: Option<&advanced::widget::Id>,_bounds: Rectangle,operate_on_children: &mut dyn FnMut(&mut dyn advanced::widget::Operation<f32>,),) {operate_on_children(self);}fn finish(&self) -> advanced::widget::operation::Outcome<f32> {advanced::widget::operation::Outcome::Some(self.height.expect("Must be able to determine the size. If this even panics, make the height optional and re-try the task when None"),)}