hdmistat/internal/layout/progressbar.go
2025-07-24 14:32:50 +02:00

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)
}