cri-o/vendor/github.com/buger/goterm/box.go

123 lines
2.5 KiB
Go

package goterm
import (
"bytes"
"strings"
)
const DEFAULT_BORDER = "- │ ┌ ┐ └ ┘"
// Box allows you to create independent parts of screen, with its own buffer and borders.
// Can be used for creating modal windows
//
// Generates boxes likes this:
// ┌--------┐
// │hello │
// │world │
// │ │
// └--------┘
//
type Box struct {
Buf *bytes.Buffer
Width int
Height int
// To get even padding: PaddingX ~= PaddingY*4
PaddingX int
PaddingY int
// Should contain 6 border pieces separated by spaces
//
// Example border:
// "- │ ┌ ┐ └ ┘"
Border string
Flags int // Not used now
}
// Create new Box.
// Width and height can be relative:
//
// // Create box with 50% with of current screen and 10 lines height
// box := tm.NewBox(50|tm.PCT, 10, 0)
//
func NewBox(width, height int, flags int) *Box {
width, height = GetXY(width, height)
box := new(Box)
box.Buf = new(bytes.Buffer)
box.Width = width
box.Height = height
box.Border = DEFAULT_BORDER
box.PaddingX = 1
box.PaddingY = 0
box.Flags = flags
return box
}
func (b *Box) Write(p []byte) (int, error) {
return b.Buf.Write(p)
}
// Render Box
func (b *Box) String() (out string) {
borders := strings.Split(b.Border, " ")
lines := strings.Split(b.Buf.String(), "\n")
// Border + padding
prefix := borders[1] + strings.Repeat(" ", b.PaddingX)
suffix := strings.Repeat(" ", b.PaddingX) + borders[1]
offset := b.PaddingY + 1 // 1 is border width
// Content width without borders and padding
contentWidth := b.Width - (b.PaddingX+1)*2
for y := 0; y < b.Height; y++ {
var line string
switch {
// Draw borders for first line
case y == 0:
line = borders[2] + strings.Repeat(borders[0], b.Width-2) + borders[3]
// Draw borders for last line
case y == (b.Height - 1):
line = borders[4] + strings.Repeat(borders[0], b.Width-2) + borders[5]
// Draw top and bottom padding
case y <= b.PaddingY || y >= (b.Height-b.PaddingY):
line = borders[1] + strings.Repeat(" ", b.Width-2) + borders[1]
// Render content
default:
if len(lines) > y-offset {
line = lines[y-offset]
} else {
line = ""
}
if len(line) > contentWidth-1 {
// If line is too large limit it
line = line[0:contentWidth]
} else {
// If line is too small enlarge it by adding spaces
line = line + strings.Repeat(" ", contentWidth-len(line))
}
line = prefix + line + suffix
}
// Don't add newline for last element
if y != b.Height-1 {
line = line + "\n"
}
out += line
}
return out
}