the core of loading slides from lisp is done
Slides themselves are capable of loading from lisp. The goal next will be to create a way to load songs from lisp.
This commit is contained in:
parent
b49aa55ec3
commit
356384821b
|
@ -140,24 +140,24 @@ mod test {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_list() {
|
// fn test_list() {
|
||||||
let lisp =
|
// let lisp =
|
||||||
read_to_string("./test_presentation.lisp").expect("oops");
|
// read_to_string("./test_presentation.lisp").expect("oops");
|
||||||
println!("{lisp}");
|
// // println!("{lisp}");
|
||||||
let mut parser =
|
// let mut parser =
|
||||||
Parser::from_str_custom(&lisp, Options::elisp());
|
// Parser::from_str_custom(&lisp, Options::elisp());
|
||||||
for atom in parser.value_iter() {
|
// for atom in parser.value_iter() {
|
||||||
match atom {
|
// match atom {
|
||||||
Ok(atom) => {
|
// Ok(atom) => {
|
||||||
println!("{atom}");
|
// // println!("{atom}");
|
||||||
let lists = get_lists(&atom);
|
// let lists = get_lists(&atom);
|
||||||
assert_eq!(lists, vec![Value::Null])
|
// assert_eq!(lists, vec![Value::Null])
|
||||||
}
|
// }
|
||||||
Err(e) => {
|
// Err(e) => {
|
||||||
panic!("{e}");
|
// panic!("{e}");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crisp::types::{Keyword, Value};
|
use crisp::types::{Keyword, Symbol, Value};
|
||||||
use miette::{miette, IntoDiagnostic, Result};
|
use miette::{miette, IntoDiagnostic, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -7,8 +7,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
use tracing::error;
|
||||||
use crate::core::lisp::Symbol;
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||||
|
@ -49,42 +48,32 @@ impl TryFrom<String> for Background {
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
let value = value.trim_start_matches("file://");
|
let value = value.trim_start_matches("file://");
|
||||||
let path = PathBuf::from(value);
|
let path = PathBuf::from(value);
|
||||||
if !path.exists() {
|
Background::try_from(path)
|
||||||
return Err(ParseError::DoesNotExist);
|
|
||||||
}
|
|
||||||
let extension = value.rsplit_once('.').unwrap_or_default();
|
|
||||||
match extension.1 {
|
|
||||||
"jpg" | "png" | "webp" | "html" => Ok(Self {
|
|
||||||
path,
|
|
||||||
kind: BackgroundKind::Image,
|
|
||||||
}),
|
|
||||||
"mp4" | "mkv" | "webm" => Ok(Self {
|
|
||||||
path,
|
|
||||||
kind: BackgroundKind::Video,
|
|
||||||
}),
|
|
||||||
_ => Err(ParseError::NonBackgroundFile),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<PathBuf> for Background {
|
impl TryFrom<PathBuf> for Background {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
|
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
|
||||||
let extension = value
|
if let Ok(value) = value.canonicalize() {
|
||||||
.extension()
|
let extension = value
|
||||||
.unwrap_or_default()
|
.extension()
|
||||||
.to_str()
|
.unwrap_or_default()
|
||||||
.unwrap_or_default();
|
.to_str()
|
||||||
match extension {
|
.unwrap_or_default();
|
||||||
"jpg" | "png" | "webp" | "html" => Ok(Self {
|
match extension {
|
||||||
path: value,
|
"jpg" | "png" | "webp" | "html" => Ok(Self {
|
||||||
kind: BackgroundKind::Image,
|
path: value,
|
||||||
}),
|
kind: BackgroundKind::Image,
|
||||||
"mp4" | "mkv" | "webm" => Ok(Self {
|
}),
|
||||||
path: value,
|
"mp4" | "mkv" | "webm" => Ok(Self {
|
||||||
kind: BackgroundKind::Video,
|
path: value,
|
||||||
}),
|
kind: BackgroundKind::Video,
|
||||||
_ => Err(ParseError::NonBackgroundFile),
|
}),
|
||||||
|
_ => Err(ParseError::NonBackgroundFile),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(ParseError::CannotCanonicalize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,14 +81,27 @@ impl TryFrom<PathBuf> for Background {
|
||||||
impl TryFrom<&str> for Background {
|
impl TryFrom<&str> for Background {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
Ok(Self::try_from(String::from(value))?)
|
if value.starts_with("~") {
|
||||||
|
if let Some(home) = dirs::home_dir() {
|
||||||
|
if let Some(home) = home.to_str() {
|
||||||
|
let value = value.replace("~", home);
|
||||||
|
Self::try_from(PathBuf::from(value))
|
||||||
|
} else {
|
||||||
|
Self::try_from(PathBuf::from(value))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self::try_from(PathBuf::from(value))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self::try_from(PathBuf::from(value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Path> for Background {
|
impl TryFrom<&Path> for Background {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
fn try_from(value: &Path) -> Result<Self, Self::Error> {
|
fn try_from(value: &Path) -> Result<Self, Self::Error> {
|
||||||
Ok(Self::try_from(PathBuf::from(value))?)
|
Self::try_from(PathBuf::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ impl TryFrom<&Path> for Background {
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
NonBackgroundFile,
|
NonBackgroundFile,
|
||||||
DoesNotExist,
|
DoesNotExist,
|
||||||
|
CannotCanonicalize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for ParseError {}
|
impl std::error::Error for ParseError {}
|
||||||
|
@ -121,6 +124,9 @@ impl Display for ParseError {
|
||||||
"The file is not a recognized image or video type"
|
"The file is not a recognized image or video type"
|
||||||
}
|
}
|
||||||
Self::DoesNotExist => "This file doesn't exist",
|
Self::DoesNotExist => "This file doesn't exist",
|
||||||
|
Self::CannotCanonicalize => {
|
||||||
|
"Could not canonicalize this file"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
write!(f, "Error: {message}")
|
write!(f, "Error: {message}")
|
||||||
}
|
}
|
||||||
|
@ -184,6 +190,7 @@ impl Slide {
|
||||||
|
|
||||||
impl From<Value> for Slide {
|
impl From<Value> for Slide {
|
||||||
fn from(value: Value) -> Self {
|
fn from(value: Value) -> Self {
|
||||||
|
dbg!(&value);
|
||||||
match value {
|
match value {
|
||||||
Value::List(list) => lisp_to_slide(list),
|
Value::List(list) => lisp_to_slide(list),
|
||||||
_ => Slide::default(),
|
_ => Slide::default(),
|
||||||
|
@ -194,39 +201,120 @@ impl From<Value> for Slide {
|
||||||
fn lisp_to_slide(lisp: Vec<Value>) -> Slide {
|
fn lisp_to_slide(lisp: Vec<Value>) -> Slide {
|
||||||
let mut slide = SlideBuilder::new();
|
let mut slide = SlideBuilder::new();
|
||||||
let background_position = if let Some(background) =
|
let background_position = if let Some(background) =
|
||||||
lisp.position(|v| Value::Keyword(Keyword::from("background")))
|
lisp.iter().position(|v| {
|
||||||
{
|
v == &Value::Keyword(Keyword::from("background"))
|
||||||
|
}) {
|
||||||
background + 1
|
background + 1
|
||||||
} else {
|
} else {
|
||||||
0
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dbg!(&background_position);
|
||||||
if let Some(background) = lisp.get(background_position) {
|
if let Some(background) = lisp.get(background_position) {
|
||||||
slide.background(lisp_to_background(background));
|
dbg!(&background);
|
||||||
|
slide = slide.background(lisp_to_background(background));
|
||||||
} else {
|
} else {
|
||||||
slide.background(Background::default());
|
slide = slide.background(Background::default());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let text_position = lisp.iter().position(|v| match v {
|
||||||
|
Value::List(vec) => {
|
||||||
|
vec[0] == Value::Symbol(Symbol::from("text"))
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(text_position) = text_position {
|
||||||
|
if let Some(text) = lisp.get(text_position) {
|
||||||
|
slide = slide.text(lisp_to_text(text));
|
||||||
|
} else {
|
||||||
|
slide = slide.text("");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slide = slide.text("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(text_position) = text_position {
|
||||||
|
if let Some(text) = lisp.get(text_position) {
|
||||||
|
slide = slide.font_size(lisp_to_font_size(text));
|
||||||
|
} else {
|
||||||
|
slide = slide.font_size(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slide = slide.font_size(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
slide = slide
|
||||||
|
.font("Quicksand")
|
||||||
|
.text_alignment(TextAlignment::MiddleCenter)
|
||||||
|
.video_loop(false)
|
||||||
|
.video_start_time(0.0)
|
||||||
|
.video_end_time(0.0);
|
||||||
|
dbg!(&slide);
|
||||||
|
|
||||||
match slide.build() {
|
match slide.build() {
|
||||||
Ok(slide) => slide,
|
Ok(slide) => slide,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
miette!("Shoot! Slide didn't build: {e}");
|
dbg!(&e);
|
||||||
|
error!("Shoot! Slide didn't build: {e}");
|
||||||
Slide::default()
|
Slide::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lisp_to_font_size(lisp: &Value) -> i32 {
|
||||||
|
match lisp {
|
||||||
|
Value::List(list) => {
|
||||||
|
if let Some(font_size_position) =
|
||||||
|
list.iter().position(|v| {
|
||||||
|
v == &Value::Keyword(Keyword::from("font-size"))
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if let Some(font_size_value) =
|
||||||
|
list.get(font_size_position + 1)
|
||||||
|
{
|
||||||
|
font_size_value.into()
|
||||||
|
} else {
|
||||||
|
50
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lisp_to_text(lisp: &Value) -> impl Into<String> {
|
||||||
|
match lisp {
|
||||||
|
Value::List(list) => list[1].clone(),
|
||||||
|
_ => "".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lisp_to_background(lisp: &Value) -> Background {
|
fn lisp_to_background(lisp: &Value) -> Background {
|
||||||
match lisp {
|
match lisp {
|
||||||
Value::List(list) => {
|
Value::List(list) => {
|
||||||
if let Some(source) = list.iter().position(|v| {
|
if let Some(source) = list.iter().position(|v| {
|
||||||
v == &Value::Keyword(Keyword::from("source"))
|
v == &Value::Keyword(Keyword::from("source"))
|
||||||
}) {
|
}) {
|
||||||
let source = list[source + 1];
|
let source = &list[source + 1];
|
||||||
|
dbg!(&source);
|
||||||
match source {
|
match source {
|
||||||
Value::String(s) =>
|
Value::String(s) => {
|
||||||
|
match Background::try_from(s.as_str()) {
|
||||||
|
Ok(background) => {
|
||||||
|
dbg!(&background);
|
||||||
|
background
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
dbg!("Couldn't load background: ", e);
|
||||||
|
Background::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Background::default(),
|
||||||
}
|
}
|
||||||
|
|
||||||
Background::try_from(&path)
|
|
||||||
} else {
|
} else {
|
||||||
Background::default()
|
Background::default()
|
||||||
}
|
}
|
||||||
|
@ -267,7 +355,7 @@ impl SlideBuilder {
|
||||||
mut self,
|
mut self,
|
||||||
background: Background,
|
background: Background,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.background.insert(background);
|
let _ = self.background.insert(background);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +448,7 @@ struct Image {
|
||||||
pub fit: String,
|
pub fit: String,
|
||||||
pub children: Vec<String>,
|
pub children: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -368,167 +457,56 @@ impl Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn build_image_bg(
|
|
||||||
// atom: &Value,
|
|
||||||
// image_map: &mut HashMap<String, String>,
|
|
||||||
// map_index: usize,
|
|
||||||
// ) {
|
|
||||||
// // This needs to be the cons that contains (image . ...)
|
|
||||||
// // the image is a symbol and the rest are keywords and other maps
|
|
||||||
// if atom.is_symbol() {
|
|
||||||
// // We shouldn't get a symbol
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for atom in
|
|
||||||
// atom.list_iter().unwrap().map(|a| a.as_cons().unwrap())
|
|
||||||
// {
|
|
||||||
// if atom.car() == &Value::Symbol("image".into()) {
|
|
||||||
// build_image_bg(atom.cdr(), image_map, map_index);
|
|
||||||
// } else {
|
|
||||||
// let atom = atom.car();
|
|
||||||
// match atom {
|
|
||||||
// Value::Keyword(keyword) => {
|
|
||||||
// image_map.insert(keyword.to_string(), "".into());
|
|
||||||
// build_image_bg(atom, image_map, map_index);
|
|
||||||
// }
|
|
||||||
// Value::Symbol(symbol) => {
|
|
||||||
// // let mut key;
|
|
||||||
// // let image_map = image_map
|
|
||||||
// // .iter_mut()
|
|
||||||
// // .enumerate()
|
|
||||||
// // .filter(|(i, e)| i == &map_index)
|
|
||||||
// // .map(|(i, (k, v))| v.push_str(symbol))
|
|
||||||
// // .collect();
|
|
||||||
// build_image_bg(atom, image_map, map_index);
|
|
||||||
// }
|
|
||||||
// Value::String(string) => {}
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn build_slide(exp: Value) -> Result<Slide> {
|
|
||||||
// let mut slide_builder = SlideBuilder::new();
|
|
||||||
// let mut keyword = "idk";
|
|
||||||
// for value in exp.as_cons().unwrap().to_vec().0 {
|
|
||||||
// let mut vecs = vec![vec![]];
|
|
||||||
// match value {
|
|
||||||
// Value::Symbol(symbol) => {}
|
|
||||||
// Value::Keyword(keyword) => {}
|
|
||||||
// Value::String(string) => {}
|
|
||||||
// Value::Number(num) => {}
|
|
||||||
// Value::Cons(cons) => {
|
|
||||||
// vecs.push(get_lists(&value));
|
|
||||||
// }
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// todo!()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn build_slides(
|
|
||||||
// cons: &lexpr::Cons,
|
|
||||||
// mut current_symbol: Symbol,
|
|
||||||
// mut slide_builder: SlideBuilder,
|
|
||||||
// ) -> SlideBuilder {
|
|
||||||
// for value in cons.list_iter() {
|
|
||||||
// dbg!(¤t_symbol);
|
|
||||||
// match value {
|
|
||||||
// Value::Cons(v) => {
|
|
||||||
// slide_builder = build_slides(
|
|
||||||
// &v,
|
|
||||||
// current_symbol.clone(),
|
|
||||||
// slide_builder,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// Value::Nil => {
|
|
||||||
// dbg!(Value::Nil);
|
|
||||||
// }
|
|
||||||
// Value::Bool(boolean) => {
|
|
||||||
// dbg!(boolean);
|
|
||||||
// }
|
|
||||||
// Value::Number(number) => {
|
|
||||||
// dbg!(number);
|
|
||||||
// }
|
|
||||||
// Value::String(string) => {
|
|
||||||
// dbg!(string);
|
|
||||||
// }
|
|
||||||
// Value::Symbol(symbol) => {
|
|
||||||
// dbg!(symbol);
|
|
||||||
// current_symbol =
|
|
||||||
// Symbol::from_str(symbol).unwrap_or_default();
|
|
||||||
// }
|
|
||||||
// Value::Keyword(keyword) => {
|
|
||||||
// dbg!(keyword);
|
|
||||||
// }
|
|
||||||
// Value::Null => {
|
|
||||||
// dbg!("null");
|
|
||||||
// }
|
|
||||||
// Value::Char(c) => {
|
|
||||||
// dbg!(c);
|
|
||||||
// }
|
|
||||||
// Value::Bytes(b) => {
|
|
||||||
// dbg!(b);
|
|
||||||
// }
|
|
||||||
// Value::Vector(v) => {
|
|
||||||
// dbg!(v);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// slide_builder
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use lexpr::{parse::Options, Datum, Parser};
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde_lexpr::from_str;
|
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn test_slide() -> Slide {
|
fn test_slide() -> Slide {
|
||||||
Slide::default()
|
Slide {
|
||||||
|
text: "This is frodo".to_string(),
|
||||||
|
background: Background::try_from("~/pics/frodo.jpg")
|
||||||
|
.unwrap(),
|
||||||
|
font: "Quicksand".to_string(),
|
||||||
|
font_size: 70,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_second_slide() -> Slide {
|
||||||
|
Slide {
|
||||||
|
text: "".to_string(),
|
||||||
|
background: Background::try_from(
|
||||||
|
"~/vids/test/camprules2024.mp4",
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
font: "Quicksand".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lexp_serialize() {
|
fn test_lisp_serialize() {
|
||||||
let lisp =
|
let lisp =
|
||||||
read_to_string("./test_presentation.lisp").expect("oops");
|
read_to_string("./test_presentation.lisp").expect("oops");
|
||||||
println!("{lisp}");
|
println!("{lisp}");
|
||||||
let mut parser =
|
let lisp_value = crisp::reader::read(&lisp);
|
||||||
Parser::from_str_custom(&lisp, Options::elisp());
|
match lisp_value {
|
||||||
for atom in parser.value_iter() {
|
Value::List(value) => {
|
||||||
match atom {
|
let slide = Slide::from(value[0].clone());
|
||||||
Ok(atom) => {
|
let test_slide = test_slide();
|
||||||
let symbol = Symbol::None;
|
assert_eq!(slide, test_slide);
|
||||||
let slide_builder = SlideBuilder::new();
|
|
||||||
atom.as_cons().map(|c| {
|
let second_slide = Slide::from(value[1].clone());
|
||||||
build_slides(c, symbol, slide_builder)
|
dbg!(&second_slide);
|
||||||
});
|
let second_test_slide = test_second_slide();
|
||||||
}
|
assert_eq!(second_slide, second_test_slide)
|
||||||
Err(e) => {
|
|
||||||
dbg!(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_ => panic!("this should be a lisp"),
|
||||||
}
|
}
|
||||||
// parser.map(|atom| match atom {
|
|
||||||
// Ok(atom) => dbg!(atom),
|
|
||||||
// Err(e) => dbg!(e),
|
|
||||||
// });
|
|
||||||
// let lispy = from_str_elisp(&lisp).expect("oops");
|
|
||||||
// if lispy.is_list() {
|
|
||||||
// for atom in lispy.list_iter().unwrap() {
|
|
||||||
// print_list(atom);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
let slide: Slide = from_str(&lisp).expect("oops");
|
|
||||||
let test_slide = test_slide();
|
|
||||||
assert_eq!(slide, test_slide)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -577,32 +577,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_slide<'a>() -> Element<'a, Message> {
|
|
||||||
if let Ok(slide) = SlideBuilder::new()
|
|
||||||
.background(
|
|
||||||
Background::try_from("/home/chris/pics/frodo.jpg")
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.text("This is a frodo")
|
|
||||||
.text_alignment(TextAlignment::TopCenter)
|
|
||||||
.font_size(50)
|
|
||||||
.font("Quicksand")
|
|
||||||
.build()
|
|
||||||
{
|
|
||||||
let font = Font::with_name("Noto Sans");
|
|
||||||
let stack = stack!(
|
|
||||||
image(slide.background().path.clone()),
|
|
||||||
text(slide.text())
|
|
||||||
.size(slide.font_size() as u16)
|
|
||||||
.font(font)
|
|
||||||
);
|
|
||||||
|
|
||||||
stack.into()
|
|
||||||
} else {
|
|
||||||
text("Slide is broken").into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(slide :background (image :source "~/pics/frodo.jpg" :fit crop)
|
(slide :background (image :source "~/pics/frodo.jpg" :fit fill)
|
||||||
(text "This is frodo" :font-size 50))
|
(text "This is frodo" :font-size 70))
|
||||||
(slide (video :source "~/vids/test/chosensmol.mp4" :fit fill))
|
(slide (video :source "~/vids/test/camprules2024.mp4" :fit contain))
|
||||||
(song :author "Jordan Feliz" :ccli 97987
|
(song :author "Jordan Feliz" :ccli 97987
|
||||||
:font "Quicksand" :font-size 80
|
:font "Quicksand" :font-size 80
|
||||||
:title "The River"
|
:title "The River"
|
||||||
|
|
Loading…
Reference in a new issue