pub struct Panel<'a> { /* private fields */ }Expand description
A bordered panel: a filled background with a box border and, optionally, one or more titles along the top and/or bottom edge.
border_style (the box outline and titles) and fill_style (the
interior background) both default to Theme::DARK (as if Panel::theme had been called);
there is no title by default, and the title set by Panel::title (if any) defaults to
Align::Center. Set whichever of these a caller needs via
Panel::border_style/Panel::fill_style/Panel::title/Panel::title_align.
Panel::title is sugar for the common case: one top, centered (by default) title. For
anything past that (a bottom title, more than one title on an edge, or a title aligned other
than via title_align), use Panel::add_title, which is fully additive: it never disturbs
title/title_align, and multiple add_title calls stack rather than overwrite each other.
§Examples
use retroglyph_core::grid::{Grid, Rect};
use retroglyph_ui::{Align, Panel, Surface, TitlePosition, Widget};
let area = Rect::new(0, 0, 20, 5);
let mut grid = Grid::new(20, 5);
Panel::new()
.title("Status")
.add_title("3 / 10", TitlePosition::Bottom, Align::Right)
.render(&mut Surface::new(&mut grid, area, 0));Not Copy (unlike most other widgets here): Panel::add_title stores its titles in a
Vec, so an unbounded number of them is exactly as cheap, and as fallible in the same ways
(only an allocation failure, never a silently dropped title), as pushing onto any other Vec.
Implementations§
Source§impl<'a> Panel<'a>
impl<'a> Panel<'a>
Sourcepub fn new() -> Self
pub fn new() -> Self
A plain, untitled panel, styled from Theme::DARK (as if Panel::theme had been
called).
Sourcepub const fn title_align(self, align: Align) -> Self
pub const fn title_align(self, align: Align) -> Self
Set how the title is aligned along the top border. Defaults to
Align::Center.
Sourcepub fn add_title(
self,
title: &'a str,
position: TitlePosition,
align: Align,
) -> Self
pub fn add_title( self, title: &'a str, position: TitlePosition, align: Align, ) -> Self
Add a title to position’s edge, aligned per align. Additive and independent of
Panel::title and of every other add_title call: nothing here overwrites another
title, so a top-left title plus a top-right status, or a top title plus a bottom hint
bar, is two calls (or three, alongside .title(...)) rather than two overlapping
Panels.
Multiple titles are allowed on the same edge. Each is drawn in declaration order:
.title(...)’s implicit top title first (if set), then add_title calls in the order
they were made, truncated to whatever room is left on that title’s edge after the
titles declared before it on the same edge have claimed theirs, the same way a single
title already truncates to fit the whole edge. A title that has no room left once earlier
titles on its edge are placed is clipped down to nothing rather than overdrawing them or
panicking. Because a Align::Center title claims its edge’s entire remaining span, a
title declared after a centered one on the same edge always has no room left; put
non-centered titles first if a centered one needs to share an edge.
Unbounded: every call is kept (this is what makes Panel not Copy; see its own doc
comment), there is no cap to silently drop past.
Sourcepub const fn border_style(self, style: Style) -> Self
pub const fn border_style(self, style: Style) -> Self
Set the box outline and title’s style.
Sourcepub const fn fill_style(self, style: Style) -> Self
pub const fn fill_style(self, style: Style) -> Self
Set the interior background’s style.
Sourcepub const fn border_type(self, border_type: BorderType) -> Self
pub const fn border_type(self, border_type: BorderType) -> Self
Set which box-drawing glyphs the border is drawn with. Defaults to
BorderType::Plain, the same as BoxBorder::border_type.
Sourcepub const fn padding(self, padding: Sides) -> Self
pub const fn padding(self, padding: Sides) -> Self
Reserve padding between the border and the rect Panel::inner returns.
Padding is not painted specially: Panel::render still fills the whole area inside the
border with fill_style (padding cells included), the same as Panel::inner’s caller
would see if they filled area themselves before drawing into the smaller inner rect.
Defaults to Sides::ZERO (no padding beyond the 1-cell border).
Sourcepub const fn inner(&self, area: Rect) -> Rect
pub const fn inner(&self, area: Rect) -> Rect
The content rect inside area’s border and padding, ready to hand to another widget.
Derived from the same 1-cell border inset Panel::render uses plus this panel’s
Panel::padding, so the two can’t drift. Saturates to a zero-sized rect (at area’s
origin) rather than underflowing when area is too small to hold the border and padding.
§Examples
use retroglyph_core::grid::Rect;
use retroglyph_ui::{Panel, Sides};
let panel = Panel::new().padding(Sides::symmetric(0, 1));
let area = Rect::new(0, 0, 20, 5);
assert_eq!(panel.inner(area), Rect::new(2, 1, 16, 3));Sourcepub fn theme(self, theme: Theme) -> Self
pub fn theme(self, theme: Theme) -> Self
Applies theme’s named roles to this panel’s border and fill: border_style becomes
theme.border on theme.title_bg (the same background the title, if any, is drawn on),
and fill_style becomes theme.panel_bg.
Like every other builder method here, whichever call comes last wins: call .theme(...)
before any manual Panel::border_style/Panel::fill_style override you want to keep.
Sourcepub fn theme_on(self, theme: Theme, bg: Color) -> Self
pub fn theme_on(self, theme: Theme, bg: Color) -> Self
Same as Panel::theme, but fill_style is drawn on bg instead of theme.panel_bg –
for a panel whose interior should read as a different surface than theme.panel_bg
(border_style still uses theme.title_bg, unaffected by bg). Panel::theme is
exactly theme_on(theme, theme.panel_bg).
Trait Implementations§
Source§impl Measure for Panel<'_>
impl Measure for Panel<'_>
Source§fn height_for(&self, _width: u16) -> u16
fn height_for(&self, _width: u16) -> u16
The 1-cell border on each edge plus this panel’s Panel::padding (the height a
zero-height inner content area would need), matching Panel::inner’s own vertical inset.
Every title (the one set by Panel::title, and any added by Panel::add_title,
whichever edge it’s on) is drawn into its border row rather than adding one of its own, so
none of them add to this count. width is unused: Panel never wraps content of its own,
only whatever a caller renders into Panel::inner, so it has nothing to measure against
width yet.