logic is being implemented properly well

This commit is contained in:
filipriec
2025-05-25 15:09:38 +02:00
parent 5d0f958a68
commit 85eb3adec7
4 changed files with 238 additions and 251 deletions

View File

@@ -14,7 +14,6 @@ use ratatui::{
use crate::components::handlers::canvas::render_canvas;
use crate::components::common::dialog;
use crate::config::binds::config::EditorKeybindingMode;
use crate::components::common::text_editor::TextEditor;
pub fn render_add_logic(
f: &mut Frame,
@@ -35,7 +34,8 @@ pub fn render_add_logic(
let inner_area = main_block.inner(area);
f.render_widget(main_block, area);
if add_logic_state.current_focus == AddLogicFocus::InputScriptContent {
// Handle full-screen script editing
if add_logic_state.current_focus == AddLogicFocus::InsideScriptContent {
let mut editor_ref = add_logic_state.script_content_editor.borrow_mut();
let border_style_color = if is_edit_mode { theme.highlight } else { theme.secondary };
let border_style = Style::default().fg(border_style_color);
@@ -44,18 +44,18 @@ pub fn render_add_logic(
let script_title_hint = match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => {
let vim_mode_status = TextEditor::get_vim_mode_status(&add_logic_state.vim_state);
let vim_mode_status = crate::components::common::text_editor::TextEditor::get_vim_mode_status(&add_logic_state.vim_state);
if is_edit_mode {
format!("Script (VIM {}) - Esc for Normal. Tab navigates from Normal.", vim_mode_status)
format!("Script (VIM {}) - Esc for Normal. Esc again to exit.", vim_mode_status)
} else {
format!("Script (VIM {}) - 'i'/'a'/'o' for Insert. Tab to navigate.", vim_mode_status)
format!("Script (VIM {}) - 'i'/'a'/'o' for Insert. Esc to exit.", vim_mode_status)
}
}
EditorKeybindingMode::Emacs | EditorKeybindingMode::Default => {
if is_edit_mode {
"Script (Editing - Esc to exit edit. Tab navigates after exit.)".to_string()
"Script (Editing - Esc to exit edit. Esc again to exit script.)".to_string()
} else {
"Script (Press Enter or Ctrl+E to edit. Tab to navigate.)".to_string()
"Script (Press Enter or Ctrl+E to edit. Esc to exit.)".to_string()
}
}
};
@@ -68,19 +68,18 @@ pub fn render_add_logic(
.border_type(BorderType::Rounded)
.border_style(border_style),
);
// Remove .widget() call - just pass the reference directly
f.render_widget(&*editor_ref, inner_area);
return;
}
// ... rest of the layout code ...
// Regular layout with preview
let main_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3),
Constraint::Length(9),
Constraint::Min(5),
Constraint::Length(3),
Constraint::Length(3), // Top info
Constraint::Length(9), // Canvas
Constraint::Min(5), // Script preview
Constraint::Length(3), // Buttons
])
.split(inner_area);
@@ -89,6 +88,7 @@ pub fn render_add_logic(
let script_content_area = main_chunks[2];
let buttons_area = main_chunks[3];
// Top info
let profile_text = Paragraph::new(vec![
Line::from(Span::styled(
format!("Profile: {}", add_logic_state.profile_name),
@@ -114,6 +114,7 @@ pub fn render_add_logic(
);
f.render_widget(profile_text, top_info_area);
// Canvas
let focus_on_canvas_inputs = matches!(
add_logic_state.current_focus,
AddLogicFocus::InputLogicName
@@ -132,32 +133,41 @@ pub fn render_add_logic(
highlight_state,
);
// Script content preview (like table preview in add_table)
{
let mut editor_ref = add_logic_state.script_content_editor.borrow_mut();
editor_ref.set_cursor_line_style(Style::default());
let border_style_color = if add_logic_state.current_focus == AddLogicFocus::InputScriptContent {
theme.highlight
let is_script_focused = add_logic_state.current_focus == AddLogicFocus::ScriptContentPreview;
let border_style_color = if is_script_focused {
theme.highlight // Green highlight when focused and ready to select
} else {
theme.secondary
};
let title_hint = match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => "Script Preview (VIM - Focus with Tab, then 'i'/'a'/'o' to edit)",
_ => "Script Preview (Focus with Tab, then Enter/Ctrl+E to edit)",
let title_text = if is_script_focused {
"Script Preview (Press Enter to edit) [FOCUSED]"
} else {
"Script Preview"
};
let title_style = if is_script_focused {
Style::default().fg(theme.highlight).add_modifier(Modifier::BOLD)
} else {
Style::default().fg(theme.fg)
};
editor_ref.set_block(
Block::default()
.title(title_hint)
.title(Span::styled(title_text, title_style))
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(border_style_color)),
);
// Remove .widget() call here too
f.render_widget(&*editor_ref, script_content_area);
}
// Buttons
let get_button_style = |button_focus: AddLogicFocus, current_focus| {
let is_focused = current_focus == button_focus;
let base_style = Style::default().fg(if is_focused {
@@ -222,6 +232,7 @@ pub fn render_add_logic(
);
f.render_widget(cancel_button, button_chunks[1]);
// Dialog
if app_state.ui.dialog.dialog_show {
dialog::render_dialog(
f,

View File

@@ -10,9 +10,7 @@ use crossterm::event::{KeyEvent, KeyCode, KeyModifiers};
use crate::services::GrpcClient;
use tokio::sync::mpsc;
use anyhow::Result;
use common::proto::multieko2::table_script::PostTableScriptRequest;
use crate::components::common::text_editor::TextEditor;
use tui_textarea::Input as TextAreaInput;
pub type SaveLogicResultSender = mpsc::Sender<Result<String>>;
@@ -27,236 +25,214 @@ pub fn handle_add_logic_navigation(
save_logic_sender: SaveLogicResultSender,
command_message: &mut String,
) -> bool {
let mut handled = false;
let general_action = config.get_general_action(key_event.code, key_event.modifiers);
if add_logic_state.current_focus == AddLogicFocus::InputScriptContent {
// === FULLSCREEN SCRIPT EDITING - COMPLETE ISOLATION ===
if add_logic_state.current_focus == AddLogicFocus::InsideScriptContent {
let mut editor_borrow = add_logic_state.script_content_editor.borrow_mut();
match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => {
if *is_edit_mode { // App considers textarea to be in "typing" (Insert) mode
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
if changed { add_logic_state.has_unsaved_changes = true; }
// Check if we've transitioned to Normal mode
if key_event.code == KeyCode::Esc && TextEditor::is_vim_normal_mode(&add_logic_state.vim_state) {
*is_edit_mode = false;
*command_message = "VIM: Normal Mode. Tab to navigate.".to_string();
}
handled = true;
} else { // App considers textarea to be in "navigation" (Normal) mode
match key_event.code {
// Keys to enter Vim Insert mode
KeyCode::Char('i') | KeyCode::Char('a') | KeyCode::Char('o') |
KeyCode::Char('I') | KeyCode::Char('A') | KeyCode::Char('O') => {
*is_edit_mode = true;
TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state
);
*command_message = "VIM: Insert Mode.".to_string();
handled = true;
}
_ => {
if general_action.is_none() {
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
if changed { add_logic_state.has_unsaved_changes = true; }
handled = true;
}
}
}
}
}
EditorKeybindingMode::Emacs | EditorKeybindingMode::Default => {
if *is_edit_mode {
if key_event.code == KeyCode::Esc && key_event.modifiers == KeyModifiers::NONE {
*is_edit_mode = false;
*command_message = "Exited script edit. Tab to navigate.".to_string();
handled = true;
} else if general_action.is_some() && (general_action.unwrap() == "next_field" || general_action.unwrap() == "prev_field") {
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state
// Handle ONLY Escape to exit fullscreen mode
if key_event.code == KeyCode::Esc && key_event.modifiers == KeyModifiers::NONE {
match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => {
if *is_edit_mode {
// First escape: try to go to Vim Normal mode
TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
if changed { add_logic_state.has_unsaved_changes = true; }
handled = true;
if TextEditor::is_vim_normal_mode(&add_logic_state.vim_state) {
*is_edit_mode = false;
*command_message = "VIM: Normal Mode. Esc again to exit script.".to_string();
}
} else {
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state
);
if changed { add_logic_state.has_unsaved_changes = true; }
handled = true;
// Second escape: exit fullscreen
add_logic_state.current_focus = AddLogicFocus::ScriptContentPreview;
app_state.ui.focus_outside_canvas = true;
*is_edit_mode = false;
*command_message = "Exited script editing.".to_string();
}
}
_ => {
if *is_edit_mode {
*is_edit_mode = false;
*command_message = "Exited script edit. Esc again to exit script.".to_string();
} else {
// Exit fullscreen
add_logic_state.current_focus = AddLogicFocus::ScriptContentPreview;
app_state.ui.focus_outside_canvas = true;
*is_edit_mode = false;
*command_message = "Exited script editing.".to_string();
}
}
}
return true;
}
if handled { return true; }
// ALL OTHER KEYS: Pass directly to textarea without any interference
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
if changed {
add_logic_state.has_unsaved_changes = true;
}
// Update edit mode status for Vim
if add_logic_state.editor_keybinding_mode == EditorKeybindingMode::Vim {
*is_edit_mode = !TextEditor::is_vim_normal_mode(&add_logic_state.vim_state);
}
return true; // Always consume the event in fullscreen mode
}
// === END FULLSCREEN ISOLATION ===
// If not handled above (e.g., Tab/Shift+Tab, or Enter when script content not in edit mode),
// process general application-level actions.
let action_str = general_action.map(String::from);
match action_str.as_deref() {
Some("exit_view") | Some("cancel_action") => {
buffer_state.update_history(AppView::Admin);
app_state.ui.show_add_logic = false;
*command_message = "Exited Add Logic".to_string();
*is_edit_mode = false;
handled = true;
// Regular navigation logic for non-fullscreen elements
let action = config.get_general_action(key_event.code, key_event.modifiers);
let current_focus = add_logic_state.current_focus;
let mut handled = true;
let mut new_focus = current_focus;
match action.as_deref() {
Some("exit_table_scroll") => {
// This shouldn't happen since we handle InsideScriptContent above
handled = false;
}
Some("next_field") | Some("prev_field") => {
let is_next = action_str.as_deref() == Some("next_field");
let previous_focus = add_logic_state.current_focus;
add_logic_state.current_focus = if is_next {
match add_logic_state.current_focus {
AddLogicFocus::InputLogicName => AddLogicFocus::InputTargetColumn,
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputDescription,
AddLogicFocus::InputDescription => AddLogicFocus::InputScriptContent,
AddLogicFocus::InputScriptContent => AddLogicFocus::SaveButton,
AddLogicFocus::SaveButton => AddLogicFocus::CancelButton,
AddLogicFocus::CancelButton => AddLogicFocus::InputLogicName,
Some("move_up") => {
match current_focus {
AddLogicFocus::InputLogicName => {
// Stay at top
}
} else {
match add_logic_state.current_focus {
AddLogicFocus::InputLogicName => AddLogicFocus::CancelButton,
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputLogicName,
AddLogicFocus::InputDescription => AddLogicFocus::InputTargetColumn,
AddLogicFocus::InputScriptContent => AddLogicFocus::InputDescription,
AddLogicFocus::SaveButton => AddLogicFocus::InputScriptContent,
AddLogicFocus::CancelButton => AddLogicFocus::SaveButton,
}
};
if add_logic_state.current_focus == AddLogicFocus::InputScriptContent {
*is_edit_mode = false;
let mode_hint = match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => "'i'/'a'/'o' to insert",
_ => "Enter/Ctrl+E to edit",
};
*command_message = format!("Focus: Script Content. Press {} or Tab.", mode_hint);
} else if matches!(add_logic_state.current_focus, AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription) {
*is_edit_mode = true;
*command_message = format!("Focus: {:?}. Edit mode ON.", add_logic_state.current_focus);
} else {
*is_edit_mode = false;
*command_message = format!("Focus: {:?}", add_logic_state.current_focus);
AddLogicFocus::InputTargetColumn => new_focus = AddLogicFocus::InputLogicName,
AddLogicFocus::InputDescription => new_focus = AddLogicFocus::InputTargetColumn,
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::InputDescription,
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::ScriptContentPreview,
AddLogicFocus::CancelButton => new_focus = AddLogicFocus::SaveButton,
_ => handled = false,
}
app_state.ui.focus_outside_canvas = !matches!(
add_logic_state.current_focus,
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription | AddLogicFocus::InputScriptContent
);
handled = true;
}
Some("move_down") => {
match current_focus {
AddLogicFocus::InputLogicName => new_focus = AddLogicFocus::InputTargetColumn,
AddLogicFocus::InputTargetColumn => new_focus = AddLogicFocus::InputDescription,
AddLogicFocus::InputDescription => {
add_logic_state.last_canvas_field = 2;
new_focus = AddLogicFocus::ScriptContentPreview;
},
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::SaveButton,
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::CancelButton,
AddLogicFocus::CancelButton => {
// Stay at bottom
}
_ => handled = false,
}
}
Some("next_option") => {
match current_focus {
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription =>
{ new_focus = AddLogicFocus::ScriptContentPreview; }
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::SaveButton,
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::CancelButton,
AddLogicFocus::CancelButton => { /* Stay at last */ }
_ => handled = false,
}
}
Some("previous_option") => {
match current_focus {
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription =>
{ /* Stay at first */ }
AddLogicFocus::ScriptContentPreview => new_focus = AddLogicFocus::InputDescription,
AddLogicFocus::SaveButton => new_focus = AddLogicFocus::ScriptContentPreview,
AddLogicFocus::CancelButton => new_focus = AddLogicFocus::SaveButton,
_ => handled = false,
}
}
Some("next_field") => {
new_focus = match current_focus {
AddLogicFocus::InputLogicName => AddLogicFocus::InputTargetColumn,
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputDescription,
AddLogicFocus::InputDescription => AddLogicFocus::ScriptContentPreview,
AddLogicFocus::ScriptContentPreview => AddLogicFocus::SaveButton,
AddLogicFocus::SaveButton => AddLogicFocus::CancelButton,
AddLogicFocus::CancelButton => AddLogicFocus::InputLogicName,
_ => current_focus,
};
}
Some("prev_field") => {
new_focus = match current_focus {
AddLogicFocus::InputLogicName => AddLogicFocus::CancelButton,
AddLogicFocus::InputTargetColumn => AddLogicFocus::InputLogicName,
AddLogicFocus::InputDescription => AddLogicFocus::InputTargetColumn,
AddLogicFocus::ScriptContentPreview => AddLogicFocus::InputDescription,
AddLogicFocus::SaveButton => AddLogicFocus::ScriptContentPreview,
AddLogicFocus::CancelButton => AddLogicFocus::SaveButton,
_ => current_focus,
};
}
Some("select") => {
match add_logic_state.current_focus {
AddLogicFocus::InputScriptContent => {
*is_edit_mode = true;
let mut editor_borrow = add_logic_state.script_content_editor.borrow_mut();
match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => {
TextEditor::handle_input(
&mut editor_borrow,
KeyEvent::new(KeyCode::Char('i'), KeyModifiers::NONE),
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
*command_message = "VIM: Insert Mode.".to_string();
}
_ => {
*command_message = "Entered script edit mode.".to_string();
}
}
handled = true;
match current_focus {
AddLogicFocus::ScriptContentPreview => {
new_focus = AddLogicFocus::InsideScriptContent;
*is_edit_mode = false; // Start in preview mode
app_state.ui.focus_outside_canvas = false; // Script is like canvas
let mode_hint = match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => "VIM mode - 'i'/'a'/'o' to edit",
_ => "Enter/Ctrl+E to edit",
};
*command_message = format!("Fullscreen script editing. {} or Esc to exit.", mode_hint);
}
AddLogicFocus::SaveButton => {
*command_message = "Save logic action".to_string();
}
AddLogicFocus::CancelButton => {
buffer_state.update_history(AppView::Admin);
app_state.ui.show_add_logic = false;
*command_message = "Cancelled Add Logic".to_string();
*is_edit_mode = false;
}
AddLogicFocus::SaveButton => { handled = true; }
AddLogicFocus::CancelButton => { *is_edit_mode = false; handled = true; }
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription => {
*is_edit_mode = !*is_edit_mode;
*command_message = format!("Field edit mode: {}", if *is_edit_mode { "ON" } else { "OFF" });
handled = true;
}
_ => handled = false,
}
}
Some("toggle_edit_mode") => {
match add_logic_state.current_focus {
AddLogicFocus::InputScriptContent => {
let mut editor_borrow = add_logic_state.script_content_editor.borrow_mut();
match add_logic_state.editor_keybinding_mode {
EditorKeybindingMode::Vim => {
if *is_edit_mode {
TextEditor::handle_input(
&mut editor_borrow,
KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE),
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
if TextEditor::is_vim_normal_mode(&add_logic_state.vim_state) {
*is_edit_mode = false;
*command_message = "VIM: Normal Mode. Tab to navigate.".to_string();
} else {
*command_message = "VIM: Still in Insert Mode (toggle error?).".to_string();
}
} else {
TextEditor::handle_input(
&mut editor_borrow,
KeyEvent::new(KeyCode::Char('i'), KeyModifiers::NONE),
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state,
);
*is_edit_mode = true;
*command_message = "VIM: Insert Mode.".to_string();
}
}
_ => {
*is_edit_mode = !*is_edit_mode;
*command_message = format!("Script edit mode: {}", if *is_edit_mode { "ON" } else { "OFF. Tab to navigate." });
}
}
handled = true;
}
match current_focus {
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription => {
*is_edit_mode = !*is_edit_mode;
*command_message = format!("Canvas field edit mode: {}", if *is_edit_mode { "ON" } else { "OFF" });
handled = true;
}
_ => { *command_message = "Cannot toggle edit mode here.".to_string(); handled = true; }
_ => {
*command_message = "Cannot toggle edit mode here.".to_string();
}
}
}
_ => {
if add_logic_state.current_focus == AddLogicFocus::InputScriptContent &&
!*is_edit_mode &&
add_logic_state.editor_keybinding_mode == EditorKeybindingMode::Vim {
let mut editor_borrow = add_logic_state.script_content_editor.borrow_mut();
let changed = TextEditor::handle_input(
&mut editor_borrow,
key_event,
&add_logic_state.editor_keybinding_mode,
&mut add_logic_state.vim_state
);
if changed { add_logic_state.has_unsaved_changes = true; }
handled = true;
_ => handled = false,
}
if handled && current_focus != new_focus {
add_logic_state.current_focus = new_focus;
// Set edit mode and canvas focus based on new focus
let new_is_canvas_input_focus = matches!(new_focus,
AddLogicFocus::InputLogicName | AddLogicFocus::InputTargetColumn | AddLogicFocus::InputDescription
);
if new_is_canvas_input_focus {
// Entering canvas - start in readonly mode
*is_edit_mode = false;
app_state.ui.focus_outside_canvas = false;
} else {
// Outside canvas
app_state.ui.focus_outside_canvas = true;
if matches!(new_focus, AddLogicFocus::ScriptContentPreview) {
*is_edit_mode = false;
}
}
}
handled
}

View File

@@ -67,7 +67,7 @@ fn find_prev_word_end(text: &str, current_pos: usize) -> usize {
pub async fn execute_action(
action: &str,
app_state: &mut AppState,
state: &mut AddLogicState, // Changed
state: &mut AddLogicState,
ideal_cursor_column: &mut usize,
key_sequence_tracker: &mut KeySequenceTracker,
command_message: &mut String,
@@ -75,7 +75,7 @@ pub async fn execute_action(
match action {
"move_up" => {
key_sequence_tracker.reset();
let num_fields = AddLogicState::INPUT_FIELD_COUNT; // Changed
let num_fields = AddLogicState::INPUT_FIELD_COUNT;
if num_fields == 0 { return Ok("No fields.".to_string()); }
let current_field = state.current_field();
@@ -87,20 +87,13 @@ pub async fn execute_action(
let new_pos = (*ideal_cursor_column).min(max_cursor_pos);
state.set_current_cursor_pos(new_pos);
} else {
// Moving up from the first field (InputLogicName)
app_state.ui.focus_outside_canvas = true;
// Focus should go to the element logically above the canvas.
// Based on AddLogicFocus, this might be CancelButton or another element.
// For AddLogic, let's assume it's CancelButton, similar to AddTable.
state.current_focus = crate::state::pages::add_logic::AddLogicFocus::CancelButton; // Changed
key_sequence_tracker.reset();
return Ok("Focus moved above canvas".to_string());
*command_message = "At top of form.".to_string();
}
Ok("".to_string())
Ok(command_message.clone())
}
"move_down" => {
key_sequence_tracker.reset();
let num_fields = AddLogicState::INPUT_FIELD_COUNT; // Changed
let num_fields = AddLogicState::INPUT_FIELD_COUNT;
if num_fields == 0 { return Ok("No fields.".to_string()); }
let current_field = state.current_field();
let last_field_index = num_fields - 1;
@@ -113,17 +106,13 @@ pub async fn execute_action(
let new_pos = (*ideal_cursor_column).min(max_cursor_pos);
state.set_current_cursor_pos(new_pos);
} else {
// Moving down from the last field (InputDescription)
// Move focus outside canvas when moving down from the last field
app_state.ui.focus_outside_canvas = true;
// Focus should go to the element logically below the canvas.
// This is likely InputScriptContent or SaveButton.
// The add_logic_nav.rs handles transitions to InputScriptContent.
// If moving from canvas directly to buttons, it would be SaveButton.
state.current_focus = crate::state::pages::add_logic::AddLogicFocus::InputScriptContent; // Or SaveButton
key_sequence_tracker.reset();
return Ok("Focus moved to script/button area".to_string());
state.last_canvas_field = 2;
state.current_focus = crate::state::pages::add_logic::AddLogicFocus::SaveButton;
*command_message = "Focus moved below canvas".to_string();
}
Ok("".to_string())
Ok(command_message.clone())
}
"move_first_line" => {
key_sequence_tracker.reset();

View File

@@ -1,7 +1,7 @@
// src/state/pages/add_logic.rs
use crate::config::binds::config::{EditorConfig, EditorKeybindingMode};
use crate::state::pages::canvas_state::CanvasState;
use crate::components::common::text_editor::{TextEditor, VimState}; // Add VimState import
use crate::components::common::text_editor::{TextEditor, VimState};
use std::cell::RefCell;
use std::rc::Rc;
use tui_textarea::TextArea;
@@ -11,8 +11,9 @@ pub enum AddLogicFocus {
#[default]
InputLogicName,
InputTargetColumn,
InputScriptContent,
InputDescription,
ScriptContentPreview, // Like ColumnsTable - can be highlighted/selected
InsideScriptContent, // Like InsideColumnsTable - full editing mode
SaveButton,
CancelButton,
}
@@ -27,12 +28,13 @@ pub struct AddLogicState {
pub script_content_editor: Rc<RefCell<TextArea<'static>>>,
pub description_input: String,
pub current_focus: AddLogicFocus,
pub last_canvas_field: usize,
pub logic_name_cursor_pos: usize,
pub target_column_cursor_pos: usize,
pub description_cursor_pos: usize,
pub has_unsaved_changes: bool,
pub editor_keybinding_mode: EditorKeybindingMode,
pub vim_state: VimState, // Add this field
pub vim_state: VimState,
}
impl AddLogicState {
@@ -47,12 +49,13 @@ impl AddLogicState {
script_content_editor: Rc::new(RefCell::new(editor)),
description_input: String::new(),
current_focus: AddLogicFocus::InputLogicName,
last_canvas_field: 2,
logic_name_cursor_pos: 0,
target_column_cursor_pos: 0,
description_cursor_pos: 0,
has_unsaved_changes: false,
editor_keybinding_mode: editor_config.keybinding_mode.clone(),
vim_state: VimState::default(), // Add this field initialization
vim_state: VimState::default(),
}
}
@@ -65,14 +68,13 @@ impl Default for AddLogicState {
}
}
// ... rest of the CanvasState implementation remains the same
impl CanvasState for AddLogicState {
fn current_field(&self) -> usize {
match self.current_focus {
AddLogicFocus::InputLogicName => 0,
AddLogicFocus::InputTargetColumn => 1,
AddLogicFocus::InputDescription => 2,
_ => 0,
_ => self.last_canvas_field,
}
}
@@ -121,9 +123,18 @@ impl CanvasState for AddLogicState {
fn set_current_field(&mut self, index: usize) {
self.current_focus = match index {
0 => AddLogicFocus::InputLogicName,
1 => AddLogicFocus::InputTargetColumn,
2 => AddLogicFocus::InputDescription,
0 => {
self.last_canvas_field = 0;
AddLogicFocus::InputLogicName
},
1 => {
self.last_canvas_field = 1;
AddLogicFocus::InputTargetColumn
},
2 => {
self.last_canvas_field = 2;
AddLogicFocus::InputDescription
},
_ => self.current_focus,
};
}