diff options
author | Daniel Baumann <daniel@debian.org> | 2024-10-20 23:07:42 +0200 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-11-09 15:38:42 +0100 |
commit | 714c83b2736d7e308bc33c49057952490eb98be2 (patch) | |
tree | 1d9ba7035798368569cd49056f4d596efc908cd8 /pkg/common/draw.go | |
parent | Initial commit. (diff) | |
download | forgejo-act-upstream/1.21.4.tar.xz forgejo-act-upstream/1.21.4.zip |
Adding upstream version 1.21.4.HEADupstream/1.21.4upstreamdebian
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'pkg/common/draw.go')
-rw-r--r-- | pkg/common/draw.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/pkg/common/draw.go b/pkg/common/draw.go new file mode 100644 index 0000000..b5b21fe --- /dev/null +++ b/pkg/common/draw.go @@ -0,0 +1,143 @@ +package common + +import ( + "fmt" + "io" + "os" + "strings" +) + +// Style is a specific style +type Style int + +// Styles +const ( + StyleDoubleLine = iota + StyleSingleLine + StyleDashedLine + StyleNoLine +) + +// NewPen creates a new pen +func NewPen(style Style, color int) *Pen { + bgcolor := 49 + if os.Getenv("CLICOLOR") == "0" { + color = 0 + bgcolor = 0 + } + return &Pen{ + style: style, + color: color, + bgcolor: bgcolor, + } +} + +type styleDef struct { + cornerTL string + cornerTR string + cornerBL string + cornerBR string + lineH string + lineV string +} + +var styleDefs = []styleDef{ + {"\u2554", "\u2557", "\u255a", "\u255d", "\u2550", "\u2551"}, + {"\u256d", "\u256e", "\u2570", "\u256f", "\u2500", "\u2502"}, + {"\u250c", "\u2510", "\u2514", "\u2518", "\u254c", "\u254e"}, + {" ", " ", " ", " ", " ", " "}, +} + +// Pen struct +type Pen struct { + style Style + color int + bgcolor int +} + +// Drawing struct +type Drawing struct { + buf *strings.Builder + width int +} + +func (p *Pen) drawTopBars(buf io.Writer, labels ...string) { + style := styleDefs[p.style] + for _, label := range labels { + bar := strings.Repeat(style.lineH, len(label)+2) + fmt.Fprintf(buf, " ") + fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor) + fmt.Fprintf(buf, "%s%s%s", style.cornerTL, bar, style.cornerTR) + fmt.Fprintf(buf, "\x1b[%dm", 0) + } + fmt.Fprintf(buf, "\n") +} +func (p *Pen) drawBottomBars(buf io.Writer, labels ...string) { + style := styleDefs[p.style] + for _, label := range labels { + bar := strings.Repeat(style.lineH, len(label)+2) + fmt.Fprintf(buf, " ") + fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor) + fmt.Fprintf(buf, "%s%s%s", style.cornerBL, bar, style.cornerBR) + fmt.Fprintf(buf, "\x1b[%dm", 0) + } + fmt.Fprintf(buf, "\n") +} +func (p *Pen) drawLabels(buf io.Writer, labels ...string) { + style := styleDefs[p.style] + for _, label := range labels { + fmt.Fprintf(buf, " ") + fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor) + fmt.Fprintf(buf, "%s %s %s", style.lineV, label, style.lineV) + fmt.Fprintf(buf, "\x1b[%dm", 0) + } + fmt.Fprintf(buf, "\n") +} + +// DrawArrow between boxes +func (p *Pen) DrawArrow() *Drawing { + drawing := &Drawing{ + buf: new(strings.Builder), + width: 1, + } + fmt.Fprintf(drawing.buf, "\x1b[%dm", p.color) + fmt.Fprintf(drawing.buf, "\u2b07") + fmt.Fprintf(drawing.buf, "\x1b[%dm", 0) + return drawing +} + +// DrawBoxes to draw boxes +func (p *Pen) DrawBoxes(labels ...string) *Drawing { + width := 0 + for _, l := range labels { + width += len(l) + 2 + 2 + 1 + } + drawing := &Drawing{ + buf: new(strings.Builder), + width: width, + } + p.drawTopBars(drawing.buf, labels...) + p.drawLabels(drawing.buf, labels...) + p.drawBottomBars(drawing.buf, labels...) + + return drawing +} + +// Draw to writer +func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) { + padSize := (centerOnWidth - d.GetWidth()) / 2 + if padSize < 0 { + padSize = 0 + } + for _, l := range strings.Split(d.buf.String(), "\n") { + if len(l) > 0 { + padding := strings.Repeat(" ", padSize) + fmt.Fprintf(writer, "%s%s\n", padding, l) + } + } +} + +// GetWidth of drawing +func (d *Drawing) GetWidth() int { + return d.width +} |