generated from GarandPLG/rust-flake-template
Add block title helpers and use them in UI
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
use ratatui::{
|
||||
style::{Color, Style, Stylize},
|
||||
text::{Line, Span},
|
||||
};
|
||||
|
||||
/// Creates a styled title `Line` for a UI block.
|
||||
///
|
||||
/// This helper builds a `Line` that looks like:
|
||||
/// ```text
|
||||
/// [ <title‑1> <separator> <title‑2> ... ]
|
||||
/// ```
|
||||
/// where each title fragment is rendered in the color supplied by the caller,
|
||||
/// and the surrounding brackets and any separator are rendered in gray.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `texts` – A slice of tuples. Each tuple contains a title fragment (`&str`)
|
||||
/// and a `Color` that should be applied to that fragment. The order of the
|
||||
/// tuples determines the order of the fragments in the final line.
|
||||
///
|
||||
/// * `separator` – An optional string that will be inserted (in gray) between
|
||||
/// successive title fragments. If `None` the fragments are concatenated
|
||||
/// directly without any separator.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `Line<'a>` that starts with a gray “\[ ”, contains the colored title
|
||||
/// fragments separated (if requested) by a gray separator, and ends with a
|
||||
/// gray “ \]”. The line can be passed directly to widgets such as `Block::title`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::style::Color;
|
||||
///
|
||||
/// let title: Line<'_> = block_title_helper(
|
||||
/// &[
|
||||
/// ("Skirmish", Color::Magenta),
|
||||
/// ("Map", Color::Green),
|
||||
/// ],
|
||||
/// Some(" - ")
|
||||
/// );
|
||||
/// // `title` now represents: [ Skirmish - Map ] with the appropriate colors.
|
||||
/// ```
|
||||
pub fn block_title_helper<'a>(texts: &[(&'a str, Color)], separator: Option<&'a str>) -> Line<'a> {
|
||||
let mut line: Line<'a> = Line::default();
|
||||
|
||||
line.spans.push(Span::from("[ ").gray());
|
||||
|
||||
for (i, (text, color)) in texts.iter().enumerate() {
|
||||
let span: Span<'a> = Span::styled(*text, Style::new().fg(*color));
|
||||
|
||||
line.spans.push(span);
|
||||
|
||||
if let Some(sep) = separator {
|
||||
if i + 1 < texts.len() {
|
||||
line.spans.push(Span::from(sep).gray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line.spans.push(Span::from(" ]").gray());
|
||||
|
||||
line
|
||||
}
|
||||
|
||||
/// Convenience wrapper for `block_title_helper` that creates a title line for a
|
||||
/// single piece of text.
|
||||
///
|
||||
/// This function builds a `Line` that looks like:
|
||||
/// ```text
|
||||
/// [ <text> ]
|
||||
/// ```
|
||||
/// where `<text>` is rendered with the supplied color, and the surrounding
|
||||
/// brackets are rendered in gray. It simply forwards the arguments to
|
||||
/// `block_title_helper` with `separator` set to `None`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `text` – The title string to display.
|
||||
///
|
||||
/// * `color` – The `Color` that should be applied to the title text.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `Line<'a>` containing the grey brackets and the coloured title text,
|
||||
/// ready to be passed to widgets such as `Block::title`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::style::Color;
|
||||
///
|
||||
/// let title: Line<'_> = block_single_title_helper("Keybindings", Color::Magenta);
|
||||
/// // `title` now represents: [ Keybindings ] with “Keybindings” coloured magenta.
|
||||
/// ```
|
||||
pub fn block_single_title_helper<'a>(text: &'a str, color: Color) -> Line<'a> {
|
||||
block_title_helper(&[(text, color)], None)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod block_title;
|
||||
|
||||
pub use block_title::{block_single_title_helper, block_title_helper};
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod app;
|
||||
pub mod helpers;
|
||||
pub mod keybind;
|
||||
pub mod keybindings;
|
||||
pub mod state;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use crate::app::{
|
||||
App,
|
||||
helpers::block_title_helper,
|
||||
keybindings::{Action, count_largest_group},
|
||||
widgets::{BoardWidget, KeybindingsWidget},
|
||||
};
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Constraint, Layout, Margin, Rect},
|
||||
style::Stylize,
|
||||
style::{Color, Stylize},
|
||||
text::Line,
|
||||
widgets::{Block, Borders, Padding, Paragraph, Widget},
|
||||
};
|
||||
@@ -69,13 +70,10 @@ pub fn skirmish_view(app: &mut App, area: Rect, buf: &mut Buffer) {
|
||||
{
|
||||
let board_block: Block = Block::new()
|
||||
.gray()
|
||||
.title(Line::from_iter([
|
||||
"[ ".gray(),
|
||||
"Skirmish".magenta(),
|
||||
" - ".gray(),
|
||||
"Map".green(),
|
||||
" ]".gray(),
|
||||
]))
|
||||
.title(block_title_helper(
|
||||
&[("Skirmish", Color::Magenta), ("Map", Color::Green)],
|
||||
Some(" - "),
|
||||
))
|
||||
.borders(Borders::LEFT | Borders::TOP | Borders::RIGHT);
|
||||
|
||||
let board_area: Rect = board_block.inner(main_area);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use crate::app::keybindings::{Action, Group, KeyBinding, binding_for};
|
||||
use crate::app::{
|
||||
helpers::block_single_title_helper,
|
||||
keybindings::{Action, Group, KeyBinding, binding_for},
|
||||
};
|
||||
use clap::ValueEnum;
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
style::Stylize,
|
||||
style::{Color, Stylize},
|
||||
text::Line,
|
||||
widgets::{Block, Borders, Padding, Paragraph, Widget},
|
||||
};
|
||||
@@ -72,11 +75,7 @@ impl Widget for KeybindingsWidget {
|
||||
|
||||
let block: Block<'_> = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.title(Line::from_iter([
|
||||
"[ ".gray(),
|
||||
"Keybindings".magenta(),
|
||||
" ]".gray(),
|
||||
]));
|
||||
.title(block_single_title_helper("Keybindings", Color::Magenta));
|
||||
|
||||
let inner: Rect = block.inner(area);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user