feat(ui): simplify AppMode minibuffer handling and panel rendering

Refactor AppMode to use MinibufferConfig for all text-entry modes. Update
command implementations to use new mode constructors. Introduce
PanelContent trait and replace panel structs with content types. Adjust
rendering to use Panel::new and minibuffer configuration. Update imports
and add MinibufferConfig struct. No functional changes; all behavior
preserved.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
This commit is contained in:
Edward Langley
2026-04-07 02:04:46 -07:00
parent de047ddf1a
commit 4b11b6e321
9 changed files with 376 additions and 320 deletions

View File

@ -18,13 +18,14 @@ use ratatui::{
use crate::model::Model;
use crate::ui::app::{App, AppMode};
use crate::ui::category_panel::CategoryPanel;
use crate::ui::formula_panel::FormulaPanel;
use crate::ui::category_panel::CategoryContent;
use crate::ui::formula_panel::FormulaContent;
use crate::ui::grid::GridWidget;
use crate::ui::help::HelpWidget;
use crate::ui::import_wizard_ui::ImportWizardWidget;
use crate::ui::panel::Panel;
use crate::ui::tile_bar::TileBar;
use crate::ui::view_panel::ViewPanel;
use crate::ui::view_panel::ViewContent;
struct TuiContext<'a> {
terminal: Terminal<CrosstermBackend<&'a mut Stdout>>,
@ -224,31 +225,20 @@ fn draw_content(f: &mut Frame, area: Rect, app: &App) {
if app.formula_panel_open {
let a = Rect::new(side.x, y, side.width, ph);
f.render_widget(
FormulaPanel::new(&app.model, &app.mode, app.formula_cursor),
a,
);
let content = FormulaContent::new(&app.model, &app.mode);
f.render_widget(Panel::new(content, &app.mode, app.formula_cursor), a);
y += ph;
}
if app.category_panel_open {
let a = Rect::new(side.x, y, side.width, ph);
f.render_widget(
CategoryPanel::new(
&app.model,
&app.mode,
app.cat_panel_cursor,
&app.expanded_cats,
),
a,
);
let content = CategoryContent::new(&app.model, &app.expanded_cats);
f.render_widget(Panel::new(content, &app.mode, app.cat_panel_cursor), a);
y += ph;
}
if app.view_panel_open {
let a = Rect::new(side.x, y, side.width, ph);
f.render_widget(
ViewPanel::new(&app.model, &app.mode, app.view_panel_cursor),
a,
);
let content = ViewContent::new(&app.model);
f.render_widget(Panel::new(content, &app.mode, app.view_panel_cursor), a);
}
} else {
grid_area = area;
@ -272,44 +262,17 @@ fn draw_tile_bar(f: &mut Frame, area: Rect, app: &App) {
}
fn draw_bottom_bar(f: &mut Frame, area: Rect, app: &App) {
// All text-entry modes use the bottom bar as a minibuffer.
let minibuf = match &app.mode {
AppMode::CommandMode { .. } => {
let buf = app.buffers.get("command").map(|s| s.as_str()).unwrap_or("");
Some((format!(":{buf}"), Color::Yellow))
}
AppMode::Editing { .. } => {
let buf = app.buffers.get("edit").map(|s| s.as_str()).unwrap_or("");
Some((format!("edit: {buf}"), Color::Green))
}
AppMode::FormulaEdit { .. } => {
let buf = app.buffers.get("formula").map(|s| s.as_str()).unwrap_or("");
Some((format!("formula: {buf}"), Color::Cyan))
}
AppMode::CategoryAdd { .. } => {
let buf = app
.buffers
.get("category")
.map(|s| s.as_str())
.unwrap_or("");
Some((format!("new category: {buf}"), Color::Yellow))
}
AppMode::ItemAdd { category, .. } => {
let buf = app.buffers.get("item").map(|s| s.as_str()).unwrap_or("");
Some((format!("add item to {category}: {buf}"), Color::Green))
}
AppMode::ExportPrompt { .. } => {
let buf = app.buffers.get("export").map(|s| s.as_str()).unwrap_or("");
Some((format!("export path: {buf}"), Color::Yellow))
}
_ => None,
};
if let Some((text, color)) = minibuf {
if let Some(mb) = app.mode.minibuffer() {
let buf = app
.buffers
.get(mb.buffer_key)
.map(|s| s.as_str())
.unwrap_or("");
let text = format!("{}{}", mb.prompt, buf);
f.render_widget(
Paragraph::new(text).style(
Style::default()
.fg(color)
.fg(mb.color)
.bg(Color::Indexed(235))
.add_modifier(Modifier::BOLD),
),