You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.6 KiB
134 lines
3.6 KiB
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<Message> { |
|
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<Message> { |
|
|
|
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<Message, (&Controls, Theme)> { |
|
Canvas::new((&*controls, theme)) |
|
.width(Length::Units(50)) |
|
.height(Length::Fill) |
|
}
|
|
|