// src/client/components1/handlers/form.rs use ratatui::{ widgets::{Paragraph, Block, Borders}, layout::{Layout, Constraint, Direction, Rect, Margin, Alignment}, style::Style, text::{Line, Span}, Frame, }; use crate::colors::Theme; use crate::client::ui::form::FormState; pub fn render_form( f: &mut Frame, area: Rect, form_state: &FormState, fields: &[&str], current_field: &usize, inputs: &[&String], theme: &Theme, is_edit_mode: bool, total_count: u64, current_position: u64, ) { // Create Adresar card let adresar_card = Block::default() .borders(Borders::ALL) .border_style(Style::default().fg(theme.border)) .title(" Adresar ") .style(Style::default().bg(theme.bg).fg(theme.fg)); f.render_widget(adresar_card, area); // Define the inner area for the form (inside the card) let inner_area = area.inner(Margin { horizontal: 1, vertical: 1, }); // Create a vertical layout for the entire form content let main_layout = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Length(1), // For count and position Constraint::Min(1), // For form fields ]) .split(inner_area); // Render the count and position at the very top let count_position_text = format!("Total: {} | Current Position: {}", total_count, current_position); let count_position_paragraph = Paragraph::new(count_position_text) .style(Style::default().fg(theme.fg)) .alignment(Alignment::Left); f.render_widget(count_position_paragraph, main_layout[0]); // Split the remaining space into label and input columns let columns = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(30), Constraint::Percentage(70)]) .split(main_layout[1]); // Create compact input container let input_container = Block::default() .borders(Borders::ALL) .border_style(if is_edit_mode { if form_state.has_unsaved_changes { Style::default().fg(theme.warning) // Red color } else { Style::default().fg(theme.accent) // Blue color } } else { Style::default().fg(theme.secondary) // Yellow color }) .style(Style::default().bg(theme.bg)); // Place the input container at the top let input_container_area = Rect { x: columns[1].x, y: columns[1].y, width: columns[1].width, height: fields.len() as u16 + 2, // +2 for borders }; f.render_widget(&input_container, input_container_area); // Input area inside borders let input_area = input_container.inner(input_container_area); // Split the remaining area for the form inputs let input_rows = Layout::default() .direction(Direction::Vertical) .constraints(vec![Constraint::Length(1); fields.len()]) .split(input_area); // Render labels close to the border for (i, field) in fields.iter().enumerate() { let label = Paragraph::new(Line::from(Span::styled( format!("{}:", field), Style::default().fg(theme.fg), ))); f.render_widget(label, Rect { x: columns[0].x, y: input_container_area.y + 1 + i as u16, // Align with input rows width: columns[0].width, height: 1, }); } // Render inputs with left-aligned text and free cursor movement for (i, input) in inputs.iter().enumerate() { let is_active = i == *current_field; let input_display = Paragraph::new(input.as_str()) .alignment(Alignment::Left) .style(if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) }); f.render_widget(input_display, input_rows[i]); // Position cursor at the correct position in the active field if is_active && is_edit_mode { // Move cursor logic inside the loop let cursor_x = input_rows[i].x + input.len() as u16; let cursor_y = input_rows[i].y; f.set_cursor_position((cursor_x, cursor_y)); // Updated to set_cursor_position } if is_active { if is_edit_mode { // Edit mode: cursor at current_cursor_pos instead of end let cursor_x = input_rows[i].x + form_state.current_cursor_pos as u16; let cursor_y = input_rows[i].y; f.set_cursor_position((cursor_x, cursor_y)); // Updated to set_cursor_position } else { // Read-only mode: cursor at current_cursor_pos let cursor_x = input_rows[i].x + form_state.current_cursor_pos as u16; let cursor_y = input_rows[i].y; f.set_cursor_position((cursor_x, cursor_y)); // Updated to set_cursor_position } } } }