making song_editor actually function
This commit is contained in:
parent
7d8c2243d8
commit
2222a88470
2 changed files with 81 additions and 68 deletions
|
|
@ -8,11 +8,12 @@ use cosmic::{
|
||||||
Font, Length,
|
Font, Length,
|
||||||
},
|
},
|
||||||
iced_wgpu::graphics::text::cosmic_text::fontdb,
|
iced_wgpu::graphics::text::cosmic_text::fontdb,
|
||||||
iced_widget::row,
|
iced_widget::{column, row},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
button, column, combo_box, container, horizontal_space, icon,
|
button, combo_box, container, horizontal_space, icon,
|
||||||
scrollable, text, text_editor, text_input,
|
progress_bar, scrollable, text, text_editor, text_input,
|
||||||
|
vertical_space,
|
||||||
},
|
},
|
||||||
Element, Task,
|
Element, Task,
|
||||||
};
|
};
|
||||||
|
|
@ -21,7 +22,7 @@ use iced_video_player::Video;
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{service_items::ServiceTrait, songs::Song},
|
core::{service_items::ServiceTrait, slide::Slide, songs::Song},
|
||||||
ui::{
|
ui::{
|
||||||
presenter::slide_view, slide_editor::SlideEditor, text_svg,
|
presenter::slide_view, slide_editor::SlideEditor, text_svg,
|
||||||
},
|
},
|
||||||
|
|
@ -47,6 +48,7 @@ pub struct SongEditor {
|
||||||
video: Option<Video>,
|
video: Option<Video>,
|
||||||
current_font: Font,
|
current_font: Font,
|
||||||
ccli: String,
|
ccli: String,
|
||||||
|
song_as_slide: Option<Vec<Slide>>,
|
||||||
slide_state: SlideEditor,
|
slide_state: SlideEditor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +72,7 @@ pub enum Message {
|
||||||
Edit(bool),
|
Edit(bool),
|
||||||
None,
|
None,
|
||||||
ChangeAuthor(String),
|
ChangeAuthor(String),
|
||||||
|
PauseVideo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SongEditor {
|
impl SongEditor {
|
||||||
|
|
@ -80,8 +83,7 @@ impl SongEditor {
|
||||||
.faces()
|
.faces()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let id = f.id;
|
let id = f.id;
|
||||||
let font_base_name: String =
|
let font_base_name: String = f.families[0].0.clone();
|
||||||
f.families.iter().map(|f| f.0.clone()).collect();
|
|
||||||
let font_weight = f.weight;
|
let font_weight = f.weight;
|
||||||
let font_style = f.style;
|
let font_style = f.style;
|
||||||
let font_stretch = f.stretch;
|
let font_stretch = f.stretch;
|
||||||
|
|
@ -114,18 +116,30 @@ impl SongEditor {
|
||||||
"65".to_string(),
|
"65".to_string(),
|
||||||
"70".to_string(),
|
"70".to_string(),
|
||||||
"80".to_string(),
|
"80".to_string(),
|
||||||
|
"90".to_string(),
|
||||||
|
"100".to_string(),
|
||||||
|
"110".to_string(),
|
||||||
|
"120".to_string(),
|
||||||
|
"130".to_string(),
|
||||||
|
"140".to_string(),
|
||||||
|
"150".to_string(),
|
||||||
|
"160".to_string(),
|
||||||
|
"170".to_string(),
|
||||||
];
|
];
|
||||||
let font_texts = fonts.iter().map(|f| f.1.clone()).collect();
|
let mut font_texts: Vec<String> =
|
||||||
|
fonts.iter().map(|f| f.1.to_string()).collect();
|
||||||
|
font_texts.dedup();
|
||||||
|
font_texts.sort();
|
||||||
Self {
|
Self {
|
||||||
song: None,
|
song: None,
|
||||||
font_db,
|
font_db,
|
||||||
fonts,
|
fonts,
|
||||||
fonts_combo: combo_box::State::new(font_texts),
|
fonts_combo: combo_box::State::new(font_texts),
|
||||||
title: "Death was Arrested".to_owned(),
|
title: "Death was Arrested".to_string(),
|
||||||
font: "Quicksand".to_owned(),
|
font: "Quicksand".to_string(),
|
||||||
font_size: 16,
|
font_size: 16,
|
||||||
font_sizes: combo_box::State::new(font_sizes),
|
font_sizes: combo_box::State::new(font_sizes),
|
||||||
verse_order: "Death was Arrested".to_owned(),
|
verse_order: "Death was Arrested".to_string(),
|
||||||
lyrics: text_editor::Content::new(),
|
lyrics: text_editor::Content::new(),
|
||||||
editing: false,
|
editing: false,
|
||||||
author: "North Point Worship".into(),
|
author: "North Point Worship".into(),
|
||||||
|
|
@ -133,8 +147,9 @@ impl SongEditor {
|
||||||
background: None,
|
background: None,
|
||||||
video: None,
|
video: None,
|
||||||
current_font: cosmic::font::default(),
|
current_font: cosmic::font::default(),
|
||||||
ccli: "8".to_owned(),
|
ccli: "8".to_string(),
|
||||||
slide_state: SlideEditor::default(),
|
slide_state: SlideEditor::default(),
|
||||||
|
song_as_slide: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update(&mut self, message: Message) -> Action {
|
pub fn update(&mut self, message: Message) -> Action {
|
||||||
|
|
@ -174,33 +189,12 @@ impl SongEditor {
|
||||||
self.background = song.background;
|
self.background = song.background;
|
||||||
}
|
}
|
||||||
Message::ChangeFont(font) => {
|
Message::ChangeFont(font) => {
|
||||||
let font_id = self
|
|
||||||
.fonts
|
|
||||||
.iter()
|
|
||||||
.filter(|f| f.1 == font)
|
|
||||||
.map(|f| f.0)
|
|
||||||
.next();
|
|
||||||
if let Some(id) = font_id
|
|
||||||
&& let Some(face) = self.font_db.face(id)
|
|
||||||
{
|
|
||||||
self.font = face.post_script_name.clone();
|
|
||||||
// self.current_font = Font::from(face);
|
|
||||||
}
|
|
||||||
self.font = font.clone();
|
self.font = font.clone();
|
||||||
|
if let Some(song) = &mut self.song {
|
||||||
let font_name = font.into_boxed_str();
|
song.font = Some(font);
|
||||||
let family = Family::Name(Box::leak(font_name));
|
let song = song.to_owned();
|
||||||
let weight = Weight::Bold;
|
return self.update_song(song);
|
||||||
let stretch = Stretch::Normal;
|
}
|
||||||
let style = Style::Normal;
|
|
||||||
let font = Font {
|
|
||||||
family,
|
|
||||||
weight,
|
|
||||||
stretch,
|
|
||||||
style,
|
|
||||||
};
|
|
||||||
self.current_font = font;
|
|
||||||
// return self.update_song(song);
|
|
||||||
}
|
}
|
||||||
Message::ChangeFontSize(size) => {
|
Message::ChangeFontSize(size) => {
|
||||||
self.font_size = size;
|
self.font_size = size;
|
||||||
|
|
@ -269,25 +263,55 @@ impl SongEditor {
|
||||||
Message::ChangeBackground,
|
Message::ChangeBackground,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Message::PauseVideo => {
|
||||||
|
if let Some(video) = &mut self.video {
|
||||||
|
let paused = video.paused();
|
||||||
|
video.set_paused(!paused);
|
||||||
|
};
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Action::None
|
Action::None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(&self) -> Element<Message> {
|
pub fn view(&self) -> Element<Message> {
|
||||||
|
let video_elements = if let Some(video) = &self.video {
|
||||||
|
let play_button = button::icon(if video.paused() {
|
||||||
|
icon::from_name("media-playback-start")
|
||||||
|
} else {
|
||||||
|
icon::from_name("media-playback-pause")
|
||||||
|
})
|
||||||
|
.on_press(Message::PauseVideo);
|
||||||
|
let video_track = progress_bar(
|
||||||
|
0.0..=video.duration().as_secs_f32(),
|
||||||
|
video.position().as_secs_f32(),
|
||||||
|
)
|
||||||
|
.height(cosmic::theme::spacing().space_s)
|
||||||
|
.width(Length::Fill);
|
||||||
|
container(
|
||||||
|
row![play_button, video_track]
|
||||||
|
.align_y(Vertical::Center)
|
||||||
|
.spacing(cosmic::theme::spacing().space_m),
|
||||||
|
)
|
||||||
|
.padding(cosmic::theme::spacing().space_s)
|
||||||
|
.center_x(Length::FillPortion(2))
|
||||||
|
} else {
|
||||||
|
container(vertical_space())
|
||||||
|
};
|
||||||
let slide_preview = container(self.slide_preview())
|
let slide_preview = container(self.slide_preview())
|
||||||
.width(Length::FillPortion(2));
|
.width(Length::FillPortion(2));
|
||||||
|
|
||||||
let column = column::with_children(vec![
|
let slide_section = column![video_elements, slide_preview]
|
||||||
|
.spacing(cosmic::theme::spacing().space_s);
|
||||||
|
let column = column![
|
||||||
self.toolbar(),
|
self.toolbar(),
|
||||||
row![
|
row![
|
||||||
container(self.left_column())
|
container(self.left_column())
|
||||||
.center_x(Length::FillPortion(2)),
|
.center_x(Length::FillPortion(2)),
|
||||||
container(slide_preview)
|
container(slide_section)
|
||||||
.center_x(Length::FillPortion(3))
|
.center_x(Length::FillPortion(2))
|
||||||
]
|
],
|
||||||
.into(),
|
]
|
||||||
])
|
|
||||||
.spacing(theme::active().cosmic().space_l());
|
.spacing(theme::active().cosmic().space_l());
|
||||||
column.into()
|
column.into()
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +348,7 @@ impl SongEditor {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
scrollable(
|
scrollable(
|
||||||
column::with_children(slides)
|
cosmic::widget::column::with_children(slides)
|
||||||
.spacing(theme::active().cosmic().space_l()),
|
.spacing(theme::active().cosmic().space_l()),
|
||||||
)
|
)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
|
|
@ -359,37 +383,26 @@ order",
|
||||||
.on_input(Message::ChangeVerseOrder);
|
.on_input(Message::ChangeVerseOrder);
|
||||||
|
|
||||||
let lyric_title = text("Lyrics");
|
let lyric_title = text("Lyrics");
|
||||||
let lyric_input = column::with_children(vec![
|
let lyric_input = column![
|
||||||
lyric_title.into(),
|
lyric_title,
|
||||||
text_editor(&self.lyrics)
|
text_editor(&self.lyrics)
|
||||||
.on_action(Message::ChangeLyrics)
|
.on_action(Message::ChangeLyrics)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.into(),
|
]
|
||||||
])
|
|
||||||
.spacing(5);
|
.spacing(5);
|
||||||
|
|
||||||
column::with_children(vec![
|
column![title_input, author_input, verse_input, lyric_input,]
|
||||||
title_input.into(),
|
.spacing(25)
|
||||||
author_input.into(),
|
.width(Length::FillPortion(2))
|
||||||
verse_input.into(),
|
.into()
|
||||||
lyric_input.into(),
|
|
||||||
])
|
|
||||||
.spacing(25)
|
|
||||||
.width(Length::FillPortion(2))
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toolbar(&self) -> Element<Message> {
|
fn toolbar(&self) -> Element<Message> {
|
||||||
let selected_font = &self.font;
|
let selected_font = &self.font;
|
||||||
let selected_font_size = {
|
let selected_font_size = if self.font_size > 0 {
|
||||||
let font_size_position = self
|
Some(&self.font_size.to_string())
|
||||||
.font_sizes
|
} else {
|
||||||
.options()
|
None
|
||||||
.iter()
|
|
||||||
.position(|s| *s == self.font_size.to_string());
|
|
||||||
self.font_sizes
|
|
||||||
.options()
|
|
||||||
.get(font_size_position.unwrap_or_default())
|
|
||||||
};
|
};
|
||||||
let font_selector = combo_box(
|
let font_selector = combo_box(
|
||||||
&self.fonts_combo,
|
&self.fonts_combo,
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ impl TextSvg {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(mut self) -> Self {
|
pub fn build(mut self) -> Self {
|
||||||
debug!("starting...");
|
// debug!("starting...");
|
||||||
|
|
||||||
let mut path = dirs::data_local_dir().unwrap();
|
let mut path = dirs::data_local_dir().unwrap();
|
||||||
path.push(PathBuf::from("lumina"));
|
path.push(PathBuf::from("lumina"));
|
||||||
|
|
@ -312,7 +312,7 @@ impl TextSvg {
|
||||||
path.set_extension("png");
|
path.set_extension("png");
|
||||||
|
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
debug!("cached");
|
// debug!("cached");
|
||||||
let handle = Handle::from_path(path);
|
let handle = Handle::from_path(path);
|
||||||
self.handle = Some(handle);
|
self.handle = Some(handle);
|
||||||
return self;
|
return self;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue