Files
bitcoin-ticker-pi/display/slot.go
T

118 lines
2.4 KiB
Go

package display
import (
"errors"
"fmt"
"image/color"
"git.dvdt.dev/david/bitcoin-ticker-pi/fonts"
rgbmatrix "git.dvdt.dev/david/bitcoin-ticker-pi/go-rpi-rgb-led-matrix"
)
type Alignment uint8
const (
Left Alignment = iota
Center
Right
)
var (
ErrUnsupportedSlotHeight = errors.New("unsupported slot height")
)
type Segment struct {
Text string
Color color.RGBA
bitmap [][]color.RGBA
}
func (s *Segment) Draw(canvas *rgbmatrix.Canvas, x, y int) {
for i, row := range s.bitmap {
drawRow(canvas, row, x, y+i)
}
}
func drawRow(canvas *rgbmatrix.Canvas, row []color.RGBA, x, y int) {
for i := 0; i < len(row); i++ {
canvas.Set(x+i, y, color.Black)
canvas.Set(x+i, y, row[i])
}
}
type Slot struct {
alignment Alignment
segmentLimit int
segmentHeight int
segmentWidth int
x, xoffset, y int
text []Segment
}
func NewSlot(alignment Alignment, limit, height, width, x, y int) *Slot {
return &Slot{
alignment: alignment,
segmentLimit: limit,
segmentHeight: height,
segmentWidth: width,
x: x,
y: y,
text: []Segment{},
}
}
func (s *Slot) Update(text []Segment) error {
if len(text) > s.segmentLimit {
text = text[:s.segmentLimit-3]
text = append(text, []Segment{
{Text: ".", Color: fonts.White},
{Text: ".", Color: fonts.White},
{Text: ".", Color: fonts.White},
}...)
}
// Default to left alignment.
s.xoffset = 0
if s.alignment == Center {
s.xoffset = ((s.segmentLimit * s.segmentWidth) - (len(text) * s.segmentWidth)) / 2
}
if s.alignment == Right {
s.xoffset = (s.segmentLimit * s.segmentWidth) - (len(text) * s.segmentWidth)
}
fmt.Printf("segmentLimit: %d\n", s.segmentLimit)
fmt.Printf("segmentWidth: %d\n", s.segmentWidth)
fmt.Printf("len(text): %d\n", len(text))
fmt.Printf("xoffset value: %d\n", s.xoffset)
var font fonts.Font
switch s.segmentHeight {
case 5:
font = fonts.Face5x4
case 7:
font = fonts.Face7x5
case 9:
font = fonts.Face9x6
case 13:
font = fonts.Face13x8
default:
return fmt.Errorf("%w: %d", ErrUnsupportedSlotHeight, s.segmentHeight)
}
for i, t := range text {
c, err := font.ToColor(t.Text, t.Color)
if err != nil {
return err
}
text[i].bitmap = c
}
s.text = text
return nil
}
func (s *Slot) Draw(canvas *rgbmatrix.Canvas) {
for i, segment := range s.text {
segment.Draw(canvas, s.x+(i*s.segmentWidth)+s.xoffset, s.y)
}
}