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);  # True

Deriving 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

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:D

The โ”Œโ”โ””โ”˜โ”€โ”‚ set. Selkie's default, and byte-identical to what Border painted before glyph sets existed.

method rounded

method rounded() returns Selkie::BorderStyle::BorderGlyphs:D

The โ•ญโ•ฎโ•ฐโ•ฏโ”€โ”‚ set โ€” single-weight edges, arc corners.

method double

method double() returns Selkie::BorderStyle::BorderGlyphs:D

The โ•”โ•—โ•šโ•โ•โ•‘ set โ€” double-ruled edges.

method heavy

method heavy() returns Selkie::BorderStyle::BorderGlyphs:D

The โ”โ”“โ”—โ”›โ”โ”ƒ set โ€” heavy-weight edges.

method ascii

method ascii() returns Selkie::BorderStyle::BorderGlyphs:D

The + + + + - | set โ€” 7-bit ASCII only.

method for

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.

Selkie v0.11.1

High-level TUI framework built on Notcurses

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

Notcurses::Native:ver<0.4.1+>:auth<zef:apogee>

Test Dependencies

Provides

  • Selkie
  • Selkie::Align
  • Selkie::Alpha
  • Selkie::App
  • Selkie::App::Internal::Animation
  • Selkie::App::Internal::Dispatch
  • Selkie::App::Internal::ErrorLog
  • Selkie::App::Internal::FocusTree
  • Selkie::App::Internal::HitTest
  • Selkie::App::Internal::IdleBudget
  • Selkie::App::Internal::OverlayTree
  • Selkie::App::Internal::RenderLoop
  • Selkie::App::Internal::ScreenModalLifecycle
  • Selkie::App::Internal::Terminal
  • Selkie::App::Internal::TerminalSequences
  • Selkie::BorderStyle
  • Selkie::Container
  • Selkie::EffectiveBounds
  • Selkie::Event
  • Selkie::Gradient
  • Selkie::Layout::Allocate
  • Selkie::Layout::HBox
  • Selkie::Layout::Split
  • Selkie::Layout::VBox
  • Selkie::Plot::Palette
  • Selkie::Plot::Scaler
  • Selkie::Plot::Ticks
  • Selkie::ScreenManager
  • Selkie::Sizing
  • Selkie::Store
  • Selkie::Style
  • Selkie::Test::Focus
  • Selkie::Test::Keys
  • Selkie::Test::Snapshot
  • Selkie::Test::Snapshot::Harness
  • Selkie::Test::Store
  • Selkie::Test::Supply
  • Selkie::Test::Tree
  • Selkie::Theme
  • Selkie::Trace
  • Selkie::Tree
  • Selkie::Tween
  • Selkie::Widget
  • Selkie::Widget::Axis
  • Selkie::Widget::BarChart
  • Selkie::Widget::Border
  • Selkie::Widget::Button
  • Selkie::Widget::CardList
  • Selkie::Widget::Checkbox
  • Selkie::Widget::CommandPalette
  • Selkie::Widget::ConfirmModal
  • Selkie::Widget::FileBrowser
  • Selkie::Widget::FocusableByDefault
  • Selkie::Widget::GradientFill
  • Selkie::Widget::Heatmap
  • Selkie::Widget::HelpOverlay
  • Selkie::Widget::Histogram
  • Selkie::Widget::Image
  • Selkie::Widget::Legend
  • Selkie::Widget::LineChart
  • Selkie::Widget::ListView
  • Selkie::Widget::Modal
  • Selkie::Widget::MultiLineInput
  • Selkie::Widget::PasswordStrength
  • Selkie::Widget::Plot
  • Selkie::Widget::ProgressBar
  • Selkie::Widget::RadioGroup
  • Selkie::Widget::RichText
  • Selkie::Widget::RichText::Span
  • Selkie::Widget::ScatterPlot
  • Selkie::Widget::ScrollView
  • Selkie::Widget::Select
  • Selkie::Widget::Sparkline
  • Selkie::Widget::Spinner
  • Selkie::Widget::TabBar
  • Selkie::Widget::Table
  • Selkie::Widget::Text
  • Selkie::Widget::TextInput
  • Selkie::Widget::TextInput::HighlightSpan
  • Selkie::Widget::TextStream
  • Selkie::Widget::Toast
  • Selkie::Widget::ViewportedCardList

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.

Built with Podlite โ€” the markup and publishing tools behind this site.