deLyrium/src/editor.rs

135 lines
3.6 KiB
Rust

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)
}