mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
io/key: [API] add InputHintOp for specifying the input hint for a tag
We're about to replace key.InputOp with a filter; this change separates the input hint into its own operation. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+6
-1
@@ -64,6 +64,7 @@ const (
|
|||||||
TypePopPass
|
TypePopPass
|
||||||
TypeInput
|
TypeInput
|
||||||
TypeKeyInput
|
TypeKeyInput
|
||||||
|
TypeKeyInputHint
|
||||||
TypeSave
|
TypeSave
|
||||||
TypeLoad
|
TypeLoad
|
||||||
TypeAux
|
TypeAux
|
||||||
@@ -139,7 +140,8 @@ const (
|
|||||||
TypePassLen = 1
|
TypePassLen = 1
|
||||||
TypePopPassLen = 1
|
TypePopPassLen = 1
|
||||||
TypeInputLen = 1
|
TypeInputLen = 1
|
||||||
TypeKeyInputLen = 1 + 1
|
TypeKeyInputLen = 1
|
||||||
|
TypeKeyInputHintLen = 1 + 1
|
||||||
TypeSaveLen = 1 + 4
|
TypeSaveLen = 1 + 4
|
||||||
TypeLoadLen = 1 + 4
|
TypeLoadLen = 1 + 4
|
||||||
TypeAuxLen = 1
|
TypeAuxLen = 1
|
||||||
@@ -414,6 +416,7 @@ var opProps = [0x100]opProp{
|
|||||||
TypePopPass: {Size: TypePopPassLen, NumRefs: 0},
|
TypePopPass: {Size: TypePopPassLen, NumRefs: 0},
|
||||||
TypeInput: {Size: TypeInputLen, NumRefs: 1},
|
TypeInput: {Size: TypeInputLen, NumRefs: 1},
|
||||||
TypeKeyInput: {Size: TypeKeyInputLen, NumRefs: 2},
|
TypeKeyInput: {Size: TypeKeyInputLen, NumRefs: 2},
|
||||||
|
TypeKeyInputHint: {Size: TypeKeyInputHintLen, NumRefs: 1},
|
||||||
TypeSave: {Size: TypeSaveLen, NumRefs: 0},
|
TypeSave: {Size: TypeSaveLen, NumRefs: 0},
|
||||||
TypeLoad: {Size: TypeLoadLen, NumRefs: 0},
|
TypeLoad: {Size: TypeLoadLen, NumRefs: 0},
|
||||||
TypeAux: {Size: TypeAuxLen, NumRefs: 0},
|
TypeAux: {Size: TypeAuxLen, NumRefs: 0},
|
||||||
@@ -477,6 +480,8 @@ func (t OpType) String() string {
|
|||||||
return "Input"
|
return "Input"
|
||||||
case TypeKeyInput:
|
case TypeKeyInput:
|
||||||
return "KeyInput"
|
return "KeyInput"
|
||||||
|
case TypeKeyInputHint:
|
||||||
|
return "KeyInputHint"
|
||||||
case TypeSave:
|
case TypeSave:
|
||||||
return "Save"
|
return "Save"
|
||||||
case TypeLoad:
|
case TypeLoad:
|
||||||
|
|||||||
+15
-9
@@ -58,6 +58,11 @@ const (
|
|||||||
TextInputOpen
|
TextInputOpen
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (q *keyQueue) inputHint(op key.InputHintOp) {
|
||||||
|
h := q.handlerFor(op.Tag)
|
||||||
|
h.hint = op.Hint
|
||||||
|
}
|
||||||
|
|
||||||
// InputState returns the last text input state as
|
// InputState returns the last text input state as
|
||||||
// determined in Frame.
|
// determined in Frame.
|
||||||
func (q *keyQueue) InputState() TextInputState {
|
func (q *keyQueue) InputState() TextInputState {
|
||||||
@@ -66,7 +71,8 @@ func (q *keyQueue) InputState() TextInputState {
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputHint returns the input mode from the most recent key.InputOp.
|
// InputHint returns the input hint from the focused handler and whether it was
|
||||||
|
// changed since the last call.
|
||||||
func (q *keyQueue) InputHint() (key.InputHint, bool) {
|
func (q *keyQueue) InputHint() (key.InputHint, bool) {
|
||||||
if q.focus == nil {
|
if q.focus == nil {
|
||||||
return q.hint, false
|
return q.hint, false
|
||||||
@@ -87,6 +93,7 @@ func (q *keyQueue) Reset() {
|
|||||||
for _, h := range q.handlers {
|
for _, h := range q.handlers {
|
||||||
h.visible, h.new = false, false
|
h.visible, h.new = false, false
|
||||||
h.order = -1
|
h.order = -1
|
||||||
|
h.hint = key.HintAny
|
||||||
}
|
}
|
||||||
q.order = q.order[:0]
|
q.order = q.order[:0]
|
||||||
q.dirOrder = q.dirOrder[:0]
|
q.dirOrder = q.dirOrder[:0]
|
||||||
@@ -277,24 +284,23 @@ func (q *keyQueue) softKeyboard(show bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *keyQueue) handlerFor(tag event.Tag, area int, bounds image.Rectangle) *keyHandler {
|
func (q *keyQueue) handlerFor(tag event.Tag) *keyHandler {
|
||||||
h, ok := q.handlers[tag]
|
h, ok := q.handlers[tag]
|
||||||
if !ok {
|
if !ok {
|
||||||
h = &keyHandler{new: true, order: -1}
|
h = &keyHandler{new: true, order: -1}
|
||||||
q.handlers[tag] = h
|
q.handlers[tag] = h
|
||||||
}
|
}
|
||||||
if h.order == -1 {
|
|
||||||
h.order = len(q.order)
|
|
||||||
q.order = append(q.order, tag)
|
|
||||||
q.dirOrder = append(q.dirOrder, dirFocusEntry{tag: tag, area: area, bounds: bounds})
|
|
||||||
}
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *keyQueue) inputOp(op key.InputOp, t f32.Affine2D, area int, bounds image.Rectangle) {
|
func (q *keyQueue) inputOp(op key.InputOp, t f32.Affine2D, area int, bounds image.Rectangle) {
|
||||||
h := q.handlerFor(op.Tag, area, bounds)
|
h := q.handlerFor(op.Tag)
|
||||||
|
if h.order == -1 {
|
||||||
|
h.order = len(q.order)
|
||||||
|
q.order = append(q.order, op.Tag)
|
||||||
|
q.dirOrder = append(q.dirOrder, dirFocusEntry{tag: op.Tag, area: area, bounds: bounds})
|
||||||
|
}
|
||||||
h.visible = true
|
h.visible = true
|
||||||
h.hint = op.Hint
|
|
||||||
h.filter = op.Keys
|
h.filter = op.Keys
|
||||||
h.trans = t
|
h.trans = t
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -494,13 +494,18 @@ func (q *Router) collect() {
|
|||||||
filter := key.Set(*encOp.Refs[1].(*string))
|
filter := key.Set(*encOp.Refs[1].(*string))
|
||||||
op := key.InputOp{
|
op := key.InputOp{
|
||||||
Tag: encOp.Refs[0].(event.Tag),
|
Tag: encOp.Refs[0].(event.Tag),
|
||||||
Hint: key.InputHint(encOp.Data[1]),
|
|
||||||
Keys: filter,
|
Keys: filter,
|
||||||
}
|
}
|
||||||
a := pc.currentArea()
|
a := pc.currentArea()
|
||||||
b := pc.currentAreaBounds()
|
b := pc.currentAreaBounds()
|
||||||
pc.keyInputOp(op)
|
pc.keyInputOp(op)
|
||||||
kq.inputOp(op, t, a, b)
|
kq.inputOp(op, t, a, b)
|
||||||
|
case ops.TypeKeyInputHint:
|
||||||
|
op := key.InputHintOp{
|
||||||
|
Tag: encOp.Refs[0].(event.Tag),
|
||||||
|
Hint: key.InputHint(encOp.Data[1]),
|
||||||
|
}
|
||||||
|
kq.inputHint(op)
|
||||||
|
|
||||||
// Semantic ops.
|
// Semantic ops.
|
||||||
case ops.TypeSemanticLabel:
|
case ops.TypeSemanticLabel:
|
||||||
|
|||||||
+14
-2
@@ -23,8 +23,6 @@ import (
|
|||||||
// focused key handler.
|
// focused key handler.
|
||||||
type InputOp struct {
|
type InputOp struct {
|
||||||
Tag event.Tag
|
Tag event.Tag
|
||||||
// Hint describes the type of text expected by Tag.
|
|
||||||
Hint InputHint
|
|
||||||
// Keys is the set of keys Tag can handle. That is, Tag will only
|
// Keys is the set of keys Tag can handle. That is, Tag will only
|
||||||
// receive an Event if its key and modifiers are accepted by Keys.Contains.
|
// receive an Event if its key and modifiers are accepted by Keys.Contains.
|
||||||
// As a special case, the topmost (first added) InputOp handler receives all
|
// As a special case, the topmost (first added) InputOp handler receives all
|
||||||
@@ -32,6 +30,12 @@ type InputOp struct {
|
|||||||
Keys Set
|
Keys Set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InputHintOp describes the type of text expected by a tag.
|
||||||
|
type InputHintOp struct {
|
||||||
|
Tag event.Tag
|
||||||
|
Hint InputHint
|
||||||
|
}
|
||||||
|
|
||||||
// SoftKeyboardCmd shows or hides the on-screen keyboard, if available.
|
// SoftKeyboardCmd shows or hides the on-screen keyboard, if available.
|
||||||
type SoftKeyboardCmd struct {
|
type SoftKeyboardCmd struct {
|
||||||
Show bool
|
Show bool
|
||||||
@@ -331,6 +335,14 @@ func (h InputOp) Add(o *op.Ops) {
|
|||||||
}
|
}
|
||||||
data := ops.Write2String(&o.Internal, ops.TypeKeyInputLen, h.Tag, string(h.Keys))
|
data := ops.Write2String(&o.Internal, ops.TypeKeyInputLen, h.Tag, string(h.Keys))
|
||||||
data[0] = byte(ops.TypeKeyInput)
|
data[0] = byte(ops.TypeKeyInput)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h InputHintOp) Add(o *op.Ops) {
|
||||||
|
if h.Tag == nil {
|
||||||
|
panic("Tag must be non-nil")
|
||||||
|
}
|
||||||
|
data := ops.Write1(&o.Internal, ops.TypeKeyInputHintLen, h.Tag)
|
||||||
|
data[0] = byte(ops.TypeKeyInputHint)
|
||||||
data[1] = byte(h.Hint)
|
data[1] = byte(h.Hint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -651,7 +651,8 @@ func (e *Editor) layout(gtx layout.Context, textMaterial, selectMaterial op.Call
|
|||||||
keys = keyFilterAllArrows
|
keys = keyFilterAllArrows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key.InputOp{Tag: &e.eventKey, Hint: e.InputHint, Keys: keys}.Add(gtx.Ops)
|
key.InputOp{Tag: &e.eventKey, Keys: keys}.Add(gtx.Ops)
|
||||||
|
key.InputHintOp{Tag: &e.eventKey, Hint: e.InputHint}.Add(gtx.Ops)
|
||||||
|
|
||||||
e.scroller.Add(gtx.Ops)
|
e.scroller.Add(gtx.Ops)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user