use crate::model::editing::Lyric; use iced::Text; use crate::model::editing::LyricEvent; use iced::widget::text_input::TextInput; use iced::Alignment; use iced::widget::scrollable::{self, Scrollable}; use iced::Space; use iced::Canvas; use iced::image::ContentFit; use crate::styles::Theme; use crate::controls::Controls; use crate::model::Editing; use iced::Image; use crate::app::Message; use iced::Element; use iced::Container; use iced::Row; use iced::Length; pub fn view_editor(editing: &mut Editing) -> Element { let row = if let Some(margin_bg) = &editing.cached_resized_bg { let (img1, img2) = ( Image::new(margin_bg.clone()) .width(Length::FillPortion(1)) .height(Length::Fill) .fit(ContentFit::Cover), Image::new(margin_bg.clone()) .width(Length::FillPortion(1)) .height(Length::Fill) .fit(ContentFit::Cover), ); Row::new() .push(img1) .push(view_progress(&editing.controls, editing.theme)) .push(view_lyrics(&mut editing.lyrics, &mut editing.scroll_state, editing.theme)) .push(img2) } else { Row::new() .push(view_progress(&editing.controls, editing.theme)) .push(view_lyrics(&mut editing.lyrics, &mut editing.scroll_state, editing.theme)) }; Container::new(row) .style(editing.theme) .height(Length::Fill) .into() } pub fn view_lyrics<'a>(lyrics: &'a mut [Lyric], scroll_state: &'a mut scrollable::State, theme: Theme) -> Element<'a, Message> { let is_sole_line = lyrics.len() == 1; let spacers = ( Space::new(Length::Fill, Length::Units(30)), Space::new(Length::Fill, Length::Units(30)), ); let scroller = lyrics.iter_mut() .enumerate() .map(|(i, l)| view_lyric(l, is_sole_line, i, theme)) .fold(Scrollable::new(scroll_state).push(spacers.0), Scrollable::push) .push(spacers.1) .width(Length::Fill) .align_items(Alignment::Center); Container::new(scroller) .height(Length::Fill) .width(Length::Units(400)) .center_y() .into() } pub fn view_lyric(lyric: &mut Lyric, show_placeholder: bool, line_no: usize, theme: Theme) -> Row { const SMALL_SIZE: u16 = 20; const LARGE_SIZE: u16 = 25; const TIMESTAMP_W: u16 = 67; const LINE_HEIGHT: u16 = 26; const TOTAL_W: u16 = 400; let is_focused = lyric.is_selected(); let placeholder = if show_placeholder { "Paste some lyrics to get started" } else if is_focused { "..." } else { "" }; let size = if is_focused { LARGE_SIZE } else { SMALL_SIZE }; let timestamp_input = TextInput::new( &mut lyric.timestamp_state, "", &lyric.timestamp_raw, move|new_value| LyricEvent::TimestampChanged(new_value).into_msg(line_no), ) .style(theme) .size(SMALL_SIZE) .width(Length::Units(TIMESTAMP_W)) .on_submit(LyricEvent::LineAdvanced.into_msg(line_no)) .into(); let text_input = TextInput::new( &mut lyric.main_state, placeholder, &lyric.value, move|new_value| LyricEvent::LyricChanged(new_value).into_msg(line_no), ) .style(theme.active_lyric(is_focused)) .size(size) .width(Length::Fill) .on_submit(LyricEvent::LineAdvanced.into_msg(line_no)) .into(); let l_bracket = Text::new("[") .size(SMALL_SIZE) .color(theme.reduced_text_color()) .into(); let r_bracket = Text::new("] ") .size(SMALL_SIZE) .color(theme.reduced_text_color()) .into(); Row::with_children(vec![l_bracket, timestamp_input, r_bracket, text_input]) .width(Length::Units(TOTAL_W)) .height(Length::Units(LINE_HEIGHT)) .align_items(Alignment::Center) } pub fn view_progress(controls: &Controls, theme: Theme) -> Canvas { Canvas::new((&*controls, theme)) .width(Length::Units(50)) .height(Length::Fill) }