forked from joejulian/gio
io/pointer: added CursorNameOp
The cursor can now be customized for a given area. Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
+6
-1
@@ -48,7 +48,8 @@ type Window struct {
|
||||
nextFrame time.Time
|
||||
delayedDraw *time.Timer
|
||||
|
||||
queue queue
|
||||
queue queue
|
||||
cursor pointer.CursorName
|
||||
|
||||
callbacks callbacks
|
||||
}
|
||||
@@ -414,6 +415,10 @@ func (w *Window) run(opts *window.Options) {
|
||||
w.setNextFrame(time.Time{})
|
||||
w.updateAnimation()
|
||||
}
|
||||
if c := w.queue.q.Cursor(); c != w.cursor {
|
||||
w.cursor = c
|
||||
w.SetCursorName(c)
|
||||
}
|
||||
w.out <- e
|
||||
}
|
||||
w.ack <- struct{}{}
|
||||
|
||||
@@ -30,6 +30,7 @@ const (
|
||||
TypeAux
|
||||
TypeClip
|
||||
TypeProfile
|
||||
TypeCursor
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,6 +56,7 @@ const (
|
||||
TypeAuxLen = 1
|
||||
TypeClipLen = 1 + 4*4 + 4 + 2 + 4
|
||||
TypeProfileLen = 1
|
||||
TypeCursorLen = 1 + 1
|
||||
)
|
||||
|
||||
func (t OpType) Size() int {
|
||||
@@ -81,12 +83,13 @@ func (t OpType) Size() int {
|
||||
TypeAuxLen,
|
||||
TypeClipLen,
|
||||
TypeProfileLen,
|
||||
TypeCursorLen,
|
||||
}[t-firstOpIndex]
|
||||
}
|
||||
|
||||
func (t OpType) NumRefs() int {
|
||||
switch t {
|
||||
case TypeKeyInput, TypePointerInput, TypeProfile, TypeCall, TypeClipboardRead, TypeClipboardWrite:
|
||||
case TypeKeyInput, TypePointerInput, TypeProfile, TypeCall, TypeClipboardRead, TypeClipboardWrite, TypeCursor:
|
||||
return 1
|
||||
case TypeImage:
|
||||
return 2
|
||||
|
||||
@@ -49,6 +49,11 @@ type AreaOp struct {
|
||||
rect image.Rectangle
|
||||
}
|
||||
|
||||
// CursorNameOp sets the cursor for the current area.
|
||||
type CursorNameOp struct {
|
||||
Name CursorName
|
||||
}
|
||||
|
||||
// InputOp declares an input handler ready for pointer
|
||||
// events.
|
||||
type InputOp struct {
|
||||
@@ -178,6 +183,11 @@ func (op AreaOp) Add(o *op.Ops) {
|
||||
bo.PutUint32(data[14:], uint32(op.rect.Max.Y))
|
||||
}
|
||||
|
||||
func (op CursorNameOp) Add(o *op.Ops) {
|
||||
data := o.Write1(opconst.TypeCursorLen, op.Name)
|
||||
data[0] = byte(opconst.TypeCursor)
|
||||
}
|
||||
|
||||
func (h InputOp) Add(o *op.Ops) {
|
||||
data := o.Write1(opconst.TypePointerInputLen, h.Tag)
|
||||
data[0] = byte(opconst.TypePointerInput)
|
||||
|
||||
@@ -17,6 +17,8 @@ import (
|
||||
type pointerQueue struct {
|
||||
hitTree []hitNode
|
||||
areas []areaNode
|
||||
cursors []cursorNode
|
||||
cursor pointer.CursorName
|
||||
handlers map[event.Tag]*pointerHandler
|
||||
pointers []pointerInfo
|
||||
reader ops.Reader
|
||||
@@ -34,6 +36,11 @@ type hitNode struct {
|
||||
tag event.Tag
|
||||
}
|
||||
|
||||
type cursorNode struct {
|
||||
name pointer.CursorName
|
||||
area int
|
||||
}
|
||||
|
||||
type pointerInfo struct {
|
||||
id pointer.ID
|
||||
pressed bool
|
||||
@@ -114,6 +121,11 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t f
|
||||
h.area = area
|
||||
h.wantsGrab = h.wantsGrab || op.Grab
|
||||
h.types = h.types | op.Types
|
||||
case opconst.TypeCursor:
|
||||
q.cursors = append(q.cursors, cursorNode{
|
||||
name: encOp.Refs[0].(pointer.CursorName),
|
||||
area: len(q.areas) - 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,6 +189,7 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) {
|
||||
}
|
||||
q.hitTree = q.hitTree[:0]
|
||||
q.areas = q.areas[:0]
|
||||
q.cursors = q.cursors[:0]
|
||||
q.reader.Reset(root)
|
||||
q.collectHandlers(&q.reader, events, f32.Affine2D{}, -1, -1, false)
|
||||
for k, h := range q.handlers {
|
||||
@@ -314,6 +327,7 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, hits []event.Tag,
|
||||
|
||||
if e.Type&h.types == e.Type {
|
||||
events.Add(k, e)
|
||||
q.cursor = pointer.CursorDefault
|
||||
}
|
||||
}
|
||||
// Deliver Enter events.
|
||||
@@ -327,11 +341,25 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, hits []event.Tag,
|
||||
|
||||
if e.Type&h.types == e.Type {
|
||||
events.Add(k, e)
|
||||
q.hitCursor(h.area)
|
||||
}
|
||||
}
|
||||
p.entered = append(p.entered[:0], hits...)
|
||||
}
|
||||
|
||||
func (q *pointerQueue) hitCursor(want int) {
|
||||
for _, c := range q.cursors {
|
||||
idx := c.area
|
||||
for idx != -1 {
|
||||
if idx == want {
|
||||
q.cursor = c.name
|
||||
return
|
||||
}
|
||||
idx = q.areas[idx].next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func searchTag(tags []event.Tag, tag event.Tag) (int, bool) {
|
||||
for i, t := range tags {
|
||||
if t == tag {
|
||||
|
||||
@@ -115,6 +115,11 @@ func (q *Router) ReadClipboard() bool {
|
||||
return q.cqueue.ReadClipboard()
|
||||
}
|
||||
|
||||
// Cursor returns the last cursor set.
|
||||
func (q *Router) Cursor() pointer.CursorName {
|
||||
return q.pqueue.cursor
|
||||
}
|
||||
|
||||
func (q *Router) collect() {
|
||||
for encOp, ok := q.reader.Decode(); ok; encOp, ok = q.reader.Decode() {
|
||||
switch opconst.OpType(encOp.Data[0]) {
|
||||
|
||||
+4
-1
@@ -379,7 +379,10 @@ func (e *Editor) Layout(gtx layout.Context, sh text.Shaper, font text.Font, size
|
||||
}
|
||||
e.makeValid()
|
||||
|
||||
return e.layout(gtx)
|
||||
dims := e.layout(gtx)
|
||||
pointer.Rect(image.Rectangle{Max: dims.Size}).Add(gtx.Ops)
|
||||
pointer.CursorNameOp{Name: pointer.CursorText}.Add(gtx.Ops)
|
||||
return dims
|
||||
}
|
||||
|
||||
func (e *Editor) layout(gtx layout.Context) layout.Dimensions {
|
||||
|
||||
Reference in New Issue
Block a user