138 lines
2.8 KiB
Go
138 lines
2.8 KiB
Go
|
package tins2020
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"strconv"
|
||
|
|
||
|
"opslag.de/schobers/geom"
|
||
|
"opslag.de/schobers/zntg/ui"
|
||
|
)
|
||
|
|
||
|
type Dial struct {
|
||
|
ui.ContainerBase
|
||
|
|
||
|
dialer Dialer
|
||
|
|
||
|
typing string // current digit
|
||
|
digitCount int // number of times the digit is pressed
|
||
|
digits []DialDigit // digits
|
||
|
}
|
||
|
|
||
|
func NewDial(dialer Dialer) *Dial {
|
||
|
dial := &Dial{dialer: dialer}
|
||
|
dial.digits = make([]DialDigit, 10)
|
||
|
|
||
|
for i := range dial.digits {
|
||
|
j := i
|
||
|
dial.digits[i].Value = strconv.Itoa(i)
|
||
|
dial.digits[i].ControlClicked().AddHandler(func(ctx ui.Context, _ ui.ControlClickedArgs) {
|
||
|
dial.userTyped(ctx, j)
|
||
|
})
|
||
|
dial.AddChild(&dial.digits[i])
|
||
|
}
|
||
|
return dial
|
||
|
}
|
||
|
|
||
|
func (d *Dial) userTyped(ctx ui.Context, i int) {
|
||
|
d.digits[i].Blink()
|
||
|
digit := strconv.Itoa(i)
|
||
|
if len(d.typing) == 0 || digit != d.typing {
|
||
|
d.typing = digit
|
||
|
d.digitCount = 1
|
||
|
} else {
|
||
|
d.digitCount++
|
||
|
}
|
||
|
|
||
|
if !d.dialer.CanUserType(i) {
|
||
|
d.typing = ""
|
||
|
d.digitCount = 0
|
||
|
d.dialer.UserGaveWrongInput()
|
||
|
} else if d.digitCount == i || d.digitCount == 10 {
|
||
|
d.typing = ""
|
||
|
d.digitCount = 0
|
||
|
d.dialer.UserTyped(ctx, i)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *Dial) Arrange(ctx ui.Context, bounds geom.RectangleF32, offset geom.PointF32, parent ui.Control) {
|
||
|
d.ControlBase.Arrange(ctx, bounds, offset, parent)
|
||
|
|
||
|
center := bounds.Center()
|
||
|
size := bounds.Size()
|
||
|
|
||
|
distance := size.Y * .3
|
||
|
for i := range d.digits {
|
||
|
angle := (float32((10-i)%10)*0.16 + .2) * math.Pi
|
||
|
pos := geom.PtF32(distance*geom.Cos32(angle), .8*distance*geom.Sin32(angle))
|
||
|
digitCenter := center.Add(pos)
|
||
|
d.digits[i].Arrange(ctx, geom.RectRelF32(digitCenter.X-24, digitCenter.Y-24, 48, 48), offset, d)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *Dial) DesiredSize(ctx ui.Context, size geom.PointF32) geom.PointF32 {
|
||
|
return geom.PtF32(size.X, geom.NaN32())
|
||
|
}
|
||
|
|
||
|
func (d *Dial) Handle(ctx ui.Context, event ui.Event) bool {
|
||
|
if d.ContainerBase.Handle(ctx, event) {
|
||
|
return true
|
||
|
}
|
||
|
switch e := event.(type) {
|
||
|
case *ui.KeyDownEvent:
|
||
|
switch e.Key {
|
||
|
case ui.Key0:
|
||
|
d.userTyped(ctx, 0)
|
||
|
case ui.KeyPad0:
|
||
|
d.userTyped(ctx, 0)
|
||
|
case ui.Key1:
|
||
|
d.userTyped(ctx, 1)
|
||
|
case ui.KeyPad1:
|
||
|
d.userTyped(ctx, 1)
|
||
|
case ui.Key2:
|
||
|
d.userTyped(ctx, 2)
|
||
|
case ui.KeyPad2:
|
||
|
d.userTyped(ctx, 2)
|
||
|
case ui.Key3:
|
||
|
d.userTyped(ctx, 3)
|
||
|
case ui.KeyPad3:
|
||
|
d.userTyped(ctx, 3)
|
||
|
case ui.Key4:
|
||
|
d.userTyped(ctx, 4)
|
||
|
case ui.KeyPad4:
|
||
|
d.userTyped(ctx, 4)
|
||
|
case ui.Key5:
|
||
|
d.userTyped(ctx, 5)
|
||
|
case ui.KeyPad5:
|
||
|
d.userTyped(ctx, 5)
|
||
|
case ui.Key6:
|
||
|
d.userTyped(ctx, 6)
|
||
|
case ui.KeyPad6:
|
||
|
d.userTyped(ctx, 6)
|
||
|
case ui.Key7:
|
||
|
d.userTyped(ctx, 7)
|
||
|
case ui.KeyPad7:
|
||
|
d.userTyped(ctx, 7)
|
||
|
case ui.Key8:
|
||
|
d.userTyped(ctx, 8)
|
||
|
case ui.KeyPad8:
|
||
|
d.userTyped(ctx, 8)
|
||
|
case ui.Key9:
|
||
|
d.userTyped(ctx, 9)
|
||
|
case ui.KeyPad9:
|
||
|
d.userTyped(ctx, 9)
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (d *Dial) Reset() {
|
||
|
d.typing = ""
|
||
|
d.digitCount = 0
|
||
|
}
|
||
|
|
||
|
func (d *Dial) Tick() {
|
||
|
for i := range d.digits {
|
||
|
d.digits[i].Tick()
|
||
|
}
|
||
|
}
|