aboutsummaryrefslogtreecommitdiff
path: root/go/ui/buffer.go
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-09-08 22:32:22 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2025-09-08 22:32:22 +0200
commitddd9cc924977201f7d2bc162c0d5fe4f86841ef1 (patch)
tree67ae8a7f34cd1e119b09e0c1925dca52855b70c4 /go/ui/buffer.go
parent6438cef725e6310c49b5f4ef615b2ee82261b11b (diff)
downloadmuhqs-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.go75
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
+}