trying to get composed slides to look right
This commit is contained in:
parent
029188d632
commit
0607ccb78d
|
@ -181,6 +181,10 @@ impl Slide {
|
||||||
pub fn font(&self) -> String {
|
pub fn font(&self) -> String {
|
||||||
self.font.clone()
|
self.font.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn video_loop(&self) -> bool {
|
||||||
|
self.video_loop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
174
src/main.rs
174
src/main.rs
|
@ -16,6 +16,7 @@ use cosmic::{widget::Container, Theme};
|
||||||
use iced_video_player::{Video, VideoPlayer};
|
use iced_video_player::{Video, VideoPlayer};
|
||||||
use miette::{miette, Result};
|
use miette::{miette, Result};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use tracing::error;
|
||||||
use tracing::{debug, level_filters::LevelFilter};
|
use tracing::{debug, level_filters::LevelFilter};
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
|
@ -55,8 +56,10 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let settings;
|
let settings;
|
||||||
if args.ui {
|
if args.ui {
|
||||||
|
debug!("main view");
|
||||||
settings = Settings::default().debug(false);
|
settings = Settings::default().debug(false);
|
||||||
} else {
|
} else {
|
||||||
|
debug!("window view");
|
||||||
settings =
|
settings =
|
||||||
Settings::default().debug(false).no_main_window(true);
|
Settings::default().debug(false).no_main_window(true);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +80,8 @@ struct App {
|
||||||
windows: Vec<window::Id>,
|
windows: Vec<window::Id>,
|
||||||
slides: Vec<Slide>,
|
slides: Vec<Slide>,
|
||||||
current_slide: Slide,
|
current_slide: Slide,
|
||||||
current_video: Option<Video>
|
active_video: Option<Video>,
|
||||||
|
preview_video: Option<Video>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
|
@ -90,8 +94,44 @@ impl Default for App {
|
||||||
.text("Hello")
|
.text("Hello")
|
||||||
.build()
|
.build()
|
||||||
.expect("oops slide");
|
.expect("oops slide");
|
||||||
let slides = vec![initial_slide];
|
let slides = vec![initial_slide.clone()];
|
||||||
let presenter = Presenter::with_app_slides(slides.clone());
|
let presenter = Presenter::with_app_slides(slides.clone());
|
||||||
|
let active_video = match initial_slide.background().kind {
|
||||||
|
crate::BackgroundKind::Image => None,
|
||||||
|
crate::BackgroundKind::Video => {
|
||||||
|
if let Ok(video) = &Url::from_file_path(
|
||||||
|
&initial_slide.background().path,
|
||||||
|
) {
|
||||||
|
match Video::new(video) {
|
||||||
|
Ok(video) => Some(video),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Problem loading initial video from slide: {e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let preview_video = match initial_slide.background().kind {
|
||||||
|
crate::BackgroundKind::Image => None,
|
||||||
|
crate::BackgroundKind::Video => {
|
||||||
|
if let Ok(video) = &Url::from_file_path(
|
||||||
|
&initial_slide.background().path,
|
||||||
|
) {
|
||||||
|
match Video::new(video) {
|
||||||
|
Ok(video) => Some(video),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Problem loading initial video from slide: {e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
presenter,
|
presenter,
|
||||||
core: Core::default(),
|
core: Core::default(),
|
||||||
|
@ -99,7 +139,9 @@ impl Default for App {
|
||||||
file: PathBuf::default(),
|
file: PathBuf::default(),
|
||||||
windows: vec![],
|
windows: vec![],
|
||||||
slides,
|
slides,
|
||||||
current_slide: initial_slide.clone(),
|
current_slide: initial_slide,
|
||||||
|
active_video,
|
||||||
|
preview_video,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +154,7 @@ enum Message {
|
||||||
CloseWindow(window::Id),
|
CloseWindow(window::Id),
|
||||||
WindowOpened(window::Id, Option<Point>),
|
WindowOpened(window::Id, Option<Point>),
|
||||||
WindowClosed(window::Id),
|
WindowClosed(window::Id),
|
||||||
|
ToggleMuteVideo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl cosmic::Application for App {
|
impl cosmic::Application for App {
|
||||||
|
@ -140,6 +183,7 @@ impl cosmic::Application for App {
|
||||||
if input.ui {
|
if input.ui {
|
||||||
windows.push(core.main_window_id().unwrap());
|
windows.push(core.main_window_id().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let initial_slide = SlideBuilder::new()
|
let initial_slide = SlideBuilder::new()
|
||||||
.background(
|
.background(
|
||||||
PathBuf::from(
|
PathBuf::from(
|
||||||
|
@ -158,23 +202,74 @@ impl cosmic::Application for App {
|
||||||
.video_end_time(0.0)
|
.video_end_time(0.0)
|
||||||
.build()
|
.build()
|
||||||
.expect("oops slide");
|
.expect("oops slide");
|
||||||
let slides = vec![initial_slide];
|
|
||||||
let presenter =
|
|
||||||
Presenter::with_app_slides(slides.clone());
|
|
||||||
|
|
||||||
|
let slides = vec![initial_slide.clone()];
|
||||||
|
let presenter = Presenter::with_app_slides(slides.clone());
|
||||||
|
let active_video = match initial_slide.background().kind {
|
||||||
|
crate::BackgroundKind::Image => None,
|
||||||
|
crate::BackgroundKind::Video => {
|
||||||
|
if let Ok(video) = &Url::from_file_path(
|
||||||
|
&initial_slide.background().path,
|
||||||
|
) {
|
||||||
|
match Video::new(video) {
|
||||||
|
Ok(mut video) => {
|
||||||
|
video.set_looping(
|
||||||
|
initial_slide.video_loop(),
|
||||||
|
);
|
||||||
|
Some(video)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Problem loading initial video from slide: {e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let preview_video = match initial_slide.background().kind {
|
||||||
|
crate::BackgroundKind::Image => None,
|
||||||
|
crate::BackgroundKind::Video => {
|
||||||
|
if let Ok(video) = &Url::from_file_path(
|
||||||
|
&initial_slide.background().path,
|
||||||
|
) {
|
||||||
|
match Video::new(video) {
|
||||||
|
Ok(mut video) => {
|
||||||
|
video.set_looping(
|
||||||
|
initial_slide.video_loop(),
|
||||||
|
);
|
||||||
|
video.set_muted(true);
|
||||||
|
Some(video)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Problem loading initial video from slide: {e}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
let mut app = App {
|
let mut app = App {
|
||||||
core,
|
|
||||||
nav_model,
|
|
||||||
file: input.file,
|
|
||||||
windows,
|
|
||||||
presenter,
|
presenter,
|
||||||
slides
|
core,
|
||||||
|
nav_model: nav_bar::Model::default(),
|
||||||
|
file: PathBuf::default(),
|
||||||
|
windows: vec![],
|
||||||
|
slides,
|
||||||
|
current_slide: initial_slide,
|
||||||
|
active_video,
|
||||||
|
preview_video,
|
||||||
};
|
};
|
||||||
|
|
||||||
let command;
|
let command;
|
||||||
if input.ui {
|
if input.ui {
|
||||||
|
debug!("main view");
|
||||||
command = app.update_title()
|
command = app.update_title()
|
||||||
} else {
|
} else {
|
||||||
|
debug!("window view");
|
||||||
command = app.show_window()
|
command = app.show_window()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,10 +321,13 @@ impl cosmic::Application for App {
|
||||||
.spacing(5),
|
.spacing(5),
|
||||||
)
|
)
|
||||||
.class(cosmic::theme::style::Button::HeaderBar)
|
.class(cosmic::theme::style::Button::HeaderBar)
|
||||||
.on_press(if window_open {
|
.on_press({
|
||||||
Message::CloseWindow(*presenter_window.unwrap())
|
debug!(window_open);
|
||||||
} else {
|
if window_open {
|
||||||
Message::OpenWindow
|
Message::CloseWindow(*presenter_window.unwrap())
|
||||||
|
} else {
|
||||||
|
Message::OpenWindow
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
"Open Window",
|
"Open Window",
|
||||||
TPosition::Bottom,
|
TPosition::Bottom,
|
||||||
|
@ -368,41 +466,22 @@ impl cosmic::Application for App {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::ToggleMuteVideo => {
|
||||||
|
if let Some(video) = &mut self.active_video {
|
||||||
|
video.set_muted(true);
|
||||||
|
}
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main window view
|
// Main window view
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
let text = text::body("This is frodo").size(20);
|
debug!("Main view");
|
||||||
let text = Container::new(text).center(Length::Fill);
|
let preview = presenter::slide_view(
|
||||||
let slide = self
|
&self.current_slide,
|
||||||
.presenter
|
&self.preview_video,
|
||||||
.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")
|
|
||||||
.content_fit(ContentFit::Cover)
|
|
||||||
.width(Length::Fill)
|
|
||||||
.height(Length::Fill),
|
|
||||||
),
|
|
||||||
crate::BackgroundKind::Video => {
|
|
||||||
if let Some(video) = &self.presenter.video {
|
|
||||||
Container::new(
|
|
||||||
VideoPlayer::new(&video)
|
|
||||||
.width(Length::Fill)
|
|
||||||
.height(Length::Fill)
|
|
||||||
.content_fit(ContentFit::Contain),
|
|
||||||
)
|
|
||||||
.center(Length::Fill)
|
|
||||||
} else {
|
|
||||||
Container::new(Space::new(0, 0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let preview = stack!(container, text);
|
|
||||||
let icon_left = icon::from_name("arrow-left");
|
let icon_left = icon::from_name("arrow-left");
|
||||||
let icon_right = icon::from_name("arrow-right");
|
let icon_right = icon::from_name("arrow-right");
|
||||||
let row = row![
|
let row = row![
|
||||||
|
@ -440,8 +519,9 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
// View for presentation
|
// View for presentation
|
||||||
fn view_window(&self, _id: window::Id) -> Element<Message> {
|
fn view_window(&self, _id: window::Id) -> Element<Message> {
|
||||||
let video = self.current_slide.background().path.clone();
|
debug!("window");
|
||||||
presenter::slide_view(&self.current_slide, &self.current_video).map(|message|Message::Present(message))
|
presenter::slide_view(&self.current_slide, &self.active_video)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{path::PathBuf, rc::Rc};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
dialog::ashpd::url::Url,
|
dialog::ashpd::url::Url,
|
||||||
iced::{widget::text, ContentFit, Length},
|
iced::{widget::text, ContentFit, Length},
|
||||||
iced_widget::{row, stack},
|
iced_widget::{row, stack, Stack},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widget::{
|
widget::{
|
||||||
button, container, icon::Named, image, Container, Space,
|
button, container, icon::Named, image, Container, Space,
|
||||||
|
@ -140,7 +140,7 @@ impl Presenter {
|
||||||
pub(crate) fn slide_view<'a>(
|
pub(crate) fn slide_view<'a>(
|
||||||
slide: &'a Slide,
|
slide: &'a Slide,
|
||||||
video: &'a Option<Video>,
|
video: &'a Option<Video>,
|
||||||
) -> Element<'a, Message> {
|
) -> Stack<'a, crate::Message, cosmic::Theme> {
|
||||||
let text = text!("{}", slide.text()).size(50);
|
let text = text!("{}", slide.text()).size(50);
|
||||||
let text = Container::new(text).center(Length::Fill);
|
let text = Container::new(text).center(Length::Fill);
|
||||||
let container = match slide.background().kind {
|
let container = match slide.background().kind {
|
||||||
|
@ -154,7 +154,7 @@ pub(crate) fn slide_view<'a>(
|
||||||
if let Some(video) = video {
|
if let Some(video) = video {
|
||||||
Container::new(
|
Container::new(
|
||||||
VideoPlayer::new(video)
|
VideoPlayer::new(video)
|
||||||
.width(Length::Fill)
|
.width(Length::Shrink)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.content_fit(ContentFit::Cover),
|
.content_fit(ContentFit::Cover),
|
||||||
)
|
)
|
||||||
|
@ -163,8 +163,7 @@ pub(crate) fn slide_view<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let stack = stack!(container, text)
|
stack!(container, text)
|
||||||
.width(Length::Fill)
|
// .width(Length::Fill)
|
||||||
.height(Length::Fill);
|
// .height(Length::Fill)
|
||||||
stack.into()
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue