Selkie.git | xt/snapshots/ | 56-gradient-stain-styled.raku


use lib 'lib';
use Selkie::Test::Snapshot;
use Selkie::Gradient;
use Selkie::Sizing;
use Selkie::Style;
use Selkie::Widget;

use Notcurses::Native;
use Notcurses::Native::Plane;

# gradient-stain recolours glyphs that are already on the plane and
# SKIPS every cell whose gcluster is 0 — which, after ncplane_erase, is
# every cell the widget never wrote to. This scenario pins both halves
# of that contract in one render:
#
#   row 0 is space-padded out to the full width, so the stain catches
#         all 20 cells and the whole bar carries the ramp;
#   row 1 is written without padding, so the stain catches only the 10
#         cells that have glyphs and the rest keep the base cell's
#         colours (and get trimmed out of the golden entirely).
#
# The difference in row length between the two style rows in the golden
# IS the assertion.
class StainedRows does Selkie::Widget {
    # Pin the base cell rather than inheriting Selkie::Theme.default's,
    # so the one legend entry contributed by the unstained cells does
    # not move when the default theme is edited.
    method base-style(--> Selkie::Style) {
        Selkie::Style.new(fg => 0x606060, bg => 0x202020);
    }

    method render() {
        return without self.plane;
        my $w = self.cols;
        return if $w == 0;

        self.apply-style(Selkie::Style.new(fg => 0xC0C0C0, bg => 0x1A1A2E));
        ncplane_erase(self.plane);

        # Padded: label on the left, a right-hand segment on the end so
        # the row has a glyph in its last column (the styled readback
        # trims trailing spaces, which would otherwise hide the padding
        # the stain is meant to demonstrate).
        my $left  = 'stain me';
        my $right = 'OK';
        my $pad   = $w - $left.chars - $right.chars;
        ncplane_putstr_yx(self.plane, 0, 0, $left ~ ' ' x $pad ~ $right);

        # Unpadded: cells 10..19 stay at gcluster 0.
        ncplane_putstr_yx(self.plane, 1, 0, 'no padding');

        # AFTER the text, never before. Explicit :fg — an omitted one
        # would reset the glyphs to the terminal default colour.
        gradient-stain(
            self.plane,
            Gradient.horizontal(0x004000, 0x00C000),
            fg => Gradient.uniform(0xFFFFFF),
        );

        self.clear-dirty;
    }
}

print render-to-string(StainedRows.new(sizing => Sizing.flex),
                       rows => 2, cols => 20, :capture-styles);