aboutsummaryrefslogtreecommitdiff
path: root/go/ui/choice.go
blob: 80902606f597d4f84c1aef866a81b9cbf680f414 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package ui

import (
	"fmt"

	"github.com/hajimehoshi/ebiten/v2"
	"muhq.space/muhqs-game/go/game"
	"muhq.space/muhqs-game/go/utils"
)

type Choice struct {
	TextBox
	choices []any
	onClick func(*Choice, int, int)
}

func NewChoice(x, y int, choices []any, onClick func(*Choice, int, int)) *Choice {
	c := &Choice{
		TextBox: *(NewAutoTextBox(x, y, "")),
		choices: choices,
		onClick: onClick,
	}

	c.renderImpl = func() *ebiten.Image {
		c.setText()
		return c.render()
	}
	return c
}

func (c *Choice) setText() {
	c.Width, c.Height = -1, -1
	t := ""
	for _, choice := range c.choices {
		switch c := choice.(type) {
		// Special case Free and FullActions
		case *game.FreeAction:
			t = fmt.Sprintf("%s%v\n", t, c.Desc)
		case *game.FullAction:
			t = fmt.Sprintf("%s↻%v\n", t, c.Desc)
		default:
			t = fmt.Sprintf("%s%v\n", t, choice)
		}
	}

	c.text = t[:len(t)-1]
}

func (c *Choice) GetChoosen(x, y int) int {
	i := (y - c.Y) / (c.Height / len(c.choices))
	if i == len(c.choices) {
		i = i - 1
	}
	return i
}

func (*Choice) IsClickable() bool { return true }
func (c *Choice) Click(x, y int) {
	c.onClick(c, x, y)
}

func NewActionChoice(x, y int, actions []game.Action, onClick func(*Choice, int, int)) *Choice {
	return NewChoice(x, y, utils.TypedSliceToInterfaceSlice(actions), onClick)
}

func NewPermChoice(x, y int, perms []game.Permanent, onClick func(*Choice, int, int)) *Choice {
	return NewChoice(x, y, utils.TypedSliceToInterfaceSlice(perms), onClick)
}

const (
	NUMBER_CHOICE_BUTTON_WIDTH int = 40
	NUMBER_CHOICE_INPUT_WIDTH  int = 40
	NUMBER_CHOICE_SUBMIT_WIDTH int = 100
	NUMBER_CHOICE_HEIGHT       int = 40
	NUMBER_CHOICE_WIDTH_MIN        = 2*NUMBER_CHOICE_BUTTON_WIDTH + NUMBER_CHOICE_INPUT_WIDTH
	NUMBER_CHOICE_WIDTH            = NUMBER_CHOICE_WIDTH_MIN + NUMBER_CHOICE_SUBMIT_WIDTH
)

type NumberChoice struct {
	WidgetBase
	numberInput  *NumberInput
	buttons      [3]Button
	AllowNegativ bool
}

func NewNumberChoice(x, y int, startValue int, onSubmit func(*NumberChoice)) *NumberChoice {
	ni := NewNumberInput(x+NUMBER_CHOICE_BUTTON_WIDTH, y, NUMBER_CHOICE_INPUT_WIDTH, NUMBER_CHOICE_HEIGHT, startValue)
	var nc *NumberChoice
	nc = &NumberChoice{
		WidgetBase:  NewWidgetBase(x, y, NUMBER_CHOICE_WIDTH, NUMBER_CHOICE_HEIGHT),
		numberInput: ni,
		buttons: [3]Button{
			NewSimpleButton(
				x, y,
				NUMBER_CHOICE_BUTTON_WIDTH, NUMBER_CHOICE_HEIGHT,
				"+1",
				func(*SimpleButton) { ni.Add(1) }),
			NewSimpleButton(
				x+NUMBER_CHOICE_BUTTON_WIDTH+NUMBER_CHOICE_INPUT_WIDTH, y,
				NUMBER_CHOICE_BUTTON_WIDTH, NUMBER_CHOICE_HEIGHT,
				"-1",
				func(*SimpleButton) {
					if ni.Number() > 0 || nc.AllowNegativ {
						ni.Add(-1)
					}
				}),
		},
		AllowNegativ: false,
	}

	if onSubmit != nil {
		nc.buttons[2] = NewSimpleButton(
			x+2*NUMBER_CHOICE_BUTTON_WIDTH+NUMBER_CHOICE_INPUT_WIDTH, y,
			NUMBER_CHOICE_SUBMIT_WIDTH, NUMBER_CHOICE_HEIGHT,
			"submit",
			func(*SimpleButton) { onSubmit(nc) })
	}
	nc.EventHandlersMap["click"] = func(x, y int) {
		for _, b := range nc.buttons {
			if b != nil && b.Contains(x, y) {
				b.Click(x, y)
				return
			}
		}
	}

	return nc
}

func (nc *NumberChoice) Draw(screen *ebiten.Image) {
	nc.buttons[0].Draw(screen)
	nc.buttons[1].Draw(screen)
	if nc.buttons[2] != nil {
		nc.buttons[2].Draw(screen)
	}
	nc.numberInput.Draw(screen)
}

func (nc *NumberChoice) GetChoosen() int {
	return nc.numberInput.Number()
}