diff --git a/src/core/songs.rs b/src/core/songs.rs index 891a889..d76dc06 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -35,6 +35,29 @@ pub struct Song { pub font: Option, pub font_size: Option, pub stroke_size: Option, + pub verses: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum Verse { + Verse { number: usize, lyric: String }, + PreChorus { number: usize, lyric: String }, + Chorus { number: usize, lyric: String }, + PostChorus { number: usize, lyric: String }, + Bridge { number: usize, lyric: String }, + Intro { number: usize, lyric: String }, + Outro { number: usize, lyric: String }, + Instrumental { number: usize, lyric: String }, + Other { number: usize, lyric: String }, +} + +impl Default for Verse { + fn default() -> Self { + Self::Verse { + number: 1, + lyric: "".into(), + } + } } impl From<&Song> for Value { @@ -162,6 +185,7 @@ impl FromRow<'_, SqliteRow> for Song { font: row.try_get(6)?, font_size: row.try_get(1)?, stroke_size: None, + verses: lyrics_to_verse(row.try_get(8)?), }) } } @@ -175,6 +199,10 @@ impl From for Song { } } +fn lyrics_to_verse(lyrics: String) -> Vec { + todo!() +} + pub fn lisp_to_song(list: Vec) -> Song { const DEFAULT_SONG_ID: i32 = 0; const DEFAULT_SONG_LOCATION: usize = 0; @@ -794,6 +822,7 @@ You saved my soul" font: Some("Quicksand Bold".to_string()), font_size: Some(60), stroke_size: None, + verses: vec![] } } diff --git a/src/ui/song_editor.rs b/src/ui/song_editor.rs index 1d75ca0..3cfbd99 100644 --- a/src/ui/song_editor.rs +++ b/src/ui/song_editor.rs @@ -5,12 +5,12 @@ use cosmic::{ dialog::file_chooser::{FileFilter, open::Dialog}, iced::{Color, Length, alignment::Vertical}, iced_wgpu::graphics::text::cosmic_text::fontdb, - iced_widget::{column, row}, + iced_widget::{column, row, vertical_rule}, theme, widget::{ - button, color_picker, combo_box, container, horizontal_space, - icon, progress_bar, scrollable, spin_button, text, - text_editor, text_input, tooltip, + button, color_picker, combo_box, container, dropdown, + horizontal_space, icon, popover, progress_bar, scrollable, + spin_button, text, text_editor, text_input, tooltip, }, }; use dirs::font_dir; @@ -47,6 +47,7 @@ pub struct SongEditor { slide_state: SlideEditor, stroke_sizes: combo_box::State, stroke_size: i32, + stroke_open: bool, } pub enum Action { @@ -72,6 +73,8 @@ pub enum Message { ChangeAuthor(String), PauseVideo, UpdateStrokeSize(i32), + OpenStroke, + CloseStroke, } impl SongEditor { @@ -136,6 +139,7 @@ impl SongEditor { song_slides: None, stroke_sizes: combo_box::State::new(stroke_sizes), stroke_size: 0, + stroke_open: false, } } pub fn update(&mut self, message: Message) -> Action { @@ -292,6 +296,12 @@ impl SongEditor { self.song = Some(song.clone()); return Action::UpdateSong(song); } + Message::OpenStroke => { + self.stroke_open = true; + } + Message::CloseStroke => { + self.stroke_open = false; + } _ => (), } Action::None @@ -413,6 +423,17 @@ order", } fn toolbar(&self) -> Element { + let cosmic::cosmic_theme::Spacing { + space_xxs, + space_xs, + space_s, + space_m, + space_l, + space_xl, + space_xxl, + .. + } = theme::spacing(); + let selected_font = &self.font; let selected_font_size = if self.font_size > 0 { Some(&self.font_size.to_string()) @@ -448,12 +469,77 @@ order", ) .gap(10); - let stroke_size_button = tooltip( - icon::from_path("./res/text-outline.svg".into()) - .symbolic(true) - .apply(button::icon) - .on_press(Message::None), - "Stroke or outline of the text", + let stroke_size_row = row![ + icon( + icon::from_path("./res/text-outline.svg".into()) + .symbolic(true) + ), + dropdown( + &["0", "1", "2", "3", "4", "5", "6", "7"], + Some(self.stroke_size as usize), + |i| Message::UpdateStrokeSize(i as i32), + ) + .gap(5.0), + ] + .spacing(3) + .align_y(Vertical::Center); + + // let stroke_sizes = container(column![ + // "1".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "2".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "3".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "4".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "5".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "6".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "7".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "8".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "9".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // "10".apply(button::standard) + // .class(theme::Button::Icon) + // .on_press(Message::None) + // .width(35), + // ]) + // .padding(theme::spacing().space_xs) + // .class(theme::Container::Dropdown); + + // let mut stroke_popup = popover(stroke_size_button) + // .modal(self.stroke_open) + // .position(popover::Position::Bottom) + // .on_close(Message::CloseStroke); + + // if self.stroke_open { + // stroke_popup = stroke_popup.popup(stroke_sizes); + // }; + let stroke_size_selector = tooltip( + stroke_size_row, + "Outline of the text", tooltip::Position::Bottom, ) .gap(10); @@ -477,21 +563,30 @@ order", .label("Background") .tooltip("Select an image or video background") .on_press(Message::PickBackground) - .padding(10); + .padding(space_s); + + // let stroke_size_selector = tooltip( + // stroke_popup, + // "Outline of the text", + // tooltip::Position::Bottom, + // ) + // .gap(10); row![ // text::body("Font:"), font_selector, // text::body("Font Size:"), font_size, - stroke_size_button, + vertical_rule(1).height(space_l), + stroke_size_selector, text::body("Stroke Color:"), stroke_color_picker, + vertical_rule(1).height(space_l), horizontal_space(), background_selector ] .align_y(Vertical::Center) - .spacing(10) + .spacing(space_s) .into() }