okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
7813617
upstream
1// Package screen provides functions and helpers to manipulate a [uv.Screen]. 2package screen 3 4import ( 5 uv"github.com/charmbracelet/ultraviolet" 6) 7 8// Clear clears the screen with empty cells. This is equivalent to filling the 9// screen with empty cells. 10// 11// If the screen implements a [Clear] method, it will be called instead of 12// filling the screen with empty cells. 13func Clear (scr uv.Screen ) { 14if c ,ok := scr .(interface { 15Clear () 16 });ok { 17c .Clear () 18return 19 } 20Fill (scr ,nil ) 21} 22 23// ClearArea clears the given area of the screen with empty cells. This is 24// equivalent to filling the area with empty cells. 25// 26// If the screen implements a [ClearArea] method, it will be called instead of 27// filling the area with empty cells. 28func ClearArea (scr uv.Screen ,area uv.Rectangle ) { 29if c ,ok := scr .(interface { 30ClearArea (area uv.Rectangle ) 31 });ok { 32c .ClearArea (area ) 33return 34 } 35FillArea (scr ,nil ,area ) 36} 37 38// Fill fills the screen with the given cell. If the cell is nil, it fills the 39// screen with empty cells. 40// 41// If the screen implements a [Fill] method, it will be called instead of 42// filling the screen with empty cells. 43func Fill (scr uv.Screen ,cell * uv.Cell ) { 44if f ,ok := scr .(interface { 45Fill (cell * uv.Cell ) 46 });ok { 47f .Fill (cell ) 48return 49 } 50FillArea (scr ,cell ,scr .Bounds ()) 51} 52 53// FillArea fills the given area of the screen with the given cell. If the cell 54// is nil, it fills the area with empty cells. 55// 56// If the screen implements a [FillArea] method, it will be called instead of 57// filling the area with empty cells. 58func FillArea (scr uv.Screen ,cell * uv.Cell ,area uv.Rectangle ) { 59if f ,ok := scr .(interface { 60FillArea (cell * uv.Cell ,area uv.Rectangle ) 61 });ok { 62f .FillArea (cell ,area ) 63return 64 } 65cellWidth := 1 66if cell != nil && cell .Width > 1 { 67cellWidth = cell .Width 68 } 69for y := area .Min .Y ;y < area .Max .Y ;y ++ { 70for x := area .Min .X ;x < area .Max .X ;x += cellWidth { 71scr .SetCell (x ,y ,cell ) 72 } 73 } 74} 75 76// CloneArea clones the given area of the screen and returns a new buffer 77// with the same size as the area. The new buffer will contain the same cells 78// as the area in the screen. 79// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again. 80// 81// If the screen implements a [CloneArea] method, it will be called instead of 82// cloning the area manually. 83func CloneArea (scr uv.Screen ,area uv.Rectangle )* uv.Buffer { 84if c ,ok := scr .(interface { 85CloneArea (area uv.Rectangle )* uv.Buffer 86 });ok { 87return c .CloneArea (area ) 88 } 89buf := uv .NewBuffer (area .Dx (),area .Dy ()) 90for y := area .Min .Y ;y < area .Max .Y ;y ++ { 91for x := area .Min .X ;x < area .Max .X ; { 92cell := scr .CellAt (x ,y ) 93if cell == nil || cell .IsZero () { 94x ++ 95continue 96 } 97buf .SetCell (x - area .Min .X ,y - area .Min .Y ,cell ) 98x += max (cell .Width ,1 ) 99 } 100 } 101return buf 102} 103 104// Clone creates a new [uv.Buffer] clone of the given screen. The new buffer will 105// have the same size as the screen and will contain the same cells. 106// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again. 107// 108// If the screen implements a [Clone] method, it will be called instead of 109// cloning the entire screen manually. 110func Clone (scr uv.Screen )* uv.Buffer { 111if c ,ok := scr .(interface { 112Clone ()* uv.Buffer 113 });ok { 114return c .Clone () 115 } 116return CloneArea (scr ,scr .Bounds ()) 117}