@@ -0,0 +1,109 @@
1+// Package screen provides functions and helpers to manipulate a [uv.Screen].
4+import uv "github.com/charmbracelet/ultraviolet"
6+// Clear clears the screen with empty cells. This is equivalent to filling the
7+// screen with empty cells.
9+// If the screen implements a [Clear] method, it will be called instead of
10+// filling the screen with empty cells.
11+func Clear(scr uv.Screen) {
12+ if c, ok := scr.(interface {
21+// ClearArea clears the given area of the screen with empty cells. This is
22+// equivalent to filling the area with empty cells.
24+// If the screen implements a [ClearArea] method, it will be called instead of
25+// filling the area with empty cells.
26+func ClearArea(scr uv.Screen, area uv.Rectangle) {
27+ if c, ok := scr.(interface {
28+ ClearArea(area uv.Rectangle)
33+ FillArea(scr, nil, area)
36+// Fill fills the screen with the given cell. If the cell is nil, it fills the
37+// screen with empty cells.
39+// If the screen implements a [Fill] method, it will be called instead of
40+// filling the screen with empty cells.
41+func Fill(scr uv.Screen, cell *uv.Cell) {
42+ if f, ok := scr.(interface {
48+ FillArea(scr, cell, scr.Bounds())
51+// FillArea fills the given area of the screen with the given cell. If the cell
52+// is nil, it fills the area with empty cells.
54+// If the screen implements a [FillArea] method, it will be called instead of
55+// filling the area with empty cells.
56+func FillArea(scr uv.Screen, cell *uv.Cell, area uv.Rectangle) {
57+ if f, ok := scr.(interface {
58+ FillArea(cell *uv.Cell, area uv.Rectangle)
60+ f.FillArea(cell, area)
63+ for y := area.Min.Y; y < area.Max.Y; y++ {
64+ for x := area.Min.X; x < area.Max.X; x++ {
65+ scr.SetCell(x, y, cell)
70+// CloneArea clones the given area of the screen and returns a new buffer
71+// with the same size as the area. The new buffer will contain the same cells
72+// as the area in the screen.
73+// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again.
75+// If the screen implements a [CloneArea] method, it will be called instead of
76+// cloning the area manually.
77+func CloneArea(scr uv.Screen, area uv.Rectangle) *uv.Buffer {
78+ if c, ok := scr.(interface {
79+ CloneArea(area uv.Rectangle) *uv.Buffer
81+ return c.CloneArea(area)
83+ buf := uv.NewBuffer(area.Dx(), area.Dy())
84+ for y := area.Min.Y; y < area.Max.Y; y++ {
85+ for x := area.Min.X; x < area.Max.X; x++ {
86+ cell := scr.CellAt(x, y)
87+ if cell == nil || cell.IsZero() {
90+ buf.SetCell(x-area.Min.X, y-area.Min.Y, cell.Clone())
96+// Clone creates a new [uv.Buffer] clone of the given screen. The new buffer will
97+// have the same size as the screen and will contain the same cells.
98+// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again.
100+// If the screen implements a [Clone] method, it will be called instead of
101+// cloning the entire screen manually.
102+func Clone(scr uv.Screen) *uv.Buffer {
103+ if c, ok := scr.(interface {
108+ return CloneArea(scr, scr.Bounds())