Selkie--BorderStyle
NAME
Selkie::BorderStyle - Box-drawing glyph sets and title alignment for framed widgets
SYNOPSIS
use Selkie::BorderStyle;
use Selkie::Widget::Border;
# Pick a stock glyph set by kind.
my $panel = Selkie::Widget::Border.new(
title => 'Characters',
border-style => BorderRounded,
title-align => TitleCenter,
);
# Or hand it a bespoke glyph table.
my $dashed = Selkie::BorderStyle::BorderGlyphs.new(
top-left => '.', top-right => '.',
bottom-left => "'", bottom-right => "'",
horizontal => '-', vertical => ':',
);
$panel.set-border-glyphs($dashed);DESCRIPTION
Two enums and a value class, shared by every widget that paints a frame.
BorderKind names the five stock glyph sets; BorderGlyphs is the six-glyph table one of those names resolves to (or that you build yourself); TitleAlign says where a title sits along its edge.
The glyph tables, in top-left top-right bottom-left bottom-right horizontal vertical order:
BorderSingle โ โ โ โ โ โ โโโโโโโโโโ
BorderRounded โญ โฎ โฐ โฏ โ โ โ single โ
BorderDouble โ โ โ โ โ โ โโโโโโโโโโ
BorderHeavy โ โ โ โ โ โ
BorderAscii + + + + - | โญโโโโโโโโโฎ
โrounded โ
โฐโโโโโโโโโฏNo automatic downgrade
Selkie never inspects the locale, TERM, or the terminal's reported capabilities to swap a Unicode glyph set for an ASCII one. Auto-downgrade would make rendering โ and therefore snapshot tests โ depend on the environment the process happens to run in, which is exactly the class of bug snapshot tests exist to catch.
BorderAscii is the escape hatch. If your app must run somewhere the box-drawing block isn't available, decide that yourself (a config flag, a --ascii switch, a %*ENV probe you own) and pass BorderAscii:
my $kind = %*ENV<MYAPP_ASCII> ?? BorderAscii !! BorderRounded;
Selkie::Widget::Border.new(:title('Log'), border-style => $kind);Custom glyph tables
Every glyph is a Str, not a codepoint, so multi-codepoint clusters work. Keep each one a single column wide though โ the frame painter assumes one cell per glyph, and a double-width glyph (CJK, most emoji) will push the frame out of alignment. Emitting a run of cols - 2 horizontals is a single putstr, so a wide horizontal glyph overflows the right corner rather than being clipped.
EXAMPLES
Resolving a kind to its table
my $g = Selkie::BorderStyle::BorderGlyphs.for(BorderDouble);
say $g.top-left; # โ
say $g.horizontal; # โ
# Resolution is cached โ the same kind always returns the same object.
say BorderGlyphs.for(BorderDouble) === BorderGlyphs.for(BorderDouble); # TrueDeriving a table from a stock one
BorderGlyphs is immutable; clone is the way to vary one glyph.
my $studded = BorderGlyphs.for(BorderSingle).clone(
top-left => 'โค', top-right => 'โฅ',
);Aligning titles
$panel.set-title-align(TitleCenter);
$panel.set-bottom-title('โ/โ scroll q quit');
$panel.set-bottom-title-align(TitleRight);SEE ALSO
Selkie::Widget::Border โ the widget that consumes all of this
Selkie::Theme โ
border/border-focusedslots pick the frame's colours; the glyph set is orthogonal
The five stock box-drawing glyph sets. BorderSingle is the default everywhere and the only one that was available before Selkie 0.11. BorderRounded is the same weight with arc corners. BorderDouble and BorderHeavy read as emphasis. BorderAscii uses nothing outside 7-bit ASCII and is the manual escape hatch for terminals or fonts without the box-drawing block โ Selkie never selects it for you (see the module Pod).
Where a title sits along the edge it's drawn on. TitleLeft is the historical (and default) placement: two columns in from the left corner. TitleCenter centres the decorated title across the full width. TitleRight ends it two columns short of the right corner. All three are clamped so the corner glyphs are never overwritten.
class Selkie::BorderStyle::BorderGlyphs
The six glyphs it takes to paint a box: four corners, one horizontal, one vertical. Build one with .for(BorderKind) for a stock set, .new for a bespoke table, or .clone off a stock set to vary a glyph or two. Instances are immutable value objects and safe to share between widgets.
has Str:D $.top-left
Top-left corner glyph, e.g. โ.
has Str:D $.top-right
Top-right corner glyph, e.g. โ.
has Str:D $.bottom-left
Bottom-left corner glyph, e.g. โ.
has Str:D $.bottom-right
Bottom-right corner glyph, e.g. โ.
has Str:D $.horizontal
Glyph tiled along the top and bottom edges, e.g. โ.
has Str:D $.vertical
Glyph drawn down the left and right edges, e.g. โ.
method single
method single() returns Selkie::BorderStyle::BorderGlyphs:DThe โโโโโโ set. Selkie's default, and byte-identical to what Border painted before glyph sets existed.
method rounded
method rounded() returns Selkie::BorderStyle::BorderGlyphs:DThe โญโฎโฐโฏโโ set โ single-weight edges, arc corners.
method double
method double() returns Selkie::BorderStyle::BorderGlyphs:DThe โโโโโโ set โ double-ruled edges.
method heavy
method heavy() returns Selkie::BorderStyle::BorderGlyphs:DThe โโโโโโ set โ heavy-weight edges.
method ascii
method ascii() returns Selkie::BorderStyle::BorderGlyphs:DThe + + + + - | set โ 7-bit ASCII only.
method for
method for(
BorderKind:D $kind
) returns Selkie::BorderStyle::BorderGlyphs:DResolve a BorderKind to its glyph table. Cached: the same kind always yields the very same object, so callers can compare with === and render loops don't allocate.