open menu in command mode now implemented
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
use crate::components::{
|
||||
render_background,
|
||||
render_buffer_list,
|
||||
render_command_line,
|
||||
render_command_line, // For the normal command line
|
||||
render_status_line,
|
||||
intro::intro::render_intro,
|
||||
handlers::sidebar::{self, calculate_sidebar_layout},
|
||||
@@ -13,18 +13,68 @@ use crate::components::{
|
||||
auth::{login::render_login, register::render_register},
|
||||
};
|
||||
use crate::config::colors::themes::Theme;
|
||||
use ratatui::layout::{Constraint, Direction, Layout};
|
||||
use ratatui::Frame;
|
||||
use ratatui::{
|
||||
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::auth::AuthState;
|
||||
use crate::state::pages::auth::LoginState;
|
||||
use crate::state::pages::auth::RegisterState;
|
||||
use crate::state::pages::intro::IntroState;
|
||||
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::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(
|
||||
f: &mut Frame,
|
||||
form_state: &mut FormState,
|
||||
@@ -35,175 +85,169 @@ pub fn render_ui(
|
||||
admin_state: &mut AdminState,
|
||||
buffer_state: &BufferState,
|
||||
theme: &Theme,
|
||||
is_edit_mode: bool,
|
||||
// These come from EventHandler
|
||||
is_event_handler_edit_mode: bool,
|
||||
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,
|
||||
current_position: u64,
|
||||
current_dir: &str,
|
||||
command_input: &str,
|
||||
command_mode: bool,
|
||||
command_message: &str,
|
||||
current_fps: f64,
|
||||
app_state: &AppState,
|
||||
app_state: &AppState, // Contains app_state.ui for layout decisions
|
||||
) {
|
||||
render_background(f, f.area(), theme);
|
||||
|
||||
// Adjust layout based on whether buffer list is shown
|
||||
let constraints = if app_state.ui.show_buffer_list {
|
||||
vec![
|
||||
Constraint::Length(1), // Buffer list
|
||||
Constraint::Min(1), // Main content
|
||||
Constraint::Length(1), // Status line
|
||||
Constraint::Length(1), // Command line
|
||||
]
|
||||
// Determine the height needed for the bottom bar (status + command/palette)
|
||||
let mut bottom_area_constraints: Vec<Constraint> = vec![Constraint::Length(1)]; // Status line
|
||||
|
||||
let command_palette_area_height = if find_file_palette_active {
|
||||
// Height for palette: 1 for input + number of visible options
|
||||
let max_visible_options = 7; // Example, can be adjusted
|
||||
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 {
|
||||
vec![
|
||||
Constraint::Min(1), // Main content
|
||||
Constraint::Length(1), // Status line (no buffer list)
|
||||
Constraint::Length(1), // Command line
|
||||
]
|
||||
0 // No command line or palette
|
||||
};
|
||||
|
||||
let root = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.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];
|
||||
if command_palette_area_height > 0 {
|
||||
bottom_area_constraints.push(Constraint::Length(command_palette_area_height));
|
||||
}
|
||||
|
||||
// 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 {
|
||||
render_intro(f, intro_state, main_content_area, theme);
|
||||
} else if app_state.ui.show_register {
|
||||
render_register(
|
||||
f,
|
||||
main_content_area,
|
||||
theme,
|
||||
register_state,
|
||||
app_state,
|
||||
register_state.current_field < 4,
|
||||
f, main_content_area, theme, register_state, app_state,
|
||||
register_state.current_field() < 4, // Example condition
|
||||
highlight_state,
|
||||
);
|
||||
} else if app_state.ui.show_add_table {
|
||||
render_add_table(
|
||||
f,
|
||||
main_content_area,
|
||||
theme,
|
||||
app_state,
|
||||
&mut admin_state.add_table_state,
|
||||
login_state.current_field < 3,
|
||||
f, main_content_area, theme, app_state, &mut admin_state.add_table_state,
|
||||
is_event_handler_edit_mode, // Or specific logic for add_table
|
||||
highlight_state,
|
||||
);
|
||||
} else if app_state.ui.show_add_logic {
|
||||
render_add_logic(
|
||||
f,
|
||||
main_content_area,
|
||||
theme,
|
||||
app_state,
|
||||
&mut admin_state.add_logic_state,
|
||||
is_edit_mode, // Pass the general edit mode status
|
||||
highlight_state,
|
||||
f, main_content_area, theme, app_state, &mut admin_state.add_logic_state,
|
||||
is_event_handler_edit_mode, highlight_state,
|
||||
);
|
||||
} else if app_state.ui.show_login {
|
||||
render_login(
|
||||
f,
|
||||
main_content_area,
|
||||
theme,
|
||||
login_state,
|
||||
app_state,
|
||||
login_state.current_field < 2,
|
||||
f, main_content_area, theme, login_state, app_state,
|
||||
login_state.current_field() < 2, // Example condition
|
||||
highlight_state,
|
||||
);
|
||||
} else if app_state.ui.show_admin {
|
||||
crate::components::admin::admin_panel::render_admin_panel(
|
||||
f,
|
||||
app_state,
|
||||
auth_state,
|
||||
admin_state,
|
||||
main_content_area,
|
||||
theme,
|
||||
&app_state.profile_tree,
|
||||
&app_state.selected_profile,
|
||||
f, app_state, auth_state, admin_state, main_content_area, theme,
|
||||
&app_state.profile_tree, &app_state.selected_profile,
|
||||
);
|
||||
} else if app_state.ui.show_form {
|
||||
let (sidebar_area, form_area) = calculate_sidebar_layout(
|
||||
app_state.ui.show_sidebar,
|
||||
main_content_area
|
||||
let (sidebar_area, form_actual_area) = calculate_sidebar_layout(
|
||||
app_state.ui.show_sidebar, main_content_area
|
||||
);
|
||||
|
||||
if let Some(sidebar_rect) = sidebar_area {
|
||||
sidebar::render_sidebar(
|
||||
f,
|
||||
sidebar_rect,
|
||||
theme,
|
||||
&app_state.profile_tree,
|
||||
&app_state.selected_profile
|
||||
f, sidebar_rect, theme, &app_state.profile_tree, &app_state.selected_profile
|
||||
);
|
||||
}
|
||||
|
||||
// This change makes the form stay stationary when toggling sidebar
|
||||
let available_width = form_area.width;
|
||||
let form_constraint = if available_width >= 80 {
|
||||
// Use main_content_area for centering when enough space
|
||||
Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([
|
||||
Constraint::Min(0),
|
||||
Constraint::Length(80),
|
||||
Constraint::Min(0),
|
||||
])
|
||||
.split(main_content_area)[1]
|
||||
let available_width = form_actual_area.width;
|
||||
let form_render_area = if available_width >= 80 {
|
||||
Layout::default().direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Min(0), Constraint::Length(80), Constraint::Min(0)])
|
||||
.split(main_content_area)[1] // Center in main_content_area if sidebar is off
|
||||
} else {
|
||||
// Use form_area (post sidebar) when limited space
|
||||
Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([
|
||||
Constraint::Min(0),
|
||||
Constraint::Length(80.min(available_width)),
|
||||
Constraint::Min(0),
|
||||
])
|
||||
.split(form_area)[1]
|
||||
Layout::default().direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Min(0), Constraint::Length(available_width.min(80)), Constraint::Min(0)])
|
||||
.split(form_actual_area)[1] // Use form_actual_area if sidebar is on
|
||||
};
|
||||
|
||||
// Convert fields to &[&str] and values to &[&String]
|
||||
let fields: Vec<&str> = form_state.fields.iter().map(|s| s.as_str()).collect();
|
||||
let values: Vec<&String> = form_state.values.iter().collect();
|
||||
|
||||
let fields_vec: Vec<&str> = form_state.fields.iter().map(AsRef::as_ref).collect();
|
||||
let values_vec: Vec<&String> = form_state.values.iter().collect();
|
||||
render_form(
|
||||
f,
|
||||
form_constraint,
|
||||
form_state,
|
||||
&fields,
|
||||
&form_state.current_field,
|
||||
&values,
|
||||
theme,
|
||||
is_edit_mode,
|
||||
highlight_state,
|
||||
total_count,
|
||||
current_position,
|
||||
f, form_render_area, form_state, &fields_vec, &form_state.current_field,
|
||||
&values_vec, theme, is_event_handler_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 app_state.ui.show_buffer_list {
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user