// src/ui/handlers/render.rs use crate::components::{ admin::add_logic::render_add_logic, admin::render_add_table, auth::{login::render_login, register::render_register}, common::dialog::render_dialog, common::find_file_palette, intro::intro::render_intro, render_background, render_command_line, render_status_line, }; use crate::sidebar::{calculate_sidebar_layout, render_sidebar}; use crate::buffer::render_buffer_list; use crate::search::render_search_palette; use crate::config::colors::themes::Theme; use crate::modes::general::command_navigation::NavigationState; use crate::buffer::state::BufferState; use crate::state::app::state::AppState; use crate::state::pages::admin::AdminState; use crate::state::pages::auth::AuthState; use crate::state::pages::auth::LoginState; use crate::state::pages::auth::RegisterState; use crate::state::pages::form::FormState; use crate::state::pages::intro::IntroState; use crate::components::render_form; use ratatui::{ layout::{Constraint, Direction, Layout}, Frame, }; #[allow(clippy::too_many_arguments)] pub fn render_ui( f: &mut Frame, form_state: &mut FormState, auth_state: &mut AuthState, login_state: &LoginState, register_state: &RegisterState, intro_state: &IntroState, admin_state: &mut AdminState, buffer_state: &BufferState, theme: &Theme, is_event_handler_edit_mode: bool, event_handler_command_input: &str, event_handler_command_mode_active: bool, event_handler_command_message: &str, navigation_state: &NavigationState, current_dir: &str, current_fps: f64, app_state: &AppState, ) { render_background(f, f.area(), theme); // --- START DYNAMIC LAYOUT LOGIC --- let status_line_height = 1; #[cfg(feature = "ui-debug")] { if let Some(debug_state) = &app_state.debug_state { if debug_state.is_error { status_line_height = 4; } } } // --- END DYNAMIC LAYOUT LOGIC --- const PALETTE_OPTIONS_HEIGHT_FOR_LAYOUT: u16 = 15; let mut bottom_area_constraints: Vec = vec![Constraint::Length(status_line_height)]; let command_palette_area_height = if navigation_state.active { 1 + PALETTE_OPTIONS_HEIGHT_FOR_LAYOUT } else if event_handler_command_mode_active { 1 } else { 0 }; if command_palette_area_height > 0 { bottom_area_constraints.push(Constraint::Length(command_palette_area_height)); } let mut main_layout_constraints = vec![Constraint::Min(1)]; if app_state.ui.show_buffer_list { main_layout_constraints.insert(0, Constraint::Length(1)); } main_layout_constraints.extend(bottom_area_constraints); let root_chunks = Layout::default() .direction(Direction::Vertical) .constraints(main_layout_constraints) .split(f.area()); let mut chunk_idx = 0; let buffer_list_area = if app_state.ui.show_buffer_list { let area = Some(root_chunks[chunk_idx]); chunk_idx += 1; area } 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 command_render_area = if command_palette_area_height > 0 { if root_chunks.len() > chunk_idx { Some(root_chunks[chunk_idx]) } else { None } } else { None }; 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, // Now using CanvasState trait method ); } else if app_state.ui.show_add_table { render_add_table( f, main_content_area, theme, app_state, &mut admin_state.add_table_state, is_event_handler_edit_mode, ); } 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_event_handler_edit_mode, ); } else if app_state.ui.show_login { render_login( f, main_content_area, theme, login_state, app_state, login_state.current_field() < 2, // Now using CanvasState trait method ); } 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, ); } else if app_state.ui.show_form { let (sidebar_area, form_actual_area) = calculate_sidebar_layout(app_state.ui.show_sidebar, main_content_area); if let Some(sidebar_rect) = sidebar_area { render_sidebar( f, sidebar_rect, theme, &app_state.profile_tree, &app_state.selected_profile, ); } 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(form_actual_area)[1] } else { Layout::default() .direction(Direction::Horizontal) .constraints([ Constraint::Min(0), Constraint::Length(available_width), Constraint::Min(0), ]) .split(form_actual_area)[1] }; render_form( f, form_render_area, app_state, form_state, app_state.current_view_table_name.as_deref().unwrap_or(""), theme, form_state.total_count, form_state.current_position, ); } if let Some(area) = buffer_list_area { render_buffer_list(f, area, theme, buffer_state, app_state); } render_status_line( f, status_line_area, current_dir, theme, is_event_handler_edit_mode, current_fps, app_state, ); if let Some(palette_or_command_area) = command_render_area { if navigation_state.active { find_file_palette::render_find_file_palette( f, palette_or_command_area, theme, navigation_state, ); } else if event_handler_command_mode_active { render_command_line( f, palette_or_command_area, event_handler_command_input, true, theme, event_handler_command_message, ); } } // This block now correctly handles drawing popups over any view. if app_state.ui.show_search_palette { if let Some(search_state) = &app_state.search_state { render_search_palette(f, f.area(), theme, search_state); } } else if app_state.ui.dialog.dialog_show { render_dialog( f, f.area(), theme, &app_state.ui.dialog.dialog_title, &app_state.ui.dialog.dialog_message, &app_state.ui.dialog.dialog_buttons, app_state.ui.dialog.dialog_active_button_index, app_state.ui.dialog.is_loading, ); } }