pub mod input;
pub mod input_manager;
pub mod layout;
pub mod state;
pub mod trait_impl;
pub use input::{KeyHint, OverlayInputHandler};
pub use input_manager::{OverlayInputManager, OverlayInputResult};
pub use layout::{ContentId, OverlayLayout, RowType};
pub use state::OverlayState;
pub use trait_impl::Overlay;
use crate::render::panel::RenderedOverlay;
use crossterm::event::KeyModifiers;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum OverlayType {
Help,
Controls,
Dashboard,
ConfigBrowser,
ConfigSave,
DirtyGuard,
PresetComparison,
KeyboardHints,
PaletteEditor,
PauseBadge,
PauseLogo,
}
impl OverlayType {
pub fn captures_input(self) -> bool {
matches!(
self,
OverlayType::Controls
| OverlayType::PaletteEditor
| OverlayType::ConfigBrowser
| OverlayType::ConfigSave
| OverlayType::DirtyGuard
)
}
pub fn closes_on_escape(self) -> bool {
!matches!(self, OverlayType::PauseBadge | OverlayType::PauseLogo)
}
pub fn z_order(self) -> u8 {
match self {
OverlayType::PauseLogo => 0,
OverlayType::PauseBadge => 1,
OverlayType::Controls => 2,
OverlayType::Dashboard => 3,
OverlayType::Help => 10,
OverlayType::ConfigBrowser => 10,
OverlayType::ConfigSave => 10,
OverlayType::KeyboardHints => 10,
OverlayType::PresetComparison => 10,
OverlayType::PaletteEditor => 10,
OverlayType::DirtyGuard => 10,
}
}
pub fn toggle_keys(self) -> &'static [char] {
match self {
OverlayType::Controls => &['h', 'H'],
OverlayType::KeyboardHints => &['?'],
OverlayType::Dashboard => &['\\', '|'],
OverlayType::PaletteEditor => &['p', 'P', '/'],
OverlayType::ConfigBrowser => &[], OverlayType::ConfigSave => &[], _ => &[],
}
}
pub fn is_toggle_key(self, key: char, modifiers: KeyModifiers) -> bool {
match self {
OverlayType::ConfigBrowser => {
modifiers.contains(KeyModifiers::CONTROL) && matches!(key, 'l' | 'L' | 'b' | 'B')
}
OverlayType::ConfigSave => {
modifiers.contains(KeyModifiers::CONTROL) && matches!(key, 's' | 'S')
}
_ => modifiers == KeyModifiers::NONE && self.toggle_keys().contains(&key),
}
}
pub fn blocks_other_keys(self) -> bool {
self.captures_input()
}
pub fn handles_escape_internally(self) -> bool {
matches!(self, OverlayType::PaletteEditor)
}
pub fn from_toggle_key(key: char, modifiers: KeyModifiers) -> Option<OverlayType> {
[
OverlayType::Controls,
OverlayType::KeyboardHints,
OverlayType::Dashboard,
OverlayType::PaletteEditor,
OverlayType::ConfigBrowser,
OverlayType::ConfigSave,
]
.into_iter()
.find(|&overlay| overlay.is_toggle_key(key, modifiers))
}
}
#[derive(Default)]
pub struct OverlayCollection<'a> {
pub pause_logo: Option<(&'a RenderedOverlay, usize, usize)>,
pub pause_badge: Option<(&'a RenderedOverlay, usize, usize)>,
pub controls: Option<(&'a RenderedOverlay, usize, usize)>,
pub dashboard: Option<(&'a RenderedOverlay, usize, usize)>,
pub config_browser: Option<(&'a RenderedOverlay, usize, usize)>,
pub config_save: Option<(&'a RenderedOverlay, usize, usize)>,
pub keyboard_hints: Option<(&'a RenderedOverlay, usize, usize)>,
pub preset_comparison: Option<(&'a RenderedOverlay, usize, usize)>,
pub palette_editor: Option<(&'a RenderedOverlay, usize, usize)>,
}
type OverlayEntry<'a> = (OverlayType, Option<(&'a RenderedOverlay, usize, usize)>);
impl<'a> OverlayCollection<'a> {
pub fn iter_by_z_order(&self) -> Vec<OverlayEntry<'a>> {
let mut overlays: Vec<(OverlayType, _, u8)> = vec![
(
OverlayType::PauseLogo,
self.pause_logo,
OverlayType::PauseLogo.z_order(),
),
(
OverlayType::PauseBadge,
self.pause_badge,
OverlayType::PauseBadge.z_order(),
),
(
OverlayType::Controls,
self.controls,
OverlayType::Controls.z_order(),
),
(
OverlayType::Dashboard,
self.dashboard,
OverlayType::Dashboard.z_order(),
),
(
OverlayType::ConfigBrowser,
self.config_browser,
OverlayType::ConfigBrowser.z_order(),
),
(
OverlayType::ConfigSave,
self.config_save,
OverlayType::ConfigSave.z_order(),
),
(
OverlayType::KeyboardHints,
self.keyboard_hints,
OverlayType::KeyboardHints.z_order(),
),
(
OverlayType::PresetComparison,
self.preset_comparison,
OverlayType::PresetComparison.z_order(),
),
(
OverlayType::PaletteEditor,
self.palette_editor,
OverlayType::PaletteEditor.z_order(),
),
];
overlays.sort_by_key(|(_, _, z)| *z);
overlays.into_iter().map(|(t, o, _)| (t, o)).collect()
}
}