96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
package layout
|
|
|
|
import (
|
|
"fmt"
|
|
"image/color"
|
|
)
|
|
|
|
const (
|
|
// Progress bar label positioning
|
|
labelTopOffset = 5
|
|
labelBottomOffset = 15
|
|
labelSizeReduction = 2
|
|
percentMultiplier = 100
|
|
percentTextOffset = 5
|
|
)
|
|
|
|
// ProgressBar draws a labeled progress bar
|
|
type ProgressBar struct {
|
|
X, Y int
|
|
Width, Height int
|
|
Value float64 // 0.0 to 1.0
|
|
Label string
|
|
LeftLabel string
|
|
RightLabel string
|
|
BarColor color.Color
|
|
BGColor color.Color
|
|
TextColor color.Color
|
|
LabelSize float64
|
|
}
|
|
|
|
// Draw renders the progress bar on the canvas
|
|
func (p *ProgressBar) Draw(canvas *Canvas) {
|
|
// Default colors
|
|
if p.BarColor == nil {
|
|
p.BarColor = color.RGBA{100, 200, 255, 255}
|
|
}
|
|
if p.BGColor == nil {
|
|
p.BGColor = color.RGBA{50, 50, 50, 255}
|
|
}
|
|
if p.TextColor == nil {
|
|
p.TextColor = color.RGBA{255, 255, 255, 255}
|
|
}
|
|
if p.LabelSize == 0 {
|
|
p.LabelSize = 14
|
|
}
|
|
|
|
// Ensure value is between 0 and 1
|
|
value := p.Value
|
|
if value < 0 {
|
|
value = 0
|
|
}
|
|
if value > 1 {
|
|
value = 1
|
|
}
|
|
|
|
// Draw background
|
|
canvas.DrawBox(p.X, p.Y, p.Width, p.Height, p.BGColor)
|
|
|
|
// Draw filled portion
|
|
filledWidth := int(float64(p.Width) * value)
|
|
if filledWidth > 0 {
|
|
canvas.DrawBox(p.X, p.Y, filledWidth, p.Height, p.BarColor)
|
|
}
|
|
|
|
// Draw label above bar if provided
|
|
if p.Label != "" {
|
|
labelStyle := TextStyle{Size: p.LabelSize, Color: p.TextColor}
|
|
_ = canvas.DrawText(p.Label, Point{X: p.X, Y: p.Y - labelTopOffset}, labelStyle)
|
|
}
|
|
|
|
// Draw left label
|
|
if p.LeftLabel != "" {
|
|
labelStyle := TextStyle{Size: p.LabelSize - labelSizeReduction, Color: p.TextColor}
|
|
_ = canvas.DrawText(p.LeftLabel, Point{X: p.X, Y: p.Y + p.Height + labelBottomOffset}, labelStyle)
|
|
}
|
|
|
|
// Draw right label
|
|
if p.RightLabel != "" {
|
|
labelStyle := TextStyle{Size: p.LabelSize - labelSizeReduction, Color: p.TextColor, Alignment: AlignRight}
|
|
_ = canvas.DrawText(p.RightLabel, Point{X: p.X + p.Width, Y: p.Y + p.Height + labelBottomOffset}, labelStyle)
|
|
}
|
|
|
|
// Draw percentage in center of bar
|
|
percentText := fmt.Sprintf("%.1f%%", value*percentMultiplier)
|
|
centerStyle := TextStyle{
|
|
Size: p.LabelSize,
|
|
Color: color.RGBA{255, 255, 255, 255},
|
|
Alignment: AlignCenter,
|
|
}
|
|
pt := Point{
|
|
X: p.X + p.Width/halfDivisor,
|
|
Y: p.Y + p.Height/halfDivisor + percentTextOffset,
|
|
}
|
|
_ = canvas.DrawText(percentText, pt, centerStyle)
|
|
}
|