deLyrium/src/app/mod.rs

147 lines
3.1 KiB
Rust

use core::time::Duration;
use iced::Subscription;
use iced::Clipboard;
use iced::Command;
use iced::Application;
use iced::Container;
use iced::Row;
use iced::Element;
use iced::Length;
use iced::Align;
use iced::executor;
use iced_futures::time;
use iced_native::subscription;
use iced_native::keyboard;
use iced_native::event::Event;
mod lyrics;
mod styles;
mod file_select;
use styles::Theme;
use file_select::FileSelector;
#[derive(Clone, Debug)]
pub struct DelyriumApp {
lyrics_component: lyrics::Lyrics,
theme: Theme,
mode: AppMode,
file_selector: file_select::FileSelector,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum AppMode {
FileSelect, Main
}
#[derive(Clone, Debug)]
pub enum Message {
LyricChanged {
line_no: usize,
new_value: String,
},
LineAdvanced(usize),
PasteSent,
Tick,
}
impl Application for DelyriumApp {
type Message = Message;
type Executor = executor::Default;
type Flags = ();
fn new(_: Self::Flags) -> (Self, Command<Message>) {
(
DelyriumApp {
lyrics_component: lyrics::Lyrics::new(),
theme: Theme::default(),
mode: AppMode::FileSelect,
file_selector: FileSelector::default(),
},
Command::none(),
)
}
fn title(&self) -> String {
String::from("Delyrium")
}
fn update(&mut self, message: Message, clipboard: &mut Clipboard) -> Command<Message>{
match message {
Message::LyricChanged { line_no, new_value } => {
self.lyrics_component.update_line(new_value, line_no);
},
Message::LineAdvanced(current_line) => {
self.lyrics_component.advance_line(current_line);
},
Message::PasteSent => {
let clip_text = clipboard.read().unwrap_or(String::new());
let clip_pasted_len = clip_text.chars()
.filter(|c| *c != '\r' && *c != '\n')
.count();
let line = self.lyrics_component.current_line_mut().1;
line.value.truncate(line.value.len() - clip_pasted_len);
self.lyrics_component.insert_text(clip_text);
},
Message::Tick => {
match self.mode {
AppMode::FileSelect => {
self.file_selector.tick();
},
_ => { },
}
}
}
Command::none()
}
fn view(&mut self) -> Element<Message> {
match self.mode {
AppMode::Main => {
Container::new(
Row::new()
.push(self.lyrics_component.view(self.theme))
)
.align_y(Align::Center)
.style(self.theme)
.height(Length::Fill)
.into()
},
AppMode::FileSelect => {
self.file_selector.view()
}
}
}
fn subscription(&self) -> Subscription<Message> {
let runtime_events = subscription::events_with(|event, _| {
match event {
Event::Keyboard(keyboard::Event::KeyPressed {key_code, modifiers}) => {
match (key_code, modifiers) {
(
keyboard::KeyCode::V,
keyboard::Modifiers { control, .. }
) if control == true => {
Some(Message::PasteSent)
}
_ => { None }
}
}
_ => { None }
}
});
let fps30 = time::every(Duration::from_millis(1000 / 30)).map(|_| Message::Tick);
match self.mode {
AppMode::FileSelect => {
Subscription::batch([
runtime_events,
fps30
])
},
AppMode::Main => runtime_events,
}
}
}