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)
This commit is contained in:
Edward Langley
2026-04-07 02:15:43 -07:00
parent 4b11b6e321
commit 5566d7349b
2 changed files with 15 additions and 2 deletions

View File

@ -59,6 +59,14 @@ impl PanelContent for FormulaContent<'_> {
buf.set_string(inner.x, inner.y + index as u16, &truncated, style); 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) { fn render_footer(&self, inner: Rect, buf: &mut Buffer) {
if matches!(self.mode, AppMode::FormulaEdit { .. }) { if matches!(self.mode, AppMode::FormulaEdit { .. }) {
let y = inner.y + inner.height.saturating_sub(1); let y = inner.y + inner.height.saturating_sub(1);

View File

@ -22,7 +22,11 @@ pub trait PanelContent {
/// Render a single item at the given row index. /// Render a single item at the given row index.
/// `inner` is the full inner area of the panel; the item occupies 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); 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) {} fn render_footer(&self, _inner: Rect, _buf: &mut Buffer) {}
} }
@ -69,8 +73,9 @@ impl<C: PanelContent> Widget for Panel<'_, C> {
return; return;
} }
let item_height = inner.height.saturating_sub(self.content.footer_height());
for i in 0..self.content.item_count() { for i in 0..self.content.item_count() {
if i as u16 >= inner.height { if i as u16 >= item_height {
break; break;
} }
let is_selected = i == self.cursor && is_active; let is_selected = i == self.cursor && is_active;