use crate::app_state_container::AppStateContainer;
use crate::buffer::{AppMode, BufferAPI};
use crate::ui::viewport_manager::{ColumnOperationResult, NavigationResult, ViewportManager};
use std::cell::RefCell;
pub trait ColumnBehavior {
fn viewport_manager(&self) -> &RefCell<Option<ViewportManager>>;
fn buffer_mut(&mut self) -> &mut dyn BufferAPI;
fn buffer(&self) -> &dyn BufferAPI;
fn state_container(&self) -> &AppStateContainer;
fn is_in_results_mode(&self) -> bool {
self.buffer().get_mode() == AppMode::Results
}
fn apply_column_navigation_result(&mut self, result: NavigationResult, direction: &str) {
let visual_position = result.column_position;
tracing::debug!(
"[COLUMN_OPS] apply_column_navigation_result: direction={}, visual_position={}",
direction,
visual_position
);
self.buffer_mut().set_current_column(visual_position);
tracing::debug!(
"[COLUMN_OPS] apply_column_navigation_result: set buffer column to {}",
visual_position
);
self.state_container().navigation_mut().selected_column = visual_position;
tracing::debug!(
"[COLUMN_OPS] apply_column_navigation_result: set navigation column to {}",
visual_position
);
if result.viewport_changed {
let mut offset = self.buffer().get_scroll_offset();
offset.1 = result.scroll_offset;
self.buffer_mut().set_scroll_offset(offset);
self.state_container().navigation_mut().scroll_offset.1 = result.scroll_offset;
}
let message = match direction {
"first" => "Moved to first column".to_string(),
"last" => "Moved to last column".to_string(),
_ => format!("Moved to column {visual_position}"),
};
self.buffer_mut().set_status_message(message);
}
fn apply_column_operation_result(&mut self, result: ColumnOperationResult) {
if !result.success {
if !result.description.is_empty() {
self.buffer_mut().set_status_message(result.description);
}
return;
}
if let Some(dataview) = result.updated_dataview {
self.buffer_mut().set_dataview(Some(dataview));
}
if let Some(new_col) = result.new_column_position {
self.state_container().navigation_mut().selected_column = new_col;
if let Some(viewport) = result.new_viewport {
let pinned_count = self
.buffer()
.get_dataview()
.as_ref()
.map_or(0, |dv| dv.get_pinned_columns().len());
self.state_container().navigation_mut().scroll_offset.1 =
viewport.start.saturating_sub(pinned_count);
}
self.buffer_mut().set_current_column(new_col);
}
self.buffer_mut().set_status_message(result.description);
}
fn hide_current_column(&mut self) {
if !self.is_in_results_mode() {
return;
}
let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
|| ColumnOperationResult::failure("No viewport manager"),
crate::ui::viewport_manager::ViewportManager::hide_current_column_with_result,
);
self.apply_column_operation_result(result);
}
fn unhide_all_columns(&mut self) {
let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
|| ColumnOperationResult::failure("No viewport manager"),
crate::ui::viewport_manager::ViewportManager::unhide_all_columns_with_result,
);
self.apply_column_operation_result(result);
}
fn move_current_column_left(&mut self) {
if !self.is_in_results_mode() {
return;
}
let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
|| ColumnOperationResult::failure("No viewport manager"),
crate::ui::viewport_manager::ViewportManager::reorder_column_left_with_result,
);
self.apply_column_operation_result(result);
}
fn move_current_column_right(&mut self) {
if !self.is_in_results_mode() {
return;
}
let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
|| ColumnOperationResult::failure("No viewport manager"),
crate::ui::viewport_manager::ViewportManager::reorder_column_right_with_result,
);
self.apply_column_operation_result(result);
}
fn move_column_left(&mut self) {
let nav_result = {
let mut viewport_borrow = self.viewport_manager().borrow_mut();
let vm = viewport_borrow
.as_mut()
.expect("ViewportManager must exist for navigation");
let current_visual = vm.get_crosshair_col();
vm.navigate_column_left(current_visual)
};
self.apply_column_navigation_result(nav_result, "left");
}
fn move_column_right(&mut self) {
let nav_result = {
let mut viewport_borrow = self.viewport_manager().borrow_mut();
let vm = viewport_borrow
.as_mut()
.expect("ViewportManager must exist for navigation");
let current_visual = vm.get_crosshair_col();
tracing::debug!(
"[COLUMN_OPS] move_column_right: current_visual from VM = {}",
current_visual
);
let result = vm.navigate_column_right(current_visual);
tracing::debug!(
"[COLUMN_OPS] move_column_right: navigation result column_position = {}",
result.column_position
);
result
};
tracing::debug!(
"[COLUMN_OPS] move_column_right: applying result with column_position = {}",
nav_result.column_position
);
self.apply_column_navigation_result(nav_result, "right");
}
fn goto_first_column(&mut self) {
let nav_result = {
let mut viewport_borrow = self.viewport_manager().borrow_mut();
viewport_borrow
.as_mut()
.expect("ViewportManager must exist for navigation")
.navigate_to_first_column()
};
self.apply_column_navigation_result(nav_result, "first");
}
fn goto_last_column(&mut self) {
let nav_result = {
let mut viewport_borrow = self.viewport_manager().borrow_mut();
viewport_borrow
.as_mut()
.expect("ViewportManager must exist for navigation")
.navigate_to_last_column()
};
self.apply_column_navigation_result(nav_result, "last");
}
}