mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 11:48:55 +01:00
parent
d7fc49355b
commit
dd6f5c4565
@ -64,11 +64,11 @@ func (t *TextField) Contains(x, y int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TextField) SetSelectionStartByCursorPosition(x, y int) bool {
|
func (t *TextField) SetSelectionStartByCursorPosition(x, y int) bool {
|
||||||
|
t.cleanUp()
|
||||||
idx, ok := t.textIndexByCursorPosition(x, y)
|
idx, ok := t.textIndexByCursorPosition(x, y)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
t.selectionStart = idx
|
t.selectionStart = idx
|
||||||
t.selectionEnd = idx
|
t.selectionEnd = idx
|
||||||
return true
|
return true
|
||||||
@ -136,29 +136,33 @@ func (t *TextField) Blur() {
|
|||||||
t.focused = false
|
t.focused = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TextField) cleanUp() {
|
||||||
|
if t.ch != nil {
|
||||||
|
select {
|
||||||
|
case state, ok := <-t.ch:
|
||||||
|
if ok && state.Committed {
|
||||||
|
t.text = t.text[:t.selectionStart] + state.Text + t.text[t.selectionEnd:]
|
||||||
|
t.selectionStart += len(state.Text)
|
||||||
|
t.selectionEnd = t.selectionStart
|
||||||
|
t.state = textinput.State{}
|
||||||
|
}
|
||||||
|
t.state = state
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if t.end != nil {
|
||||||
|
t.end()
|
||||||
|
t.ch = nil
|
||||||
|
t.end = nil
|
||||||
|
t.state = textinput.State{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TextField) Update() {
|
func (t *TextField) Update() {
|
||||||
if !t.focused {
|
if !t.focused {
|
||||||
// If the text field still has a session, read the last state and process it just in case.
|
// If the text field still has a session, read the last state and process it just in case.
|
||||||
if t.ch != nil {
|
t.cleanUp()
|
||||||
select {
|
|
||||||
case state, ok := <-t.ch:
|
|
||||||
if ok && state.Committed {
|
|
||||||
t.text = t.text[:t.selectionStart] + state.Text + t.text[t.selectionEnd:]
|
|
||||||
t.selectionStart += len(state.Text)
|
|
||||||
t.selectionEnd = t.selectionStart
|
|
||||||
t.state = textinput.State{}
|
|
||||||
}
|
|
||||||
t.state = state
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if t.end != nil {
|
|
||||||
t.end()
|
|
||||||
t.ch = nil
|
|
||||||
t.end = nil
|
|
||||||
t.state = textinput.State{}
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package textinput
|
package textinput
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
@ -77,6 +78,10 @@ func (t *textInput) init() {
|
|||||||
if e.Get("code").String() == "Tab" {
|
if e.Get("code").String() == "Tab" {
|
||||||
e.Call("preventDefault")
|
e.Call("preventDefault")
|
||||||
}
|
}
|
||||||
|
if e.Get("code").String() == "Enter" || e.Get("key").String() == "Enter" {
|
||||||
|
// Ignore Enter key to avoid ebiten.IsKeyPressed(ebiten.KeyEnter) unexpectedly becomes true, especially for iOS Safari.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if !e.Get("isComposing").Bool() {
|
if !e.Get("isComposing").Bool() {
|
||||||
ui.Get().UpdateInputFromEvent(e)
|
ui.Get().UpdateInputFromEvent(e)
|
||||||
}
|
}
|
||||||
@ -104,6 +109,7 @@ func (t *textInput) init() {
|
|||||||
t.trySend(true)
|
t.trySend(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Though `isComposing` is false, send the text as being not committed for text completion on mobile browsers.
|
||||||
t.trySend(false)
|
t.trySend(false)
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
@ -143,18 +149,37 @@ func (t *textInput) Start(x, y int) (chan State, func()) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.session != nil {
|
|
||||||
t.session.end()
|
|
||||||
t.session = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if js.Global().Get("_ebitengine_textinput_ready").Truthy() {
|
if js.Global().Get("_ebitengine_textinput_ready").Truthy() {
|
||||||
|
if t.session != nil {
|
||||||
|
t.session.end()
|
||||||
|
}
|
||||||
s := newSession()
|
s := newSession()
|
||||||
t.session = s
|
t.session = s
|
||||||
js.Global().Get("window").Set("_ebitengine_textinput_ready", js.Undefined())
|
js.Global().Get("window").Set("_ebitengine_textinput_ready", js.Undefined())
|
||||||
return s.ch, s.end
|
return s.ch, s.end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a textarea is focused, create a session immediately.
|
||||||
|
// A virtual keyboard should already be shown on mobile browsers.
|
||||||
|
if document.Get("activeElement").Equal(t.textareaElement) {
|
||||||
|
t.textareaElement.Set("value", "")
|
||||||
|
t.textareaElement.Call("focus")
|
||||||
|
style := t.textareaElement.Get("style")
|
||||||
|
style.Set("left", fmt.Sprintf("%dpx", x))
|
||||||
|
style.Set("top", fmt.Sprintf("%dpx", y))
|
||||||
|
|
||||||
|
if t.session == nil {
|
||||||
|
s := newSession()
|
||||||
|
t.session = s
|
||||||
|
}
|
||||||
|
return t.session.ch, t.session.end
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.session != nil {
|
||||||
|
t.session.end()
|
||||||
|
t.session = nil
|
||||||
|
}
|
||||||
|
|
||||||
// On iOS Safari, `focus` works only in user-interaction events (#2898).
|
// On iOS Safari, `focus` works only in user-interaction events (#2898).
|
||||||
// Assuming Start is called every tick, defer the starting process to the next user-interaction event.
|
// Assuming Start is called every tick, defer the starting process to the next user-interaction event.
|
||||||
js.Global().Get("window").Set("_ebitengine_textinput_x", x)
|
js.Global().Get("window").Set("_ebitengine_textinput_x", x)
|
||||||
|
Loading…
Reference in New Issue
Block a user