270 lines
8.5 KiB
Rust
270 lines
8.5 KiB
Rust
// 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,
|
|
common::search_palette::render_search_palette,
|
|
handlers::sidebar::{self, calculate_sidebar_layout},
|
|
intro::intro::render_intro,
|
|
render_background,
|
|
render_buffer_list,
|
|
render_command_line,
|
|
render_status_line,
|
|
};
|
|
use crate::config::colors::themes::Theme;
|
|
use crate::modes::general::command_navigation::NavigationState;
|
|
use crate::state::app::buffer::BufferState;
|
|
use crate::state::app::highlight::HighlightState as LocalHighlightState;
|
|
use canvas::canvas::HighlightState as CanvasHighlightState;
|
|
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 ratatui::{
|
|
layout::{Constraint, Direction, Layout},
|
|
Frame,
|
|
};
|
|
|
|
// Helper function to convert between HighlightState types
|
|
fn convert_highlight_state(local: &LocalHighlightState) -> CanvasHighlightState {
|
|
match local {
|
|
LocalHighlightState::Off => CanvasHighlightState::Off,
|
|
LocalHighlightState::Characterwise { anchor } => CanvasHighlightState::Characterwise { anchor: *anchor },
|
|
LocalHighlightState::Linewise { anchor_line } => CanvasHighlightState::Linewise { anchor_line: *anchor_line },
|
|
}
|
|
}
|
|
|
|
#[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,
|
|
highlight_state: &LocalHighlightState, // Keep using local version
|
|
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 mut 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<Constraint> = 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 {
|
|
sidebar::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]
|
|
};
|
|
|
|
// CHANGED: Convert local HighlightState to canvas HighlightState for FormState
|
|
let canvas_highlight_state = convert_highlight_state(highlight_state);
|
|
form_state.render(
|
|
f,
|
|
form_render_area,
|
|
theme,
|
|
is_event_handler_edit_mode,
|
|
&canvas_highlight_state, // Use converted version
|
|
);
|
|
}
|
|
|
|
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,
|
|
);
|
|
}
|
|
}
|