mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2026-04-23 00:07:15 +08:00
exp/textinput: unexport State and Start
macOS requires the information of the current selection to implement IME correctly, then the user must use Field. Field is no longer just a wrapper API. As this package is experimental, it is OK to have a breaking change, though this is not ideal. Updates #3233
This commit is contained in:
@@ -75,9 +75,9 @@ type Field struct {
|
||||
selectionStartInBytes int
|
||||
selectionEndInBytes int
|
||||
|
||||
ch <-chan State
|
||||
ch <-chan textInputState
|
||||
end func()
|
||||
state State
|
||||
state textInputState
|
||||
err error
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func (f *Field) HandleInput(x, y int) (handled bool, err error) {
|
||||
if f.ch == nil {
|
||||
// TODO: On iOS Safari, Start doesn't work as expected (#2898).
|
||||
// Handle a click event and focus the textarea there.
|
||||
f.ch, f.end = Start(x, y)
|
||||
f.ch, f.end = start(x, y)
|
||||
// Start returns nil for non-supported envrionments, or when unable to start text inputting for some reasons.
|
||||
if f.ch == nil {
|
||||
return handled, nil
|
||||
@@ -121,12 +121,12 @@ func (f *Field) HandleInput(x, y int) (handled bool, err error) {
|
||||
if !ok {
|
||||
f.ch = nil
|
||||
f.end = nil
|
||||
f.state = State{}
|
||||
f.state = textInputState{}
|
||||
break readchar
|
||||
}
|
||||
if state.Committed && state.Text == "\x7f" {
|
||||
// DEL should not modify the text (#3212).
|
||||
f.state = State{}
|
||||
f.state = textInputState{}
|
||||
continue
|
||||
}
|
||||
handled = true
|
||||
@@ -134,7 +134,7 @@ func (f *Field) HandleInput(x, y int) (handled bool, err error) {
|
||||
f.text = f.text[:f.selectionStartInBytes] + state.Text + f.text[f.selectionEndInBytes:]
|
||||
f.selectionStartInBytes += len(state.Text)
|
||||
f.selectionEndInBytes = f.selectionStartInBytes
|
||||
f.state = State{}
|
||||
f.state = textInputState{}
|
||||
continue
|
||||
}
|
||||
f.state = state
|
||||
@@ -189,7 +189,7 @@ func (f *Field) cleanUp() {
|
||||
f.text = f.text[:f.selectionStartInBytes] + state.Text + f.text[f.selectionEndInBytes:]
|
||||
f.selectionStartInBytes += len(state.Text)
|
||||
f.selectionEndInBytes = f.selectionStartInBytes
|
||||
f.state = State{}
|
||||
f.state = textInputState{}
|
||||
}
|
||||
f.state = state
|
||||
default:
|
||||
@@ -201,7 +201,7 @@ func (f *Field) cleanUp() {
|
||||
f.end()
|
||||
f.ch = nil
|
||||
f.end = nil
|
||||
f.state = State{}
|
||||
f.state = textInputState{}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -24,10 +24,10 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||
)
|
||||
|
||||
// State represents the current state of text inputting.
|
||||
// textInputState represents the current state of text inputting.
|
||||
//
|
||||
// State is the low-level API. For most use cases, Field is easier to use.
|
||||
type State struct {
|
||||
// textInputState is the low-level API. For most use cases, Field is easier to use.
|
||||
type textInputState struct {
|
||||
// Text represents the current inputting text.
|
||||
Text string
|
||||
|
||||
@@ -44,13 +44,13 @@ type State struct {
|
||||
Error error
|
||||
}
|
||||
|
||||
// Start starts text inputting.
|
||||
// Start returns a channel to send the state repeatedly, and a function to end the text inputting.
|
||||
// start starts text inputting.
|
||||
// start returns a channel to send the state repeatedly, and a function to end the text inputting.
|
||||
//
|
||||
// Start is the low-level API. For most use cases, Field is easier to use.
|
||||
// start is the low-level API. For most use cases, Field is easier to use.
|
||||
//
|
||||
// Start returns nil and nil if the current environment doesn't support this package.
|
||||
func Start(x, y int) (states <-chan State, close func()) {
|
||||
// start returns nil and nil if the current environment doesn't support this package.
|
||||
func start(x, y int) (states <-chan textInputState, close func()) {
|
||||
cx, cy := ui.Get().LogicalPositionToClientPositionInNativePixels(float64(x), float64(y))
|
||||
return theTextInput.Start(int(cx), int(cy))
|
||||
}
|
||||
@@ -60,13 +60,13 @@ func convertUTF16CountToByteCount(text string, c int) int {
|
||||
}
|
||||
|
||||
type session struct {
|
||||
ch chan State
|
||||
ch chan textInputState
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func newSession() *session {
|
||||
return &session{
|
||||
ch: make(chan State, 1),
|
||||
ch: make(chan textInputState, 1),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func (s *session) end() {
|
||||
close(s.done)
|
||||
}
|
||||
|
||||
func (s *session) trySend(state State) {
|
||||
func (s *session) trySend(state textInputState) {
|
||||
for {
|
||||
select {
|
||||
case s.ch <- state:
|
||||
|
||||
@@ -33,7 +33,7 @@ type textInput struct {
|
||||
|
||||
var theTextInput textInput
|
||||
|
||||
func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
func (t *textInput) Start(x, y int) (<-chan textInputState, func()) {
|
||||
ui.Get().RunOnMainThread(func() {
|
||||
t.start(x, y)
|
||||
})
|
||||
@@ -49,7 +49,7 @@ func (t *textInput) update(text string, start, end int, committed bool) {
|
||||
if t.session != nil {
|
||||
startInBytes := convertUTF16CountToByteCount(text, start)
|
||||
endInBytes := convertUTF16CountToByteCount(text, end)
|
||||
t.session.trySend(State{
|
||||
t.session.trySend(textInputState{
|
||||
Text: text,
|
||||
CompositionSelectionStartInBytes: startInBytes,
|
||||
CompositionSelectionEndInBytes: endInBytes,
|
||||
|
||||
@@ -156,7 +156,7 @@ body.addEventListener("keyup", handler);`)
|
||||
// TODO: What about other events like wheel?
|
||||
}
|
||||
|
||||
func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
func (t *textInput) Start(x, y int) (<-chan textInputState, func()) {
|
||||
if !t.textareaElement.Truthy() {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -220,7 +220,7 @@ func (t *textInput) trySend(committed bool) {
|
||||
startInBytes := convertUTF16CountToByteCount(textareaValue, start)
|
||||
endInBytes := convertUTF16CountToByteCount(textareaValue, end)
|
||||
|
||||
t.session.trySend(State{
|
||||
t.session.trySend(textInputState{
|
||||
Text: textareaValue,
|
||||
CompositionSelectionStartInBytes: startInBytes,
|
||||
CompositionSelectionEndInBytes: endInBytes,
|
||||
|
||||
@@ -27,7 +27,7 @@ type textInput struct {
|
||||
|
||||
var theTextInput textInput
|
||||
|
||||
func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
func (t *textInput) Start(x, y int) (<-chan textInputState, func()) {
|
||||
// AppendInputChars is updated only when the tick is updated.
|
||||
// If the tick is not updated, return nil immediately.
|
||||
tick := ebiten.Tick()
|
||||
@@ -46,7 +46,7 @@ func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
if len(t.rs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
s.ch <- State{
|
||||
s.ch <- textInputState{
|
||||
Text: string(t.rs),
|
||||
Committed: true,
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ type textInput struct {
|
||||
|
||||
var theTextInput textInput
|
||||
|
||||
func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
func (t *textInput) Start(x, y int) (<-chan textInputState, func()) {
|
||||
if microsoftgdk.IsXbox() {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func (t *textInput) Start(x, y int) (<-chan State, func()) {
|
||||
t.session = session
|
||||
})
|
||||
if err != nil {
|
||||
session.ch <- State{Error: err}
|
||||
session.ch <- textInputState{Error: err}
|
||||
session.end()
|
||||
}
|
||||
return session.ch, func() {
|
||||
@@ -144,13 +144,13 @@ func (t *textInput) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintptr) u
|
||||
if lParam&(_GCS_RESULTSTR|_GCS_COMPSTR) != 0 {
|
||||
if lParam&_GCS_RESULTSTR != 0 {
|
||||
if err := t.commit(); err != nil {
|
||||
t.session.ch <- State{Error: err}
|
||||
t.session.ch <- textInputState{Error: err}
|
||||
t.end()
|
||||
}
|
||||
}
|
||||
if lParam&_GCS_COMPSTR != 0 {
|
||||
if err := t.update(); err != nil {
|
||||
t.session.ch <- State{Error: err}
|
||||
t.session.ch <- textInputState{Error: err}
|
||||
t.end()
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ func (t *textInput) wndProc(hWnd uintptr, uMsg uint32, wParam, lParam uintptr) u
|
||||
// send must be called from the main thread.
|
||||
func (t *textInput) send(text string, startInBytes, endInBytes int, committed bool) {
|
||||
if t.session != nil {
|
||||
t.session.trySend(State{
|
||||
t.session.trySend(textInputState{
|
||||
Text: text,
|
||||
CompositionSelectionStartInBytes: startInBytes,
|
||||
CompositionSelectionEndInBytes: endInBytes,
|
||||
|
||||
Reference in New Issue
Block a user