diff --git a/src/core/images.rs b/src/core/images.rs index beba760..4eb16dd 100644 --- a/src/core/images.rs +++ b/src/core/images.rs @@ -3,7 +3,7 @@ use crate::{Background, Slide, SlideBuilder, TextAlignment}; use super::{ content::Content, kinds::ServiceItemKind, - model::{LibraryKind, Model}, + model::{get_db, LibraryKind, Model}, service_items::ServiceTrait, }; use crisp::types::{Keyword, Symbol, Value}; @@ -45,7 +45,13 @@ impl Content for Image { } fn background(&self) -> Option { - Background::try_from(self.path.clone()).ok() + if let Ok(background) = + Background::try_from(self.path.clone()) + { + Some(background) + } else { + None + } } fn subtext(&self) -> String { diff --git a/src/core/lisp.rs b/src/core/lisp.rs index 2c1a666..ad795d2 100644 --- a/src/core/lisp.rs +++ b/src/core/lisp.rs @@ -133,6 +133,12 @@ pub(crate) fn get_lists(exp: &Value) -> Vec { #[cfg(test)] mod test { + use std::fs::read_to_string; + + use lexpr::{parse::Options, Parser}; + use pretty_assertions::assert_eq; + + use super::*; // #[test] // fn test_list() { diff --git a/src/core/model.rs b/src/core/model.rs index a0afcd0..14ed67c 100644 --- a/src/core/model.rs +++ b/src/core/model.rs @@ -4,6 +4,8 @@ use cosmic::iced::Executor; use miette::{miette, Result}; use sqlx::{Connection, SqliteConnection}; +use super::kinds::ServiceItemKind; + #[derive(Debug, Clone)] pub struct Model { pub items: Vec, diff --git a/src/core/presentations.rs b/src/core/presentations.rs index 106f8c4..164a9dd 100644 --- a/src/core/presentations.rs +++ b/src/core/presentations.rs @@ -13,7 +13,7 @@ use crate::{Background, Slide, SlideBuilder, TextAlignment}; use super::{ content::Content, kinds::ServiceItemKind, - model::{LibraryKind, Model}, + model::{get_db, LibraryKind, Model}, service_items::ServiceTrait, }; @@ -57,7 +57,13 @@ impl Content for Presentation { } fn background(&self) -> Option { - Background::try_from(self.path.clone()).ok() + if let Ok(background) = + Background::try_from(self.path.clone()) + { + Some(background) + } else { + None + } } fn subtext(&self) -> String { diff --git a/src/core/service_items.rs b/src/core/service_items.rs index c9483cd..f84d231 100644 --- a/src/core/service_items.rs +++ b/src/core/service_items.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes}; use crisp::types::{Keyword, Symbol, Value}; -use miette::Result; +use miette::{miette, Result}; use tracing::{debug, error}; use crate::Slide; @@ -153,48 +153,52 @@ impl From<&Value> for ServiceItem { database_id: 0, kind: ServiceItemKind::Content(slide), } - } else if let Some(background) = - list.get(background_pos) - { - match background { - Value::List(item) => match &item[0] { - Value::Symbol(Symbol(s)) - if s == "image" => - { - Self::from(&Image::from( - background, - )) - } - Value::Symbol(Symbol(s)) - if s == "video" => - { - Self::from(&Video::from( - background, - )) - } - Value::Symbol(Symbol(s)) - if s == "presentation" => - { - Self::from(&Presentation::from( - background, - )) - } - _ => todo!(), - }, - _ => { - error!( - "There is no background here: {:?}", - background - ); - ServiceItem::default() - } - } } else { - error!( - "There is no background here: {:?}", - background_pos - ); - ServiceItem::default() + if let Some(background) = + list.get(background_pos) + { + match background { + Value::List(item) => match &item[0] { + Value::Symbol(Symbol(s)) + if s == "image" => + { + Self::from(&Image::from( + background, + )) + } + Value::Symbol(Symbol(s)) + if s == "video" => + { + Self::from(&Video::from( + background, + )) + } + Value::Symbol(Symbol(s)) + if s == "presentation" => + { + Self::from( + &Presentation::from( + background, + ), + ) + } + _ => todo!(), + }, + _ => { + error!( + "There is no background here: {:?}", + background + ); + ServiceItem::default() + } + } + } else { + error!( + "There is no background here: {:?}", + background_pos + ); + ServiceItem::default() + } } } Value::Symbol(Symbol(s)) if s == "song" => { @@ -338,7 +342,7 @@ mod test { use crate::core::presentations::PresKind; use super::*; - use pretty_assertions::assert_eq; + use pretty_assertions::{assert_eq, assert_ne}; fn test_song() -> Song { Song { diff --git a/src/core/slide.rs b/src/core/slide.rs index 277034d..662710a 100644 --- a/src/core/slide.rs +++ b/src/core/slide.rs @@ -1,5 +1,6 @@ // use cosmic::dialog::ashpd::url::Url; use crisp::types::{Keyword, Symbol, Value}; +use gstreamer::query::Uri; use iced_video_player::Video; use miette::{miette, Result}; use serde::{Deserialize, Serialize}; @@ -12,15 +13,7 @@ use tracing::error; use super::songs::Song; #[derive( - Clone, - Copy, - Debug, - Default, - PartialEq, - Eq, - Serialize, - Deserialize, - Hash, + Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize, )] pub enum TextAlignment { TopLeft, diff --git a/src/core/songs.rs b/src/core/songs.rs index 20dbebb..52f4b13 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -8,14 +8,14 @@ use sqlx::{ pool::PoolConnection, query, sqlite::SqliteRow, FromRow, Row, Sqlite, SqliteConnection, SqlitePool, }; -use tracing::error; +use tracing::{debug, error}; use crate::{core::slide, Slide, SlideBuilder}; use super::{ content::Content, kinds::ServiceItemKind, - model::{LibraryKind, Model}, + model::{get_db, LibraryKind, Model}, service_items::ServiceTrait, slide::{Background, TextAlignment}, }; @@ -132,7 +132,10 @@ impl FromRow<'_, SqliteRow> for Song { }), background: { let string: String = row.try_get(7)?; - Background::try_from(string).ok() + match Background::try_from(string) { + Ok(background) => Some(background), + Err(_) => None, + } }, text_alignment: Some({ let horizontal_alignment: String = row.try_get(3)?; @@ -420,7 +423,7 @@ pub async fn update_song_in_db( if let Some(vo) = item.verse_order { vo.into_iter() .map(|mut s| { - s.push(' '); + s.push_str(" "); s }) .collect::() @@ -535,6 +538,7 @@ impl Song { lyric_list.push(lyric.to_string()); } else { // error!("NOT WORKING!"); + () }; } // for lyric in lyric_list.iter() { @@ -552,7 +556,7 @@ mod test { use std::fs::read_to_string; use super::*; - use pretty_assertions::assert_eq; + use pretty_assertions::{assert_eq, assert_ne}; #[test] pub fn test_song_lyrics() { @@ -720,7 +724,7 @@ You saved my soul" let lisp = read_to_string("./test_song.lisp").expect("oops"); let lisp_value = crisp::reader::read(&lisp); match lisp_value { - Value::List(v) => v.first().unwrap().clone(), + Value::List(v) => v.get(0).unwrap().clone(), _ => Value::Nil, } } diff --git a/src/core/videos.rs b/src/core/videos.rs index c0c1dfb..c3fe4e0 100644 --- a/src/core/videos.rs +++ b/src/core/videos.rs @@ -3,7 +3,7 @@ use crate::{Background, SlideBuilder, TextAlignment}; use super::{ content::Content, kinds::ServiceItemKind, - model::{LibraryKind, Model}, + model::{get_db, LibraryKind, Model}, service_items::ServiceTrait, slide::Slide, }; @@ -50,7 +50,13 @@ impl Content for Video { } fn background(&self) -> Option { - Background::try_from(self.path.clone()).ok() + if let Ok(background) = + Background::try_from(self.path.clone()) + { + Some(background) + } else { + None + } } fn subtext(&self) -> String { diff --git a/src/lisp.rs b/src/lisp.rs index 2f803e4..e5baa50 100644 --- a/src/lisp.rs +++ b/src/lisp.rs @@ -37,14 +37,17 @@ pub fn parse_lisp(value: Value) -> Vec { #[cfg(test)] mod test { - use std::{fs::read_to_string, path::PathBuf}; + use std::{ + fs::read_to_string, + path::{Path, PathBuf}, + }; use crate::{ core::{ images::Image, kinds::ServiceItemKind, service_items::ServiceTrait, songs::Song, videos::Video, }, - Background, TextAlignment, + Background, Slide, SlideBuilder, TextAlignment, }; use super::*; diff --git a/src/main.rs b/src/main.rs index 91ae9ee..62c36a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use clap::{command, Parser}; +use core::model::{get_db, LibraryKind}; use core::service_items::{ServiceItem, ServiceItemModel}; use core::slide::*; use core::songs::Song; @@ -13,12 +14,13 @@ use cosmic::iced_widget::{column, row}; use cosmic::widget::dnd_destination::DragId; use cosmic::widget::nav_bar::nav_bar_style; use cosmic::widget::segmented_button::Entity; -use cosmic::widget::text; use cosmic::widget::tooltip::Position as TPosition; use cosmic::widget::{ - button, horizontal_space, nav_bar, search_input, tooltip, Space, + button, horizontal_space, nav_bar, search_input, text_input, + tooltip, Space, }; use cosmic::widget::{icon, slider}; +use cosmic::widget::{text, toggler}; use cosmic::{executor, Application, ApplicationExt, Element}; use cosmic::{prelude::*, theme}; use cosmic::{widget::Container, Theme}; @@ -128,7 +130,7 @@ enum Message { EditorToggle(bool), } -const HEADER_SPACE: u16 = 6; +const HEADER_SPACE: u16 = 20; impl cosmic::Application for App { type Executor = executor::Default; @@ -298,11 +300,11 @@ impl cosmic::Application for App { .into()] } fn header_end(&self) -> Vec> { - // let editor_toggle = toggler(self.editor_mode.is_some()) - // .label("Editor") - // .spacing(10) - // .width(Length::Shrink) - // .on_toggle(Message::EditorToggle); + let editor_toggle = toggler(self.editor_mode.is_some()) + .label("Editor") + .spacing(10) + .width(Length::Shrink) + .on_toggle(Message::EditorToggle); let presenter_window = self.windows.get(1); let text = if self.presentation_open { @@ -312,30 +314,7 @@ impl cosmic::Application for App { }; vec![ - tooltip( - button::custom( - row!( - Container::new( - icon::from_name("document-edit-symbolic") - .scale(3) - ) - .center_y(Length::Fill), - text::body(if self.editor_mode.is_some() { - "Present Mode" - } else { - "Edit Mode" - }) - ) - .spacing(5), - ) - .class(cosmic::theme::style::Button::HeaderBar) - .on_press(Message::EditorToggle( - self.editor_mode.is_none(), - )), - "Enter Edit Mode", - TPosition::Bottom, - ) - .into(), + editor_toggle.into(), horizontal_space().width(HEADER_SPACE).into(), tooltip( button::custom( @@ -374,8 +353,12 @@ impl cosmic::Application for App { button::custom( row!( Container::new( - icon::from_name("view-list-symbolic") - .scale(3) + icon::from_name(if self.library_open { + "arrow-right" + } else { + "view-list-symbolic" + }) + .scale(3) ) .center_y(Length::Fill), text::body(if self.library_open { @@ -719,7 +702,7 @@ impl cosmic::Application for App { let library = if self.library_open { Container::new(if let Some(library) = &self.library { - library.view().map(Message::Library) + library.view().map(|m| Message::Library(m)) } else { Space::new(0, 0).into() }) @@ -730,7 +713,7 @@ impl cosmic::Application for App { }; let song_editor = - self.song_editor.view().map(Message::SongEditor); + self.song_editor.view().map(|m| Message::SongEditor(m)); let row = row![ Container::new( @@ -744,7 +727,8 @@ impl cosmic::Application for App { .class(theme::style::Button::Transparent) ) .center_y(Length::Fill) - .align_right(Length::FillPortion(1)), + .align_right(Length::Fill) + .width(Length::FillPortion(1)), Container::new(slide_preview) .center_y(Length::Fill) .width(Length::FillPortion(3)), @@ -759,7 +743,8 @@ impl cosmic::Application for App { .class(theme::style::Button::Transparent) ) .center_y(Length::Fill) - .align_left(Length::FillPortion(1)), + .align_left(Length::Fill) + .width(Length::FillPortion(1)), library ] .width(Length::Fill) @@ -878,6 +863,8 @@ where #[cfg(test)] mod test { + use super::*; + use pretty_assertions::assert_eq; fn test_slide() -> String { let slide = r#"(slide (image :source "./somehting.jpg" :fill cover diff --git a/src/ui/library.rs b/src/ui/library.rs index 1c09e13..c89ed15 100644 --- a/src/ui/library.rs +++ b/src/ui/library.rs @@ -1,22 +1,21 @@ -use std::rc::Rc; - use cosmic::{ iced::{ alignment::Vertical, clipboard::dnd::DndAction, futures::FutureExt, Background, Border, Color, Length, }, - iced_core::widget::tree::State, iced_widget::{column, row as rowm, text as textm}, theme, widget::{ button, container, horizontal_space, icon, mouse_area, responsive, row, scrollable, text, text_input, Container, - DndSource, Space, Widget, + DndSource, Icon, Space, Widget, }, Element, Task, }; -use miette::{IntoDiagnostic, Result}; -use sqlx::{pool::PoolConnection, Sqlite, SqlitePool}; +use miette::{miette, IntoDiagnostic, Result}; +use sqlx::{ + pool::PoolConnection, Sqlite, SqliteConnection, SqlitePool, +}; use tracing::{debug, error, warn}; use crate::core::{ @@ -360,7 +359,7 @@ impl<'a> Library { |(index, item)| { let service_item = item.to_service_item(); let drag_item = - Box::new(self.single_item(index, item, &model)); + self.single_item(index, item, model); let visual_item = self .single_item(index, item, model) .map(|_| Message::None); @@ -387,25 +386,11 @@ impl<'a> Library { )), ) .action(DndAction::Copy) - .drag_icon({ - let model = model.kind.clone(); - move |i| { - let state = State::None; - let icon = match model { - LibraryKind::Song => icon::from_name( - "folder-music-symbolic", - ) - , - LibraryKind::Video => icon::from_name("folder-videos-symbolic"), - LibraryKind::Image => icon::from_name("folder-pictures-symbolic"), - LibraryKind::Presentation => icon::from_name("x-office-presentation-symbolic"), - }; - ( - icon.into(), - state, - i, - ) - }}) + // .drag_icon(move |i| { + // let state = + // drag_item.as_widget().state(); + // (drag_item, state, i) + // }) .drag_content(move || { service_item.to_owned() }) @@ -413,11 +398,10 @@ impl<'a> Library { }, ) }) - .spacing(2) - .width(Length::Fill), + .spacing(2) + .width(Length::Fill), ) - .spacing(5) - .height(Length::Fill); + .spacing(5); let library_toolbar = rowm!( text_input("Search...", ""), diff --git a/src/ui/presenter.rs b/src/ui/presenter.rs index 12a7c13..8526c4e 100644 --- a/src/ui/presenter.rs +++ b/src/ui/presenter.rs @@ -1,4 +1,4 @@ -use miette::{IntoDiagnostic, Result}; +use miette::{miette, IntoDiagnostic, Result}; use std::{fs::File, io::BufReader, path::PathBuf, sync::Arc}; use cosmic::{ @@ -13,7 +13,7 @@ use cosmic::{ scrollable::{ scroll_to, AbsoluteOffset, Direction, Scrollbar, }, - span, stack, + span, stack, text, }, prelude::*, widget::{ @@ -29,10 +29,13 @@ use url::Url; use crate::{ core::{service_items::ServiceItemModel, slide::Slide}, - ui::text_svg::{self, Font as SvgFont}, BackgroundKind, }; +use super::text_svg::{ + self, shadow, stroke, Font as SvgFont, TextSvg, +}; + const REFERENCE_WIDTH: f32 = 1920.0; const REFERENCE_HEIGHT: f32 = 1080.0; @@ -525,43 +528,39 @@ async fn start_audio(sink: Arc, audio: PathBuf) { fn scale_font(font_size: f32, width: f32) -> f32 { let scale_factor = (REFERENCE_WIDTH / width).sqrt(); // debug!(scale_factor); - - if font_size > 0.0 { + let font_size = if font_size > 0.0 { font_size / scale_factor } else { 50.0 - } + }; + font_size } -pub(crate) fn slide_view( +pub(crate) fn slide_view<'a>( slide: Slide, - video: &Option