use crate::config::Settings;
use crate::ui::{Msg, TEMsg, TFMsg};
use tui_realm_stdlib::Input;
use tuirealm::command::{Cmd, Direction, Position};
use tuirealm::event::{Key, KeyEvent, KeyModifiers, NoUserEvent};
use tuirealm::props::{Alignment, BorderType, Borders, Color, InputType};
use tuirealm::{Component, Event, MockComponent};
#[derive(MockComponent)]
pub struct TEInputArtist {
component: Input,
config: Settings,
}
impl TEInputArtist {
pub fn new(config: &Settings) -> Self {
Self {
component: Input::default()
.foreground(
config
.style_color_symbol
.library_foreground()
.unwrap_or(Color::Cyan),
)
.background(
config
.style_color_symbol
.library_background()
.unwrap_or(Color::Black),
)
.borders(
Borders::default()
.color(
config
.style_color_symbol
.library_border()
.unwrap_or(Color::LightYellow),
)
.modifiers(BorderType::Rounded),
)
.input_type(InputType::Text)
.title(" Search artist ", Alignment::Left),
config: config.clone(),
}
}
}
impl Component<Msg, NoUserEvent> for TEInputArtist {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
let config = self.config.clone();
handle_input_ev(
self,
ev,
&config,
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputArtistBlurDown)),
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputArtistBlurUp)),
)
}
}
#[derive(MockComponent)]
pub struct TEInputTitle {
component: Input,
config: Settings,
}
impl TEInputTitle {
pub fn new(config: &Settings) -> Self {
Self {
component: Input::default()
.foreground(
config
.style_color_symbol
.library_foreground()
.unwrap_or(Color::Cyan),
)
.background(
config
.style_color_symbol
.library_background()
.unwrap_or(Color::Black),
)
.borders(
Borders::default()
.color(
config
.style_color_symbol
.library_border()
.unwrap_or(Color::LightYellow),
)
.modifiers(BorderType::Rounded),
)
.input_type(InputType::Text)
.title(" Search track name ", Alignment::Left),
config: config.clone(),
}
}
}
impl Component<Msg, NoUserEvent> for TEInputTitle {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
let config = self.config.clone();
handle_input_ev(
self,
ev,
&config,
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputTitleBlurDown)),
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputTitleBlurUp)),
)
}
}
#[allow(clippy::needless_pass_by_value)]
fn handle_input_ev(
component: &mut dyn Component<Msg, NoUserEvent>,
ev: Event<NoUserEvent>,
config: &Settings,
on_key_down: Msg,
on_key_up: Msg,
) -> Option<Msg> {
match ev {
Event::Keyboard(keyevent) if keyevent == config.keys.config_save.key_event() => {
Some(Msg::TagEditor(TEMsg::TERename))
}
Event::Keyboard(KeyEvent {
code: Key::Down | Key::Tab,
..
}) => Some(on_key_down),
Event::Keyboard(
KeyEvent { code: Key::Up, .. }
| KeyEvent {
code: Key::BackTab,
modifiers: KeyModifiers::SHIFT,
},
) => Some(on_key_up),
Event::Keyboard(keyevent) if keyevent == config.keys.global_esc.key_event() => {
Some(Msg::TagEditor(TEMsg::TagEditorClose(None)))
}
Event::Keyboard(KeyEvent {
code: Key::Left, ..
}) => {
component.perform(Cmd::Move(Direction::Left));
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Right, ..
}) => {
component.perform(Cmd::Move(Direction::Right));
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Home, ..
}) => {
component.perform(Cmd::GoTo(Position::Begin));
Some(Msg::None)
}
Event::Keyboard(KeyEvent { code: Key::End, .. }) => {
component.perform(Cmd::GoTo(Position::End));
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Delete, ..
}) => {
component.perform(Cmd::Cancel);
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Backspace,
..
}) => {
component.perform(Cmd::Delete);
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Char(ch),
modifiers: KeyModifiers::SHIFT | KeyModifiers::NONE,
}) => {
component.perform(Cmd::Type(ch));
Some(Msg::None)
}
Event::Keyboard(KeyEvent {
code: Key::Enter, ..
}) => Some(Msg::TagEditor(TEMsg::TESearch)),
_ => None,
}
}
#[derive(MockComponent)]
pub struct TEInputAlbum {
component: Input,
config: Settings,
}
impl TEInputAlbum {
pub fn new(config: &Settings) -> Self {
Self {
component: Input::default()
.foreground(
config
.style_color_symbol
.library_foreground()
.unwrap_or(Color::Cyan),
)
.background(
config
.style_color_symbol
.library_background()
.unwrap_or(Color::Black),
)
.borders(
Borders::default()
.color(
config
.style_color_symbol
.library_border()
.unwrap_or(Color::LightYellow),
)
.modifiers(BorderType::Rounded),
)
.input_type(InputType::Text)
.title(" Album ", Alignment::Left),
config: config.clone(),
}
}
}
impl Component<Msg, NoUserEvent> for TEInputAlbum {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
let config = self.config.clone();
handle_input_ev(
self,
ev,
&config,
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputAlbumBlurDown)),
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputAlbumBlurUp)),
)
}
}
#[derive(MockComponent)]
pub struct TEInputGenre {
component: Input,
config: Settings,
}
impl TEInputGenre {
pub fn new(config: &Settings) -> Self {
Self {
component: Input::default()
.foreground(
config
.style_color_symbol
.library_foreground()
.unwrap_or(Color::Cyan),
)
.background(
config
.style_color_symbol
.library_background()
.unwrap_or(Color::Black),
)
.borders(
Borders::default()
.color(
config
.style_color_symbol
.library_border()
.unwrap_or(Color::LightYellow),
)
.modifiers(BorderType::Rounded),
)
.input_type(InputType::Text)
.title(" Genre ", Alignment::Left),
config: config.clone(),
}
}
}
impl Component<Msg, NoUserEvent> for TEInputGenre {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
let config = self.config.clone();
handle_input_ev(
self,
ev,
&config,
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputGenreBlurDown)),
Msg::TagEditor(TEMsg::TEFocus(TFMsg::InputGenreBlurUp)),
)
}
}