mirror of
https://github.com/Maks1mS/bubbles.git
synced 2025-03-14 13:03:44 +03:00
Support for solid (non-gradient) fills too
This commit is contained in:
parent
1e16eca939
commit
0f06d78b92
@ -15,6 +15,7 @@ var color func(string) termenv.Color = termenv.ColorProfile().Color
|
|||||||
//
|
//
|
||||||
// progress := NewModel(
|
// progress := NewModel(
|
||||||
// WithRamp("#ff0000", "#0000ff"),
|
// WithRamp("#ff0000", "#0000ff"),
|
||||||
|
// WithoutPercentage(),
|
||||||
// )
|
// )
|
||||||
type Option func(*Model)
|
type Option func(*Model)
|
||||||
|
|
||||||
@ -29,35 +30,51 @@ func WithRamp(colorA, colorB string) Option {
|
|||||||
b, _ := colorful.Hex(colorB)
|
b, _ := colorful.Hex(colorB)
|
||||||
return func(m *Model) {
|
return func(m *Model) {
|
||||||
m.useRamp = true
|
m.useRamp = true
|
||||||
m.colorA = a
|
m.rampColorA = a
|
||||||
m.colorB = b
|
m.rampColorB = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithScaledRamp scales the gradient to fit the width of the filled portion of
|
||||||
|
// the progress bar.
|
||||||
|
func WithScaledRamp() Option {
|
||||||
|
return func(m *Model) {
|
||||||
|
m.scaleRamp = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutPercentage hides the numeric percentage.
|
||||||
|
func WithoutPercentage() Option {
|
||||||
|
return func(m *Model) {
|
||||||
|
m.ShowPercentage = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
// Left side color of progress bar. By default, it's #00dbde
|
|
||||||
colorA colorful.Color
|
|
||||||
|
|
||||||
// Left side color of progress bar. By default, it's #fc00ff
|
|
||||||
colorB colorful.Color
|
|
||||||
|
|
||||||
// Total width of the progress bar, including percentage, if set.
|
// Total width of the progress bar, including percentage, if set.
|
||||||
Width int
|
Width int
|
||||||
|
|
||||||
// Rune for "filled" sections of the progress bar.
|
// "Filled" sections of the progress bar
|
||||||
Full rune
|
Full rune
|
||||||
|
FullColor string
|
||||||
|
|
||||||
// Rune for "empty" sections of progress bar.
|
// "Empty" sections of progress bar
|
||||||
Empty rune
|
Empty rune
|
||||||
|
EmptyColor string
|
||||||
|
|
||||||
// if true, gradient will be setted from start to end of filled part. Instead, it'll work
|
// Settings for rendering the numeric percentage
|
||||||
// on all proggress bar length
|
ShowPercentage bool
|
||||||
FullGradientMode bool
|
PercentFormat string // a fmt string for a float
|
||||||
|
|
||||||
ShowPercent bool
|
|
||||||
PercentFormat string
|
|
||||||
|
|
||||||
useRamp bool
|
useRamp bool
|
||||||
|
rampColorA colorful.Color
|
||||||
|
rampColorB colorful.Color
|
||||||
|
|
||||||
|
// When true, we scale the gradient to fit the width of the filled section
|
||||||
|
// of the progress bar. When false, the width of the gradient will be set
|
||||||
|
// to the full width of the progress bar.
|
||||||
|
scaleRamp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewModel returns a model with default values.
|
// NewModel returns a model with default values.
|
||||||
@ -65,8 +82,10 @@ func NewModel(opts ...Option) *Model {
|
|||||||
m := &Model{
|
m := &Model{
|
||||||
Width: 40,
|
Width: 40,
|
||||||
Full: '█',
|
Full: '█',
|
||||||
|
FullColor: "#7571F9",
|
||||||
Empty: '░',
|
Empty: '░',
|
||||||
ShowPercent: true,
|
EmptyColor: "#606060",
|
||||||
|
ShowPercentage: true,
|
||||||
PercentFormat: " %3.0f%%",
|
PercentFormat: " %3.0f%%",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +97,7 @@ func NewModel(opts ...Option) *Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) View(percent float64) string {
|
func (m Model) View(percent float64) string {
|
||||||
if m.ShowPercent {
|
if m.ShowPercentage {
|
||||||
s := fmt.Sprintf(m.PercentFormat, percent*100)
|
s := fmt.Sprintf(m.PercentFormat, percent*100)
|
||||||
w := ansi.PrintableRuneWidth(s)
|
w := ansi.PrintableRuneWidth(s)
|
||||||
return m.bar(percent, w) + s
|
return m.bar(percent, w) + s
|
||||||
@ -87,24 +106,37 @@ func (m Model) View(percent float64) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) bar(percent float64, textWidth int) string {
|
func (m Model) bar(percent float64, textWidth int) string {
|
||||||
w := m.Width - textWidth
|
var (
|
||||||
|
b = strings.Builder{}
|
||||||
|
tw = m.Width - textWidth // total width
|
||||||
|
fw = int(float64(tw) * percent) // filled width
|
||||||
|
p float64
|
||||||
|
)
|
||||||
|
|
||||||
ramp := make([]string, int(float64(w)*percent))
|
if m.useRamp {
|
||||||
for i := 0; i < len(ramp); i++ {
|
// Gradient fill
|
||||||
gradientPart := float64(w)
|
for i := 0; i < fw; i++ {
|
||||||
if m.FullGradientMode {
|
if m.scaleRamp {
|
||||||
gradientPart = float64(len(ramp))
|
p = float64(i) / float64(fw)
|
||||||
|
} else {
|
||||||
|
p = float64(i) / float64(tw)
|
||||||
}
|
}
|
||||||
percent := float64(i) / gradientPart
|
c := m.rampColorA.BlendLuv(m.rampColorB, p).Hex()
|
||||||
c := m.colorA.BlendLuv(m.colorB, percent)
|
b.WriteString(termenv.
|
||||||
ramp[i] = c.Hex()
|
String(string(m.Full)).
|
||||||
|
Foreground(color(c)).
|
||||||
|
String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Solid fill
|
||||||
|
s := termenv.String(string(m.Full)).Foreground(color(m.FullColor)).String()
|
||||||
|
b.WriteString(strings.Repeat(s, fw))
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullCells string
|
// Empty fill
|
||||||
for i := 0; i < len(ramp); i++ {
|
e := termenv.String(string(m.Empty)).Foreground(color(m.EmptyColor)).String()
|
||||||
fullCells += termenv.String(string(m.Full)).Foreground(color(ramp[i])).String()
|
b.WriteString(strings.Repeat(e, tw-fw))
|
||||||
}
|
|
||||||
|
|
||||||
fullCells += strings.Repeat(string(m.Empty), w-len(ramp))
|
return b.String()
|
||||||
return fullCells
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user