-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
159 lines (142 loc) · 3.37 KB
/
main.go
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"embed"
"fmt"
"strconv"
"strings"
w "github.com/i2y/wasabi"
a "github.com/i2y/wasabi/modifier/attr"
)
//go:embed assets
var assets embed.FS
func main() {
app := w.NewDesktopApp("Calc", 380, 486, w.Assets(assets))
app.Run(calc)
}
type Calc struct {
display *w.State[string]
operator string
result, operand float64
waitingForOperand bool
}
func NewCalc() *Calc {
return &Calc{
display: w.NewState("0"),
}
}
func (c *Calc) NumberClicked(number int) {
if c.waitingForOperand {
c.display.Set(strconv.Itoa(number))
c.waitingForOperand = false
} else {
if c.display.Get() == "0" {
c.display.Set(strconv.Itoa(number))
} else {
c.display.Set(c.display.Get() + strconv.Itoa(number))
}
}
}
func (c *Calc) OperatorClicked(operator string) {
if !c.waitingForOperand {
c.operand, _ = strconv.ParseFloat(c.display.Get(), 64)
switch c.operator {
case "+":
c.result += c.operand
case "-":
c.result -= c.operand
case "×":
c.result *= c.operand
case "÷":
if c.operand != 0 {
c.result /= c.operand
} else {
c.display.Set("Error")
return
}
default:
c.result = c.operand
}
c.display.Set(fmt.Sprintf("%g", c.result))
}
c.operator = operator
c.waitingForOperand = true
}
func (c *Calc) EqualsClicked() {
c.OperatorClicked("=")
c.operator = ""
}
func (c *Calc) DecimalPointClicked() {
if c.waitingForOperand {
c.display.Set("0")
c.waitingForOperand = false
}
if !strings.Contains(c.display.Get(), ".") {
c.display.Set(c.display.Get() + ".")
}
}
func (c *Calc) ClearClicked() {
c.display.Set("0")
c.operator = ""
c.result = 0
c.operand = 0
c.waitingForOperand = false
}
func calc(f *w.Factory) w.Element {
c := NewCalc()
return f.Div(a.Class("bg-white shadow-xl p-5"))(
f.Reactive(c.display, func() w.Element {
return f.Input(
a.Class("w-full p-3 text-right text-white text-2xl mb-5"),
a.Readonly(true),
a.Value(c.display.Get()),
)()
}),
f.Div(a.Class("grid grid-cols-4 gap-2"))(
clear(f, c, 3), op(f, c, "÷", 1),
num(f, c, 7, 1), num(f, c, 8, 1), num(f, c, 9, 1), op(f, c, "×", 1),
num(f, c, 4, 1), num(f, c, 5, 1), num(f, c, 6, 1), op(f, c, "-", 1),
num(f, c, 1, 1), num(f, c, 2, 1), num(f, c, 3, 1), op(f, c, "+", 1),
num(f, c, 0, 2), dot(f, c, 1), eq(f, c, 1),
),
)
}
func num(f *w.Factory, calc *Calc, num, colspan int) w.Element {
return f.Button(
a.Class("btn btn-primary col-span-"+strconv.Itoa(colspan)),
a.OnClick(func() {
calc.NumberClicked(num)
}),
)(f.Text(strconv.Itoa(num)))
}
func op(f *w.Factory, calc *Calc, op string, colspan int) w.Element {
return f.Button(
a.Class("btn btn-accent col-span-"+strconv.Itoa(colspan)),
a.OnClick(func() {
calc.OperatorClicked(op)
}),
)(f.Text(op))
}
func eq(f *w.Factory, calc *Calc, colspan int) w.Element {
return f.Button(
a.Class("btn btn-secondary col-span-"+strconv.Itoa(colspan)),
a.OnClick(func() {
calc.EqualsClicked()
}),
)(f.Text("="))
}
func dot(f *w.Factory, calc *Calc, colspan int) w.Element {
return f.Button(
a.Class("btn btn-primary col-span-"+strconv.Itoa(colspan)),
a.OnClick(func() {
calc.DecimalPointClicked()
}),
)(f.Text("."))
}
func clear(f *w.Factory, calc *Calc, colspan int) w.Element {
return f.Button(
a.Class("btn btn-accent col-span-"+strconv.Itoa(colspan)),
a.OnClick(func() {
calc.ClearClicked()
}),
)(f.Text("AC"))
}