open menu in command mode now implemented
This commit is contained in:
@@ -83,6 +83,7 @@ quit = ["q"]
|
|||||||
force_quit = ["q!"]
|
force_quit = ["q!"]
|
||||||
save_and_quit = ["wq"]
|
save_and_quit = ["wq"]
|
||||||
revert = ["r"]
|
revert = ["r"]
|
||||||
|
find_file_palette_toggle = ["ff"]
|
||||||
|
|
||||||
[editor]
|
[editor]
|
||||||
keybinding_mode = "vim" # Options: "default", "vim", "emacs"
|
keybinding_mode = "vim" # Options: "default", "vim", "emacs"
|
||||||
|
|||||||
@@ -6,27 +6,37 @@ use ratatui::{
|
|||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
|
pub fn render_command_line(
|
||||||
|
f: &mut Frame,
|
||||||
|
area: Rect,
|
||||||
|
input: &str, // This is event_handler.command_input
|
||||||
|
active: bool, // This is event_handler.command_mode
|
||||||
|
theme: &Theme,
|
||||||
|
message: &str, // This is event_handler.command_message
|
||||||
|
// Palette-specific parameters are removed
|
||||||
|
) {
|
||||||
|
// This function now only renders the normal command line.
|
||||||
|
// The find_file_palette_active check in render_ui ensures this is called appropriately.
|
||||||
|
|
||||||
pub fn render_command_line(f: &mut Frame, area: Rect, input: &str, active: bool, theme: &Theme, message: &str) {
|
if !active { // If not in normal command mode, render minimally or nothing
|
||||||
let prompt = if active {
|
let paragraph = Paragraph::new("")
|
||||||
":"
|
.block(Block::default().style(Style::default().bg(theme.bg)));
|
||||||
} else {
|
f.render_widget(paragraph, area);
|
||||||
""
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Combine the prompt, input, and message
|
let prompt = ":";
|
||||||
let display_text = if message.is_empty() {
|
let display_text = if message.is_empty() || message == ":" {
|
||||||
format!("{}{}", prompt, input)
|
format!("{}{}", prompt, input)
|
||||||
} else {
|
} else {
|
||||||
|
if input.is_empty() { // If command was just executed, input is cleared, show message
|
||||||
|
message.to_string()
|
||||||
|
} else { // Show input and message
|
||||||
format!("{}{} | {}", prompt, input, message)
|
format!("{}{} | {}", prompt, input, message)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let style = if active {
|
let style = Style::default().fg(theme.accent); // Style for active command line
|
||||||
Style::default().fg(theme.accent)
|
|
||||||
} else {
|
|
||||||
Style::default().fg(theme.fg)
|
|
||||||
};
|
|
||||||
|
|
||||||
let paragraph = Paragraph::new(display_text)
|
let paragraph = Paragraph::new(display_text)
|
||||||
.block(Block::default().style(Style::default().bg(theme.bg)))
|
.block(Block::default().style(Style::default().bg(theme.bg)))
|
||||||
.style(style);
|
.style(style);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ use crate::tui::functions::common::register::RegisterResult;
|
|||||||
use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender;
|
use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender;
|
||||||
use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender;
|
use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender;
|
||||||
use crate::functions::modes::navigation::add_logic_nav;
|
use crate::functions::modes::navigation::add_logic_nav;
|
||||||
|
use crossterm::event::{KeyCode, KeyModifiers};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EventOutcome {
|
pub enum EventOutcome {
|
||||||
@@ -66,6 +67,10 @@ pub struct EventHandler {
|
|||||||
pub register_result_sender: mpsc::Sender<RegisterResult>,
|
pub register_result_sender: mpsc::Sender<RegisterResult>,
|
||||||
pub save_table_result_sender: SaveTableResultSender,
|
pub save_table_result_sender: SaveTableResultSender,
|
||||||
pub save_logic_result_sender: SaveLogicResultSender,
|
pub save_logic_result_sender: SaveLogicResultSender,
|
||||||
|
pub find_file_palette_active: bool,
|
||||||
|
pub find_file_options: Vec<String>,
|
||||||
|
pub find_file_selected_index: Option<usize>,
|
||||||
|
pub find_file_input: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventHandler {
|
impl EventHandler {
|
||||||
@@ -83,15 +88,30 @@ impl EventHandler {
|
|||||||
highlight_state: HighlightState::Off,
|
highlight_state: HighlightState::Off,
|
||||||
edit_mode_cooldown: false,
|
edit_mode_cooldown: false,
|
||||||
ideal_cursor_column: 0,
|
ideal_cursor_column: 0,
|
||||||
key_sequence_tracker: KeySequenceTracker::new(800),
|
key_sequence_tracker: KeySequenceTracker::new(400),
|
||||||
auth_client: AuthClient::new().await?,
|
auth_client: AuthClient::new().await?,
|
||||||
login_result_sender,
|
login_result_sender,
|
||||||
register_result_sender,
|
register_result_sender,
|
||||||
save_table_result_sender,
|
save_table_result_sender,
|
||||||
save_logic_result_sender,
|
save_logic_result_sender,
|
||||||
|
find_file_palette_active: false,
|
||||||
|
find_file_options: vec![
|
||||||
|
"src/main.rs".to_string(),
|
||||||
|
"src/lib.rs".to_string(),
|
||||||
|
"Cargo.toml".to_string(),
|
||||||
|
"README.md".to_string(),
|
||||||
|
"config.toml".to_string(),
|
||||||
|
"src/ui/handlers/ui.rs".to_string(),
|
||||||
|
"src/modes/handlers/event.rs".to_string(),
|
||||||
|
"another_file.txt".to_string(),
|
||||||
|
"yet_another_one.md".to_string(),
|
||||||
|
],
|
||||||
|
find_file_selected_index: None,
|
||||||
|
find_file_input: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn handle_event(
|
pub async fn handle_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
@@ -110,6 +130,25 @@ impl EventHandler {
|
|||||||
total_count: u64,
|
total_count: u64,
|
||||||
current_position: &mut u64,
|
current_position: &mut u64,
|
||||||
) -> Result<EventOutcome> {
|
) -> Result<EventOutcome> {
|
||||||
|
// Handle find file palette first
|
||||||
|
if self.find_file_palette_active {
|
||||||
|
if let Event::Key(key) = event {
|
||||||
|
if key.code == KeyCode::Esc {
|
||||||
|
self.find_file_palette_active = false;
|
||||||
|
self.find_file_input.clear();
|
||||||
|
self.find_file_selected_index = None;
|
||||||
|
self.command_message = "Find File palette closed".to_string();
|
||||||
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
|
}
|
||||||
|
if let KeyCode::Char(c) = key.code {
|
||||||
|
self.find_file_input.push(c);
|
||||||
|
} else if key.code == KeyCode::Backspace {
|
||||||
|
self.find_file_input.pop();
|
||||||
|
}
|
||||||
|
return Ok(EventOutcome::Ok("Palette event consumed".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let current_mode = ModeManager::derive_mode(app_state, self, admin_state);
|
let current_mode = ModeManager::derive_mode(app_state, self, admin_state);
|
||||||
app_state.update_mode(current_mode);
|
app_state.update_mode(current_mode);
|
||||||
|
|
||||||
@@ -121,7 +160,7 @@ impl EventHandler {
|
|||||||
else if ui.show_admin { AppView::Admin }
|
else if ui.show_admin { AppView::Admin }
|
||||||
else if ui.show_add_logic { AppView::AddLogic }
|
else if ui.show_add_logic { AppView::AddLogic }
|
||||||
else if ui.show_add_table { AppView::AddTable }
|
else if ui.show_add_table { AppView::AddTable }
|
||||||
else if ui.show_form { AppView::Form } // Remove the dynamic name part
|
else if ui.show_form { AppView::Form }
|
||||||
else { AppView::Scratch }
|
else { AppView::Scratch }
|
||||||
};
|
};
|
||||||
buffer_state.update_history(current_view);
|
buffer_state.update_history(current_view);
|
||||||
@@ -158,7 +197,6 @@ impl EventHandler {
|
|||||||
return Ok(EventOutcome::Ok(message));
|
return Ok(EventOutcome::Ok(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if !matches!(current_mode, AppMode::Edit | AppMode::Command) {
|
if !matches!(current_mode, AppMode::Edit | AppMode::Command) {
|
||||||
if let Some(action) = config.get_action_for_key_in_mode(
|
if let Some(action) = config.get_action_for_key_in_mode(
|
||||||
&config.keybindings.global, key_code, modifiers
|
&config.keybindings.global, key_code, modifiers
|
||||||
@@ -174,13 +212,8 @@ impl EventHandler {
|
|||||||
return Ok(EventOutcome::Ok("Switched to previous buffer".to_string()));
|
return Ok(EventOutcome::Ok("Switched to previous buffer".to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//"close_buffer" => {
|
|
||||||
// let message = buffer_state.close_buffer_with_intro_fallback();
|
|
||||||
// return Ok(EventOutcome::Ok(message));
|
|
||||||
//}
|
|
||||||
"close_buffer" => {
|
"close_buffer" => {
|
||||||
// TODO: Replace with actual table name from server response
|
let current_table_name = Some("2025_customer");
|
||||||
let current_table_name = Some("2025_customer"); // Your hardcoded table name
|
|
||||||
let message = buffer_state.close_buffer_with_intro_fallback(current_table_name);
|
let message = buffer_state.close_buffer_with_intro_fallback(current_table_name);
|
||||||
return Ok(EventOutcome::Ok(message));
|
return Ok(EventOutcome::Ok(message));
|
||||||
}
|
}
|
||||||
@@ -191,7 +224,6 @@ impl EventHandler {
|
|||||||
|
|
||||||
match current_mode {
|
match current_mode {
|
||||||
AppMode::General => {
|
AppMode::General => {
|
||||||
// Prioritize Admin Panel navigation if it's visible
|
|
||||||
if app_state.ui.show_admin
|
if app_state.ui.show_admin
|
||||||
&& auth_state.role.as_deref() == Some("admin") {
|
&& auth_state.role.as_deref() == Some("admin") {
|
||||||
if admin_nav::handle_admin_navigation(
|
if admin_nav::handle_admin_navigation(
|
||||||
@@ -205,7 +237,7 @@ impl EventHandler {
|
|||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --- Add Logic Page Navigation ---
|
|
||||||
if app_state.ui.show_add_logic {
|
if app_state.ui.show_add_logic {
|
||||||
let client_clone = grpc_client.clone();
|
let client_clone = grpc_client.clone();
|
||||||
let sender_clone = self.save_logic_result_sender.clone();
|
let sender_clone = self.save_logic_result_sender.clone();
|
||||||
@@ -225,7 +257,6 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Add Table Page Navigation ---
|
|
||||||
if app_state.ui.show_add_table {
|
if app_state.ui.show_add_table {
|
||||||
let client_clone = grpc_client.clone();
|
let client_clone = grpc_client.clone();
|
||||||
let sender_clone = self.save_table_result_sender.clone();
|
let sender_clone = self.save_table_result_sender.clone();
|
||||||
@@ -238,7 +269,6 @@ impl EventHandler {
|
|||||||
client_clone,
|
client_clone,
|
||||||
sender_clone,
|
sender_clone,
|
||||||
&mut self.command_message,
|
&mut self.command_message,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
@@ -296,7 +326,7 @@ impl EventHandler {
|
|||||||
UiContext::Dialog => {
|
UiContext::Dialog => {
|
||||||
"Internal error: Unexpected dialog state".to_string()
|
"Internal error: Unexpected dialog state".to_string()
|
||||||
}
|
}
|
||||||
}; // Semicolon added here
|
};
|
||||||
return Ok(EventOutcome::Ok(message));
|
return Ok(EventOutcome::Ok(message));
|
||||||
}
|
}
|
||||||
other => return other,
|
other => return other,
|
||||||
@@ -304,7 +334,6 @@ impl EventHandler {
|
|||||||
},
|
},
|
||||||
|
|
||||||
AppMode::ReadOnly => {
|
AppMode::ReadOnly => {
|
||||||
// Check for Linewise highlight first
|
|
||||||
if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise")
|
if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise")
|
||||||
&& ModeManager::can_enter_highlight_mode(current_mode)
|
&& ModeManager::can_enter_highlight_mode(current_mode)
|
||||||
{
|
{
|
||||||
@@ -315,7 +344,6 @@ impl EventHandler {
|
|||||||
self.command_message = "-- LINE HIGHLIGHT --".to_string();
|
self.command_message = "-- LINE HIGHLIGHT --".to_string();
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
// Check for Character-wise highlight
|
|
||||||
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode")
|
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode")
|
||||||
&& ModeManager::can_enter_highlight_mode(current_mode)
|
&& ModeManager::can_enter_highlight_mode(current_mode)
|
||||||
{
|
{
|
||||||
@@ -330,7 +358,6 @@ impl EventHandler {
|
|||||||
self.command_message = "-- HIGHLIGHT --".to_string();
|
self.command_message = "-- HIGHLIGHT --".to_string();
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
// Check for entering edit mode (before cursor)
|
|
||||||
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before")
|
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before")
|
||||||
&& ModeManager::can_enter_edit_mode(current_mode) {
|
&& ModeManager::can_enter_edit_mode(current_mode) {
|
||||||
self.is_edit_mode = true;
|
self.is_edit_mode = true;
|
||||||
@@ -339,7 +366,6 @@ impl EventHandler {
|
|||||||
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
|
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
// Check for entering edit mode (after cursor)
|
|
||||||
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
|
else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
|
||||||
&& ModeManager::can_enter_edit_mode(current_mode) {
|
&& ModeManager::can_enter_edit_mode(current_mode) {
|
||||||
let current_input = if app_state.ui.show_login || app_state.ui.show_register{
|
let current_input = if app_state.ui.show_login || app_state.ui.show_register{
|
||||||
@@ -369,7 +395,6 @@ impl EventHandler {
|
|||||||
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
|
terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
// Check for entering command mode
|
|
||||||
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_command_mode")
|
else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_command_mode")
|
||||||
&& ModeManager::can_enter_command_mode(current_mode) {
|
&& ModeManager::can_enter_command_mode(current_mode) {
|
||||||
self.command_mode = true;
|
self.command_mode = true;
|
||||||
@@ -378,7 +403,6 @@ impl EventHandler {
|
|||||||
return Ok(EventOutcome::Ok(String::new()));
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for common actions (save, quit, etc.) only if no mode change happened
|
|
||||||
if let Some(action) = config.get_common_action(key_code, modifiers) {
|
if let Some(action) = config.get_common_action(key_code, modifiers) {
|
||||||
match action {
|
match action {
|
||||||
"save" | "force_quit" | "save_and_quit" | "revert" => {
|
"save" | "force_quit" | "save_and_quit" | "revert" => {
|
||||||
@@ -400,7 +424,6 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no mode change or specific common action handled, delegate to read_only handler
|
|
||||||
let (_should_exit, message) = read_only::handle_read_only_event(
|
let (_should_exit, message) = read_only::handle_read_only_event(
|
||||||
app_state,
|
app_state,
|
||||||
key,
|
key,
|
||||||
@@ -418,22 +441,17 @@ impl EventHandler {
|
|||||||
&mut self.edit_mode_cooldown,
|
&mut self.edit_mode_cooldown,
|
||||||
&mut self.ideal_cursor_column,
|
&mut self.ideal_cursor_column,
|
||||||
).await?;
|
).await?;
|
||||||
// Note: handle_read_only_event should ignore mode entry keys internally now
|
|
||||||
return Ok(EventOutcome::Ok(message));
|
return Ok(EventOutcome::Ok(message));
|
||||||
}, // End AppMode::ReadOnly
|
},
|
||||||
|
|
||||||
AppMode::Highlight => {
|
AppMode::Highlight => {
|
||||||
// --- Handle Highlight Mode Specific Keys ---
|
|
||||||
// 1. Check for Exit first
|
|
||||||
if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") {
|
if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") {
|
||||||
self.highlight_state = HighlightState::Off;
|
self.highlight_state = HighlightState::Off;
|
||||||
self.command_message = "Exited highlight mode".to_string();
|
self.command_message = "Exited highlight mode".to_string();
|
||||||
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
// 2. Check for Switch to Linewise
|
|
||||||
else if config.get_highlight_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") {
|
else if config.get_highlight_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") {
|
||||||
// Only switch if currently characterwise
|
|
||||||
if let HighlightState::Characterwise { anchor } = self.highlight_state {
|
if let HighlightState::Characterwise { anchor } = self.highlight_state {
|
||||||
self.highlight_state = HighlightState::Linewise { anchor_line: anchor.0 };
|
self.highlight_state = HighlightState::Linewise { anchor_line: anchor.0 };
|
||||||
self.command_message = "-- LINE HIGHLIGHT --".to_string();
|
self.command_message = "-- LINE HIGHLIGHT --".to_string();
|
||||||
@@ -460,14 +478,9 @@ impl EventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AppMode::Edit => {
|
AppMode::Edit => {
|
||||||
// First, check for common actions (save, revert, etc.) that apply in Edit mode
|
|
||||||
// These might take precedence or have different behavior than the edit handler
|
|
||||||
if let Some(action) = config.get_common_action(key_code, modifiers) {
|
if let Some(action) = config.get_common_action(key_code, modifiers) {
|
||||||
// Handle common actions like save, revert, force_quit, save_and_quit
|
|
||||||
// Ensure these actions return EventOutcome directly if they might exit the app
|
|
||||||
match action {
|
match action {
|
||||||
"save" | "force_quit" | "save_and_quit" | "revert" => {
|
"save" | "force_quit" | "save_and_quit" | "revert" => {
|
||||||
// This call likely returns EventOutcome, handle it directly
|
|
||||||
return common_mode::handle_core_action(
|
return common_mode::handle_core_action(
|
||||||
action,
|
action,
|
||||||
form_state,
|
form_state,
|
||||||
@@ -482,16 +495,10 @@ impl EventHandler {
|
|||||||
total_count,
|
total_count,
|
||||||
).await;
|
).await;
|
||||||
},
|
},
|
||||||
// Handle other common actions if necessary
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
// If a common action was handled but didn't return/exit,
|
|
||||||
// we might want to stop further processing for this key event.
|
|
||||||
// Depending on the action, you might return Ok(EventOutcome::Ok(...)) here.
|
|
||||||
// For now, assume common actions either exit or don't prevent further processing.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no common action took precedence, delegate to the edit-specific handler
|
|
||||||
let edit_result = edit::handle_edit_event(
|
let edit_result = edit::handle_edit_event(
|
||||||
key,
|
key,
|
||||||
config,
|
config,
|
||||||
@@ -508,7 +515,6 @@ impl EventHandler {
|
|||||||
|
|
||||||
match edit_result {
|
match edit_result {
|
||||||
Ok(edit::EditEventOutcome::ExitEditMode) => {
|
Ok(edit::EditEventOutcome::ExitEditMode) => {
|
||||||
// The edit handler signaled to exit the mode
|
|
||||||
self.is_edit_mode = false;
|
self.is_edit_mode = false;
|
||||||
self.edit_mode_cooldown = true;
|
self.edit_mode_cooldown = true;
|
||||||
let has_changes = if app_state.ui.show_login { login_state.has_unsaved_changes() }
|
let has_changes = if app_state.ui.show_login { login_state.has_unsaved_changes() }
|
||||||
@@ -520,7 +526,6 @@ impl EventHandler {
|
|||||||
"Read-only mode".to_string()
|
"Read-only mode".to_string()
|
||||||
};
|
};
|
||||||
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
|
||||||
// Adjust cursor position if needed
|
|
||||||
let current_input = if app_state.ui.show_login { login_state.get_current_input() }
|
let current_input = if app_state.ui.show_login { login_state.get_current_input() }
|
||||||
else if app_state.ui.show_register { register_state.get_current_input() }
|
else if app_state.ui.show_register { register_state.get_current_input() }
|
||||||
else { form_state.get_current_input() };
|
else { form_state.get_current_input() };
|
||||||
@@ -536,48 +541,100 @@ impl EventHandler {
|
|||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
Ok(edit::EditEventOutcome::Message(msg)) => {
|
Ok(edit::EditEventOutcome::Message(msg)) => {
|
||||||
// Stay in edit mode, update message if not empty
|
|
||||||
if !msg.is_empty() {
|
if !msg.is_empty() {
|
||||||
self.command_message = msg;
|
self.command_message = msg;
|
||||||
}
|
}
|
||||||
self.key_sequence_tracker.reset(); // Reset sequence tracker on successful edit action
|
self.key_sequence_tracker.reset();
|
||||||
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Handle error from the edit handler
|
|
||||||
return Err(e.into());
|
return Err(e.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, // End AppMode::Edit
|
},
|
||||||
|
|
||||||
AppMode::Command => {
|
AppMode::Command => {
|
||||||
let outcome = command_mode::handle_command_event(
|
// Handle immediate command mode actions
|
||||||
key,
|
if config.is_exit_command_mode(key_code, modifiers) {
|
||||||
config,
|
self.command_input.clear();
|
||||||
app_state,
|
self.command_message.clear();
|
||||||
login_state,
|
|
||||||
register_state,
|
|
||||||
form_state,
|
|
||||||
&mut self.command_input,
|
|
||||||
&mut self.command_message,
|
|
||||||
grpc_client,
|
|
||||||
command_handler,
|
|
||||||
terminal,
|
|
||||||
current_position,
|
|
||||||
total_count,
|
|
||||||
).await?;
|
|
||||||
|
|
||||||
if let EventOutcome::Ok(msg) = &outcome {
|
|
||||||
if msg == "Exited command mode" {
|
|
||||||
self.command_mode = false;
|
self.command_mode = false;
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
return Ok(EventOutcome::Ok("Exited command mode".to_string()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if config.is_command_execute(key_code, modifiers) {
|
||||||
|
let outcome = command_mode::handle_command_event(
|
||||||
|
key, config, app_state, login_state, register_state, form_state,
|
||||||
|
&mut self.command_input, &mut self.command_message,
|
||||||
|
grpc_client, command_handler, terminal, current_position, total_count,
|
||||||
|
).await?;
|
||||||
|
self.command_mode = false;
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
return Ok(outcome);
|
return Ok(outcome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle backspace
|
||||||
|
if key_code == KeyCode::Backspace {
|
||||||
|
self.command_input.pop();
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle character input and sequences
|
||||||
|
if let KeyCode::Char(c) = key_code {
|
||||||
|
if c == 'f' {
|
||||||
|
self.key_sequence_tracker.add_key(key_code);
|
||||||
|
let sequence = self.key_sequence_tracker.get_sequence();
|
||||||
|
|
||||||
|
if config.matches_key_sequence_generalized(&sequence) == Some("find_file_palette_toggle") {
|
||||||
|
if app_state.ui.show_form || app_state.ui.show_intro {
|
||||||
|
self.find_file_palette_active = true;
|
||||||
|
self.find_file_input.clear();
|
||||||
|
self.find_file_selected_index = if self.find_file_options.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(0)
|
||||||
|
};
|
||||||
|
self.command_mode = false;
|
||||||
|
self.command_input.clear();
|
||||||
|
self.command_message = "Find File:".to_string();
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
return Ok(EventOutcome::Ok("Find File palette activated".to_string()));
|
||||||
|
} else {
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
self.command_input.push('f');
|
||||||
|
self.command_input.push('f');
|
||||||
|
self.command_message = "Find File not available in this view.".to_string();
|
||||||
|
return Ok(EventOutcome::Ok(self.command_message.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.is_key_sequence_prefix(&sequence) {
|
||||||
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c != 'f' && !self.key_sequence_tracker.current_sequence.is_empty() {
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.command_input.push(c);
|
||||||
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset tracker for other keys
|
||||||
|
self.key_sequence_tracker.reset();
|
||||||
|
return Ok(EventOutcome::Ok(String::new()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.edit_mode_cooldown = false;
|
self.edit_mode_cooldown = false;
|
||||||
Ok(EventOutcome::Ok(self.command_message.clone()))
|
Ok(EventOutcome::Ok(self.command_message.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_processed_command(&self, command: &str) -> bool {
|
||||||
|
matches!(command, "w" | "q" | "q!" | "wq" | "r")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ impl ModeManager {
|
|||||||
event_handler: &EventHandler,
|
event_handler: &EventHandler,
|
||||||
admin_state: &AdminState,
|
admin_state: &AdminState,
|
||||||
) -> AppMode {
|
) -> AppMode {
|
||||||
|
if event_handler.find_file_palette_active {
|
||||||
|
return AppMode::General;
|
||||||
|
}
|
||||||
|
|
||||||
if event_handler.command_mode {
|
if event_handler.command_mode {
|
||||||
return AppMode::Command;
|
return AppMode::Command;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
use crate::components::{
|
use crate::components::{
|
||||||
render_background,
|
render_background,
|
||||||
render_buffer_list,
|
render_buffer_list,
|
||||||
render_command_line,
|
render_command_line, // For the normal command line
|
||||||
render_status_line,
|
render_status_line,
|
||||||
intro::intro::render_intro,
|
intro::intro::render_intro,
|
||||||
handlers::sidebar::{self, calculate_sidebar_layout},
|
handlers::sidebar::{self, calculate_sidebar_layout},
|
||||||
@@ -13,18 +13,68 @@ use crate::components::{
|
|||||||
auth::{login::render_login, register::render_register},
|
auth::{login::render_login, register::render_register},
|
||||||
};
|
};
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
use ratatui::layout::{Constraint, Direction, Layout};
|
use ratatui::{
|
||||||
use ratatui::Frame;
|
layout::{Constraint, Direction, Layout, Rect}, // Added Rect
|
||||||
|
style::Style, // Added Style for render_find_file_palette
|
||||||
|
widgets::{Block, List, ListItem, Paragraph}, // Added for render_find_file_palette
|
||||||
|
Frame,
|
||||||
|
};
|
||||||
|
use crate::state::pages::canvas_state::CanvasState;
|
||||||
use crate::state::pages::form::FormState;
|
use crate::state::pages::form::FormState;
|
||||||
use crate::state::pages::auth::AuthState;
|
use crate::state::pages::auth::AuthState;
|
||||||
use crate::state::pages::auth::LoginState;
|
use crate::state::pages::auth::LoginState;
|
||||||
use crate::state::pages::auth::RegisterState;
|
use crate::state::pages::auth::RegisterState;
|
||||||
use crate::state::pages::intro::IntroState;
|
use crate::state::pages::intro::IntroState;
|
||||||
use crate::state::app::buffer::BufferState;
|
use crate::state::app::buffer::BufferState;
|
||||||
use crate::state::app::state::AppState;
|
use crate::state::app::state::AppState; // AppState is needed for app_state.ui checks
|
||||||
use crate::state::pages::admin::AdminState;
|
use crate::state::pages::admin::AdminState;
|
||||||
use crate::state::app::highlight::HighlightState;
|
use crate::state::app::highlight::HighlightState;
|
||||||
|
|
||||||
|
// ++ New function to render the Find File Palette ++
|
||||||
|
fn render_find_file_palette(
|
||||||
|
f: &mut Frame,
|
||||||
|
area: Rect,
|
||||||
|
theme: &Theme,
|
||||||
|
palette_input: &str, // Specific input for the palette
|
||||||
|
options: &[String],
|
||||||
|
selected_index: Option<usize>,
|
||||||
|
) {
|
||||||
|
let chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints([
|
||||||
|
Constraint::Length(1), // For palette input line
|
||||||
|
Constraint::Min(0), // For options list
|
||||||
|
])
|
||||||
|
.split(area);
|
||||||
|
|
||||||
|
// Draw the palette input line
|
||||||
|
let prompt_text = format!("Find File: {}", palette_input); // Using palette_input
|
||||||
|
let input_paragraph = Paragraph::new(prompt_text)
|
||||||
|
.style(Style::default().fg(theme.accent).bg(theme.bg));
|
||||||
|
f.render_widget(input_paragraph, chunks[0]);
|
||||||
|
|
||||||
|
// Draw the list of options
|
||||||
|
if !options.is_empty() && chunks.len() > 1 {
|
||||||
|
let list_items: Vec<ListItem> = options
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, opt_str)| {
|
||||||
|
let style = if Some(idx) == selected_index {
|
||||||
|
Style::default().fg(theme.bg).bg(theme.accent) // Highlight selected
|
||||||
|
} else {
|
||||||
|
Style::default().fg(theme.fg).bg(theme.bg)
|
||||||
|
};
|
||||||
|
ListItem::new(opt_str.as_str()).style(style)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let options_list = List::new(list_items)
|
||||||
|
.block(Block::default().style(Style::default().bg(theme.bg)));
|
||||||
|
f.render_widget(options_list, chunks[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn render_ui(
|
pub fn render_ui(
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
form_state: &mut FormState,
|
form_state: &mut FormState,
|
||||||
@@ -35,175 +85,169 @@ pub fn render_ui(
|
|||||||
admin_state: &mut AdminState,
|
admin_state: &mut AdminState,
|
||||||
buffer_state: &BufferState,
|
buffer_state: &BufferState,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
is_edit_mode: bool,
|
// These come from EventHandler
|
||||||
|
is_event_handler_edit_mode: bool,
|
||||||
highlight_state: &HighlightState,
|
highlight_state: &HighlightState,
|
||||||
|
event_handler_command_input: &str, // For normal command line
|
||||||
|
event_handler_command_mode_active: bool, // Normal command line active?
|
||||||
|
event_handler_command_message: &str,
|
||||||
|
// ++ Find File Palette specific state from EventHandler ++
|
||||||
|
find_file_palette_active: bool,
|
||||||
|
find_file_options: &[String],
|
||||||
|
find_file_selected_index: Option<usize>,
|
||||||
|
find_file_palette_input: &str, // Input for the palette
|
||||||
|
// General app state
|
||||||
total_count: u64,
|
total_count: u64,
|
||||||
current_position: u64,
|
current_position: u64,
|
||||||
current_dir: &str,
|
current_dir: &str,
|
||||||
command_input: &str,
|
|
||||||
command_mode: bool,
|
|
||||||
command_message: &str,
|
|
||||||
current_fps: f64,
|
current_fps: f64,
|
||||||
app_state: &AppState,
|
app_state: &AppState, // Contains app_state.ui for layout decisions
|
||||||
) {
|
) {
|
||||||
render_background(f, f.area(), theme);
|
render_background(f, f.area(), theme);
|
||||||
|
|
||||||
// Adjust layout based on whether buffer list is shown
|
// Determine the height needed for the bottom bar (status + command/palette)
|
||||||
let constraints = if app_state.ui.show_buffer_list {
|
let mut bottom_area_constraints: Vec<Constraint> = vec![Constraint::Length(1)]; // Status line
|
||||||
vec![
|
|
||||||
Constraint::Length(1), // Buffer list
|
let command_palette_area_height = if find_file_palette_active {
|
||||||
Constraint::Min(1), // Main content
|
// Height for palette: 1 for input + number of visible options
|
||||||
Constraint::Length(1), // Status line
|
let max_visible_options = 7; // Example, can be adjusted
|
||||||
Constraint::Length(1), // Command line
|
1 + find_file_options.iter().take(max_visible_options).count().min(max_visible_options) as u16
|
||||||
]
|
} else if event_handler_command_mode_active {
|
||||||
|
1 // Height for normal command line
|
||||||
} else {
|
} else {
|
||||||
vec![
|
0 // No command line or palette
|
||||||
Constraint::Min(1), // Main content
|
|
||||||
Constraint::Length(1), // Status line (no buffer list)
|
|
||||||
Constraint::Length(1), // Command line
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let root = Layout::default()
|
if command_palette_area_height > 0 {
|
||||||
.direction(Direction::Vertical)
|
bottom_area_constraints.push(Constraint::Length(command_palette_area_height));
|
||||||
.constraints(constraints)
|
|
||||||
.split(f.area());
|
|
||||||
|
|
||||||
let mut buffer_list_area = None;
|
|
||||||
let main_content_area;
|
|
||||||
let status_line_area;
|
|
||||||
let command_line_area;
|
|
||||||
|
|
||||||
// Assign areas based on layout
|
|
||||||
if app_state.ui.show_buffer_list {
|
|
||||||
buffer_list_area = Some(root[0]);
|
|
||||||
main_content_area = root[1];
|
|
||||||
status_line_area = root[2];
|
|
||||||
command_line_area = root[3];
|
|
||||||
} else {
|
|
||||||
main_content_area = root[0];
|
|
||||||
status_line_area = root[1];
|
|
||||||
command_line_area = root[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Main layout: Buffer List (optional), Main Content, Bottom Area (Status + Command/Palette)
|
||||||
|
let mut main_layout_constraints = vec![Constraint::Min(1)]; // Main Content
|
||||||
|
if app_state.ui.show_buffer_list {
|
||||||
|
main_layout_constraints.insert(0, Constraint::Length(1)); // Buffer List
|
||||||
|
}
|
||||||
|
main_layout_constraints.extend(bottom_area_constraints); // Add status and command/palette
|
||||||
|
|
||||||
|
let root_chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints(main_layout_constraints)
|
||||||
|
.split(f.area());
|
||||||
|
|
||||||
|
// Assign areas
|
||||||
|
let mut chunk_idx = 0;
|
||||||
|
let buffer_list_area = if app_state.ui.show_buffer_list {
|
||||||
|
chunk_idx += 1;
|
||||||
|
Some(root_chunks[0])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let main_content_area = root_chunks[chunk_idx];
|
||||||
|
chunk_idx += 1;
|
||||||
|
|
||||||
|
let status_line_area = root_chunks[chunk_idx];
|
||||||
|
chunk_idx += 1;
|
||||||
|
|
||||||
|
let mut command_render_area = None; // For normal command line or palette
|
||||||
|
if command_palette_area_height > 0 {
|
||||||
|
if root_chunks.len() > chunk_idx {
|
||||||
|
command_render_area = Some(root_chunks[chunk_idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Render main content views ---
|
||||||
if app_state.ui.show_intro {
|
if app_state.ui.show_intro {
|
||||||
render_intro(f, intro_state, main_content_area, theme);
|
render_intro(f, intro_state, main_content_area, theme);
|
||||||
} else if app_state.ui.show_register {
|
} else if app_state.ui.show_register {
|
||||||
render_register(
|
render_register(
|
||||||
f,
|
f, main_content_area, theme, register_state, app_state,
|
||||||
main_content_area,
|
register_state.current_field() < 4, // Example condition
|
||||||
theme,
|
|
||||||
register_state,
|
|
||||||
app_state,
|
|
||||||
register_state.current_field < 4,
|
|
||||||
highlight_state,
|
highlight_state,
|
||||||
);
|
);
|
||||||
} else if app_state.ui.show_add_table {
|
} else if app_state.ui.show_add_table {
|
||||||
render_add_table(
|
render_add_table(
|
||||||
f,
|
f, main_content_area, theme, app_state, &mut admin_state.add_table_state,
|
||||||
main_content_area,
|
is_event_handler_edit_mode, // Or specific logic for add_table
|
||||||
theme,
|
|
||||||
app_state,
|
|
||||||
&mut admin_state.add_table_state,
|
|
||||||
login_state.current_field < 3,
|
|
||||||
highlight_state,
|
highlight_state,
|
||||||
);
|
);
|
||||||
} else if app_state.ui.show_add_logic {
|
} else if app_state.ui.show_add_logic {
|
||||||
render_add_logic(
|
render_add_logic(
|
||||||
f,
|
f, main_content_area, theme, app_state, &mut admin_state.add_logic_state,
|
||||||
main_content_area,
|
is_event_handler_edit_mode, highlight_state,
|
||||||
theme,
|
|
||||||
app_state,
|
|
||||||
&mut admin_state.add_logic_state,
|
|
||||||
is_edit_mode, // Pass the general edit mode status
|
|
||||||
highlight_state,
|
|
||||||
);
|
);
|
||||||
} else if app_state.ui.show_login {
|
} else if app_state.ui.show_login {
|
||||||
render_login(
|
render_login(
|
||||||
f,
|
f, main_content_area, theme, login_state, app_state,
|
||||||
main_content_area,
|
login_state.current_field() < 2, // Example condition
|
||||||
theme,
|
|
||||||
login_state,
|
|
||||||
app_state,
|
|
||||||
login_state.current_field < 2,
|
|
||||||
highlight_state,
|
highlight_state,
|
||||||
);
|
);
|
||||||
} else if app_state.ui.show_admin {
|
} else if app_state.ui.show_admin {
|
||||||
crate::components::admin::admin_panel::render_admin_panel(
|
crate::components::admin::admin_panel::render_admin_panel(
|
||||||
f,
|
f, app_state, auth_state, admin_state, main_content_area, theme,
|
||||||
app_state,
|
&app_state.profile_tree, &app_state.selected_profile,
|
||||||
auth_state,
|
|
||||||
admin_state,
|
|
||||||
main_content_area,
|
|
||||||
theme,
|
|
||||||
&app_state.profile_tree,
|
|
||||||
&app_state.selected_profile,
|
|
||||||
);
|
);
|
||||||
} else if app_state.ui.show_form {
|
} else if app_state.ui.show_form {
|
||||||
let (sidebar_area, form_area) = calculate_sidebar_layout(
|
let (sidebar_area, form_actual_area) = calculate_sidebar_layout(
|
||||||
app_state.ui.show_sidebar,
|
app_state.ui.show_sidebar, main_content_area
|
||||||
main_content_area
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(sidebar_rect) = sidebar_area {
|
if let Some(sidebar_rect) = sidebar_area {
|
||||||
sidebar::render_sidebar(
|
sidebar::render_sidebar(
|
||||||
f,
|
f, sidebar_rect, theme, &app_state.profile_tree, &app_state.selected_profile
|
||||||
sidebar_rect,
|
|
||||||
theme,
|
|
||||||
&app_state.profile_tree,
|
|
||||||
&app_state.selected_profile
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
let available_width = form_actual_area.width;
|
||||||
// This change makes the form stay stationary when toggling sidebar
|
let form_render_area = if available_width >= 80 {
|
||||||
let available_width = form_area.width;
|
Layout::default().direction(Direction::Horizontal)
|
||||||
let form_constraint = if available_width >= 80 {
|
.constraints([Constraint::Min(0), Constraint::Length(80), Constraint::Min(0)])
|
||||||
// Use main_content_area for centering when enough space
|
.split(main_content_area)[1] // Center in main_content_area if sidebar is off
|
||||||
Layout::default()
|
|
||||||
.direction(Direction::Horizontal)
|
|
||||||
.constraints([
|
|
||||||
Constraint::Min(0),
|
|
||||||
Constraint::Length(80),
|
|
||||||
Constraint::Min(0),
|
|
||||||
])
|
|
||||||
.split(main_content_area)[1]
|
|
||||||
} else {
|
} else {
|
||||||
// Use form_area (post sidebar) when limited space
|
Layout::default().direction(Direction::Horizontal)
|
||||||
Layout::default()
|
.constraints([Constraint::Min(0), Constraint::Length(available_width.min(80)), Constraint::Min(0)])
|
||||||
.direction(Direction::Horizontal)
|
.split(form_actual_area)[1] // Use form_actual_area if sidebar is on
|
||||||
.constraints([
|
|
||||||
Constraint::Min(0),
|
|
||||||
Constraint::Length(80.min(available_width)),
|
|
||||||
Constraint::Min(0),
|
|
||||||
])
|
|
||||||
.split(form_area)[1]
|
|
||||||
};
|
};
|
||||||
|
let fields_vec: Vec<&str> = form_state.fields.iter().map(AsRef::as_ref).collect();
|
||||||
// Convert fields to &[&str] and values to &[&String]
|
let values_vec: Vec<&String> = form_state.values.iter().collect();
|
||||||
let fields: Vec<&str> = form_state.fields.iter().map(|s| s.as_str()).collect();
|
|
||||||
let values: Vec<&String> = form_state.values.iter().collect();
|
|
||||||
|
|
||||||
render_form(
|
render_form(
|
||||||
f,
|
f, form_render_area, form_state, &fields_vec, &form_state.current_field,
|
||||||
form_constraint,
|
&values_vec, theme, is_event_handler_edit_mode, highlight_state,
|
||||||
form_state,
|
total_count, current_position,
|
||||||
&fields,
|
|
||||||
&form_state.current_field,
|
|
||||||
&values,
|
|
||||||
theme,
|
|
||||||
is_edit_mode,
|
|
||||||
highlight_state,
|
|
||||||
total_count,
|
|
||||||
current_position,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// --- End Render main content views ---
|
||||||
|
|
||||||
// Render buffer list if enabled and area is available
|
// Render buffer list if enabled
|
||||||
if let Some(area) = buffer_list_area {
|
if let Some(area) = buffer_list_area {
|
||||||
if app_state.ui.show_buffer_list {
|
if app_state.ui.show_buffer_list {
|
||||||
render_buffer_list(f, area, theme, buffer_state, app_state);
|
render_buffer_list(f, area, theme, buffer_state, app_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render_status_line(f, status_line_area, current_dir, theme, is_edit_mode, current_fps);
|
|
||||||
render_command_line(f, command_line_area, command_input, command_mode, theme, command_message);
|
// Render status line
|
||||||
|
render_status_line(f, status_line_area, current_dir, theme, is_event_handler_edit_mode, current_fps);
|
||||||
|
|
||||||
|
// Render Find File Palette OR Normal Command Line
|
||||||
|
if let Some(area) = command_render_area {
|
||||||
|
if find_file_palette_active {
|
||||||
|
render_find_file_palette(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
theme,
|
||||||
|
find_file_palette_input, // Pass palette-specific input
|
||||||
|
find_file_options,
|
||||||
|
find_file_selected_index,
|
||||||
|
);
|
||||||
|
} else if event_handler_command_mode_active {
|
||||||
|
// Normal command line
|
||||||
|
render_command_line(
|
||||||
|
f,
|
||||||
|
area,
|
||||||
|
event_handler_command_input,
|
||||||
|
true, // It's active
|
||||||
|
theme,
|
||||||
|
event_handler_command_message,
|
||||||
|
// No palette-specific args for normal command line
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,14 +209,20 @@ pub async fn run_ui() -> Result<()> {
|
|||||||
&mut admin_state,
|
&mut admin_state,
|
||||||
&buffer_state,
|
&buffer_state,
|
||||||
&theme,
|
&theme,
|
||||||
event_handler.is_edit_mode,
|
event_handler.is_edit_mode, // is_event_handler_edit_mode
|
||||||
&event_handler.highlight_state,
|
&event_handler.highlight_state,
|
||||||
|
&event_handler.command_input, // event_handler_command_input
|
||||||
|
event_handler.command_mode, // event_handler_command_mode_active
|
||||||
|
&event_handler.command_message, // event_handler_command_message
|
||||||
|
// Find File Palette specific state
|
||||||
|
event_handler.find_file_palette_active,
|
||||||
|
&event_handler.find_file_options,
|
||||||
|
event_handler.find_file_selected_index,
|
||||||
|
&event_handler.find_file_input,
|
||||||
|
// General app state
|
||||||
app_state.total_count,
|
app_state.total_count,
|
||||||
app_state.current_position,
|
app_state.current_position,
|
||||||
&app_state.current_dir,
|
&app_state.current_dir,
|
||||||
&event_handler.command_input,
|
|
||||||
event_handler.command_mode,
|
|
||||||
&event_handler.command_message,
|
|
||||||
current_fps,
|
current_fps,
|
||||||
&app_state,
|
&app_state,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user