Compare commits

...

2 Commits

Author SHA1 Message Date
filipriec
5e101bef14 tab is triggering the suggestion dropdown menu, but ctrl+n and ctrl+p only cycle through it 2025-04-12 23:56:14 +02:00
filipriec
149949ad99 better dropdown gui 2025-04-12 22:42:06 +02:00
5 changed files with 31 additions and 28 deletions

View File

@@ -51,11 +51,11 @@ exit_edit_mode = ["esc","ctrl+e"]
delete_char_forward = ["delete"]
delete_char_backward = ["backspace"]
next_field = ["enter"]
prev_field = ["backtab"]
prev_field = ["shift+enter"]
move_left = ["left"]
move_right = ["right"]
suggestion_down = ["shift+tab"]
suggestion_up = ["tab"]
suggestion_down = ["ctrl+n", "tab"]
suggestion_up = ["ctrl+p", "shift+tab"]
select_suggestion = ["enter"]
exit_suggestion_mode = ["esc"]

View File

@@ -6,6 +6,7 @@ use crate::{
components::common::{dialog, autocomplete},
state::state::AppState,
state::canvas_state::CanvasState,
modes::handlers::mode_manager::AppMode,
};
use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Rect, Margin},
@@ -136,11 +137,13 @@ pub fn render_register(
);
// --- Render Autocomplete Dropdown (Draw AFTER buttons) ---
if let Some(suggestions) = state.get_suggestions() {
let selected = state.get_selected_suggestion_index();
if !suggestions.is_empty() {
if let Some(input_rect) = active_field_rect {
autocomplete::render_autocomplete_dropdown(f, input_rect, f.size(), theme, suggestions, selected);
if app_state.current_mode == AppMode::Edit {
if let Some(suggestions) = state.get_suggestions() {
let selected = state.get_selected_suggestion_index();
if !suggestions.is_empty() {
if let Some(input_rect) = active_field_rect {
autocomplete::render_autocomplete_dropdown(f, input_rect, f.size(), theme, suggestions, selected);
}
}
}
}

View File

@@ -59,8 +59,11 @@ pub fn render_autocomplete_dropdown(
.enumerate()
.map(|(i, s)| {
let is_selected = selected_index == Some(i);
ListItem::new(s.as_str()).style(if is_selected {
// Style for selected item (highlight background)
let s_width = s.width() as u16;
let padding_needed = dropdown_width.saturating_sub(s_width);
let padded_s = format!("{}{}", s, " ".repeat(padding_needed as usize));
ListItem::new(padded_s).style(if is_selected {
Style::default()
.fg(theme.bg) // Text color on highlight
.bg(theme.highlight) // Highlight background

View File

@@ -311,7 +311,7 @@ pub async fn execute_edit_action<S: CanvasState + Any + Send>(
register_state.selected_suggestion_index = Some(if current_index >= max_index { 0 } else { current_index + 1 });
Ok("Suggestion changed down".to_string())
}
"suggestion_up" if register_state.show_role_suggestions => {
"suggestion_up" if register_state.in_suggestion_mode => {
let max_index = register_state.role_suggestions.len().saturating_sub(1);
let current_index = register_state.selected_suggestion_index.unwrap_or(0);
register_state.selected_suggestion_index = Some(if current_index == 0 { max_index } else { current_index.saturating_sub(1) });
@@ -336,10 +336,12 @@ pub async fn execute_edit_action<S: CanvasState + Any + Send>(
register_state.in_suggestion_mode = false;
Ok("Suggestions hidden".to_string())
}
_ => Ok("".to_string()) // Action doesn't apply in this state (e.g., suggestions not shown)
"suggestion_down" | "suggestion_up" | "select_suggestion" => {
Ok("Suggestion action ignored: Not in suggestion mode.".to_string())
}
_ => Ok("".to_string())
}
} else {
// Action received but not applicable to the current field
Ok("".to_string())
}
} else {

View File

@@ -8,7 +8,7 @@ use crate::state::pages::form::FormState;
use crate::functions::modes::edit::{auth_e, form_e};
use crate::modes::handlers::event::EventOutcome;
use crate::state::state::AppState;
use crossterm::event::{KeyCode, KeyEvent};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
pub async fn handle_edit_event(
key: KeyEvent,
@@ -82,24 +82,19 @@ pub async fn handle_edit_event(
if let Some(action) = config.get_edit_action_for_key(key.code, key.modifiers) {
// --- Special Handling for Tab/Shift+Tab in Role Field ---
if app_state.ui.show_register && register_state.current_field() == 4 {
match action {
"suggestion_up" | "suggestion_down" => { // Mapped to Tab/Shift+Tab
if !register_state.in_suggestion_mode {
register_state.update_role_suggestions();
if !register_state.role_suggestions.is_empty() {
register_state.in_suggestion_mode = true;
register_state.selected_suggestion_index = Some(0);
return Ok("Suggestions shown".to_string());
} else {
return Ok("No suggestions available".to_string());
}
}
if !register_state.in_suggestion_mode && key.code == KeyCode::Tab && key.modifiers == KeyModifiers::NONE {
register_state.update_role_suggestions();
if !register_state.role_suggestions.is_empty() {
register_state.in_suggestion_mode = true;
register_state.selected_suggestion_index = Some(0); // Select first suggestion
return Ok("Suggestions shown".to_string());
} else {
return Ok("No suggestions available".to_string());
}
_ => {}
}
}
// --- End Special Handling ---
return if app_state.ui.show_login {
auth_e::execute_edit_action(
action,