diff --git a/src/presentation/mod.rs b/src/presentation/mod.rs index b49573d..6c110c1 100644 --- a/src/presentation/mod.rs +++ b/src/presentation/mod.rs @@ -173,8 +173,8 @@ impl Presentation { } /// Poll every async render operation in the current slide and check whether they're completed. - pub(crate) fn poll_slide_async_renders(&mut self) -> RenderAsyncState { - let slide = self.current_slide_mut(); + pub(crate) fn poll_slide_async_renders(&mut self, slide: usize) -> RenderAsyncState { + let slide = &mut self.slides[slide]; let mut slide_state = RenderAsyncState::Rendered; for operation in slide.iter_operations_mut() { if let RenderOperation::RenderAsync(operation) = operation { diff --git a/src/presenter.rs b/src/presenter.rs index 2bdbcb2..5f0641f 100644 --- a/src/presenter.rs +++ b/src/presenter.rs @@ -156,12 +156,12 @@ impl<'a> Presenter<'a> { self.try_scale_transition_images()?; break; } - CommandSideEffect::NextSlide => { - self.next_slide(&mut drawer)?; + CommandSideEffect::AnimateNextSlide => { + self.animate_next_slide(&mut drawer)?; break; } - CommandSideEffect::PreviousSlide => { - self.previous_slide(&mut drawer)?; + CommandSideEffect::AnimatePreviousSlide => { + self.animate_previous_slide(&mut drawer)?; break; } CommandSideEffect::None => (), @@ -203,15 +203,19 @@ impl<'a> Presenter<'a> { return Ok(false); } let current_index = self.state.presentation().current_slide_index(); - if self.slides_with_pending_async_renders.contains(¤t_index) { - let state = self.state.presentation_mut().poll_slide_async_renders(); + self.poll_slide_async_renders(current_index) + } + + fn poll_slide_async_renders(&mut self, slide: usize) -> Result { + if self.slides_with_pending_async_renders.contains(&slide) { + let state = self.state.presentation_mut().poll_slide_async_renders(slide); match state { RenderAsyncState::NotStarted | RenderAsyncState::Rendering { modified: false } => (), RenderAsyncState::Rendering { modified: true } => { return Ok(true); } RenderAsyncState::Rendered | RenderAsyncState::JustFinishedRendering => { - self.slides_with_pending_async_renders.remove(¤t_index); + self.slides_with_pending_async_renders.remove(&slide); return Ok(true); } }; @@ -279,7 +283,7 @@ impl<'a> Presenter<'a> { if !presentation.jump_next() { false } else if presentation.current_slide_index() != current_slide { - return CommandSideEffect::NextSlide; + return CommandSideEffect::AnimateNextSlide; } else { true } @@ -290,7 +294,7 @@ impl<'a> Presenter<'a> { if !presentation.jump_previous() { false } else if presentation.current_slide_index() != current_slide { - return CommandSideEffect::PreviousSlide; + return CommandSideEffect::AnimatePreviousSlide; } else { true } @@ -436,10 +440,12 @@ impl<'a> Presenter<'a> { } } - fn next_slide(&mut self, drawer: &mut TerminalDrawer) -> RenderResult { + fn animate_next_slide(&mut self, drawer: &mut TerminalDrawer) -> RenderResult { let Some(config) = self.options.transition.clone() else { return Ok(()); }; + self.poll_and_scale_images()?; + let options = drawer.render_engine_options(); let presentation = self.state.presentation_mut(); let dimensions = WindowSize::current(self.options.font_size_fallback)?; @@ -451,14 +457,20 @@ impl<'a> Presenter<'a> { self.animate_transition(drawer, left, right, direction, dimensions, config) } - fn previous_slide(&mut self, drawer: &mut TerminalDrawer) -> RenderResult { + fn animate_previous_slide(&mut self, drawer: &mut TerminalDrawer) -> RenderResult { let Some(config) = self.options.transition.clone() else { return Ok(()); }; + self.poll_and_scale_images()?; + let options = drawer.render_engine_options(); let presentation = self.state.presentation_mut(); let dimensions = WindowSize::current(self.options.font_size_fallback)?; presentation.jump_next(); + + // Re-borrow to avoid calling fns above while mutably borrowing + let presentation = self.state.presentation_mut(); + let right = Self::virtual_render(presentation.current_slide(), dimensions.clone(), &options)?; presentation.jump_previous(); let left = Self::virtual_render(presentation.current_slide(), dimensions.clone(), &options)?; @@ -547,6 +559,17 @@ impl<'a> Presenter<'a> { engine.render(slide.iter_visible_operations())?; Ok(term.into_contents()) } + + fn poll_and_scale_images(&mut self) -> RenderResult { + let mut needs_scaling = false; + for index in 0..self.state.presentation().iter_slides().count() { + needs_scaling = self.poll_slide_async_renders(index)? || needs_scaling; + } + if needs_scaling { + self.try_scale_transition_images()?; + } + Ok(()) + } } enum CommandSideEffect { @@ -554,8 +577,8 @@ enum CommandSideEffect { Suspend, Redraw, Reload, - NextSlide, - PreviousSlide, + AnimateNextSlide, + AnimatePreviousSlide, None, }