131 lines
3.1 KiB
Go
131 lines
3.1 KiB
Go
package pterm
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/atomicgo/cursor"
|
|
|
|
"github.com/pterm/pterm/internal"
|
|
)
|
|
|
|
// DefaultArea is the default area printer.
|
|
var DefaultArea = AreaPrinter{}
|
|
|
|
// AreaPrinter prints an area which can be updated easily.
|
|
// use this printer for live output like charts, algorithm visualizations, simulations and even games.
|
|
type AreaPrinter struct {
|
|
RemoveWhenDone bool
|
|
Fullscreen bool
|
|
Center bool
|
|
|
|
content string
|
|
isActive bool
|
|
|
|
area *cursor.Area
|
|
}
|
|
|
|
// GetContent returns the current area content.
|
|
func (p *AreaPrinter) GetContent() string {
|
|
return p.content
|
|
}
|
|
|
|
// WithRemoveWhenDone removes the AreaPrinter content after it is stopped.
|
|
func (p AreaPrinter) WithRemoveWhenDone(b ...bool) *AreaPrinter {
|
|
p.RemoveWhenDone = internal.WithBoolean(b)
|
|
return &p
|
|
}
|
|
|
|
// WithFullscreen sets the AreaPrinter height the same height as the terminal, making it fullscreen.
|
|
func (p AreaPrinter) WithFullscreen(b ...bool) *AreaPrinter {
|
|
p.Fullscreen = internal.WithBoolean(b)
|
|
return &p
|
|
}
|
|
|
|
// WithCenter centers the AreaPrinter content to the terminal.
|
|
func (p AreaPrinter) WithCenter(b ...bool) *AreaPrinter {
|
|
p.Center = internal.WithBoolean(b)
|
|
return &p
|
|
}
|
|
|
|
// Update overwrites the content of the AreaPrinter.
|
|
// Can be used live.
|
|
func (p *AreaPrinter) Update(text ...interface{}) {
|
|
if p.area == nil {
|
|
newArea := cursor.NewArea()
|
|
p.area = &newArea
|
|
}
|
|
str := Sprint(text...)
|
|
p.content = str
|
|
|
|
if p.Center {
|
|
str = DefaultCenter.Sprint(str)
|
|
}
|
|
|
|
if p.Fullscreen {
|
|
str = strings.TrimRight(str, "\n")
|
|
height := GetTerminalHeight()
|
|
contentHeight := strings.Count(str, "\n")
|
|
|
|
topPadding := 0
|
|
bottomPadding := height - contentHeight - 2
|
|
|
|
if p.Center {
|
|
topPadding = (bottomPadding / 2) + 1
|
|
bottomPadding /= 2
|
|
}
|
|
|
|
if height > contentHeight {
|
|
str = strings.Repeat("\n", topPadding) + str
|
|
str += strings.Repeat("\n", bottomPadding)
|
|
}
|
|
}
|
|
p.area.Update(str)
|
|
}
|
|
|
|
// Start the AreaPrinter.
|
|
func (p *AreaPrinter) Start(text ...interface{}) (*AreaPrinter, error) {
|
|
p.isActive = true
|
|
str := Sprint(text...)
|
|
newArea := cursor.NewArea()
|
|
p.area = &newArea
|
|
|
|
p.Update(str)
|
|
|
|
return p, nil
|
|
}
|
|
|
|
// Stop terminates the AreaPrinter immediately.
|
|
// The AreaPrinter will not resolve into anything.
|
|
func (p *AreaPrinter) Stop() error {
|
|
p.isActive = false
|
|
if p.RemoveWhenDone {
|
|
p.Clear()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GenericStart runs Start, but returns a LivePrinter.
|
|
// This is used for the interface LivePrinter.
|
|
// You most likely want to use Start instead of this in your program.
|
|
func (p *AreaPrinter) GenericStart() (*LivePrinter, error) {
|
|
_, _ = p.Start()
|
|
lp := LivePrinter(p)
|
|
return &lp, nil
|
|
}
|
|
|
|
// GenericStop runs Stop, but returns a LivePrinter.
|
|
// This is used for the interface LivePrinter.
|
|
// You most likely want to use Stop instead of this in your program.
|
|
func (p *AreaPrinter) GenericStop() (*LivePrinter, error) {
|
|
_ = p.Stop()
|
|
lp := LivePrinter(p)
|
|
return &lp, nil
|
|
}
|
|
|
|
// Wrapper function that clears the content of the Area.
|
|
// Moves the cursor to the bottom of the terminal, clears n lines upwards from
|
|
// the current position and moves the cursor again.
|
|
func (p *AreaPrinter) Clear() {
|
|
p.area.Clear()
|
|
}
|