From 5566d7349b40edc0ce4d3231fde9d9971856075a Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Tue, 7 Apr 2026 02:15:43 -0700 Subject: [PATCH] feat(ui): add footer support to panels Add footer_height method to PanelContent trait with default 0. Implement footer_height in FormulaContent to return 1 when in FormulaEdit mode. Update Panel::render to subtract footer height from item height. This enables optional footers in panels. Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF) --- src/ui/formula_panel.rs | 8 ++++++++ src/ui/panel.rs | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ui/formula_panel.rs b/src/ui/formula_panel.rs index eb66931..e7cb5c1 100644 --- a/src/ui/formula_panel.rs +++ b/src/ui/formula_panel.rs @@ -59,6 +59,14 @@ impl PanelContent for FormulaContent<'_> { buf.set_string(inner.x, inner.y + index as u16, &truncated, style); } + fn footer_height(&self) -> u16 { + if matches!(self.mode, AppMode::FormulaEdit { .. }) { + 1 + } else { + 0 + } + } + fn render_footer(&self, inner: Rect, buf: &mut Buffer) { if matches!(self.mode, AppMode::FormulaEdit { .. }) { let y = inner.y + inner.height.saturating_sub(1); diff --git a/src/ui/panel.rs b/src/ui/panel.rs index 29ee7e6..496d6c0 100644 --- a/src/ui/panel.rs +++ b/src/ui/panel.rs @@ -22,7 +22,11 @@ pub trait PanelContent { /// Render a single item at the given row index. /// `inner` is the full inner area of the panel; the item occupies row `index`. fn render_item(&self, index: usize, is_selected: bool, inner: Rect, buf: &mut Buffer); - /// Optional footer rendered below the items (e.g. inline hints). + /// Number of lines the footer occupies (used to reserve space). + fn footer_height(&self) -> u16 { + 0 + } + /// Optional footer rendered in the reserved space at the bottom. fn render_footer(&self, _inner: Rect, _buf: &mut Buffer) {} } @@ -69,8 +73,9 @@ impl Widget for Panel<'_, C> { return; } + let item_height = inner.height.saturating_sub(self.content.footer_height()); for i in 0..self.content.item_count() { - if i as u16 >= inner.height { + if i as u16 >= item_height { break; } let is_selected = i == self.cursor && is_active;