adding song updates
Some checks failed
/ test (push) Has been cancelled

This commit is contained in:
Chris Cochrun 2025-11-17 10:31:17 -06:00
parent 920f7cf497
commit 168ecd9840
2 changed files with 137 additions and 13 deletions

View file

@ -35,6 +35,29 @@ pub struct Song {
pub font: Option<String>, pub font: Option<String>,
pub font_size: Option<i32>, pub font_size: Option<i32>,
pub stroke_size: Option<i32>, pub stroke_size: Option<i32>,
pub verses: Vec<Verse>,
}
#[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 { impl From<&Song> for Value {
@ -162,6 +185,7 @@ impl FromRow<'_, SqliteRow> for Song {
font: row.try_get(6)?, font: row.try_get(6)?,
font_size: row.try_get(1)?, font_size: row.try_get(1)?,
stroke_size: None, stroke_size: None,
verses: lyrics_to_verse(row.try_get(8)?),
}) })
} }
} }
@ -175,6 +199,10 @@ impl From<Value> for Song {
} }
} }
fn lyrics_to_verse(lyrics: String) -> Vec<Verse> {
todo!()
}
pub fn lisp_to_song(list: Vec<Value>) -> Song { pub fn lisp_to_song(list: Vec<Value>) -> Song {
const DEFAULT_SONG_ID: i32 = 0; const DEFAULT_SONG_ID: i32 = 0;
const DEFAULT_SONG_LOCATION: usize = 0; const DEFAULT_SONG_LOCATION: usize = 0;
@ -794,6 +822,7 @@ You saved my soul"
font: Some("Quicksand Bold".to_string()), font: Some("Quicksand Bold".to_string()),
font_size: Some(60), font_size: Some(60),
stroke_size: None, stroke_size: None,
verses: vec![]
} }
} }

View file

@ -5,12 +5,12 @@ use cosmic::{
dialog::file_chooser::{FileFilter, open::Dialog}, dialog::file_chooser::{FileFilter, open::Dialog},
iced::{Color, Length, alignment::Vertical}, iced::{Color, Length, alignment::Vertical},
iced_wgpu::graphics::text::cosmic_text::fontdb, iced_wgpu::graphics::text::cosmic_text::fontdb,
iced_widget::{column, row}, iced_widget::{column, row, vertical_rule},
theme, theme,
widget::{ widget::{
button, color_picker, combo_box, container, horizontal_space, button, color_picker, combo_box, container, dropdown,
icon, progress_bar, scrollable, spin_button, text, horizontal_space, icon, popover, progress_bar, scrollable,
text_editor, text_input, tooltip, spin_button, text, text_editor, text_input, tooltip,
}, },
}; };
use dirs::font_dir; use dirs::font_dir;
@ -47,6 +47,7 @@ pub struct SongEditor {
slide_state: SlideEditor, slide_state: SlideEditor,
stroke_sizes: combo_box::State<i32>, stroke_sizes: combo_box::State<i32>,
stroke_size: i32, stroke_size: i32,
stroke_open: bool,
} }
pub enum Action { pub enum Action {
@ -72,6 +73,8 @@ pub enum Message {
ChangeAuthor(String), ChangeAuthor(String),
PauseVideo, PauseVideo,
UpdateStrokeSize(i32), UpdateStrokeSize(i32),
OpenStroke,
CloseStroke,
} }
impl SongEditor { impl SongEditor {
@ -136,6 +139,7 @@ impl SongEditor {
song_slides: None, song_slides: None,
stroke_sizes: combo_box::State::new(stroke_sizes), stroke_sizes: combo_box::State::new(stroke_sizes),
stroke_size: 0, stroke_size: 0,
stroke_open: false,
} }
} }
pub fn update(&mut self, message: Message) -> Action { pub fn update(&mut self, message: Message) -> Action {
@ -292,6 +296,12 @@ impl SongEditor {
self.song = Some(song.clone()); self.song = Some(song.clone());
return Action::UpdateSong(song); return Action::UpdateSong(song);
} }
Message::OpenStroke => {
self.stroke_open = true;
}
Message::CloseStroke => {
self.stroke_open = false;
}
_ => (), _ => (),
} }
Action::None Action::None
@ -413,6 +423,17 @@ order",
} }
fn toolbar(&self) -> Element<Message> { fn toolbar(&self) -> Element<Message> {
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 = &self.font;
let selected_font_size = if self.font_size > 0 { let selected_font_size = if self.font_size > 0 {
Some(&self.font_size.to_string()) Some(&self.font_size.to_string())
@ -448,12 +469,77 @@ order",
) )
.gap(10); .gap(10);
let stroke_size_button = tooltip( let stroke_size_row = row![
icon::from_path("./res/text-outline.svg".into()) icon(
.symbolic(true) icon::from_path("./res/text-outline.svg".into())
.apply(button::icon) .symbolic(true)
.on_press(Message::None), ),
"Stroke or outline of the text", 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, tooltip::Position::Bottom,
) )
.gap(10); .gap(10);
@ -477,21 +563,30 @@ order",
.label("Background") .label("Background")
.tooltip("Select an image or video background") .tooltip("Select an image or video background")
.on_press(Message::PickBackground) .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![ row![
// text::body("Font:"), // text::body("Font:"),
font_selector, font_selector,
// text::body("Font Size:"), // text::body("Font Size:"),
font_size, font_size,
stroke_size_button, vertical_rule(1).height(space_l),
stroke_size_selector,
text::body("Stroke Color:"), text::body("Stroke Color:"),
stroke_color_picker, stroke_color_picker,
vertical_rule(1).height(space_l),
horizontal_space(), horizontal_space(),
background_selector background_selector
] ]
.align_y(Vertical::Center) .align_y(Vertical::Center)
.spacing(10) .spacing(space_s)
.into() .into()
} }