use super::super::app::{App, SettingValue, SettingsCategory};
use crate::event::Key;
use crate::handlers::common_key_events::{down_event, left_event, right_event, up_event};
pub fn handler(key: Key, app: &mut App) {
if app.settings_edit_mode {
handle_edit_mode(key, app);
} else {
handle_navigation(key, app);
}
}
fn handle_navigation(key: Key, app: &mut App) {
match key {
key if left_event(key) => switch_category_left(app),
key if right_event(key) => switch_category_right(app),
key if down_event(key) => select_next_item(app),
key if up_event(key) => select_previous_item(app),
Key::Enter => enter_edit_mode(app),
key if key == app.user_config.keys.save_settings => save_settings(app),
Key::Esc => {
app.pop_navigation_stack();
}
key if key == app.user_config.keys.back => {
app.pop_navigation_stack();
}
_ => {}
}
}
fn handle_edit_mode(key: Key, app: &mut App) {
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
match &setting.value {
SettingValue::Bool(_) => handle_bool_edit(key, app),
SettingValue::Number(_) => handle_number_edit(key, app),
SettingValue::Preset(_) => handle_preset_edit(key, app),
SettingValue::Key(_) => handle_key_edit(key, app),
SettingValue::String(_) | SettingValue::Color(_) => handle_string_edit(key, app),
}
}
}
fn handle_bool_edit(key: Key, app: &mut App) {
match key {
Key::Enter | Key::Char(' ') => {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
if let SettingValue::Bool(v) = setting.value {
setting.value = SettingValue::Bool(!v);
}
}
app.settings_edit_mode = false;
}
Key::Esc => {
app.settings_edit_mode = false;
}
key if left_event(key) || right_event(key) => {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
if let SettingValue::Bool(v) = setting.value {
setting.value = SettingValue::Bool(!v);
}
}
}
_ => {}
}
}
fn handle_number_edit(key: Key, app: &mut App) {
match key {
Key::Enter => {
if let Ok(num) = app.settings_edit_buffer.parse::<i64>() {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
setting.value = SettingValue::Number(num);
}
}
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
Key::Esc => {
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
Key::Char(c) if c.is_ascii_digit() || c == '-' => {
app.settings_edit_buffer.push(c);
}
Key::Backspace => {
app.settings_edit_buffer.pop();
}
key if up_event(key) => {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
if let SettingValue::Number(v) = setting.value {
let new_val = v + 1;
setting.value = SettingValue::Number(new_val);
app.settings_edit_buffer = new_val.to_string();
}
}
}
key if down_event(key) => {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
if let SettingValue::Number(v) = setting.value {
let new_val = v - 1;
setting.value = SettingValue::Number(new_val);
app.settings_edit_buffer = new_val.to_string();
}
}
}
_ => {}
}
}
fn handle_string_edit(key: Key, app: &mut App) {
match key {
Key::Enter => {
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
let new_value = app.settings_edit_buffer.clone();
match &setting.value {
SettingValue::String(_) => {
setting.value = SettingValue::String(new_value);
}
SettingValue::Color(_) => {
setting.value = SettingValue::Color(new_value);
}
_ => {}
}
}
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
Key::Esc => {
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
Key::Char(c) => {
app.settings_edit_buffer.push(c);
}
Key::Backspace => {
app.settings_edit_buffer.pop();
}
_ => {}
}
}
fn check_keybinding_conflict(app: &App, new_key: Key, current_setting_id: &str) -> Option<String> {
for setting in &app.settings_items {
if setting.id == current_setting_id {
continue;
}
if !setting.id.starts_with("keys.") {
continue;
}
if let SettingValue::Key(key_string) = &setting.value {
if let Ok(existing_key) = crate::user_config::parse_key_public(key_string.clone()) {
if existing_key == new_key {
return Some(setting.name.clone());
}
}
}
}
None
}
fn handle_key_edit(key: Key, app: &mut App) {
match key {
Key::Esc => {
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
_ => {
if let Err(e) = crate::user_config::check_reserved_keys_public(key) {
app.handle_error(anyhow::anyhow!("{}", e));
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
return;
}
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
if let Some(conflict_name) = check_keybinding_conflict(app, key, &setting.id) {
let key_display = key_to_config_string(&key);
app.handle_error(anyhow::anyhow!(
"Key {} is already assigned to {}",
key_display,
conflict_name
));
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
return;
}
}
let key_string = key_to_config_string(&key);
if let Some(setting) = app.settings_items.get_mut(app.settings_selected_index) {
setting.value = SettingValue::Key(key_string);
}
app.settings_edit_mode = false;
app.settings_edit_buffer.clear();
}
}
}
fn key_to_config_string(key: &Key) -> String {
match key {
Key::Char(c) if *c == ' ' => "space".to_string(),
Key::Char(c) => c.to_string(),
Key::Ctrl(c) => format!("ctrl-{}", c),
Key::Alt(c) => format!("alt-{}", c),
Key::Enter => "enter".to_string(),
Key::Esc => "esc".to_string(),
Key::Backspace => "backspace".to_string(),
Key::Delete => "del".to_string(),
Key::Left => "left".to_string(),
Key::Right => "right".to_string(),
Key::Up => "up".to_string(),
Key::Down => "down".to_string(),
Key::PageUp => "pageup".to_string(),
Key::PageDown => "pagedown".to_string(),
Key::Home => "home".to_string(),
Key::End => "end".to_string(),
Key::Tab => "tab".to_string(),
Key::Ins => "ins".to_string(),
Key::F0 => "f0".to_string(),
Key::F1 => "f1".to_string(),
Key::F2 => "f2".to_string(),
Key::F3 => "f3".to_string(),
Key::F4 => "f4".to_string(),
Key::F5 => "f5".to_string(),
Key::F6 => "f6".to_string(),
Key::F7 => "f7".to_string(),
Key::F8 => "f8".to_string(),
Key::F9 => "f9".to_string(),
Key::F10 => "f10".to_string(),
Key::F11 => "f11".to_string(),
Key::F12 => "f12".to_string(),
Key::Unknown => "unknown".to_string(),
}
}
fn switch_category_left(app: &mut App) {
let current_index = app.settings_category.index();
let new_index = if current_index == 0 {
SettingsCategory::all().len() - 1
} else {
current_index - 1
};
app.settings_category = SettingsCategory::from_index(new_index);
app.settings_selected_index = 0;
app.load_settings_for_category();
}
fn switch_category_right(app: &mut App) {
let current_index = app.settings_category.index();
let new_index = (current_index + 1) % SettingsCategory::all().len();
app.settings_category = SettingsCategory::from_index(new_index);
app.settings_selected_index = 0;
app.load_settings_for_category();
}
fn select_next_item(app: &mut App) {
if !app.settings_items.is_empty() {
app.settings_selected_index = (app.settings_selected_index + 1) % app.settings_items.len();
}
}
fn select_previous_item(app: &mut App) {
if !app.settings_items.is_empty() {
if app.settings_selected_index == 0 {
app.settings_selected_index = app.settings_items.len() - 1;
} else {
app.settings_selected_index -= 1;
}
}
}
fn enter_edit_mode(app: &mut App) {
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
if let SettingValue::Bool(v) = setting.value {
if let Some(setting_mut) = app.settings_items.get_mut(app.settings_selected_index) {
setting_mut.value = SettingValue::Bool(!v);
}
return;
}
if let SettingValue::Preset(ref preset_name) = setting.value {
use crate::user_config::ThemePreset;
let current = ThemePreset::from_name(preset_name);
let next = current.next();
if let Some(setting_mut) = app.settings_items.get_mut(app.settings_selected_index) {
setting_mut.value = SettingValue::Preset(next.name().to_string());
}
return;
}
app.settings_edit_mode = true;
app.settings_edit_buffer = match &setting.value {
SettingValue::Bool(_) => String::new(), SettingValue::Number(v) => v.to_string(),
SettingValue::String(v) => v.clone(),
SettingValue::Key(v) => v.clone(),
SettingValue::Color(v) => v.clone(),
SettingValue::Preset(_) => String::new(), };
}
}
fn handle_preset_edit(key: Key, app: &mut App) {
use crate::user_config::ThemePreset;
match key {
Key::Enter | Key::Char(' ') => {
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
if let SettingValue::Preset(ref preset_name) = setting.value {
let current = ThemePreset::from_name(preset_name);
let next = current.next();
if let Some(setting_mut) = app.settings_items.get_mut(app.settings_selected_index) {
setting_mut.value = SettingValue::Preset(next.name().to_string());
}
}
}
app.settings_edit_mode = false;
}
Key::Esc => {
app.settings_edit_mode = false;
}
key if right_event(key) => {
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
if let SettingValue::Preset(ref preset_name) = setting.value {
let current = ThemePreset::from_name(preset_name);
let next = current.next();
if let Some(setting_mut) = app.settings_items.get_mut(app.settings_selected_index) {
setting_mut.value = SettingValue::Preset(next.name().to_string());
}
}
}
}
key if left_event(key) => {
if let Some(setting) = app.settings_items.get(app.settings_selected_index) {
if let SettingValue::Preset(ref preset_name) = setting.value {
let current = ThemePreset::from_name(preset_name);
let prev = current.prev();
if let Some(setting_mut) = app.settings_items.get_mut(app.settings_selected_index) {
setting_mut.value = SettingValue::Preset(prev.name().to_string());
}
}
}
}
_ => {}
}
}
fn save_settings(app: &mut App) {
app.apply_settings_changes();
if let Err(e) = app.user_config.save_config() {
app.handle_error(anyhow::anyhow!("Failed to save settings: {}", e));
}
}