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