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