Skeleton of new manual input state
This commit is contained in:
parent
8b008292cb
commit
cba1f2dff6
68
src/tui/app/machine/input_state.rs
Normal file
68
src/tui/app/machine/input_state.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use crate::tui::app::{
|
||||||
|
machine::{App, AppInner, AppMachine},
|
||||||
|
AppPublic, AppState, IAppInteractInput,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::match_state::MatchState;
|
||||||
|
|
||||||
|
pub struct InputState {
|
||||||
|
string: String,
|
||||||
|
client: InputClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum InputClient {
|
||||||
|
Match(MatchState),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppMachine<InputState> {
|
||||||
|
pub fn input_state(inner: AppInner, client: InputClient) -> Self {
|
||||||
|
AppMachine {
|
||||||
|
inner,
|
||||||
|
state: InputState {
|
||||||
|
string: String::new(),
|
||||||
|
client,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AppMachine<InputState>> for App {
|
||||||
|
fn from(machine: AppMachine<InputState>) -> Self {
|
||||||
|
AppState::Input(machine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a mut AppMachine<InputState>> for AppPublic<'a> {
|
||||||
|
fn from(machine: &'a mut AppMachine<InputState>) -> Self {
|
||||||
|
AppPublic {
|
||||||
|
inner: (&mut machine.inner).into(),
|
||||||
|
state: AppState::Input(&machine.state.string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppInteractInput for AppMachine<InputState> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
|
fn append_character(mut self, ch: char) -> Self::APP {
|
||||||
|
self.state.string.push(ch);
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_character(mut self) -> Self::APP {
|
||||||
|
self.state.string.pop();
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confirm(self) -> Self::APP {
|
||||||
|
match self.state.client {
|
||||||
|
InputClient::Match(state) => AppMachine::match_state(self.inner, state).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cancel(self) -> Self::APP {
|
||||||
|
match self.state.client {
|
||||||
|
InputClient::Match(state) => AppMachine::match_state(self.inner, state).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ use crate::tui::app::{
|
|||||||
MatchStateInfo, MatchStatePublic, WidgetState,
|
MatchStateInfo, MatchStatePublic, WidgetState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fetch_state::FetchState;
|
use super::{fetch_state::FetchState, input_state::InputClient};
|
||||||
|
|
||||||
impl ArtistMatches {
|
impl ArtistMatches {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@ -16,6 +16,14 @@ impl ArtistMatches {
|
|||||||
fn push_cannot_have_mbid(&mut self) {
|
fn push_cannot_have_mbid(&mut self) {
|
||||||
self.list.push(MatchOption::CannotHaveMbid)
|
self.list.push(MatchOption::CannotHaveMbid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_manual_input_mbid(&mut self) {
|
||||||
|
self.list.push(MatchOption::ManualInputMbid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_manual_input_mbid(&self, index: usize) -> bool {
|
||||||
|
self.list.get(index) == Some(&MatchOption::ManualInputMbid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlbumMatches {
|
impl AlbumMatches {
|
||||||
@ -26,6 +34,14 @@ impl AlbumMatches {
|
|||||||
fn push_cannot_have_mbid(&mut self) {
|
fn push_cannot_have_mbid(&mut self) {
|
||||||
self.list.push(MatchOption::CannotHaveMbid)
|
self.list.push(MatchOption::CannotHaveMbid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_manual_input_mbid(&mut self) {
|
||||||
|
self.list.push(MatchOption::ManualInputMbid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_manual_input_mbid(&self, index: usize) -> bool {
|
||||||
|
self.list.get(index) == Some(&MatchOption::ManualInputMbid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MatchStateInfo {
|
impl MatchStateInfo {
|
||||||
@ -36,12 +52,26 @@ impl MatchStateInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_cannot_have_mbid(&mut self) {
|
fn push_cannot_have_mbid(&mut self) {
|
||||||
match self {
|
match self {
|
||||||
Self::Artist(a) => a.push_cannot_have_mbid(),
|
Self::Artist(a) => a.push_cannot_have_mbid(),
|
||||||
Self::Album(a) => a.push_cannot_have_mbid(),
|
Self::Album(a) => a.push_cannot_have_mbid(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_manual_input_mbid(&mut self) {
|
||||||
|
match self {
|
||||||
|
Self::Artist(a) => a.push_manual_input_mbid(),
|
||||||
|
Self::Album(a) => a.push_manual_input_mbid(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_manual_input_mbid(&self, index: usize) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Artist(a) => a.is_manual_input_mbid(index),
|
||||||
|
Self::Album(a) => a.is_manual_input_mbid(index),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MatchState {
|
pub struct MatchState {
|
||||||
@ -56,6 +86,7 @@ impl MatchState {
|
|||||||
if let Some(ref mut current) = current {
|
if let Some(ref mut current) = current {
|
||||||
state.list.select(Some(0));
|
state.list.select(Some(0));
|
||||||
current.push_cannot_have_mbid();
|
current.push_cannot_have_mbid();
|
||||||
|
current.push_manual_input_mbid();
|
||||||
}
|
}
|
||||||
MatchState {
|
MatchState {
|
||||||
current,
|
current,
|
||||||
@ -116,6 +147,12 @@ impl IAppInteractMatch for AppMachine<MatchState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn select(self) -> Self::APP {
|
fn select(self) -> Self::APP {
|
||||||
|
if let Some(index) = self.state.state.list.selected() {
|
||||||
|
// selected() implies current exists
|
||||||
|
if self.state.current.as_ref().unwrap().is_manual_input_mbid(index) {
|
||||||
|
return AppMachine::input_state(self.inner, InputClient::Match(self.state)).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
AppMachine::app_fetch_next(self.inner, self.state.fetch)
|
AppMachine::app_fetch_next(self.inner, self.state.fetch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ mod critical_state;
|
|||||||
mod error_state;
|
mod error_state;
|
||||||
mod fetch_state;
|
mod fetch_state;
|
||||||
mod info_state;
|
mod info_state;
|
||||||
|
mod input_state;
|
||||||
mod match_state;
|
mod match_state;
|
||||||
mod reload_state;
|
mod reload_state;
|
||||||
mod search_state;
|
mod search_state;
|
||||||
@ -20,6 +21,7 @@ use critical_state::CriticalState;
|
|||||||
use error_state::ErrorState;
|
use error_state::ErrorState;
|
||||||
use fetch_state::FetchState;
|
use fetch_state::FetchState;
|
||||||
use info_state::InfoState;
|
use info_state::InfoState;
|
||||||
|
use input_state::InputState;
|
||||||
use match_state::MatchState;
|
use match_state::MatchState;
|
||||||
use reload_state::ReloadState;
|
use reload_state::ReloadState;
|
||||||
use search_state::SearchState;
|
use search_state::SearchState;
|
||||||
@ -33,6 +35,7 @@ pub type App = AppState<
|
|||||||
AppMachine<SearchState>,
|
AppMachine<SearchState>,
|
||||||
AppMachine<FetchState>,
|
AppMachine<FetchState>,
|
||||||
AppMachine<MatchState>,
|
AppMachine<MatchState>,
|
||||||
|
AppMachine<InputState>,
|
||||||
AppMachine<ErrorState>,
|
AppMachine<ErrorState>,
|
||||||
AppMachine<CriticalState>,
|
AppMachine<CriticalState>,
|
||||||
>;
|
>;
|
||||||
@ -77,6 +80,7 @@ impl App {
|
|||||||
AppState::Search(search_state) => &search_state.inner,
|
AppState::Search(search_state) => &search_state.inner,
|
||||||
AppState::Fetch(fetch_state) => &fetch_state.inner,
|
AppState::Fetch(fetch_state) => &fetch_state.inner,
|
||||||
AppState::Match(match_state) => &match_state.inner,
|
AppState::Match(match_state) => &match_state.inner,
|
||||||
|
AppState::Input(input_state) => &input_state.inner,
|
||||||
AppState::Error(error_state) => &error_state.inner,
|
AppState::Error(error_state) => &error_state.inner,
|
||||||
AppState::Critical(critical_state) => &critical_state.inner,
|
AppState::Critical(critical_state) => &critical_state.inner,
|
||||||
}
|
}
|
||||||
@ -90,6 +94,7 @@ impl App {
|
|||||||
AppState::Search(search_state) => &mut search_state.inner,
|
AppState::Search(search_state) => &mut search_state.inner,
|
||||||
AppState::Fetch(fetch_state) => &mut fetch_state.inner,
|
AppState::Fetch(fetch_state) => &mut fetch_state.inner,
|
||||||
AppState::Match(match_state) => &mut match_state.inner,
|
AppState::Match(match_state) => &mut match_state.inner,
|
||||||
|
AppState::Input(input_state) => &mut input_state.inner,
|
||||||
AppState::Error(error_state) => &mut error_state.inner,
|
AppState::Error(error_state) => &mut error_state.inner,
|
||||||
AppState::Critical(critical_state) => &mut critical_state.inner,
|
AppState::Critical(critical_state) => &mut critical_state.inner,
|
||||||
}
|
}
|
||||||
@ -103,6 +108,7 @@ impl IApp for App {
|
|||||||
type SearchState = AppMachine<SearchState>;
|
type SearchState = AppMachine<SearchState>;
|
||||||
type FetchState = AppMachine<FetchState>;
|
type FetchState = AppMachine<FetchState>;
|
||||||
type MatchState = AppMachine<MatchState>;
|
type MatchState = AppMachine<MatchState>;
|
||||||
|
type InputState = AppMachine<InputState>;
|
||||||
type ErrorState = AppMachine<ErrorState>;
|
type ErrorState = AppMachine<ErrorState>;
|
||||||
type CriticalState = AppMachine<CriticalState>;
|
type CriticalState = AppMachine<CriticalState>;
|
||||||
|
|
||||||
@ -124,6 +130,7 @@ impl IApp for App {
|
|||||||
Self::SearchState,
|
Self::SearchState,
|
||||||
Self::FetchState,
|
Self::FetchState,
|
||||||
Self::MatchState,
|
Self::MatchState,
|
||||||
|
Self::InputState,
|
||||||
Self::ErrorState,
|
Self::ErrorState,
|
||||||
Self::CriticalState,
|
Self::CriticalState,
|
||||||
> {
|
> {
|
||||||
@ -142,14 +149,15 @@ impl<T: Into<App>> IAppBase for T {
|
|||||||
impl IAppAccess for App {
|
impl IAppAccess for App {
|
||||||
fn get(&mut self) -> AppPublic {
|
fn get(&mut self) -> AppPublic {
|
||||||
match self {
|
match self {
|
||||||
AppState::Browse(browse) => browse.into(),
|
AppState::Browse(state) => state.into(),
|
||||||
AppState::Info(info) => info.into(),
|
AppState::Info(state) => state.into(),
|
||||||
AppState::Reload(reload) => reload.into(),
|
AppState::Reload(state) => state.into(),
|
||||||
AppState::Search(search) => search.into(),
|
AppState::Search(state) => state.into(),
|
||||||
AppState::Fetch(fetch) => fetch.into(),
|
AppState::Fetch(state) => state.into(),
|
||||||
AppState::Match(matches) => matches.into(),
|
AppState::Match(state) => state.into(),
|
||||||
AppState::Error(error) => error.into(),
|
AppState::Input(state) => state.into(),
|
||||||
AppState::Critical(critical) => critical.into(),
|
AppState::Error(state) => state.into(),
|
||||||
|
AppState::Critical(state) => state.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,57 +202,86 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<BS, IS, RS, SS, FS, MS, ES, CS> AppState<BS, IS, RS, SS, FS, MS, ES, CS> {
|
impl<
|
||||||
pub fn unwrap_browse(self) -> BS {
|
BrowseState,
|
||||||
|
InfoState,
|
||||||
|
ReloadState,
|
||||||
|
SearchState,
|
||||||
|
FetchState,
|
||||||
|
MatchState,
|
||||||
|
InputState,
|
||||||
|
ErrorState,
|
||||||
|
CriticalState,
|
||||||
|
>
|
||||||
|
AppState<
|
||||||
|
BrowseState,
|
||||||
|
InfoState,
|
||||||
|
ReloadState,
|
||||||
|
SearchState,
|
||||||
|
FetchState,
|
||||||
|
MatchState,
|
||||||
|
InputState,
|
||||||
|
ErrorState,
|
||||||
|
CriticalState,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
pub fn unwrap_browse(self) -> BrowseState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Browse(browse) => browse,
|
AppState::Browse(browse) => browse,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_info(self) -> IS {
|
pub fn unwrap_info(self) -> InfoState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Info(info) => info,
|
AppState::Info(info) => info,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_reload(self) -> RS {
|
pub fn unwrap_reload(self) -> ReloadState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Reload(reload) => reload,
|
AppState::Reload(reload) => reload,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_search(self) -> SS {
|
pub fn unwrap_search(self) -> SearchState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Search(search) => search,
|
AppState::Search(search) => search,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_fetch(self) -> FS {
|
pub fn unwrap_fetch(self) -> FetchState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Fetch(fetch) => fetch,
|
AppState::Fetch(fetch) => fetch,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_match(self) -> MS {
|
pub fn unwrap_match(self) -> MatchState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Match(matches) => matches,
|
AppState::Match(matches) => matches,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_error(self) -> ES {
|
pub fn unwrap_input(self) -> InputState {
|
||||||
|
match self {
|
||||||
|
AppState::Input(input) => input,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_error(self) -> ErrorState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Error(error) => error,
|
AppState::Error(error) => error,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_critical(self) -> CS {
|
pub fn unwrap_critical(self) -> CriticalState {
|
||||||
match self {
|
match self {
|
||||||
AppState::Critical(critical) => critical,
|
AppState::Critical(critical) => critical,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
|
@ -15,6 +15,7 @@ pub enum AppState<
|
|||||||
SearchState,
|
SearchState,
|
||||||
FetchState,
|
FetchState,
|
||||||
MatchState,
|
MatchState,
|
||||||
|
InputState,
|
||||||
ErrorState,
|
ErrorState,
|
||||||
CriticalState,
|
CriticalState,
|
||||||
> {
|
> {
|
||||||
@ -24,6 +25,7 @@ pub enum AppState<
|
|||||||
Search(SearchState),
|
Search(SearchState),
|
||||||
Fetch(FetchState),
|
Fetch(FetchState),
|
||||||
Match(MatchState),
|
Match(MatchState),
|
||||||
|
Input(InputState),
|
||||||
Error(ErrorState),
|
Error(ErrorState),
|
||||||
Critical(CriticalState),
|
Critical(CriticalState),
|
||||||
}
|
}
|
||||||
@ -37,6 +39,7 @@ pub trait IApp {
|
|||||||
+ IAppInteractFetch<APP = Self>
|
+ IAppInteractFetch<APP = Self>
|
||||||
+ IAppEventFetch<APP = Self>;
|
+ IAppEventFetch<APP = Self>;
|
||||||
type MatchState: IAppBase<APP = Self> + IAppInteractMatch<APP = Self>;
|
type MatchState: IAppBase<APP = Self> + IAppInteractMatch<APP = Self>;
|
||||||
|
type InputState: IAppBase<APP = Self> + IAppInteractInput<APP = Self>;
|
||||||
type ErrorState: IAppBase<APP = Self> + IAppInteractError<APP = Self>;
|
type ErrorState: IAppBase<APP = Self> + IAppInteractError<APP = Self>;
|
||||||
type CriticalState: IAppBase<APP = Self>;
|
type CriticalState: IAppBase<APP = Self>;
|
||||||
|
|
||||||
@ -53,6 +56,7 @@ pub trait IApp {
|
|||||||
Self::SearchState,
|
Self::SearchState,
|
||||||
Self::FetchState,
|
Self::FetchState,
|
||||||
Self::MatchState,
|
Self::MatchState,
|
||||||
|
Self::InputState,
|
||||||
Self::ErrorState,
|
Self::ErrorState,
|
||||||
Self::CriticalState,
|
Self::CriticalState,
|
||||||
>;
|
>;
|
||||||
@ -129,6 +133,15 @@ pub trait IAppInteractMatch {
|
|||||||
fn abort(self) -> Self::APP;
|
fn abort(self) -> Self::APP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IAppInteractInput {
|
||||||
|
type APP: IApp;
|
||||||
|
|
||||||
|
fn append_character(self, ch: char) -> Self::APP;
|
||||||
|
fn delete_character(self) -> Self::APP;
|
||||||
|
fn confirm(self) -> Self::APP;
|
||||||
|
fn cancel(self) -> Self::APP;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait IAppInteractError {
|
pub trait IAppInteractError {
|
||||||
type APP: IApp;
|
type APP: IApp;
|
||||||
|
|
||||||
@ -157,6 +170,7 @@ pub struct AppPublicInner<'app> {
|
|||||||
pub enum MatchOption<T> {
|
pub enum MatchOption<T> {
|
||||||
Match(Match<T>),
|
Match(Match<T>),
|
||||||
CannotHaveMbid,
|
CannotHaveMbid,
|
||||||
|
ManualInputMbid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<Match<T>> for MatchOption<T> {
|
impl<T> From<Match<T>> for MatchOption<T> {
|
||||||
@ -201,9 +215,31 @@ pub struct MatchStatePublic<'app> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type AppPublicState<'app> =
|
pub type AppPublicState<'app> =
|
||||||
AppState<(), (), (), &'app str, (), MatchStatePublic<'app>, &'app str, &'app str>;
|
AppState<(), (), (), &'app str, (), MatchStatePublic<'app>, &'app str, &'app str, &'app str>;
|
||||||
|
|
||||||
impl<BS, IS, RS, SS, FS, MS, ES, CS> AppState<BS, IS, RS, SS, FS, MS, ES, CS> {
|
impl<
|
||||||
|
BrowseState,
|
||||||
|
InfoState,
|
||||||
|
ReloadState,
|
||||||
|
SearchState,
|
||||||
|
FetchState,
|
||||||
|
MatchState,
|
||||||
|
InputState,
|
||||||
|
ErrorState,
|
||||||
|
CriticalState,
|
||||||
|
>
|
||||||
|
AppState<
|
||||||
|
BrowseState,
|
||||||
|
InfoState,
|
||||||
|
ReloadState,
|
||||||
|
SearchState,
|
||||||
|
FetchState,
|
||||||
|
MatchState,
|
||||||
|
InputState,
|
||||||
|
ErrorState,
|
||||||
|
CriticalState,
|
||||||
|
>
|
||||||
|
{
|
||||||
pub fn is_search(&self) -> bool {
|
pub fn is_search(&self) -> bool {
|
||||||
matches!(self, AppState::Search(_))
|
matches!(self, AppState::Search(_))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use crate::tui::{
|
|||||||
event::{Event, EventError, EventReceiver},
|
event::{Event, EventError, EventReceiver},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::app::{IAppBase, IAppEventFetch};
|
use super::app::{IAppBase, IAppEventFetch, IAppInteractInput};
|
||||||
|
|
||||||
#[cfg_attr(test, automock)]
|
#[cfg_attr(test, automock)]
|
||||||
pub trait IEventHandler<APP: IApp> {
|
pub trait IEventHandler<APP: IApp> {
|
||||||
@ -26,6 +26,7 @@ trait IEventHandlerPrivate<APP: IApp> {
|
|||||||
fn handle_search_key_event(app: <APP as IApp>::SearchState, key_event: KeyEvent) -> APP;
|
fn handle_search_key_event(app: <APP as IApp>::SearchState, key_event: KeyEvent) -> APP;
|
||||||
fn handle_fetch_key_event(app: <APP as IApp>::FetchState, key_event: KeyEvent) -> APP;
|
fn handle_fetch_key_event(app: <APP as IApp>::FetchState, key_event: KeyEvent) -> APP;
|
||||||
fn handle_match_key_event(app: <APP as IApp>::MatchState, key_event: KeyEvent) -> APP;
|
fn handle_match_key_event(app: <APP as IApp>::MatchState, key_event: KeyEvent) -> APP;
|
||||||
|
fn handle_input_key_event(app: <APP as IApp>::InputState, key_event: KeyEvent) -> APP;
|
||||||
fn handle_error_key_event(app: <APP as IApp>::ErrorState, key_event: KeyEvent) -> APP;
|
fn handle_error_key_event(app: <APP as IApp>::ErrorState, key_event: KeyEvent) -> APP;
|
||||||
fn handle_critical_key_event(app: <APP as IApp>::CriticalState, key_event: KeyEvent) -> APP;
|
fn handle_critical_key_event(app: <APP as IApp>::CriticalState, key_event: KeyEvent) -> APP;
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ impl<APP: IApp> IEventHandlerPrivate<APP> for EventHandler {
|
|||||||
}
|
}
|
||||||
AppState::Fetch(fetch_state) => Self::handle_fetch_key_event(fetch_state, key_event),
|
AppState::Fetch(fetch_state) => Self::handle_fetch_key_event(fetch_state, key_event),
|
||||||
AppState::Match(match_state) => Self::handle_match_key_event(match_state, key_event),
|
AppState::Match(match_state) => Self::handle_match_key_event(match_state, key_event),
|
||||||
|
AppState::Input(input_state) => Self::handle_input_key_event(input_state, key_event),
|
||||||
AppState::Error(error_state) => Self::handle_error_key_event(error_state, key_event),
|
AppState::Error(error_state) => Self::handle_error_key_event(error_state, key_event),
|
||||||
AppState::Critical(critical_state) => {
|
AppState::Critical(critical_state) => {
|
||||||
Self::handle_critical_key_event(critical_state, key_event)
|
Self::handle_critical_key_event(critical_state, key_event)
|
||||||
@ -84,14 +86,15 @@ impl<APP: IApp> IEventHandlerPrivate<APP> for EventHandler {
|
|||||||
|
|
||||||
fn handle_fetch_result_ready_event(app: APP) -> APP {
|
fn handle_fetch_result_ready_event(app: APP) -> APP {
|
||||||
match app.state() {
|
match app.state() {
|
||||||
AppState::Browse(browse_state) => browse_state.no_op(),
|
AppState::Browse(state) => state.no_op(),
|
||||||
AppState::Info(info_state) => info_state.no_op(),
|
AppState::Info(state) => state.no_op(),
|
||||||
AppState::Reload(reload_state) => reload_state.no_op(),
|
AppState::Reload(state) => state.no_op(),
|
||||||
AppState::Search(search_state) => search_state.no_op(),
|
AppState::Search(state) => state.no_op(),
|
||||||
AppState::Fetch(fetch_state) => fetch_state.fetch_result_ready(),
|
AppState::Fetch(fetch_state) => fetch_state.fetch_result_ready(),
|
||||||
AppState::Match(match_state) => match_state.no_op(),
|
AppState::Match(state) => state.no_op(),
|
||||||
AppState::Error(error_state) => error_state.no_op(),
|
AppState::Input(state) => state.no_op(),
|
||||||
AppState::Critical(critical_state) => critical_state.no_op(),
|
AppState::Error(state) => state.no_op(),
|
||||||
|
AppState::Critical(state) => state.no_op(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +199,25 @@ impl<APP: IApp> IEventHandlerPrivate<APP> for EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_input_key_event(app: <APP as IApp>::InputState, key_event: KeyEvent) -> APP {
|
||||||
|
if key_event.modifiers == KeyModifiers::CONTROL {
|
||||||
|
return match key_event.code {
|
||||||
|
KeyCode::Char('g') | KeyCode::Char('G') => app.cancel(),
|
||||||
|
_ => app.no_op(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
match key_event.code {
|
||||||
|
// Add/remove character.
|
||||||
|
KeyCode::Char(ch) => app.append_character(ch),
|
||||||
|
KeyCode::Backspace => app.delete_character(),
|
||||||
|
// Return.
|
||||||
|
KeyCode::Esc | KeyCode::Enter => app.confirm(),
|
||||||
|
// Othey keys.
|
||||||
|
_ => app.no_op(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_error_key_event(app: <APP as IApp>::ErrorState, _key_event: KeyEvent) -> APP {
|
fn handle_error_key_event(app: <APP as IApp>::ErrorState, _key_event: KeyEvent) -> APP {
|
||||||
// Any key dismisses the error.
|
// Any key dismisses the error.
|
||||||
app.dismiss_error()
|
app.dismiss_error()
|
||||||
|
@ -137,6 +137,7 @@ impl UiDisplay {
|
|||||||
match_artist.score,
|
match_artist.score,
|
||||||
),
|
),
|
||||||
MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(),
|
MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(),
|
||||||
|
MatchOption::ManualInputMbid => Self::display_manual_input_mbid().to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,12 +154,17 @@ impl UiDisplay {
|
|||||||
match_album.score,
|
match_album.score,
|
||||||
),
|
),
|
||||||
MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(),
|
MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(),
|
||||||
|
MatchOption::ManualInputMbid => Self::display_manual_input_mbid().to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_cannot_have_mbid() -> &'static str {
|
fn display_cannot_have_mbid() -> &'static str {
|
||||||
"-- Cannot have a MusicBrainz Identifier --"
|
"-- Cannot have a MusicBrainz Identifier --"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_manual_input_mbid() -> &'static str {
|
||||||
|
"-- Manually enter a MusicBrainz Identifier --"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -67,6 +67,13 @@ impl Minibuffer<'_> {
|
|||||||
],
|
],
|
||||||
columns: 2,
|
columns: 2,
|
||||||
},
|
},
|
||||||
|
AppState::Input(_) => Minibuffer {
|
||||||
|
paragraphs: vec![
|
||||||
|
Paragraph::new("enter: confirm"),
|
||||||
|
Paragraph::new("ctrl+g: cancel"),
|
||||||
|
],
|
||||||
|
columns: 2,
|
||||||
|
},
|
||||||
AppState::Error(_) => Minibuffer {
|
AppState::Error(_) => Minibuffer {
|
||||||
paragraphs: vec![Paragraph::new(
|
paragraphs: vec![Paragraph::new(
|
||||||
"Press any key to dismiss the error message...",
|
"Press any key to dismiss the error message...",
|
||||||
|
@ -211,6 +211,7 @@ mod tests {
|
|||||||
info: m.info,
|
info: m.info,
|
||||||
state: m.state,
|
state: m.state,
|
||||||
}),
|
}),
|
||||||
|
AppState::Input(s) => AppState::Input(s),
|
||||||
AppState::Error(s) => AppState::Error(s),
|
AppState::Error(s) => AppState::Error(s),
|
||||||
AppState::Critical(s) => AppState::Critical(s),
|
AppState::Critical(s) => AppState::Critical(s),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user