display-test/components/progressbar.go
2024-09-22 21:53:22 +03:00

118 lines
2.4 KiB
Go

package components
import (
"fmt"
"io"
"gitea.unprism.ru/yotia/display-test/drawer"
)
type progressBar struct {
drawer drawer.Drawer // Drawer with dysplay
mask uint32 // Flush mask
progress float64
rect rect // Rect
}
type ProgressBar interface {
RectGetter
SetProgress(coef float64) // Value from 0 to 1
Draw() // For any cases
Clear() // Clear space of bar
Flush() // For those times like after SetPos
io.Closer
}
// Creation function
// Now the only way to chage shape is to recreate component
func NewProgressBar(drawer drawer.Drawer, x, y, w, h int) (ProgressBar, error) {
if err := drawer.GetDisplay().IsReady(); err != nil {
return nil, fmt.Errorf("display is ready: %w", err)
}
// Check for correct sizes
if w < 4 {
return nil, fmt.Errorf("invalid width: below 4")
}
if h < 4 {
return nil, fmt.Errorf("invalid height: below 4")
}
pb := progressBar{
drawer: drawer,
rect: rect{x, y, w, h},
}
pb.updateMask()
pb.Draw()
pb.Flush()
return &pb, nil
}
func (pb *progressBar) Flush() {
pb.drawer.GetDisplay().FlushByMask(pb.mask)
}
func (pb *progressBar) updateMask() {
pb.mask = 0
// Implementation dependent !!!
// Now for mt12232
y0 := min(3, max(0, int(pb.rect.y/8)))
y1 := min(3, max(0, int((pb.rect.y+pb.rect.h-1)/8)))
x0 := min(1, max(0, int(pb.rect.x/61)))
x1 := min(1, max(0, int((pb.rect.x+pb.rect.w-1)/61)))
//log.Println(x0, y0, x1, y1)
for y := y0; y <= y1; y++ {
for x := x0; x <= x1; x++ {
pb.mask |= (1 << (x*4 + y))
}
}
}
func (pb *progressBar) Close() error {
return nil
}
func (pb *progressBar) Clear() {
pb.drawer.FillBar(pb.rect.x, pb.rect.y, pb.rect.x+pb.rect.w, pb.rect.y+pb.rect.h, 0x00)
}
// Draw whole bar
func (pb *progressBar) Draw() {
// Shape:
// Bounds - 1px
// Padding - 1px
// Progress - the rest space
pb.Clear()
pb.drawer.PutBar(pb.rect.x, pb.rect.y, pb.rect.x+pb.rect.w, pb.rect.y+pb.rect.h, 0xFF)
pb.drawBar()
}
// Draw only bar(without frames)
func (pb *progressBar) drawBar() {
w := int(float64(pb.rect.w-4) * pb.progress)
pb.drawer.FillBar(pb.rect.x+2, pb.rect.y+2, pb.rect.x+2+w, pb.rect.y+pb.rect.h-2, 0xFF)
}
func (pb *progressBar) SetProgress(coef float64) {
pb.progress = max(0, min(1, coef))
pb.drawBar()
pb.Flush()
}
func (pb *progressBar) GetPos() (int, int) {
return pb.rect.x, pb.rect.y
}
func (pb *progressBar) GetSize() (int, int) {
return pb.rect.w, pb.rect.h
}