1 // SPDX-License-Identifier: Unlicense OR MIT
2 3 // Event system types ported from gioui.org/io/{event,key,pointer,clipboard,system,transfer,semantic}.
4 // All sub-packages merged into package gio with prefixed names to avoid collisions.
5 6 package gio
7 8 import (
9 "bytes"
10 "io"
11 "time"
12 )
13 14 // ---------------------------------------------------------------------------
15 // event - core interfaces
16 // ---------------------------------------------------------------------------
17 18 // Tag is the stable identifier for an event handler.
19 // For a handler h, the tag is typically &h.
20 type Tag any
21 22 // Event is the marker interface for events.
23 type Event interface {
24 ImplementsEvent()
25 }
26 27 // Filter represents a filter for Event types.
28 type Filter interface {
29 ImplementsFilter()
30 }
31 32 // InputCommand represents a request such as moving the focus or reading the clipboard.
33 type InputCommand interface {
34 ImplementsCommand()
35 }
36 37 // EventOp declares a tag for input routing at the current transformation
38 // and clip area hierarchy. It panics if tag is nil.
39 func EventOp(o *OpList, tag Tag) {
40 if tag == nil {
41 panic("Tag must be non-nil")
42 }
43 data := WriteOps1(&o.Internal, TypeInputLen, tag)
44 data[0] = byte(TypeInput)
45 }
46 47 // ---------------------------------------------------------------------------
48 // key - key events, names, modifiers
49 // ---------------------------------------------------------------------------
50 51 // KeyFilter matches any KeyEvent that matches the parameters.
52 type KeyFilter struct {
53 // Focus is the tag that must be focused for the filter to match. It has no
54 // effect if it is nil.
55 Focus Tag
56 // Required is the set of modifiers that must be included in events matched.
57 Required Modifiers
58 // Optional is the set of modifiers that may be included in events matched.
59 Optional Modifiers
60 // Name of the key to be matched. As a special case, the empty Name matches
61 // every key not matched by any other filter.
62 Name KeyName
63 }
64 65 // KeyInputHintOp describes the type of text expected by a tag.
66 type KeyInputHintOp struct {
67 Tag Tag
68 Hint InputHint
69 }
70 71 // SoftKeyboardCmd shows or hides the on-screen keyboard, if available.
72 type SoftKeyboardCmd struct {
73 Show bool
74 }
75 76 // SelectionCmd updates the selection for an input handler.
77 type SelectionCmd struct {
78 Tag Tag
79 KeyRange
80 Caret
81 }
82 83 // SnippetCmd updates the content snippet for an input handler.
84 type SnippetCmd struct {
85 Tag Tag
86 Snippet
87 }
88 89 // KeyRange represents a range of text, such as an editor's selection.
90 // Start and End are in runes.
91 type KeyRange struct {
92 Start int
93 End int
94 }
95 96 // Snippet represents a snippet of text content used for communicating between
97 // an editor and an input method.
98 type Snippet struct {
99 KeyRange
100 Text string
101 }
102 103 // Caret represents the position of a caret.
104 type Caret struct {
105 // Pos is the intersection point of the caret and its baseline.
106 Pos Point
107 // Ascent is the length of the caret above its baseline.
108 Ascent float32
109 // Descent is the length of the caret below its baseline.
110 Descent float32
111 }
112 113 // SelectionEvent is generated when an input method changes the selection.
114 type SelectionEvent KeyRange
115 116 // SnippetEvent is generated when the snippet range is updated by an input method.
117 type SnippetEvent KeyRange
118 119 // KeyFocusEvent is generated when a handler gains or loses focus.
120 type KeyFocusEvent struct {
121 Focus bool
122 }
123 124 // KeyEvent is generated when a key is pressed. For text input use KeyEditEvent.
125 type KeyEvent struct {
126 // Name of the key.
127 Name KeyName
128 // Modifiers is the set of active modifiers when the key was pressed.
129 Modifiers Modifiers
130 // State is the state of the key when the event was fired.
131 State KeyState
132 }
133 134 // KeyEditEvent requests an edit by an input method.
135 type KeyEditEvent struct {
136 // Range specifies the range to replace with Text.
137 Range KeyRange
138 Text string
139 }
140 141 // KeyFocusFilter matches any KeyFocusEvent, KeyEditEvent, SnippetEvent,
142 // or SelectionEvent with the specified target.
143 type KeyFocusFilter struct {
144 // Target is a tag specified in a previous EventOp.
145 Target Tag
146 }
147 148 // InputHint changes the on-screen-keyboard type. That hints the type of data
149 // that might be entered by the user.
150 type InputHint uint8
151 152 const (
153 // HintAny hints that any input is expected.
154 HintAny InputHint = iota
155 // HintText hints that text input is expected. It may activate auto-correction and suggestions.
156 HintText
157 // HintNumeric hints that numeric input is expected. It may activate shortcuts for 0-9, "." and ",".
158 HintNumeric
159 // HintEmail hints that email input is expected. It may activate shortcuts for common email characters, such as "@" and ".com".
160 HintEmail
161 // HintURL hints that URL input is expected. It may activate shortcuts for common URL fragments such as "/" and ".com".
162 HintURL
163 // HintTelephone hints that telephone number input is expected. It may activate shortcuts for 0-9, "#" and "*".
164 HintTelephone
165 // HintPassword hints that password input is expected. It may disable autocorrection and enable password autofill.
166 HintPassword
167 )
168 169 // KeyState is the state of a key during an event.
170 type KeyState uint8
171 172 const (
173 // KeyPress is the state of a pressed key.
174 KeyPress KeyState = iota
175 // KeyRelease is the state of a key that has been released.
176 KeyRelease
177 )
178 179 // Modifiers
180 type Modifiers uint32
181 182 const (
183 // ModCtrl is the ctrl modifier key.
184 ModCtrl Modifiers = 1 << iota
185 // ModCommand is the command modifier key found on Apple keyboards.
186 ModCommand
187 // ModShift is the shift modifier key.
188 ModShift
189 // ModAlt is the alt modifier key, or the option key on Apple keyboards.
190 ModAlt
191 // ModSuper is the "logo" modifier key, often represented by a Windows logo.
192 ModSuper
193 )
194 195 // ModShortcut is the platform's shortcut modifier (WASM: always Ctrl).
196 const ModShortcut = ModCtrl
197 198 // ModShortcutAlt is the platform's alternative shortcut modifier (WASM: always Ctrl).
199 const ModShortcutAlt = ModCtrl
200 201 // KeyName is the identifier for a keyboard key.
202 //
203 // For letters, the upper case form is used, via unicode.ToUpper.
204 // The shift modifier is taken into account, all other modifiers are ignored.
205 // For example, the "shift-1" and "ctrl-shift-1" combinations both give the
206 // Name "!" with the US keyboard layout.
207 type KeyName string
208 209 const (
210 KeyNameLeftArrow KeyName = "\xe2\x86\x90"
211 KeyNameRightArrow KeyName = "\xe2\x86\x92"
212 KeyNameUpArrow KeyName = "\xe2\x86\x91"
213 KeyNameDownArrow KeyName = "\xe2\x86\x93"
214 KeyNameReturn KeyName = "\xe2\x8f\x8e"
215 KeyNameEnter KeyName = "\xe2\x8c\xa4"
216 KeyNameEscape KeyName = "\xe2\x8e\x8b"
217 KeyNameHome KeyName = "\xe2\x87\xb1"
218 KeyNameEnd KeyName = "\xe2\x87\xb2"
219 KeyNameDeleteBackward KeyName = "\xe2\x8c\xab"
220 KeyNameDeleteForward KeyName = "\xe2\x8c\xa6"
221 KeyNamePageUp KeyName = "\xe2\x87\x9e"
222 KeyNamePageDown KeyName = "\xe2\x87\x9f"
223 KeyNameTab KeyName = "Tab"
224 KeyNameSpace KeyName = "Space"
225 KeyNameCtrl KeyName = "Ctrl"
226 KeyNameShift KeyName = "Shift"
227 KeyNameAlt KeyName = "Alt"
228 KeyNameSuper KeyName = "Super"
229 KeyNameCommand KeyName = "\xe2\x8c\x98"
230 KeyNameF1 KeyName = "F1"
231 KeyNameF2 KeyName = "F2"
232 KeyNameF3 KeyName = "F3"
233 KeyNameF4 KeyName = "F4"
234 KeyNameF5 KeyName = "F5"
235 KeyNameF6 KeyName = "F6"
236 KeyNameF7 KeyName = "F7"
237 KeyNameF8 KeyName = "F8"
238 KeyNameF9 KeyName = "F9"
239 KeyNameF10 KeyName = "F10"
240 KeyNameF11 KeyName = "F11"
241 KeyNameF12 KeyName = "F12"
242 KeyNameBack KeyName = "Back"
243 )
244 245 type FocusDirection int
246 247 const (
248 FocusRight FocusDirection = iota
249 FocusLeft
250 FocusUp
251 FocusDown
252 FocusForward
253 FocusBackward
254 )
255 256 // Contain reports whether m contains all modifiers in m2.
257 func (m Modifiers) Contain(m2 Modifiers) bool {
258 return m&m2 == m2
259 }
260 261 // FocusCmd requests to set or clear the keyboard focus.
262 type FocusCmd struct {
263 // Tag is the new focus. The focus is cleared if Tag is nil, or if Tag
264 // has no EventOp references.
265 Tag Tag
266 }
267 268 func (h KeyInputHintOp) Add(o *OpList) {
269 if h.Tag == nil {
270 panic("Tag must be non-nil")
271 }
272 data := WriteOps1(&o.Internal, TypeKeyInputHintLen, h.Tag)
273 data[0] = byte(TypeKeyInputHint)
274 data[1] = byte(h.Hint)
275 }
276 277 func (KeyEditEvent) ImplementsEvent() {}
278 func (KeyEvent) ImplementsEvent() {}
279 func (KeyFocusEvent) ImplementsEvent() {}
280 func (SnippetEvent) ImplementsEvent() {}
281 func (SelectionEvent) ImplementsEvent() {}
282 283 func (FocusCmd) ImplementsCommand() {}
284 func (SoftKeyboardCmd) ImplementsCommand() {}
285 func (SelectionCmd) ImplementsCommand() {}
286 func (SnippetCmd) ImplementsCommand() {}
287 288 func (KeyFilter) ImplementsFilter() {}
289 func (KeyFocusFilter) ImplementsFilter() {}
290 291 func (m Modifiers) String() string {
292 var parts []string
293 if m.Contain(ModCtrl) {
294 parts = append(parts, string(KeyNameCtrl))
295 }
296 if m.Contain(ModCommand) {
297 parts = append(parts, string(KeyNameCommand))
298 }
299 if m.Contain(ModShift) {
300 parts = append(parts, string(KeyNameShift))
301 }
302 if m.Contain(ModAlt) {
303 parts = append(parts, string(KeyNameAlt))
304 }
305 if m.Contain(ModSuper) {
306 parts = append(parts, string(KeyNameSuper))
307 }
308 return bytes.Join(parts, "-")
309 }
310 311 func (s KeyState) String() string {
312 switch s {
313 case KeyPress:
314 return "Press"
315 case KeyRelease:
316 return "Release"
317 default:
318 panic("invalid KeyState")
319 }
320 }
321 322 // ---------------------------------------------------------------------------
323 // pointer - pointer events, cursor types
324 // ---------------------------------------------------------------------------
325 326 // PointerEvent is a pointer event.
327 type PointerEvent struct {
328 Kind PointerKind
329 Source PointerSource
330 // PointerID is the id for the pointer and can be used to track a particular
331 // pointer from Press to Release.
332 PointerID PointerID
333 // Priority is the priority of the receiving handler for this event.
334 Priority PointerPriority
335 // Time is when the event was received. The timestamp is relative to an
336 // undefined base.
337 Time time.Duration
338 // Buttons are the set of pressed mouse buttons for this event.
339 Buttons PointerButtons
340 // Position is the coordinates of the event in the local coordinate system
341 // of the receiving tag.
342 Position Point
343 // Scroll is the scroll amount, if any.
344 Scroll Point
345 // Modifiers is the set of active modifiers when the mouse button was pressed.
346 Modifiers Modifiers
347 }
348 349 // PassOp sets the pass-through mode. InputOps added while the pass-through
350 // mode is set don't block events to siblings.
351 type PassOp struct{}
352 353 // PassStack represents a PassOp on the pass stack.
354 type PassStack struct {
355 ops *Ops
356 id StackID
357 macroID uint32
358 }
359 360 // PointerFilter matches every PointerEvent that targets the Tag and whose kind
361 // is included in Kinds.
362 type PointerFilter struct {
363 Target Tag
364 // Kinds is a bitwise-or of event types to match.
365 Kinds PointerKind
366 // ScrollX and ScrollY constrain the range of scrolling events delivered
367 // to Target.
368 ScrollX ScrollRange
369 ScrollY ScrollRange
370 }
371 372 // ScrollRange describes the range of scrolling distances in an axis.
373 type ScrollRange struct {
374 Min, Max int
375 }
376 377 // GrabCmd requests a pointer grab on the pointer identified by ID.
378 type GrabCmd struct {
379 Tag Tag
380 ID PointerID
381 }
382 383 type PointerID uint16
384 385 // PointerKind of a PointerEvent.
386 type PointerKind uint
387 388 // PointerPriority of a PointerEvent.
389 type PointerPriority uint8
390 391 // PointerSource of a PointerEvent.
392 type PointerSource uint8
393 394 // PointerButtons is a set of mouse buttons.
395 type PointerButtons uint8
396 397 // Cursor denotes a pre-defined cursor shape. Its Add method adds an operation
398 // that sets the cursor shape for the current clip area.
399 type Cursor byte
400 401 // The cursors correspond to CSS pointer naming.
402 const (
403 CursorDefault Cursor = iota
404 CursorNone
405 CursorText
406 CursorVerticalText
407 CursorPointer
408 CursorCrosshair
409 CursorAllScroll
410 CursorColResize
411 CursorRowResize
412 CursorGrab
413 CursorGrabbing
414 CursorNotAllowed
415 CursorWait
416 CursorProgress
417 CursorNorthWestResize
418 CursorNorthEastResize
419 CursorSouthWestResize
420 CursorSouthEastResize
421 CursorNorthSouthResize
422 CursorEastWestResize
423 CursorWestResize
424 CursorEastResize
425 CursorNorthResize
426 CursorSouthResize
427 CursorNorthEastSouthWestResize
428 CursorNorthWestSouthEastResize
429 )
430 431 const (
432 // Cancel is generated when the current gesture is interrupted.
433 PointerCancel PointerKind = 1 << iota
434 // PointerPress of a pointer.
435 PointerPress
436 // PointerRelease of a pointer.
437 PointerRelease
438 // PointerMove of a pointer.
439 PointerMove
440 // PointerDrag of a pointer.
441 PointerDrag
442 // PointerEnter - pointer enters an area watching for pointer input.
443 PointerEnter
444 // PointerLeave - pointer leaves an area watching for pointer input.
445 PointerLeave
446 // PointerScroll of a pointer.
447 PointerScroll
448 )
449 450 const (
451 // Mouse generated event.
452 Mouse PointerSource = iota
453 // Touch generated event.
454 Touch
455 )
456 457 const (
458 // Shared priority is for handlers that are part of a matching set larger than 1.
459 Shared PointerPriority = iota
460 // Grabbed is used for matching sets of size 1.
461 Grabbed
462 )
463 464 const (
465 // ButtonPrimary is the primary button, usually the left button for a
466 // right-handed user.
467 ButtonPrimary PointerButtons = 1 << iota
468 // ButtonSecondary is the secondary button, usually the right button for a
469 // right-handed user.
470 ButtonSecondary
471 // ButtonTertiary is the tertiary button, usually the middle button.
472 ButtonTertiary
473 // ButtonQuaternary is the fourth button, usually used for browser
474 // navigation (backward).
475 ButtonQuaternary
476 // ButtonQuinary is the fifth button, usually used for browser
477 // navigation (forward).
478 ButtonQuinary
479 )
480 481 func (s ScrollRange) Union(s2 ScrollRange) ScrollRange {
482 return ScrollRange{
483 Min: min(s.Min, s2.Min),
484 Max: max(s.Max, s2.Max),
485 }
486 }
487 488 // Push the current pass mode to the pass stack and set the pass mode.
489 func (p PassOp) Push(o *OpList) PassStack {
490 id, mid := PushOp(&o.Internal, PassStackKind)
491 data := WriteOps(&o.Internal, TypePassLen)
492 data[0] = byte(TypePass)
493 return PassStack{ops: &o.Internal, id: id, macroID: mid}
494 }
495 496 func (p PassStack) Pop() {
497 PopOp(p.ops, PassStackKind, p.id, p.macroID)
498 data := WriteOps(p.ops, TypePopPassLen)
499 data[0] = byte(TypePopPass)
500 }
501 502 func (c Cursor) Add(o *OpList) {
503 data := WriteOps(&o.Internal, TypeCursorLen)
504 data[0] = byte(TypeCursor)
505 data[1] = byte(c)
506 }
507 508 func (t PointerKind) String() string {
509 if t == PointerCancel {
510 return "Cancel"
511 }
512 var buf []byte
513 for tt := PointerKind(1); tt > 0; tt <<= 1 {
514 if t&tt > 0 {
515 if len(buf) > 0 {
516 buf = append(buf, '|')
517 }
518 buf = append(buf, (t & tt).string()...)
519 }
520 }
521 return buf
522 }
523 524 func (t PointerKind) string() string {
525 switch t {
526 case PointerPress:
527 return "Press"
528 case PointerRelease:
529 return "Release"
530 case PointerCancel:
531 return "Cancel"
532 case PointerMove:
533 return "Move"
534 case PointerDrag:
535 return "Drag"
536 case PointerEnter:
537 return "Enter"
538 case PointerLeave:
539 return "Leave"
540 case PointerScroll:
541 return "Scroll"
542 default:
543 panic("unknown PointerKind")
544 }
545 }
546 547 func (p PointerPriority) String() string {
548 switch p {
549 case Shared:
550 return "Shared"
551 case Grabbed:
552 return "Grabbed"
553 default:
554 panic("unknown priority")
555 }
556 }
557 558 func (s PointerSource) String() string {
559 switch s {
560 case Mouse:
561 return "Mouse"
562 case Touch:
563 return "Touch"
564 default:
565 panic("unknown source")
566 }
567 }
568 569 // Contain reports whether the set b contains all of the buttons.
570 func (b PointerButtons) Contain(buttons PointerButtons) bool {
571 return b&buttons == buttons
572 }
573 574 func (b PointerButtons) String() string {
575 var parts []string
576 if b.Contain(ButtonPrimary) {
577 parts = append(parts, "ButtonPrimary")
578 }
579 if b.Contain(ButtonSecondary) {
580 parts = append(parts, "ButtonSecondary")
581 }
582 if b.Contain(ButtonTertiary) {
583 parts = append(parts, "ButtonTertiary")
584 }
585 if b.Contain(ButtonQuaternary) {
586 parts = append(parts, "ButtonQuaternary")
587 }
588 if b.Contain(ButtonQuinary) {
589 parts = append(parts, "ButtonQuinary")
590 }
591 return bytes.Join(parts, "|")
592 }
593 594 func (c Cursor) String() string {
595 switch c {
596 case CursorDefault:
597 return "Default"
598 case CursorNone:
599 return "None"
600 case CursorText:
601 return "Text"
602 case CursorVerticalText:
603 return "VerticalText"
604 case CursorPointer:
605 return "Pointer"
606 case CursorCrosshair:
607 return "Crosshair"
608 case CursorAllScroll:
609 return "AllScroll"
610 case CursorColResize:
611 return "ColResize"
612 case CursorRowResize:
613 return "RowResize"
614 case CursorGrab:
615 return "Grab"
616 case CursorGrabbing:
617 return "Grabbing"
618 case CursorNotAllowed:
619 return "NotAllowed"
620 case CursorWait:
621 return "Wait"
622 case CursorProgress:
623 return "Progress"
624 case CursorNorthWestResize:
625 return "NorthWestResize"
626 case CursorNorthEastResize:
627 return "NorthEastResize"
628 case CursorSouthWestResize:
629 return "SouthWestResize"
630 case CursorSouthEastResize:
631 return "SouthEastResize"
632 case CursorNorthSouthResize:
633 return "NorthSouthResize"
634 case CursorEastWestResize:
635 return "EastWestResize"
636 case CursorWestResize:
637 return "WestResize"
638 case CursorEastResize:
639 return "EastResize"
640 case CursorNorthResize:
641 return "NorthResize"
642 case CursorSouthResize:
643 return "SouthResize"
644 case CursorNorthEastSouthWestResize:
645 return "NorthEastSouthWestResize"
646 case CursorNorthWestSouthEastResize:
647 return "NorthWestSouthEastResize"
648 default:
649 panic("unknown Cursor")
650 }
651 }
652 653 func (PointerEvent) ImplementsEvent() {}
654 655 func (GrabCmd) ImplementsCommand() {}
656 657 func (PointerFilter) ImplementsFilter() {}
658 659 // ---------------------------------------------------------------------------
660 // clipboard - clipboard events
661 // ---------------------------------------------------------------------------
662 663 // ClipboardWriteCmd copies data to the clipboard.
664 type ClipboardWriteCmd struct {
665 Type string
666 Data io.ReadCloser
667 }
668 669 // ClipboardReadCmd requests clipboard contents, delivered to the handler
670 // through a TransferDataEvent.
671 type ClipboardReadCmd struct {
672 Tag Tag
673 }
674 675 func (ClipboardWriteCmd) ImplementsCommand() {}
676 func (ClipboardReadCmd) ImplementsCommand() {}
677 678 // ---------------------------------------------------------------------------
679 // system - system actions, decoration, locale
680 // ---------------------------------------------------------------------------
681 682 // ActionInputOp makes the current clip area available for system gestures.
683 type ActionInputOp SystemAction
684 685 // SystemAction is a set of window decoration actions.
686 type SystemAction uint
687 688 const (
689 ActionMinimize SystemAction = 1 << iota
690 ActionMaximize
691 ActionUnmaximize
692 ActionFullscreen
693 ActionRaise
694 ActionCenter
695 ActionClose
696 ActionMove
697 )
698 699 func (a ActionInputOp) Add(o *OpList) {
700 data := WriteOps(&o.Internal, TypeActionInputLen)
701 data[0] = byte(TypeActionInput)
702 data[1] = byte(a)
703 }
704 705 func (a SystemAction) String() string {
706 var buf []byte
707 for b := SystemAction(1); a != 0; b <<= 1 {
708 if a&b != 0 {
709 if len(buf) > 0 {
710 buf = append(buf, '|')
711 }
712 buf = append(buf, b.string()...)
713 a &^= b
714 }
715 }
716 return buf
717 }
718 719 func (a SystemAction) string() string {
720 switch a {
721 case ActionMinimize:
722 return "ActionMinimize"
723 case ActionMaximize:
724 return "ActionMaximize"
725 case ActionUnmaximize:
726 return "ActionUnmaximize"
727 case ActionClose:
728 return "ActionClose"
729 case ActionMove:
730 return "ActionMove"
731 case ActionFullscreen:
732 return "ActionFullscreen"
733 case ActionRaise:
734 return "ActionRaise"
735 case ActionCenter:
736 return "ActionCenter"
737 }
738 return ""
739 }
740 741 // Locale provides language information for the current system.
742 type Locale struct {
743 // Language is the BCP-47 tag for the primary language of the system.
744 Language string
745 // Direction indicates the primary direction of text and layout flow.
746 Direction TextDirection
747 }
748 749 const (
750 axisShift = iota
751 progressionShift
752 )
753 754 // TextDirection defines a direction for text flow.
755 type TextDirection byte
756 757 const (
758 // LTR is left-to-right text.
759 LTR TextDirection = TextDirection(Horizontal<<axisShift) | TextDirection(FromOrigin<<progressionShift)
760 // RTL is right-to-left text.
761 RTL TextDirection = TextDirection(Horizontal<<axisShift) | TextDirection(TowardOrigin<<progressionShift)
762 )
763 764 // Axis returns the axis of the text layout.
765 func (d TextDirection) Axis() TextAxis {
766 return TextAxis((d & (1 << axisShift)) >> axisShift)
767 }
768 769 // Progression returns the way that the text flows relative to the origin.
770 func (d TextDirection) Progression() TextProgression {
771 return TextProgression((d & (1 << progressionShift)) >> progressionShift)
772 }
773 774 func (d TextDirection) String() string {
775 switch d {
776 case RTL:
777 return "RTL"
778 default:
779 return "LTR"
780 }
781 }
782 783 // TextAxis defines the layout axis of text.
784 type TextAxis byte
785 786 const (
787 // Horizontal indicates text that flows along the X axis.
788 Horizontal TextAxis = iota
789 // Vertical indicates text that flows along the Y axis.
790 Vertical
791 )
792 793 // TextProgression indicates how text flows along an axis relative to the
794 // origin. The origin is the upper-left corner of coordinate space.
795 type TextProgression byte
796 797 const (
798 // FromOrigin indicates text that flows along its axis away from the origin.
799 FromOrigin TextProgression = iota
800 // TowardOrigin indicates text that flows along its axis towards the origin.
801 TowardOrigin
802 )
803 804 // ---------------------------------------------------------------------------
805 // transfer - data transfer operations
806 // ---------------------------------------------------------------------------
807 808 // TransferOfferCmd is used by data sources as a response to a TransferRequestEvent.
809 type TransferOfferCmd struct {
810 Tag Tag
811 Type string
812 Data io.ReadCloser
813 }
814 815 func (TransferOfferCmd) ImplementsCommand() {}
816 817 // TransferSourceFilter filters for any TransferRequestEvent that match a MIME
818 // type as well as TransferInitiateEvent and TransferCancelEvent.
819 type TransferSourceFilter struct {
820 Target Tag
821 Type string
822 }
823 824 // TransferTargetFilter filters for any TransferDataEvent whose type matches a
825 // MIME type as well as TransferCancelEvent.
826 type TransferTargetFilter struct {
827 Target Tag
828 Type string
829 }
830 831 // TransferRequestEvent requests data from a data source. The source must
832 // respond with a TransferOfferCmd.
833 type TransferRequestEvent struct {
834 Type string
835 }
836 837 func (TransferRequestEvent) ImplementsEvent() {}
838 839 // TransferInitiateEvent is sent to a data source when a drag-and-drop
840 // transfer gesture is initiated. Potential data targets also receive the event.
841 type TransferInitiateEvent struct{}
842 843 func (TransferInitiateEvent) ImplementsEvent() {}
844 845 // TransferCancelEvent is sent to data sources and targets to cancel the
846 // effects of a TransferInitiateEvent.
847 type TransferCancelEvent struct{}
848 849 func (TransferCancelEvent) ImplementsEvent() {}
850 851 // TransferDataEvent is sent to the target receiving the transfer.
852 type TransferDataEvent struct {
853 Type string
854 // Open returns the transfer data. It is only valid to call Open in the
855 // frame the TransferDataEvent is received. The caller must close the return
856 // value after use.
857 Open func() io.ReadCloser
858 }
859 860 func (TransferDataEvent) ImplementsEvent() {}
861 862 func (TransferSourceFilter) ImplementsFilter() {}
863 func (TransferTargetFilter) ImplementsFilter() {}
864 865 // ---------------------------------------------------------------------------
866 // semantic - accessibility data
867 // ---------------------------------------------------------------------------
868 869 // SemanticLabelOp provides the content of a textual component.
870 type SemanticLabelOp string
871 872 // SemanticDescriptionOp describes a component.
873 type SemanticDescriptionOp string
874 875 // SemanticClassOp provides the component class.
876 type SemanticClassOp int
877 878 const (
879 SemanticUnknown SemanticClassOp = iota
880 SemanticButton
881 SemanticCheckBox
882 SemanticEditor
883 SemanticRadioButton
884 SemanticSwitch
885 )
886 887 // SemanticSelectedOp describes the selected state for components that have
888 // boolean state.
889 type SemanticSelectedOp bool
890 891 // SemanticEnabledOp describes the enabled state.
892 type SemanticEnabledOp bool
893 894 func (l SemanticLabelOp) Add(o *OpList) {
895 data := WriteOps1String(&o.Internal, TypeSemanticLabelLen, string(l))
896 data[0] = byte(TypeSemanticLabel)
897 }
898 899 func (d SemanticDescriptionOp) Add(o *OpList) {
900 data := WriteOps1String(&o.Internal, TypeSemanticDescLen, string(d))
901 data[0] = byte(TypeSemanticDesc)
902 }
903 904 func (c SemanticClassOp) Add(o *OpList) {
905 data := WriteOps(&o.Internal, TypeSemanticClassLen)
906 data[0] = byte(TypeSemanticClass)
907 data[1] = byte(c)
908 }
909 910 func (s SemanticSelectedOp) Add(o *OpList) {
911 data := WriteOps(&o.Internal, TypeSemanticSelectedLen)
912 data[0] = byte(TypeSemanticSelected)
913 if s {
914 data[1] = 1
915 }
916 }
917 918 func (e SemanticEnabledOp) Add(o *OpList) {
919 data := WriteOps(&o.Internal, TypeSemanticEnabledLen)
920 data[0] = byte(TypeSemanticEnabled)
921 if e {
922 data[1] = 1
923 }
924 }
925 926 func (c SemanticClassOp) String() string {
927 switch c {
928 case SemanticUnknown:
929 return "Unknown"
930 case SemanticButton:
931 return "Button"
932 case SemanticCheckBox:
933 return "CheckBox"
934 case SemanticEditor:
935 return "Editor"
936 case SemanticRadioButton:
937 return "RadioButton"
938 case SemanticSwitch:
939 return "Switch"
940 default:
941 panic("invalid SemanticClassOp")
942 }
943 }
944