trying to make the slide preview more composable

This commit is contained in:
Chris Cochrun 2024-11-15 09:37:17 -06:00
parent f81efdeef3
commit 029188d632
2 changed files with 75 additions and 19 deletions

View file

@ -1,5 +1,6 @@
use clap::{command, Parser};
use cosmic::app::{Core, Settings, Task};
use cosmic::dialog::ashpd::url::Url;
use cosmic::iced::keyboard::Key;
use cosmic::iced::window::Position;
use cosmic::iced::{
@ -12,7 +13,7 @@ use cosmic::widget::tooltip::Position as TPosition;
use cosmic::widget::{button, image, nav_bar, text, tooltip, Space};
use cosmic::{executor, Application, ApplicationExt, Element};
use cosmic::{widget::Container, Theme};
use iced_video_player::VideoPlayer;
use iced_video_player::{Video, VideoPlayer};
use miette::{miette, Result};
use std::path::PathBuf;
use tracing::{debug, level_filters::LevelFilter};
@ -68,16 +69,18 @@ fn theme(_state: &App) -> Theme {
Theme::dark()
}
struct App<'a> {
struct App {
core: Core,
nav_model: nav_bar::Model,
file: PathBuf,
presenter: Presenter<'a>,
presenter: Presenter,
windows: Vec<window::Id>,
slides: Vec<Slide>,
current_slide: Slide,
current_video: Option<Video>
}
impl Default for App<'_> {
impl Default for App {
fn default() -> Self {
let initial_slide = SlideBuilder::new()
.background(PathBuf::from(
@ -88,14 +91,15 @@ impl Default for App<'_> {
.build()
.expect("oops slide");
let slides = vec![initial_slide];
let presenter = Presenter::with_app_slides(&slides);
let presenter = Presenter::with_app_slides(slides.clone());
Self {
presenter,
core: Core::default(),
nav_model: nav_bar::Model::default(),
file: PathBuf::default(),
windows: vec![],
slides: vec![initial_slide],
slides,
current_slide: initial_slide.clone(),
}
}
}
@ -154,8 +158,9 @@ impl cosmic::Application for App {
.video_end_time(0.0)
.build()
.expect("oops slide");
let slides = vec![initial_slide];
let presenter =
Presenter::with_initial_slide(initial_slide.clone());
Presenter::with_app_slides(slides.clone());
let mut app = App {
core,
@ -163,7 +168,7 @@ impl cosmic::Application for App {
file: input.file,
windows,
presenter,
slides: vec![initial_slide],
slides
};
let command;
@ -375,6 +380,7 @@ impl cosmic::Application for App {
.slides
.get(self.presenter.current_slide as usize)
.unwrap();
debug!("rewritten");
let container = match slide.background().kind {
crate::BackgroundKind::Image => Container::new(
image("/home/chris/pics/frodo.jpg")
@ -434,9 +440,8 @@ impl cosmic::Application for App {
// View for presentation
fn view_window(&self, _id: window::Id) -> Element<Message> {
self.presenter
.view()
.map(|message| Message::Present(message))
let video = self.current_slide.background().path.clone();
presenter::slide_view(&self.current_slide, &self.current_video).map(|message|Message::Present(message))
}
}

View file

@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::{path::PathBuf, rc::Rc};
use cosmic::{
dialog::ashpd::url::Url,
@ -11,14 +11,14 @@ use cosmic::{
Task,
};
use iced_video_player::{Video, VideoPlayer};
use miette::{Context, IntoDiagnostic};
use miette::{Context, IntoDiagnostic, Result};
use tracing::{debug, error};
use crate::core::slide::Slide;
// #[derive(Default, Clone, Debug)]
pub(crate) struct Presenter<'a> {
pub slides: &'a Vec<Slide>,
pub(crate) struct Presenter {
pub slides: Vec<Slide>,
pub current_slide: i16,
pub video: Option<Video>,
}
@ -30,12 +30,31 @@ pub(crate) enum Message {
SlideChange(u8),
}
impl<'a> Presenter<'a> {
pub fn with_app_slides(slides: &'a Vec<Slide>) -> Self {
impl Presenter {
pub fn with_app_slides(slides: Vec<Slide>) -> Self {
Self {
slides: slides,
slides: slides.clone(),
current_slide: 0,
video: None,
video: {
if let Some(slide) = slides.get(0) {
let path = slide.background().path.clone();
if path.exists() {
let url = Url::from_file_path(path).unwrap();
let result = Video::new(&url);
match result {
Ok(v) => Some(v),
Err(e) => {
error!("Had an error creating the video object: {e}");
None
}
}
} else {
None
}
} else {
None
}
},
}
}
// pub fn with_initial_slide(slide: Slide) -> Self {
@ -117,3 +136,35 @@ impl<'a> Presenter<'a> {
stack.into()
}
}
pub(crate) fn slide_view<'a>(
slide: &'a Slide,
video: &'a Option<Video>,
) -> Element<'a, Message> {
let text = text!("{}", slide.text()).size(50);
let text = Container::new(text).center(Length::Fill);
let container = match slide.background().kind {
crate::BackgroundKind::Image => Container::new(
image("/home/chris/pics/frodo.jpg")
.content_fit(ContentFit::Cover)
.width(Length::Fill)
.height(Length::Fill),
),
crate::BackgroundKind::Video => {
if let Some(video) = video {
Container::new(
VideoPlayer::new(video)
.width(Length::Fill)
.height(Length::Fill)
.content_fit(ContentFit::Cover),
)
} else {
Container::new(Space::new(Length::Fill, Length::Fill))
}
}
};
let stack = stack!(container, text)
.width(Length::Fill)
.height(Length::Fill);
stack.into()
}