diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-09-08 22:32:22 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-09-08 22:32:22 +0200 |
| commit | ddd9cc924977201f7d2bc162c0d5fe4f86841ef1 (patch) | |
| tree | 67ae8a7f34cd1e119b09e0c1925dca52855b70c4 /go/ui/buffer.go | |
| parent | 6438cef725e6310c49b5f4ef615b2ee82261b11b (diff) | |
| download | muhqs-game-ddd9cc924977201f7d2bc162c0d5fe4f86841ef1.tar.gz muhqs-game-ddd9cc924977201f7d2bc162c0d5fe4f86841ef1.zip | |
support action targeting from the stack buffer
Diffstat (limited to 'go/ui/buffer.go')
| -rw-r--r-- | go/ui/buffer.go | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/go/ui/buffer.go b/go/ui/buffer.go index d2a4667e..c44bbdd0 100644 --- a/go/ui/buffer.go +++ b/go/ui/buffer.go @@ -8,6 +8,7 @@ import ( "github.com/hajimehoshi/ebiten/v2/text/v2" "muhq.space/muhqs-game/go/font" + "muhq.space/muhqs-game/go/game" ) var ( @@ -18,6 +19,7 @@ var ( type Buffer struct { WidgetBase lines []string + highlights map[int]color.Color pos int font *text.GoTextFace lineSpacing float64 @@ -30,6 +32,7 @@ func NewBuffer(x, y int, width, height int) *Buffer { b := &Buffer{ NewWidgetBase(x, y, width, height), []string{}, + make(map[int]color.Color), 0, font.Font18, 1.5, @@ -45,14 +48,18 @@ func (b *Buffer) render() *ebiten.Image { img := ebiten.NewImage(b.Width, b.Height) img.Fill(b.bg) var y float64 = -b.font.Size - for _, line := range b.lines[b.pos:] { + for i, line := range b.lines[b.pos:] { _, h := text.Measure(line, b.font, b.font.Size*b.lineSpacing) y += h if y > float64(b.Height) { break } op := &text.DrawOptions{} - op.ColorScale.ScaleWithColor(b.fg) + if clr, highlighted := b.highlights[i]; highlighted { + op.ColorScale.ScaleWithColor(clr) + } else { + op.ColorScale.ScaleWithColor(b.fg) + } op.GeoM.Translate(b.xMargin, float64(y)) op.LineSpacing = b.font.Size * b.lineSpacing text.Draw(img, line, b.font, op) @@ -129,3 +136,67 @@ func (b *Buffer) Fg(fg color.Color) *Buffer { b.fg = fg return b } + +type StackBuffer struct { + Buffer + actions []game.Action +} + +func NewStackBuffer(x, y int, width, height int, actions []game.Action) *StackBuffer { + sb := &StackBuffer{Buffer: *NewBuffer(x, y, width, height)} + // This is needed because we do not use the pointer created in NewBuffer + sb.renderImpl = func() *ebiten.Image { return sb.render() } + + for _, action := range actions { + sb.AddAction(action) + } + return sb +} + +func (b *StackBuffer) AddAction(a game.Action) { + b.AddLine(a.String()) + b.actions = append(b.actions, a) +} + +func (b *StackBuffer) AddHighlight(a game.Action, clr color.Color) { + for i, ba := range b.actions { + if a == ba { + b.highlights[i] = clr + } + } + b.ForceRedraw() +} + +func (b *StackBuffer) ClearHighlights() { + b.highlights = make(map[int]color.Color) + b.ForceRedraw() +} + +func (b *StackBuffer) RemoveLast() { + b.Buffer.RemoveLast() + + // Remove potential highlight + i := len(b.actions) - 1 + if _, found := b.highlights[i]; found { + delete(b.highlights, i) + } + + b.actions = b.actions[:i] +} + +func (b *StackBuffer) FindObjectAt(x, y int) any { + if !b.Contains(x, y) { + return nil + } + + var _y float64 = 0 + for i, line := range b.lines[b.pos:] { + _, h := text.Measure(line, b.font, b.font.Size*b.lineSpacing) + _y += h + + if int(_y)+b.Y >= y { + return b.actions[i] + } + } + return nil +} |
