gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/pointer/pointer.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package pointer
     4  
     5  import (
     6  	"encoding/binary"
     7  	"image"
     8  	"time"
     9  
    10  	"gioui.org/ui"
    11  	"gioui.org/ui/f32"
    12  	"gioui.org/ui/internal/opconst"
    13  )
    14  
    15  // Event is a pointer event.
    16  type Event struct {
    17  	Type   Type
    18  	Source Source
    19  	// PointerID is the id for the pointer and can be used
    20  	// to track a particular pointer from Press to
    21  	// Release or Cancel.
    22  	PointerID ID
    23  	// Priority is the priority of the receiving handler
    24  	// for this event.
    25  	Priority Priority
    26  	// Time is when the event was received. The
    27  	// timestamp is relative to an undefined base.
    28  	Time time.Duration
    29  	// Hit is set when the event was within the registered
    30  	// area for the handler. Hit can be false when a pointer
    31  	// was pressed within the hit area, and then dragged
    32  	// outside it.
    33  	Hit bool
    34  	// Position is the position of the event, relative to
    35  	// the current transformation, as set by ui.TransformOp.
    36  	Position f32.Point
    37  	// Scroll is the scroll amount, if any.
    38  	Scroll f32.Point
    39  }
    40  
    41  // RectAreaOp updates the hit area to the intersection
    42  // of the current hit area with a rectangular area.
    43  type RectAreaOp struct {
    44  	// Rect defines the rectangle. The current transform
    45  	// is applied to it.
    46  	Rect image.Rectangle
    47  }
    48  
    49  // EllipseAreaOp updates the hit area to the intersection
    50  // of the current hit area with an elliptical area.
    51  type EllipseAreaOp struct {
    52  	// Rect is the bounds for the ellipse. The current transform
    53  	// is applied to the rectangle.
    54  	Rect image.Rectangle
    55  }
    56  
    57  // Must match the structure in input.areaOp
    58  type areaOp struct {
    59  	kind areaKind
    60  	rect image.Rectangle
    61  }
    62  
    63  // InputOp declares an input handler ready for pointer
    64  // events.
    65  type InputOp struct {
    66  	Key ui.Key
    67  	// Grab, if set, request that the handler get
    68  	// Grabbed priority.
    69  	Grab bool
    70  }
    71  
    72  // PassOp sets the pass-through mode.
    73  type PassOp struct {
    74  	Pass bool
    75  }
    76  
    77  type ID uint16
    78  
    79  // Type of an Event.
    80  type Type uint8
    81  
    82  // Priority of an Event.
    83  type Priority uint8
    84  
    85  // Source of an Event.
    86  type Source uint8
    87  
    88  // Must match app/internal/input.areaKind
    89  type areaKind uint8
    90  
    91  const (
    92  	// A Cancel event is generated when the current gesture is
    93  	// interrupted by other handlers or the system.
    94  	Cancel Type = iota
    95  	// Press of a pointer.
    96  	Press
    97  	// Release of a pointer.
    98  	Release
    99  	// Move of a pointer.
   100  	Move
   101  )
   102  
   103  const (
   104  	// Mouse generated event.
   105  	Mouse Source = iota
   106  	// Touch generated event.
   107  	Touch
   108  )
   109  
   110  const (
   111  	// Shared priority is for handlers that
   112  	// are part of a matching set larger than 1.
   113  	Shared Priority = iota
   114  	// Foremost is like Shared, but the handler is
   115  	// the foremost in the matching set.
   116  	Foremost
   117  	// Grabbed is used for matching sets of size 1.
   118  	Grabbed
   119  )
   120  
   121  const (
   122  	areaRect areaKind = iota
   123  	areaEllipse
   124  )
   125  
   126  func (op RectAreaOp) Add(ops *ui.Ops) {
   127  	areaOp{
   128  		kind: areaRect,
   129  		rect: op.Rect,
   130  	}.add(ops)
   131  }
   132  
   133  func (op EllipseAreaOp) Add(ops *ui.Ops) {
   134  	areaOp{
   135  		kind: areaEllipse,
   136  		rect: op.Rect,
   137  	}.add(ops)
   138  }
   139  
   140  func (op areaOp) add(o *ui.Ops) {
   141  	data := make([]byte, opconst.TypeAreaLen)
   142  	data[0] = byte(opconst.TypeArea)
   143  	data[1] = byte(op.kind)
   144  	bo := binary.LittleEndian
   145  	bo.PutUint32(data[2:], uint32(op.rect.Min.X))
   146  	bo.PutUint32(data[6:], uint32(op.rect.Min.Y))
   147  	bo.PutUint32(data[10:], uint32(op.rect.Max.X))
   148  	bo.PutUint32(data[14:], uint32(op.rect.Max.Y))
   149  	o.Write(data)
   150  }
   151  
   152  func (h InputOp) Add(o *ui.Ops) {
   153  	data := make([]byte, opconst.TypePointerInputLen)
   154  	data[0] = byte(opconst.TypePointerInput)
   155  	if h.Grab {
   156  		data[1] = 1
   157  	}
   158  	o.Write(data, h.Key)
   159  }
   160  
   161  func (op PassOp) Add(o *ui.Ops) {
   162  	data := make([]byte, opconst.TypePassLen)
   163  	data[0] = byte(opconst.TypePass)
   164  	if op.Pass {
   165  		data[1] = 1
   166  	}
   167  	o.Write(data)
   168  }
   169  
   170  func (t Type) String() string {
   171  	switch t {
   172  	case Press:
   173  		return "Press"
   174  	case Release:
   175  		return "Release"
   176  	case Cancel:
   177  		return "Cancel"
   178  	case Move:
   179  		return "Move"
   180  	default:
   181  		panic("unknown Type")
   182  	}
   183  }
   184  
   185  func (p Priority) String() string {
   186  	switch p {
   187  	case Shared:
   188  		return "Shared"
   189  	case Foremost:
   190  		return "Foremost"
   191  	case Grabbed:
   192  		return "Grabbed"
   193  	default:
   194  		panic("unknown priority")
   195  	}
   196  }
   197  
   198  func (s Source) String() string {
   199  	switch s {
   200  	case Mouse:
   201  		return "Mouse"
   202  	case Touch:
   203  		return "Touch"
   204  	default:
   205  		panic("unknown source")
   206  	}
   207  }
   208  
   209  func (Event) ImplementsEvent() {}