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 }