okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
f54d8ec
main
1package uv 2 3// NormalBorder returns a standard-type border with a normal weight and 90 4// degree corners. 5func NormalBorder ()Border { 6return Border { 7Top :Side {Content :"─" }, 8Bottom :Side {Content :"─" }, 9Left :Side {Content :"│" }, 10Right :Side {Content :"│" }, 11TopLeft :Side {Content :"┌" }, 12TopRight :Side {Content :"┐" }, 13BottomLeft :Side {Content :"└" }, 14BottomRight :Side {Content :"┘" }, 15 } 16} 17 18// RoundedBorder returns a border with rounded corners. 19func RoundedBorder ()Border { 20return Border { 21Top :Side {Content :"─" }, 22Bottom :Side {Content :"─" }, 23Left :Side {Content :"│" }, 24Right :Side {Content :"│" }, 25TopLeft :Side {Content :"╭" }, 26TopRight :Side {Content :"╮" }, 27BottomLeft :Side {Content :"╰" }, 28BottomRight :Side {Content :"╯" }, 29 } 30} 31 32// BlockBorder returns a border that takes the whole block. 33func BlockBorder ()Border { 34return Border { 35Top :Side {Content :"█" }, 36Bottom :Side {Content :"█" }, 37Left :Side {Content :"█" }, 38Right :Side {Content :"█" }, 39TopLeft :Side {Content :"█" }, 40TopRight :Side {Content :"█" }, 41BottomLeft :Side {Content :"█" }, 42BottomRight :Side {Content :"█" }, 43 } 44} 45 46// OuterHalfBlockBorder returns a half-block border that sits outside the frame. 47func OuterHalfBlockBorder ()Border { 48return Border { 49Top :Side {Content :"▀" }, 50Bottom :Side {Content :"▄" }, 51Left :Side {Content :"▌" }, 52Right :Side {Content :"▐" }, 53TopLeft :Side {Content :"▛" }, 54TopRight :Side {Content :"▜" }, 55BottomLeft :Side {Content :"▙" }, 56BottomRight :Side {Content :"▟" }, 57 } 58} 59 60// InnerHalfBlockBorder returns a half-block border that sits inside the frame. 61func InnerHalfBlockBorder ()Border { 62return Border { 63Top :Side {Content :"▄" }, 64Bottom :Side {Content :"▀" }, 65Left :Side {Content :"▐" }, 66Right :Side {Content :"▌" }, 67TopLeft :Side {Content :"▗" }, 68TopRight :Side {Content :"▖" }, 69BottomLeft :Side {Content :"▝" }, 70BottomRight :Side {Content :"▘" }, 71 } 72} 73 74// ThickBorder returns a border that's thicker than the one returned by 75// NormalBorder. 76func ThickBorder ()Border { 77return Border { 78Top :Side {Content :"━" }, 79Bottom :Side {Content :"━" }, 80Left :Side {Content :"┃" }, 81Right :Side {Content :"┃" }, 82TopLeft :Side {Content :"┏" }, 83TopRight :Side {Content :"┓" }, 84BottomLeft :Side {Content :"┗" }, 85BottomRight :Side {Content :"┛" }, 86 } 87} 88 89// DoubleBorder returns a border comprised of two thin strokes. 90func DoubleBorder ()Border { 91return Border { 92Top :Side {Content :"═" }, 93Bottom :Side {Content :"═" }, 94Left :Side {Content :"║" }, 95Right :Side {Content :"║" }, 96TopLeft :Side {Content :"╔" }, 97TopRight :Side {Content :"╗" }, 98BottomLeft :Side {Content :"╚" }, 99BottomRight :Side {Content :"╝" }, 100 } 101} 102 103// HiddenBorder returns a border that renders as a series of single-cell 104// spaces. It's useful for cases when you want to remove a standard border but 105// maintain layout positioning. This said, you can still apply a background 106// color to a hidden border. 107func HiddenBorder ()Border { 108return Border { 109Top :Side {Content :" " }, 110Bottom :Side {Content :" " }, 111Left :Side {Content :" " }, 112Right :Side {Content :" " }, 113TopLeft :Side {Content :" " }, 114TopRight :Side {Content :" " }, 115BottomLeft :Side {Content :" " }, 116BottomRight :Side {Content :" " }, 117 } 118} 119 120// MarkdownBorder return a table border in markdown style. 121func MarkdownBorder ()Border { 122return Border { 123Left :Side {Content :"|" }, 124Right :Side {Content :"|" }, 125TopLeft :Side {Content :"|" }, 126TopRight :Side {Content :"|" }, 127BottomLeft :Side {Content :"|" }, 128BottomRight :Side {Content :"|" }, 129 } 130} 131 132// ASCIIBorder returns a table border with ASCII characters. 133func ASCIIBorder ()Border { 134return Border { 135Top :Side {Content :"-" }, 136Bottom :Side {Content :"-" }, 137Left :Side {Content :"|" }, 138Right :Side {Content :"|" }, 139TopLeft :Side {Content :"+" }, 140TopRight :Side {Content :"+" }, 141BottomLeft :Side {Content :"+" }, 142BottomRight :Side {Content :"+" }, 143 } 144} 145 146// Side represents a single border side with its properties. 147type Side struct { 148Content string 149Style 150Link 151} 152 153// Border represents a border with its properties. 154type Border struct { 155Top Side 156Bottom Side 157Left Side 158Right Side 159TopLeft Side 160TopRight Side 161BottomLeft Side 162BottomRight Side 163} 164 165// Style returns a new [Border] with the given style applied to all [Side]s. 166func (b Border )Style (style Style )Border { 167b .Top .Style = style 168b .Bottom .Style = style 169b .Left .Style = style 170b .Right .Style = style 171b .TopLeft .Style = style 172b .TopRight .Style = style 173b .BottomLeft .Style = style 174b .BottomRight .Style = style 175return b 176} 177 178// Link returns a new [Border] with the given link applied to all [Side]s. 179func (b Border )Link (link Link )Border { 180b .Top .Link = link 181b .Bottom .Link = link 182b .Left .Link = link 183b .Right .Link = link 184b .TopLeft .Link = link 185b .TopRight .Link = link 186b .BottomLeft .Link = link 187b .BottomRight .Link = link 188return b 189} 190 191// Draw draws the border around the given component. 192func (b * Border )Draw (scr Screen ,area Rectangle ) { 193for y := area .Min .Y ;y < area .Max .Y ;y ++ { 194for x := area .Min .X ;x < area .Max .X ;x ++ { 195var cell * Cell 196switch { 197case y == area .Min .Y && x == area .Min .X : 198cell = borderCell (scr ,& b .TopLeft ) 199case y == area .Min .Y && x == area .Max .X - 1 : 200cell = borderCell (scr ,& b .TopRight ) 201case y == area .Max .Y - 1 && x == area .Min .X : 202cell = borderCell (scr ,& b .BottomLeft ) 203case y == area .Max .Y - 1 && x == area .Max .X - 1 : 204cell = borderCell (scr ,& b .BottomRight ) 205case y == area .Min .Y : 206cell = borderCell (scr ,& b .Top ) 207case y == area .Max .Y - 1 : 208cell = borderCell (scr ,& b .Bottom ) 209case x == area .Min .X : 210cell = borderCell (scr ,& b .Left ) 211case x == area .Max .X - 1 : 212cell = borderCell (scr ,& b .Right ) 213default : 214continue 215 } 216if cell == nil { 217continue 218 } 219scr .SetCell (x ,y ,cell ) 220 } 221 } 222} 223 224func borderCell (scr Screen ,b * Side )* Cell { 225c := NewCell (scr .WidthMethod (),b .Content ) 226if c != nil { 227c .Style = b .Style 228c .Link = b .Link 229 } 230return c 231}