Use device on-screen keyboard on Android

This commit is contained in:
Trevor Slocum 2024-01-21 18:00:50 -08:00
parent 2199e9aa22
commit 300456e6cf
7 changed files with 147 additions and 277 deletions

View file

@ -1,5 +1,6 @@
1.2.7:
- Draw checkers in home spaces sideways
- Use device on-screen keyboard on Android
1.2.6:
- Add rating column to list of matches

View file

@ -136,20 +136,13 @@ type board struct {
replayPauseButton *etk.Button
replayGrid *etk.Grid
inputGrid *etk.Grid
showKeyboardButton *etk.Button
uiGrid *etk.Grid
frame *etk.Frame
lastKeyboardToggle time.Time
inputGrid *etk.Grid
uiGrid *etk.Grid
frame *etk.Frame
leaveGameGrid *etk.Grid
confirmLeaveGameFrame *etk.Frame
chatGrid *etk.Grid
floatInputGrid *etk.Grid
floatChatGrid *etk.Grid
fontFace font.Face
lineHeight int
lineOffset int
@ -222,9 +215,6 @@ func NewBoard() *board {
uiGrid: etk.NewGrid(),
frame: etk.NewFrame(),
confirmLeaveGameFrame: etk.NewFrame(),
chatGrid: etk.NewGrid(),
floatChatGrid: etk.NewGrid(),
floatInputGrid: etk.NewGrid(),
speed: bgammon.SpeedMedium,
showPipCount: true,
highlightAvailable: true,
@ -311,6 +301,7 @@ func NewBoard() *board {
oldLabel.SetVertical(messeji.AlignCenter)
b.changePasswordOld = etk.NewInput("", "", func(text string) (handled bool) {
b.selectChangePassword()
return false
})
b.changePasswordOld.Field.SetBackgroundColor(frameColor)
@ -326,6 +317,7 @@ func NewBoard() *board {
newLabel.SetVertical(messeji.AlignCenter)
b.changePasswordNew = etk.NewInput("", "", func(text string) (handled bool) {
b.selectChangePassword()
return false
})
b.changePasswordNew.Field.SetBackgroundColor(frameColor)
@ -522,8 +514,9 @@ func NewBoard() *board {
b.leaveGameGrid.SetVisible(false)
}
b.showKeyboardButton = etk.NewButton(gotext.Get("Show Keyboard"), b.toggleKeyboard)
b.recreateInputGrid()
b.inputGrid = etk.NewGrid()
b.inputGrid.SetColumnSizes(-1)
b.inputGrid.AddChildAt(inputBuffer, 0, 0, 1, 1)
timerLabel := etk.NewText("0:00")
timerLabel.SetForegroundColor(triangleA)
@ -544,19 +537,11 @@ func NewBoard() *board {
b.showMenuButton = etk.NewButton("Menu", b.toggleMenu)
b.matchStatusGrid = etk.NewGrid()
if !AutoEnableTouchInput {
b.matchStatusGrid.SetColumnSizes(int(b.verticalBorderSize/4), -1, -1, -1, int(b.verticalBorderSize/4))
} else {
b.matchStatusGrid.SetColumnSizes(int(b.verticalBorderSize/4), -1, -1, int(b.verticalBorderSize/4))
}
b.matchStatusGrid.SetColumnSizes(int(b.verticalBorderSize/4), -1, -1, -1, int(b.verticalBorderSize/4))
b.matchStatusGrid.AddChildAt(b.timerLabel, 1, 0, 1, 1)
b.matchStatusGrid.AddChildAt(b.clockLabel, 2, 0, 1, 1)
x := 3
if !AutoEnableTouchInput {
b.matchStatusGrid.AddChildAt(b.showMenuButton, x, 0, 1, 1)
x++
}
b.matchStatusGrid.AddChildAt(etk.NewBox(), x, 0, 1, 1)
b.matchStatusGrid.AddChildAt(b.showMenuButton, 3, 0, 1, 1)
b.matchStatusGrid.AddChildAt(etk.NewBox(), 4, 0, 1, 1)
b.replayPauseButton = etk.NewButton("|>", b.selectReplayPause)
@ -609,25 +594,6 @@ func NewBoard() *board {
b.frame.AddChild(etk.NewFrame(b.selectRollGrid))
{
b.chatGrid.SetBackground(frameColor)
b.chatGrid.AddChildAt(floatStatusBuffer, 0, 0, 1, 1)
b.chatGrid.AddChildAt(etk.NewBox(), 0, 1, 1, 1)
b.chatGrid.AddChildAt(b.floatInputGrid, 0, 2, 1, 1)
padding := etk.NewBox()
padding.SetBackground(frameColor)
g := b.floatChatGrid
g.SetRowSizes(-1, -1, -1)
g.AddChildAt(b.chatGrid, 0, 1, 1, 1)
g.AddChildAt(padding, 0, 2, 1, 1)
g.SetVisible(false)
b.frame.AddChild(g)
}
b.frame.AddChild(b.floatChatGrid)
{
f := etk.NewFrame()
f.AddChild(b.menuGrid)
@ -642,8 +608,6 @@ func NewBoard() *board {
b.frame.AddChild(f)
}
b.frame.AddChild(etk.NewFrame(game.keyboard))
b.frame.AddChild(game.tutorialFrame)
b.fontUpdated()
@ -672,7 +636,6 @@ func (b *board) fontUpdated() {
}
}
statusBuffer.SetFont(bufferFont, fontMutex)
floatStatusBuffer.SetFont(bufferFont, fontMutex)
gameBuffer.SetFont(bufferFont, fontMutex)
inputBuffer.Field.SetFont(bufferFont, fontMutex)
@ -682,8 +645,6 @@ func (b *board) fontUpdated() {
b.showMenuButton.Label.SetFont(smallFont, fontMutex)
}
b.showKeyboardButton.Label.SetFont(largeFont, fontMutex)
b.timerLabel.SetFont(b.fontFace, fontMutex)
b.clockLabel.SetFont(b.fontFace, fontMutex)
@ -702,39 +663,17 @@ func (b *board) fontUpdated() {
b.playerPipCount.SetFont(bufferFont, fontMutex)
}
func (b *board) recreateInputGrid() {
if b.inputGrid == nil {
b.inputGrid = etk.NewGrid()
} else {
b.inputGrid.Clear()
}
b.floatInputGrid.Clear()
if game.TouchInput {
b.inputGrid.AddChildAt(inputBuffer, 0, 0, 2, 1)
b.floatInputGrid.AddChildAt(inputBuffer, 0, 0, 2, 1)
b.inputGrid.AddChildAt(etk.NewBox(), 0, 1, 2, 1)
b.floatInputGrid.AddChildAt(etk.NewBox(), 0, 1, 2, 1)
b.inputGrid.AddChildAt(b.showMenuButton, 0, 2, 1, 1)
b.floatInputGrid.AddChildAt(b.showMenuButton, 0, 2, 1, 1)
b.inputGrid.AddChildAt(b.showKeyboardButton, 1, 2, 1, 1)
b.floatInputGrid.AddChildAt(b.showKeyboardButton, 1, 2, 1, 1)
b.inputGrid.SetRowSizes(52, int(b.horizontalBorderSize/2), -1)
b.floatInputGrid.SetRowSizes(52, int(b.horizontalBorderSize/2), -1)
} else {
b.inputGrid.AddChildAt(inputBuffer, 0, 0, 1, 1)
b.floatInputGrid.AddChildAt(inputBuffer, 0, 0, 1, 1)
}
}
func (b *board) recreateUIGrid() {
b.uiGrid.Clear()
b.uiGrid.AddChildAt(etk.NewBox(), 0, 0, 1, 1)
b.uiGrid.AddChildAt(b.matchStatusGrid, 0, 1, 1, 1)
b.uiGrid.AddChildAt(etk.NewBox(), 0, 2, 1, 1)
gridY := 3
if AutoEnableTouchInput {
b.uiGrid.AddChildAt(b.inputGrid, 0, gridY, 1, 1)
b.uiGrid.AddChildAt(etk.NewBox(), 0, gridY+1, 1, 1)
gridY += 2
}
if game.replay {
f := smallFont
if defaultFontSize == extraLargeFontSize {
@ -756,14 +695,18 @@ func (b *board) recreateUIGrid() {
g.AddChildAt(b.replayGrid, 0, 0, 1, 1)
g.AddChildAt(subGrid, 0, 2, 1, 1)
g.AddChildAt(statusBuffer, 0, 4, 1, 1)
b.uiGrid.AddChildAt(g, 0, 3, 1, 3)
b.uiGrid.AddChildAt(g, 0, gridY, 1, 3)
gridY++
} else {
b.uiGrid.AddChildAt(statusBuffer, 0, 3, 1, 1)
b.uiGrid.AddChildAt(etk.NewBox(), 0, 4, 1, 1)
b.uiGrid.AddChildAt(gameBuffer, 0, 5, 1, 1)
b.uiGrid.AddChildAt(statusBuffer, 0, gridY, 1, 1)
b.uiGrid.AddChildAt(etk.NewBox(), 0, gridY+1, 1, 1)
b.uiGrid.AddChildAt(gameBuffer, 0, gridY+2, 1, 1)
gridY += 3
}
if !AutoEnableTouchInput {
b.uiGrid.AddChildAt(etk.NewBox(), 0, gridY, 1, 1)
b.uiGrid.AddChildAt(b.inputGrid, 0, gridY+1, 1, 1)
}
b.uiGrid.AddChildAt(etk.NewBox(), 0, 6, 1, 1)
b.uiGrid.AddChildAt(b.inputGrid, 0, 7, 1, 1)
}
func (b *board) showButtonGrid(buttonGrid *etk.Grid) {
@ -930,27 +873,6 @@ func (b *board) toggleMenu() error {
return nil
}
func (b *board) toggleKeyboard() error {
t := time.Now()
if !b.lastKeyboardToggle.IsZero() && t.Sub(b.lastKeyboardToggle) < 200*time.Millisecond {
return nil
}
b.lastKeyboardToggle = t
if game.keyboard.Visible() {
game.keyboard.SetVisible(false)
b.floatChatGrid.SetVisible(false)
b.uiGrid.SetRect(b.uiGrid.Rect())
b.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
} else {
b.floatChatGrid.SetVisible(true)
b.floatChatGrid.SetRect(b.floatChatGrid.Rect())
game.keyboard.SetVisible(true)
b.showKeyboardButton.Label.SetText(gotext.Get("Hide Keyboard"))
}
return nil
}
func (b *board) selectRoll() error {
b.Client.Out <- []byte("roll")
return nil
@ -1867,18 +1789,17 @@ func (b *board) setRect(x, y, w, h int) {
b.setSpaceRects()
b.updateBackgroundImage()
b.recreateInputGrid()
b.processState()
inputAndButtons := 52
if game.TouchInput {
inputAndButtons = 52 + int(b.verticalBorderSize)/2 + game.scale(baseButtonHeight)
}
matchStatus := 36
if game.scaleFactor >= 1.25 {
matchStatus = 44
if game.scaleFactor >= 1.25 || AutoEnableTouchInput {
matchStatus *= 2
}
if AutoEnableTouchInput {
b.uiGrid.SetRowSizes(int(b.verticalBorderSize/2), matchStatus, int(b.verticalBorderSize/2), fieldHeight, int(b.verticalBorderSize/2), -1, int(b.verticalBorderSize/2), -1)
} else {
b.uiGrid.SetRowSizes(int(b.verticalBorderSize/2), matchStatus, int(b.verticalBorderSize/2), -1, int(b.verticalBorderSize/2), -1, int(b.verticalBorderSize/2), fieldHeight)
}
b.uiGrid.SetRowSizes(int(b.verticalBorderSize/2), matchStatus, int(b.verticalBorderSize/2), -1, int(b.verticalBorderSize/2), -1, int(b.verticalBorderSize/2), int(inputAndButtons))
{
dialogWidth := game.scale(620)
@ -1931,8 +1852,6 @@ func (b *board) setRect(x, y, w, h int) {
b.menuGrid.SetColumnSizes(-1, game.scale(10), -1, game.scale(10), -1)
b.chatGrid.SetRowSizes(-1, int(b.verticalBorderSize)/2, inputAndButtons)
var padding int
if b.w >= 600 {
padding = 20

View file

@ -25,7 +25,6 @@ import (
"code.rocket9labs.com/tslocum/bgammon-tabula-bot/bot"
"code.rocket9labs.com/tslocum/bgammon/pkg/server"
"code.rocket9labs.com/tslocum/etk"
"code.rocket9labs.com/tslocum/etk/kibodo"
"code.rocket9labs.com/tslocum/etk/messeji"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/audio"
@ -41,7 +40,7 @@ import (
"golang.org/x/text/language"
)
const version = "v1.2.6"
const version = "v1.2.7"
const DefaultServerAddress = "wss://ws.bgammon.org"
@ -103,10 +102,9 @@ var (
)
var (
statusBuffer = etk.NewText("")
floatStatusBuffer = etk.NewText("")
gameBuffer = etk.NewText("")
inputBuffer = etk.NewInput("", "", acceptInput)
statusBuffer = etk.NewText("")
gameBuffer = etk.NewText("")
inputBuffer = etk.NewInput("", "", acceptInput)
statusLogged bool
gameLogged bool
@ -155,12 +153,10 @@ func l(s string) {
m := time.Now().Format("3:04") + " " + s
if statusLogged {
_, _ = statusBuffer.Write([]byte("\n" + m))
_, _ = floatStatusBuffer.Write([]byte("\n" + m))
scheduleFrame()
return
}
_, _ = statusBuffer.Write([]byte(m))
_, _ = floatStatusBuffer.Write([]byte(m))
statusLogged = true
scheduleFrame()
}
@ -184,6 +180,11 @@ func init() {
loadAudioAssets()
if AutoEnableTouchInput {
etk.Bindings.ConfirmRune = 199
etk.Bindings.BackRune = 231
}
if defaultFontSize == extraLargeFontSize {
etk.Style.TextFont = extraLargeFont
} else {
@ -204,9 +205,6 @@ func init() {
statusBuffer.SetForegroundColor(bufferTextColor)
statusBuffer.SetBackgroundColor(bufferBackgroundColor)
floatStatusBuffer.SetForegroundColor(bufferTextColor)
floatStatusBuffer.SetBackgroundColor(bufferBackgroundColor)
gameBuffer.SetForegroundColor(bufferTextColor)
gameBuffer.SetBackgroundColor(bufferBackgroundColor)
@ -459,15 +457,6 @@ func setViewBoard(view bool) {
game.layoutBoard()
}
g := game
if g.keyboard.Visible() || g.Board.floatChatGrid.Visible() {
g.keyboard.SetVisible(false)
g.Board.floatChatGrid.SetVisible(false)
g.connectKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.lobby.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.Board.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
}
game.Board.selectRollGrid.SetVisible(false)
if viewBoard {
@ -578,21 +567,21 @@ type Game struct {
lobby *lobby
keyboardHint *etk.Text
keyboardHintVisible bool
keyboardHintDismissed bool
volume float64 // Volume range is 0-1.
runeBuffer []rune
debugImg *ebiten.Image
keyboard *etk.Keyboard
keyboardInput []*kibodo.Input
cpuProfile *os.File
connectUsername *etk.Input
connectPassword *etk.Input
connectServer *etk.Input
connectKeyboardButton *etk.Button
connectUsername *etk.Input
connectPassword *etk.Input
connectServer *etk.Input
registerEmail *etk.Input
registerUsername *etk.Input
@ -604,7 +593,8 @@ type Game struct {
tutorialFrame *etk.Frame
pressedKeys []ebiten.Key
pressedKeys []ebiten.Key
pressedRunes []rune
cursorX, cursorY int
TouchInput bool
@ -661,8 +651,6 @@ func NewGame() *Game {
g := &Game{
runeBuffer: make([]rune, 24),
keyboard: etk.NewKeyboard(),
TouchInput: AutoEnableTouchInput,
tutorialFrame: etk.NewFrame(),
@ -673,8 +661,6 @@ func NewGame() *Game {
Mutex: &sync.Mutex{},
}
g.keyboard.SetScheduleFrameFunc(scheduleFrame)
g.keyboard.SetVisible(false)
g.tutorialFrame.SetPositionChildren(true)
game = g
@ -683,13 +669,6 @@ func NewGame() *Game {
g.Board = NewBoard()
g.lobby = NewLobby()
if AutoEnableTouchInput {
g.keyboard.SetKeys(kibodo.KeysMobileQWERTY)
g.keyboard.SetExtendedKeys(kibodo.KeysMobileSymbols)
} else {
g.keyboard.SetKeys(kibodo.KeysQWERTY)
}
xPadding := 10
yPadding := 20
labelWidth := 200
@ -704,6 +683,7 @@ func NewGame() *Game {
connectAddress = DefaultServerAddress
}
g.connectServer = etk.NewInput("", connectAddress, func(text string) (handled bool) {
g.selectConnect()
return false
})
@ -715,16 +695,19 @@ func NewGame() *Game {
serverLabel := newCenteredText(gotext.Get("Server"))
g.registerEmail = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConfirmRegister()
return false
})
centerInput(g.registerEmail)
g.registerUsername = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConfirmRegister()
return false
})
centerInput(g.registerUsername)
g.registerPassword = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConfirmRegister()
return false
})
centerInput(g.registerPassword)
@ -782,6 +765,7 @@ func NewGame() *Game {
serverLabel := newCenteredText(gotext.Get("Server"))
g.resetEmail = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConfirmReset()
return false
})
centerInput(g.resetEmail)
@ -835,20 +819,6 @@ func NewGame() *Game {
passwordLabel := newCenteredText(gotext.Get("Password"))
serverLabel := newCenteredText(gotext.Get("Server"))
g.connectKeyboardButton = etk.NewButton(gotext.Get("Show Keyboard"), func() error {
if g.keyboard.Visible() {
g.keyboard.SetVisible(false)
g.connectKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.lobby.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.Board.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
} else {
g.EnableTouchInput()
g.keyboard.SetVisible(true)
g.connectKeyboardButton.Label.SetText(gotext.Get("Hide Keyboard"))
}
return nil
})
infoLabel := etk.NewText(gotext.Get("To log in as a guest, enter a username (if you want) and do not enter a password."))
footerLabel := etk.NewText("Boxcars " + version)
@ -856,11 +826,13 @@ func NewGame() *Game {
footerLabel.SetVertical(messeji.AlignEnd)
g.connectUsername = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConnect()
return false
})
centerInput(g.connectUsername)
g.connectPassword = etk.NewInput("", "", func(text string) (handled bool) {
g.selectConnect()
return false
})
centerInput(g.connectPassword)
@ -916,7 +888,7 @@ func NewGame() *Game {
grid.AddChildAt(footerLabel, 1, g.connectGridY+3, 3, 1)
connectGrid = grid
connectFrame = etk.NewFrame(connectGrid, etk.NewFrame(game.keyboard))
connectFrame = etk.NewFrame(connectGrid)
connectFrame.SetPositionChildren(true)
}
@ -928,16 +900,19 @@ func NewGame() *Game {
variantLabel := newCenteredText(gotext.Get("Variant"))
g.lobby.createGameName = etk.NewInput("", "", func(text string) (handled bool) {
g.lobby.confirmCreateGame()
return false
})
centerInput(g.lobby.createGameName)
g.lobby.createGamePoints = etk.NewInput("", "", func(text string) (handled bool) {
g.lobby.confirmCreateGame()
return false
})
centerInput(g.lobby.createGamePoints)
g.lobby.createGamePassword = etk.NewInput("", "", func(text string) (handled bool) {
g.lobby.confirmCreateGame()
return false
})
centerInput(g.lobby.createGamePassword)
@ -1020,7 +995,6 @@ func NewGame() *Game {
createGameFrame = etk.NewFrame()
createGameFrame.SetPositionChildren(true)
createGameFrame.AddChild(createGameContainer)
createGameFrame.AddChild(etk.NewFrame(g.keyboard, g.lobby.showKeyboardButton))
createGameFrame.AddChild(g.tutorialFrame)
}
@ -1030,6 +1004,7 @@ func NewGame() *Game {
passwordLabel := newCenteredText(gotext.Get("Password"))
g.lobby.joinGamePassword = etk.NewInput("", "", func(text string) (handled bool) {
g.lobby.confirmJoinGame()
return false
})
centerInput(g.lobby.joinGamePassword)
@ -1053,7 +1028,6 @@ func NewGame() *Game {
joinGameFrame = etk.NewFrame()
joinGameFrame.SetPositionChildren(true)
joinGameFrame.AddChild(joinGameContainer)
joinGameFrame.AddChild(etk.NewFrame(g.keyboard, g.lobby.showKeyboardButton))
joinGameFrame.AddChild(g.tutorialFrame)
}
@ -1081,6 +1055,7 @@ func NewGame() *Game {
}
g.lobby.historyUsername = etk.NewInput("", "", func(text string) (handled bool) {
g.selectHistorySearch()
return false
})
centerInput(g.lobby.historyUsername)
@ -1216,6 +1191,12 @@ func NewGame() *Game {
listGamesFrame.AddChild(g.tutorialFrame)
}
if AutoEnableTouchInput {
g.keyboardHint = etk.NewText(gotext.Get("Press back to toggle the keyboard.") + "\n\n" + gotext.Get("Long press back to exit the application.") + "\n\n" + gotext.Get("Tap to dismiss this pop-up."))
g.keyboardHint.SetHorizontal(messeji.AlignCenter)
g.keyboardHint.SetVertical(messeji.AlignCenter)
}
g.needLayoutConnect = true
g.needLayoutLobby = true
g.needLayoutBoard = true
@ -2064,11 +2045,6 @@ func (g *Game) Connect() {
l("*** " + gotext.Get("Connecting..."))
g.keyboard.SetVisible(false)
g.connectKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.lobby.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.Board.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
if g.Password != "" {
g.lobby.historyButton.SetVisible(true)
}
@ -2135,11 +2111,6 @@ func (g *Game) ConnectLocal(conn net.Conn) {
l("*** " + gotext.Get("Playing offline."))
g.keyboard.SetVisible(false)
g.connectKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.lobby.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.Board.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
g.setRoot(listGamesFrame)
g.Client = newClient("", g.Username, g.Password, false)
@ -2273,6 +2244,13 @@ func (g *Game) selectHistoryNext() error {
}
func (g *Game) handleInput(keys []ebiten.Key) error {
if len(keys) == 0 {
return nil
} else if AutoEnableTouchInput {
scheduleFrame()
log.Println("SCHEDULE FRAME ON KEYS")
}
if !g.loggedIn {
for _, key := range keys {
switch key {
@ -2402,30 +2380,26 @@ func (g *Game) handleInput(keys []ebiten.Key) error {
return nil
}
func (g *Game) handleTouch(p image.Point) {
if p.X == 0 && p.Y == 0 {
return
func (g *Game) handleTouch(p image.Point) bool {
if g.keyboardHintDismissed || (p.X == 0 && p.Y == 0) {
return false
}
if g.keyboardHintVisible && p.X >= 0 && p.X < g.screenW && p.Y >= 0 && p.Y < g.screenH/3 {
g.keyboardHintVisible = false
g.keyboardHintDismissed = true
return true
}
w := etk.At(p)
if w == nil {
return
return false
}
switch w.(type) {
case *etk.Input:
g.keyboard.SetVisible(true)
var btn *etk.Button
if !g.loggedIn {
btn = g.connectKeyboardButton
} else if !viewBoard {
btn = g.lobby.showKeyboardButton
} else {
btn = g.Board.showKeyboardButton
g.Board.lastKeyboardToggle = time.Now()
g.Board.floatChatGrid.SetVisible(true)
g.Board.floatChatGrid.SetRect(g.Board.floatChatGrid.Rect())
}
btn.Label.SetText(gotext.Get("Hide Keyboard"))
g.keyboardHintVisible = true
}
return false
}
// Update is called by Ebitengine only when user input occurs, or a frame is
@ -2465,6 +2439,7 @@ func (g *Game) Update() error {
g.pressedKeys = inpututil.AppendPressedKeys(g.pressedKeys[:0])
if len(g.pressedKeys) > 0 {
log.Printf("PRESSED %+v", g.pressedKeys)
scheduleFrame()
}
@ -2500,7 +2475,9 @@ func (g *Game) Update() error {
g.EnableTouchInput()
cx, cy = ebiten.TouchPosition(id)
if cx != 0 || cy != 0 {
g.handleTouch(image.Point{cx, cy})
if g.handleTouch(image.Point{cx, cy}) {
return nil
}
break
}
}
@ -2513,6 +2490,14 @@ func (g *Game) Update() error {
return err
}
if AutoEnableTouchInput {
g.pressedRunes = ebiten.AppendInputChars(g.pressedRunes[:0])
if len(g.pressedRunes) != 0 {
log.Printf("PRESSED RUNES %+v", g.pressedRunes)
scheduleFrame()
}
}
if !g.TouchInput {
g.touchIDs = inpututil.AppendJustPressedTouchIDs(g.touchIDs[:0])
if len(g.touchIDs) > 0 {
@ -2525,19 +2510,6 @@ func (g *Game) Update() error {
}
if !g.loggedIn {
if len(g.keyboardInput) > 0 {
w := etk.Focused()
if w != nil {
for _, event := range g.keyboardInput {
if event.Rune > 0 {
w.HandleKeyboard(-1, event.Rune)
} else {
w.HandleKeyboard(event.Key, 0)
}
}
}
}
err = etk.Update()
if err != nil {
return err
@ -2560,17 +2532,6 @@ func (g *Game) Update() error {
}
}
w := etk.Focused()
if w != nil {
for _, event := range g.keyboardInput {
if event.Rune > 0 {
w.HandleKeyboard(-1, event.Rune)
} else {
w.HandleKeyboard(event.Key, 0)
}
}
}
if g.lobby.showCreateGame {
pointsText := g.lobby.createGamePoints.Text()
if pointsText != "" {
@ -2580,14 +2541,6 @@ func (g *Game) Update() error {
}
} else {
g.Board.Update()
for _, event := range g.keyboardInput {
if event.Rune > 0 {
inputBuffer.HandleKeyboard(-1, event.Rune)
} else {
inputBuffer.HandleKeyboard(event.Key, 0)
}
}
}
err = etk.Update()
@ -2597,6 +2550,17 @@ func (g *Game) Update() error {
return nil
}
func (g *Game) drawKeyboardHint(screen *ebiten.Image) {
if !g.keyboardHintVisible {
return
}
r := image.Rect(0, 0, g.screenW, g.screenH/3)
screen.SubImage(r).(*ebiten.Image).Fill(frameColor)
screen.SubImage(image.Rect(0, g.screenH/3, g.screenW, g.screenH/3+4)).(*ebiten.Image).Fill(borderColor)
g.keyboardHint.SetRect(r)
g.keyboardHint.Draw(screen)
}
func (g *Game) Draw(screen *ebiten.Image) {
g.Lock()
defer g.Unlock()
@ -2633,6 +2597,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
if err != nil {
log.Fatal(err)
}
g.drawKeyboardHint(screen)
return
}
@ -2647,6 +2612,8 @@ func (g *Game) Draw(screen *ebiten.Image) {
g.Board.drawDraggedCheckers(screen)
g.drawKeyboardHint(screen)
if Debug > 0 {
g.drawBuffer.Reset()
@ -2715,9 +2682,6 @@ func (g *Game) layoutLobby() {
g.lobby.buttonBarHeight = g.scale(baseButtonHeight)
g.setBufferRects()
g.lobby.showKeyboardButton.SetVisible(g.TouchInput)
g.lobby.showKeyboardButton.SetRect(image.Rect(g.screenW-400, 0, g.screenW, int(76)))
if !g.loadedLobby {
updateAllButtons(game.lobby.buttonsGrid)
g.loadedLobby = true
@ -2759,7 +2723,6 @@ func (g *Game) layoutBoard() {
if !g.loadedBoard {
updateAllButtons(game.Board.menuGrid)
updateAllButtons(game.Board.leaveGameGrid)
updateAllButtons(game.Board.floatChatGrid)
g.loadedBoard = true
}
}
@ -2811,7 +2774,6 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
}
statusBuffer.SetScrollBarColors(etk.Style.ScrollAreaColor, etk.Style.ScrollHandleColor)
floatStatusBuffer.SetScrollBarColors(etk.Style.ScrollAreaColor, etk.Style.ScrollHandleColor)
gameBuffer.SetScrollBarColors(etk.Style.ScrollAreaColor, etk.Style.ScrollHandleColor)
inputBuffer.Field.SetScrollBarColors(etk.Style.ScrollAreaColor, etk.Style.ScrollHandleColor)
g.lobby.availableMatchesList.SetScrollBarColors(etk.Style.ScrollAreaColor, etk.Style.ScrollHandleColor)
@ -2820,7 +2782,6 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
{
scrollBarWidth := g.scale(32)
statusBuffer.SetScrollBarWidth(scrollBarWidth)
floatStatusBuffer.SetScrollBarWidth(scrollBarWidth)
gameBuffer.SetScrollBarWidth(scrollBarWidth)
inputBuffer.Field.SetScrollBarWidth(scrollBarWidth)
}
@ -2847,7 +2808,6 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
padding := g.bufferPadding()
statusBuffer.SetPadding(padding)
floatStatusBuffer.SetPadding(padding)
gameBuffer.SetPadding(padding)
inputBuffer.Field.SetPadding(padding)
@ -2858,8 +2818,6 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
g.Board.updateOpponentLabel()
g.Board.updatePlayerLabel()
g.keyboard.SetRect(image.Rect(0, game.screenH-game.screenH/3, game.screenW, game.screenH))
if g.LoadReplay != nil {
go g.HandleReplay(g.LoadReplay)
g.LoadReplay = nil
@ -2913,9 +2871,6 @@ func (g *Game) EnableTouchInput() {
}
g.TouchInput = true
g.keyboard.SetKeys(kibodo.KeysMobileQWERTY)
g.keyboard.SetExtendedKeys(kibodo.KeysMobileSymbols)
// Update layout.
g.forceLayout = true

View file

@ -89,10 +89,8 @@ type lobby struct {
availableMatchesList *etk.List
historyButton *etk.Button
showKeyboardButton *etk.Button
buttonsGrid *etk.Grid
frame *etk.Frame
historyButton *etk.Button
buttonsGrid *etk.Grid
}
func NewLobby() *lobby {
@ -134,24 +132,9 @@ func NewLobby() *lobby {
matchList.SetHighlightColor(color.RGBA{79, 55, 30, 255})
matchList.AddChildAt(newCenteredText(gotext.Get("Loading...")), 0, 0)
l.availableMatchesList = matchList
l.showKeyboardButton = etk.NewButton(gotext.Get("Show Keyboard"), l.toggleKeyboard)
l.frame = etk.NewFrame()
l.frame.AddChild(l.showKeyboardButton)
return l
}
func (l *lobby) toggleKeyboard() error {
if game.keyboard.Visible() {
game.keyboard.SetVisible(false)
l.showKeyboardButton.Label.SetText(gotext.Get("Show Keyboard"))
} else {
game.keyboard.SetVisible(true)
l.showKeyboardButton.Label.SetText(gotext.Get("Hide Keyboard"))
}
return nil
}
func (l *lobby) toggleVariantAcey() error {
l.createGameTabulaCheckbox.SetSelected(false)
return nil

View file

@ -43,6 +43,9 @@ msgstr ""
msgid "Available"
msgstr ""
msgid "Backgammon"
msgstr ""
msgid "Bearing Off"
msgstr ""
@ -130,9 +133,6 @@ msgstr ""
msgid "Good Luck, Have Fun"
msgstr ""
msgid "Hide Keyboard"
msgstr ""
msgid "Highlight legal moves"
msgstr ""
@ -166,6 +166,9 @@ msgstr ""
msgid "Logged in as guest"
msgstr ""
msgid "Long press back to exit the application."
msgstr ""
msgid "Match Name"
msgstr ""
@ -175,6 +178,9 @@ msgstr ""
msgid "Medium"
msgstr ""
msgid "Multi"
msgstr ""
msgid "Name"
msgstr ""
@ -211,6 +217,9 @@ msgstr ""
msgid "Points"
msgstr ""
msgid "Press back to toggle the keyboard."
msgstr ""
msgid "Private"
msgstr ""
@ -262,15 +271,15 @@ msgstr ""
msgid "Settings"
msgstr ""
msgid "Show Keyboard"
msgstr ""
msgid "Show moves"
msgstr ""
msgid "Show pip count"
msgstr ""
msgid "Single"
msgstr ""
msgid "Slow"
msgstr ""
@ -289,6 +298,9 @@ msgstr ""
msgid "Tabula"
msgstr ""
msgid "Tap to dismiss this pop-up."
msgstr ""
msgid "This concludes the tutorial. To share feedback and chat with other players visit %s"
msgstr ""

6
go.mod
View file

@ -4,8 +4,8 @@ go 1.17
require (
code.rocket9labs.com/tslocum/bgammon v0.0.0-20240117214045-3607efee4129
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120044556-60982417c592
code.rocket9labs.com/tslocum/etk v0.0.0-20240119041154-d2c44cc232f6
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120074310-6968c426a4e1
code.rocket9labs.com/tslocum/etk v0.0.0-20240122001849-b8e1658b3f49
code.rocket9labs.com/tslocum/tabula v0.0.0-20240118055336-21a3dea3f702
github.com/hajimehoshi/ebiten/v2 v2.6.3
github.com/leonelquinteros/gotext v1.5.3-0.20231003122255-12a99145a351
@ -25,7 +25,7 @@ require (
github.com/alexedwards/argon2id v1.0.0 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/ebitengine/oto/v3 v3.1.0 // indirect
github.com/ebitengine/purego v0.5.1 // indirect
github.com/ebitengine/purego v0.5.2 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.3.2 // indirect

12
go.sum
View file

@ -2,10 +2,10 @@ code.rocket9labs.com/tslocum/bei v0.0.0-20240108012722-6db380cc190b h1:Y0a14Kf/h
code.rocket9labs.com/tslocum/bei v0.0.0-20240108012722-6db380cc190b/go.mod h1:tS60/VNAJphKvDBkSLQhKALa15msIAuWWfEKNc4oFZc=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20240117214045-3607efee4129 h1:wguf0figCFqnSxAK8wAznDor28ZEkElA2ShoZmqLRHg=
code.rocket9labs.com/tslocum/bgammon v0.0.0-20240117214045-3607efee4129/go.mod h1:LAki3jpHOsr4fwaK0xC9tkg+wgu/9ZNEqqx1zE3/HP4=
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120044556-60982417c592 h1:vLCTYMZfu6otPNNQG/vgFibct+p1fsKGxk1eCddRAi4=
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120044556-60982417c592/go.mod h1:w6xR2lWW3xUo7KlCOaJ+Jbs29AfQVRQEJ2W1vb0IuOo=
code.rocket9labs.com/tslocum/etk v0.0.0-20240119041154-d2c44cc232f6 h1:uXG3IWWGkMG/mDjk1YsWJfQMbssYh3weoGuz1knFSuE=
code.rocket9labs.com/tslocum/etk v0.0.0-20240119041154-d2c44cc232f6/go.mod h1:+mJqiyL/Ne30kcpnaQ1+XjYxI3PZA7HfWY0ReHeSMEA=
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120074310-6968c426a4e1 h1:FsUNZJjzoYixG36Hxf0eYov0no6GGWjEVdmvGWjol7Y=
code.rocket9labs.com/tslocum/bgammon-tabula-bot v0.0.0-20240120074310-6968c426a4e1/go.mod h1:w6xR2lWW3xUo7KlCOaJ+Jbs29AfQVRQEJ2W1vb0IuOo=
code.rocket9labs.com/tslocum/etk v0.0.0-20240122001849-b8e1658b3f49 h1:OcdDIzebupJx2uj6lKw6uip537C+RTa39RBpsvOErPc=
code.rocket9labs.com/tslocum/etk v0.0.0-20240122001849-b8e1658b3f49/go.mod h1:2IXUt2b3de6r0IX5W5uR1vvTw1Z+JcX/ATC1woaaW2E=
code.rocket9labs.com/tslocum/tabula v0.0.0-20240118055336-21a3dea3f702 h1:NGZILSBynzLZF84WKZyAuoWsZFq37uvEcP2dFvPsY/8=
code.rocket9labs.com/tslocum/tabula v0.0.0-20240118055336-21a3dea3f702/go.mod h1:WEJXESKXqrMFLAArikQ79lpRibNeeE1C0VruxXYMF5M=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@ -33,8 +33,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ebitengine/oto/v3 v3.1.0 h1:9tChG6rizyeR2w3vsygTTTVVJ9QMMyu00m2yBOCch6U=
github.com/ebitengine/oto/v3 v3.1.0/go.mod h1:IK1QTnlfZK2GIB6ziyECm433hAdTaPpOsGMLhEyEGTg=
github.com/ebitengine/purego v0.5.1 h1:hNunhThpOf1vzKl49v6YxIsXLhl92vbBEv1/2Ez3ZrY=
github.com/ebitengine/purego v0.5.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/ebitengine/purego v0.5.2 h1:r2MQEtkGzZ4LRtFZVAg5bjYKnUbxxloaeuGxH0t7qfs=
github.com/ebitengine/purego v0.5.2/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df/go.mod h1:GJr+FCSXshIwgHBtLglIg9M2l2kQSi6QjVAngtzI08Y=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=