remove pdf module for inserting the handles as a slide field
This ensures that there isn't a need to duplicate tracking which index we have and which one is currently active, instead we pre create all the handles.
This commit is contained in:
parent
ad14135ddf
commit
191dd0255d
5 changed files with 65 additions and 189 deletions
|
|
@ -2,7 +2,6 @@ use crate::core::model::LibraryKind;
|
|||
|
||||
pub mod double_ended_slider;
|
||||
pub mod library;
|
||||
pub mod pdf;
|
||||
pub mod presenter;
|
||||
pub mod slide_editor;
|
||||
pub mod song_editor;
|
||||
|
|
|
|||
161
src/ui/pdf.rs
161
src/ui/pdf.rs
|
|
@ -1,161 +0,0 @@
|
|||
use std::path::Path;
|
||||
|
||||
use cosmic::iced::ContentFit;
|
||||
use cosmic::iced::Length;
|
||||
use cosmic::widget::image;
|
||||
use cosmic::widget::image::Handle;
|
||||
use cosmic::Element;
|
||||
use miette::IntoDiagnostic;
|
||||
use miette::Result;
|
||||
use miette::Severity;
|
||||
use mupdf::Colorspace;
|
||||
use mupdf::Document;
|
||||
use mupdf::Matrix;
|
||||
use tracing::debug;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PdfViewer {
|
||||
document: Option<Document>,
|
||||
pages: Option<Vec<Handle>>,
|
||||
current_page: Option<Handle>,
|
||||
current_index: usize,
|
||||
}
|
||||
|
||||
pub enum Message {}
|
||||
|
||||
impl PdfViewer {
|
||||
pub fn with_pdf(pdf: impl AsRef<Path>) -> Result<Self> {
|
||||
let pdf_path = pdf.as_ref();
|
||||
let document = Document::open(pdf_path).into_diagnostic()?;
|
||||
let pages = document.pages().into_diagnostic()?;
|
||||
let pages: Vec<Handle> = pages
|
||||
.filter_map(|page| {
|
||||
let Some(page) = page.ok() else {
|
||||
return None;
|
||||
};
|
||||
let matrix = Matrix::IDENTITY;
|
||||
let colorspace = Colorspace::device_rgb();
|
||||
let Ok(pixmap) = page
|
||||
.to_pixmap(&matrix, &colorspace, true, true)
|
||||
.into_diagnostic()
|
||||
else {
|
||||
error!("Can't turn this page into pixmap");
|
||||
return None;
|
||||
};
|
||||
let handle = pixmap.samples().to_vec();
|
||||
Some(Handle::from_bytes(handle))
|
||||
})
|
||||
.collect();
|
||||
let Some(page) = document.pages().into_diagnostic()?.next()
|
||||
else {
|
||||
return Err(miette::miette!(
|
||||
severity = Severity::Warning,
|
||||
"There isn't a first page here"
|
||||
));
|
||||
};
|
||||
let page = page.into_diagnostic()?;
|
||||
let matrix = Matrix::IDENTITY;
|
||||
let colorspace = Colorspace::device_rgb();
|
||||
let pixmap = page
|
||||
.to_pixmap(&matrix, &colorspace, true, true)
|
||||
.into_diagnostic()?;
|
||||
let handle = pixmap.samples().to_vec();
|
||||
Ok(Self {
|
||||
document: Some(document),
|
||||
pages: Some(pages),
|
||||
current_index: 0,
|
||||
current_page: Some(Handle::from_bytes(handle)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert_pdf(
|
||||
&mut self,
|
||||
pdf: impl AsRef<Path>,
|
||||
) -> Result<()> {
|
||||
let pdf_path = pdf.as_ref();
|
||||
let document = Document::open(pdf_path).into_diagnostic()?;
|
||||
let pages = document.pages().into_diagnostic()?;
|
||||
|
||||
let pages: Vec<Handle> = pages
|
||||
.filter_map(|page| {
|
||||
let Some(page) = page.ok() else {
|
||||
return None;
|
||||
};
|
||||
let matrix = Matrix::IDENTITY;
|
||||
let colorspace = Colorspace::device_rgb();
|
||||
let Ok(pixmap) = page
|
||||
.to_pixmap(&matrix, &colorspace, true, true)
|
||||
.into_diagnostic()
|
||||
else {
|
||||
error!("Can't turn this page into pixmap");
|
||||
return None;
|
||||
};
|
||||
debug!(?pixmap);
|
||||
Some(Handle::from_rgba(
|
||||
pixmap.width(),
|
||||
pixmap.height(),
|
||||
pixmap.samples().to_vec(),
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
let Some(page) = document.pages().into_diagnostic()?.next()
|
||||
else {
|
||||
return Err(miette::miette!(
|
||||
severity = Severity::Warning,
|
||||
"There isn't a first page here"
|
||||
));
|
||||
};
|
||||
self.current_page = pages.get(0).map(|h| h.to_owned());
|
||||
self.document = Some(document);
|
||||
self.pages = Some(pages);
|
||||
self.current_index = 0;
|
||||
debug!(?self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn next_page(&mut self) -> Result<()> {
|
||||
let Some(ref pages) = self.pages else {
|
||||
return Err(miette::miette!("No pages in doc"));
|
||||
};
|
||||
let Some(page) = pages.get(self.current_index + 1) else {
|
||||
return Err(miette::miette!("There isn't a next page"));
|
||||
};
|
||||
self.current_page = Some(page.to_owned());
|
||||
self.current_index += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn previous_page(&mut self) -> Result<()> {
|
||||
if self.current_index == 0 {
|
||||
return Err(miette::miette!("You are at the first page"));
|
||||
}
|
||||
let Some(ref pages) = self.pages else {
|
||||
return Err(miette::miette!("No pages in doc"));
|
||||
};
|
||||
let Some(page) = pages.get(self.current_index - 1) else {
|
||||
return Err(miette::miette!(
|
||||
"There isn't a previous page"
|
||||
));
|
||||
};
|
||||
self.current_page = Some(page.to_owned());
|
||||
self.current_index -= 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn view(&self, index: u32) -> Option<Element<Message>> {
|
||||
let Some(pages) = &self.pages else {
|
||||
return None;
|
||||
};
|
||||
let Some(handle) = pages.get(index as usize) else {
|
||||
return None;
|
||||
};
|
||||
Some(
|
||||
image(handle)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.content_fit(ContentFit::Contain)
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -53,7 +53,6 @@ pub(crate) struct Presenter {
|
|||
hovered_slide: Option<(usize, usize)>,
|
||||
scroll_id: Id,
|
||||
current_font: Font,
|
||||
pdf_viewer: PdfViewer,
|
||||
}
|
||||
|
||||
pub(crate) enum Action {
|
||||
|
|
@ -174,7 +173,6 @@ impl Presenter {
|
|||
},
|
||||
scroll_id: Id::unique(),
|
||||
current_font: cosmic::font::default(),
|
||||
pdf_viewer: PdfViewer::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,11 +223,6 @@ impl Presenter {
|
|||
self.reset_video();
|
||||
}
|
||||
|
||||
if slide.background().kind == BackgroundKind::Pdf {
|
||||
self.pdf_viewer
|
||||
.insert_pdf(&slide.background().path);
|
||||
}
|
||||
|
||||
let offset = AbsoluteOffset {
|
||||
x: {
|
||||
if self.current_slide_index > 2 {
|
||||
|
|
@ -411,7 +404,6 @@ impl Presenter {
|
|||
slide_view(
|
||||
&self.current_slide,
|
||||
&self.video,
|
||||
&self.pdf_viewer,
|
||||
self.current_font,
|
||||
false,
|
||||
true,
|
||||
|
|
@ -422,7 +414,6 @@ impl Presenter {
|
|||
slide_view(
|
||||
&self.current_slide,
|
||||
&self.video,
|
||||
&self.pdf_viewer,
|
||||
self.current_font,
|
||||
false,
|
||||
false,
|
||||
|
|
@ -459,7 +450,6 @@ impl Presenter {
|
|||
let container = slide_view(
|
||||
&slide,
|
||||
&self.video,
|
||||
&self.pdf_viewer,
|
||||
font,
|
||||
true,
|
||||
false,
|
||||
|
|
@ -722,7 +712,6 @@ fn scale_font(font_size: f32, width: f32) -> f32 {
|
|||
pub(crate) fn slide_view<'a>(
|
||||
slide: &'a Slide,
|
||||
video: &'a Option<Video>,
|
||||
pdf_viewer: &'a PdfViewer,
|
||||
font: Font,
|
||||
delegate: bool,
|
||||
hide_mouse: bool,
|
||||
|
|
@ -799,17 +788,26 @@ pub(crate) fn slide_view<'a>(
|
|||
Container::new(Space::new(0, 0))
|
||||
}
|
||||
}
|
||||
BackgroundKind::Pdf => Container::new(
|
||||
if let Some(pdf) = pdf_viewer.view(slide.pdf_index())
|
||||
{
|
||||
pdf.map(|_| Message::None)
|
||||
BackgroundKind::Pdf => {
|
||||
if let Some(pdf) = slide.pdf_page() {
|
||||
Container::new(
|
||||
image(pdf)
|
||||
.content_fit(ContentFit::Cover)
|
||||
.width(width)
|
||||
.height(size.height),
|
||||
)
|
||||
.center_x(width)
|
||||
.center_y(size.height)
|
||||
.clip(true)
|
||||
.into()
|
||||
} else {
|
||||
Space::new(0.0, 0.0).into()
|
||||
},
|
||||
)
|
||||
.center_x(width)
|
||||
.center_y(size.height)
|
||||
.clip(true),
|
||||
Container::new(Space::new(0.0, 0.0))
|
||||
.center_x(width)
|
||||
.center_y(size.height)
|
||||
.clip(true)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
BackgroundKind::Html => todo!(),
|
||||
};
|
||||
let stack = stack!(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue