Selkie.git | docs/api/ | Selkie--BorderStyle.md
NAME
====
Selkie::BorderStyle - Box-drawing glyph sets and title alignment for framed widgets
SYNOPSIS
========
```raku
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`:
```raku
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
-----------------------------
```raku
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); # True
```
Deriving a table from a stock one
---------------------------------
`BorderGlyphs` is immutable; `clone` is the way to vary one glyph.
```raku
my $studded = BorderGlyphs.for(BorderSingle).clone(
top-left => '◤', top-right => '◥',
);
```
Aligning titles
---------------
```raku
$panel.set-title-align(TitleCenter);
$panel.set-bottom-title('↑/↓ scroll q quit');
$panel.set-bottom-title-align(TitleRight);
```
SEE ALSO
========
* [Selkie::Widget::Border](Selkie--Widget--Border.md) — the widget that consumes all of this
* [Selkie::Theme](Selkie--Theme.md) — `border` / `border-focused` slots 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
```raku
method single() returns Selkie::BorderStyle::BorderGlyphs:D
```
The `┌┐└┘─│` set. Selkie's default, and byte-identical to what `Border` painted before glyph sets existed.
### method rounded
```raku
method rounded() returns Selkie::BorderStyle::BorderGlyphs:D
```
The `╭╮╰╯─│` set — single-weight edges, arc corners.
### method double
```raku
method double() returns Selkie::BorderStyle::BorderGlyphs:D
```
The `╔╗╚╝═║` set — double-ruled edges.
### method heavy
```raku
method heavy() returns Selkie::BorderStyle::BorderGlyphs:D
```
The `┏┓┗┛━┃` set — heavy-weight edges.
### method ascii
```raku
method ascii() returns Selkie::BorderStyle::BorderGlyphs:D
```
The `+ + + + - |` set — 7-bit ASCII only.
### method for
```raku
method for(
BorderKind:D $kind
) returns Selkie::BorderStyle::BorderGlyphs:D
```
Resolve 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.