|
|
|
@ -4,6 +4,7 @@ import (
|
|
|
|
|
"image" |
|
|
|
|
"image/color" |
|
|
|
|
"log" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/hajimehoshi/ebiten/v2" |
|
|
|
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" |
|
|
|
@ -28,7 +29,8 @@ type Keyboard struct {
|
|
|
|
|
|
|
|
|
|
keys [][]*Key |
|
|
|
|
|
|
|
|
|
background *ebiten.Image |
|
|
|
|
background *ebiten.Image |
|
|
|
|
backgroundDirty bool |
|
|
|
|
|
|
|
|
|
op *ebiten.DrawImageOptions |
|
|
|
|
|
|
|
|
@ -87,7 +89,7 @@ func (k *Keyboard) SetRect(x, y, w, h int) {
|
|
|
|
|
k.x, k.y, k.w, k.h = x, y, w, h |
|
|
|
|
|
|
|
|
|
k.updateKeyRects() |
|
|
|
|
k.drawBackground() |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (k *Keyboard) GetKeys() [][]*Key { |
|
|
|
@ -98,13 +100,13 @@ func (k *Keyboard) SetKeys(keys [][]*Key) {
|
|
|
|
|
k.keys = keys |
|
|
|
|
|
|
|
|
|
k.updateKeyRects() |
|
|
|
|
k.drawBackground() |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (k *Keyboard) SetLabelFont(face font.Face) { |
|
|
|
|
k.labelFont = face |
|
|
|
|
|
|
|
|
|
k.drawBackground() |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (k *Keyboard) SetHideShortcuts(shortcuts []ebiten.Key) { |
|
|
|
@ -132,6 +134,10 @@ func (k *Keyboard) updateKeyRects() {
|
|
|
|
|
key.y = (cellH + cellPaddingH) * row |
|
|
|
|
key.w = cellW |
|
|
|
|
key.h = cellH |
|
|
|
|
|
|
|
|
|
if i == len(rowKeys)-1 { |
|
|
|
|
key.w = k.w - key.x |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -175,7 +181,7 @@ func (k *Keyboard) Hit(key *Key) {
|
|
|
|
|
|
|
|
|
|
if input.Key == ebiten.KeyShift { |
|
|
|
|
k.shift = !k.shift |
|
|
|
|
k.drawBackground() |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
return |
|
|
|
|
} else if k.handleHideKey(input.Key) { |
|
|
|
|
// Hidden
|
|
|
|
@ -199,25 +205,51 @@ func (k *Keyboard) Update() error {
|
|
|
|
|
for _, r := range k.internalBuffer { |
|
|
|
|
k.inputBuffer <- &Input{Rune: r} // Pass through
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Read keys
|
|
|
|
|
for _, key := range allKeys { |
|
|
|
|
if inpututil.IsKeyJustPressed(key) { |
|
|
|
|
if k.handleHideKey(key) { |
|
|
|
|
// Hidden
|
|
|
|
|
return nil |
|
|
|
|
} else { |
|
|
|
|
// Read keys
|
|
|
|
|
for _, key := range allKeys { |
|
|
|
|
if inpututil.IsKeyJustPressed(key) { |
|
|
|
|
if k.handleHideKey(key) { |
|
|
|
|
// Hidden
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
k.inputBuffer <- &Input{Key: key} // Pass through
|
|
|
|
|
} |
|
|
|
|
k.inputBuffer <- &Input{Key: key} // Pass through
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Handle mouse input
|
|
|
|
|
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { |
|
|
|
|
if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) { |
|
|
|
|
x, y := ebiten.CursorPosition() |
|
|
|
|
|
|
|
|
|
key := k.at(x, y) |
|
|
|
|
if key != nil { |
|
|
|
|
for _, rowKeys := range k.keys { |
|
|
|
|
for _, rowKey := range rowKeys { |
|
|
|
|
rowKey.pressed = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
key.pressed = true |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
|
|
|
|
|
k.Hit(key) |
|
|
|
|
|
|
|
|
|
// TODO replace with pressUntil
|
|
|
|
|
go func() { |
|
|
|
|
time.Sleep(50 * time.Millisecond) |
|
|
|
|
|
|
|
|
|
key.pressed = false |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
ebiten.ScheduleFrame() |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
} else if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { |
|
|
|
|
x, y := ebiten.CursorPosition() |
|
|
|
|
|
|
|
|
|
key := k.at(x, y) |
|
|
|
|
if key != nil { |
|
|
|
|
key.pressed = true |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Handle touch input
|
|
|
|
@ -227,7 +259,19 @@ func (k *Keyboard) Update() error {
|
|
|
|
|
|
|
|
|
|
key := k.at(x, y) |
|
|
|
|
if key != nil { |
|
|
|
|
key.pressed = true |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
|
|
|
|
|
k.Hit(key) |
|
|
|
|
|
|
|
|
|
// TODO replace with pressUntil
|
|
|
|
|
go func() { |
|
|
|
|
time.Sleep(50 * time.Millisecond) |
|
|
|
|
|
|
|
|
|
key.pressed = false |
|
|
|
|
k.backgroundDirty = true |
|
|
|
|
ebiten.ScheduleFrame() |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
@ -266,10 +310,16 @@ func (k *Keyboard) drawBackground() {
|
|
|
|
|
y := key.h / 2 |
|
|
|
|
text.Draw(img, label, k.labelFont, x, y, color.White) |
|
|
|
|
|
|
|
|
|
if key.pressed { |
|
|
|
|
k.op.ColorM.Scale(1, 1, 1, 0.6) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Draw key
|
|
|
|
|
k.op.GeoM.Reset() |
|
|
|
|
k.op.GeoM.Translate(float64(key.x), float64(key.y)) |
|
|
|
|
buffer.DrawImage(img, k.op) |
|
|
|
|
|
|
|
|
|
k.op.ColorM.Reset() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -282,6 +332,11 @@ func (k *Keyboard) Draw(target *ebiten.Image) {
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if k.backgroundDirty { |
|
|
|
|
k.drawBackground() |
|
|
|
|
k.backgroundDirty = false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
k.op.GeoM.Reset() |
|
|
|
|
k.op.GeoM.Translate(float64(k.x), float64(k.y)) |
|
|
|
|
k.op.ColorM.Scale(1, 1, 1, k.alpha) |
|
|
|
|