use crossterm::event::{KeyCode, KeyModifiers};
use super::{Focus, Outcome, State};
use crate::{clipboard, input, nav, overlay::PopupFlow, theme::parse_color};
pub(super) fn handle(
state: &mut State,
key: crossterm::event::KeyEvent,
) -> PopupFlow<Outcome> {
match key.code {
KeyCode::Enter => {
return PopupFlow::Done(Outcome::Done(state.current_color()));
}
KeyCode::Esc => {
return PopupFlow::Done(Outcome::Back(state.current_color()));
}
KeyCode::Tab | KeyCode::Down => {
state.cycle_focus(1);
return PopupFlow::Continue;
}
KeyCode::BackTab | KeyCode::Up => {
state.cycle_focus(-1);
return PopupFlow::Continue;
}
_ => {}
}
match state.focus {
Focus::Hex => handle_hex(state, key),
Focus::Channel(index) => handle_channel(state, index, key),
Focus::Presets => handle_presets(state, key),
}
}
fn handle_hex(
state: &mut State,
key: crossterm::event::KeyEvent,
) -> PopupFlow<Outcome> {
if state.hex.handle_key(key)
&& let Some(color) = parse_color(state.hex.value())
{
state.adopt(color);
}
PopupFlow::Continue
}
pub(super) fn handle_paste(
state: &mut State,
text: &str,
) -> PopupFlow<Outcome> {
if state.focus == Focus::Hex {
state.hex.paste(text);
if let Some(color) = parse_color(state.hex.value()) {
state.adopt(color);
}
}
PopupFlow::Continue
}
fn handle_channel(
state: &mut State,
index: usize,
key: crossterm::event::KeyEvent,
) -> PopupFlow<Outcome> {
if input::is_command(key) {
return PopupFlow::Continue;
}
let channel = state.model.channels()[index];
let step = if key.modifiers.contains(KeyModifiers::SHIFT) {
1.0
} else {
channel.coarse
};
match key.code {
KeyCode::Left | KeyCode::Char('h') => state.adjust(index, -step),
KeyCode::Right | KeyCode::Char('l') => state.adjust(index, step),
KeyCode::Home => state.set(index, channel.min),
KeyCode::End => state.set(index, channel.max),
KeyCode::PageUp => state.adjust(index, -channel.page()),
KeyCode::PageDown => state.adjust(index, channel.page()),
KeyCode::Char('m') => state.set_model(state.model.next()),
KeyCode::Char('y') => copy_hex(state),
KeyCode::Char('s') => {
return PopupFlow::Done(Outcome::Swatches(state.current_color()));
}
_ => {}
}
PopupFlow::Continue
}
fn handle_presets(
state: &mut State,
key: crossterm::event::KeyEvent,
) -> PopupFlow<Outcome> {
if input::is_command(key) {
return PopupFlow::Continue;
}
let count = state.presets.len();
match key.code {
KeyCode::Left | KeyCode::Char('h') => {
select_preset(state, nav::cycle(state.preset, count, -1));
}
KeyCode::Right | KeyCode::Char('l') => {
select_preset(state, nav::cycle(state.preset, count, 1));
}
KeyCode::Home => select_preset(state, 0),
KeyCode::End => select_preset(state, count.saturating_sub(1)),
KeyCode::Char('m') => state.set_model(state.model.next()),
KeyCode::Char('y') => copy_hex(state),
KeyCode::Char('s') => {
return PopupFlow::Done(Outcome::Swatches(state.current_color()));
}
_ => {}
}
PopupFlow::Continue
}
fn select_preset(state: &mut State, index: usize) {
state.preset = index;
state.adopt(state.presets[index]);
state.sync_hex();
}
fn copy_hex(state: &State) {
let _ = clipboard::copy(&state.current_color().to_hex());
}