status bar display

This commit is contained in:
2026-06-21 12:32:09 -05:00
parent a45c5a0a68
commit 9b53552f4a
7 changed files with 126 additions and 9 deletions
+32 -6
View File
@@ -18,6 +18,7 @@ mod overlay;
mod render;
mod scroll_overlay;
mod speech;
mod status;
mod term;
mod transition;
mod ui;
@@ -37,6 +38,7 @@ use crate::menu::MenuWidget;
use crate::mode::{Mode, PendingMode};
use crate::scroll_overlay::ScrollOverlayWidget;
use crate::speech::SpeechBubblesWidget;
use crate::status::StatusSidebarWidget;
use crate::ui::Ui;
use kiln_core::game::GameState;
use kiln_core::log::LogLine;
@@ -330,12 +332,30 @@ fn draw_play(frame: &mut Frame, game: &GameState, ui: &mut Ui) {
format!(" {} ", board.name)
};
// Carve a fixed-width status sidebar off the left edge when enabled; the
// board/log layout below operates on whatever area is left (`content_area`).
let content_area = if ui.show_status {
// Overlap by one column so the sidebar's right border and the board's
// left border share a cell (both blocks merge their borders).
let [sidebar_area, rest] =
Layout::horizontal([Constraint::Length(STATUS_SIDEBAR_WIDTH), Constraint::Min(0)])
.spacing(Spacing::Overlap(1))
.areas(frame.area());
frame.render_widget(
StatusSidebarWidget::new(game.player_health - 2, game.player_gems),
sidebar_area,
);
rest
} else {
frame.area()
};
if ui.log.open {
// Split the screen: board on top, log panel of `height` at the bottom.
// Split the content area: board on top, log panel of `height` at the bottom.
let [board_area, log_area] =
Layout::vertical([Constraint::Min(3), Constraint::Length(ui.log.height)])
.spacing(Spacing::Overlap(1))
.areas(frame.area());
.areas(content_area);
let block = Block::bordered()
.title(title)
@@ -345,15 +365,21 @@ fn draw_play(frame: &mut Frame, game: &GameState, ui: &mut Ui) {
draw_board_area(frame, inner, game, ui);
frame.render_stateful_widget(LogWidget::new(&game.log), log_area, &mut ui.log);
} else {
// Panel closed: board fills the screen, latest message in the border.
let mut block = Block::bordered().title(title);
// Panel closed: board fills the content area, latest message in the border.
// Merge borders so a joined edge with the status sidebar renders cleanly.
let mut block = Block::bordered()
.title(title)
.merge_borders(MergeStrategy::Exact);
block = block.title_bottom(log_preview_line(&game.log).left_aligned());
let inner = block.inner(frame.area());
frame.render_widget(block, frame.area());
let inner = block.inner(content_area);
frame.render_widget(block, content_area);
draw_board_area(frame, inner, game, ui);
}
}
/// Width (in terminal columns, borders included) of the play-mode status sidebar.
const STATUS_SIDEBAR_WIDTH: u16 = 18;
/// Renders the inner board area: either the active board-layer animation or the live board.
///
/// If `ui.pending_transition` is set, pre-renders both boards into a new