1 // SPDX-License-Identifier: Unlicense OR MIT
2 3 package widget_test
4 5 import (
6 "fmt"
7 "image"
8 9 "github.com/p9c/p9/pkg/gel/gio/f32"
10 "github.com/p9c/p9/pkg/gel/gio/io/pointer"
11 "github.com/p9c/p9/pkg/gel/gio/io/router"
12 "github.com/p9c/p9/pkg/gel/gio/layout"
13 "github.com/p9c/p9/pkg/gel/gio/op"
14 "github.com/p9c/p9/pkg/gel/gio/widget"
15 )
16 17 func ExampleClickable_passthrough() {
18 // When laying out clickable widgets on top of each other,
19 // pointer events can be passed down for the underlying
20 // widgets to pick them up.
21 var button1, button2 widget.Clickable
22 var r router.Router
23 gtx := layout.Context{
24 Ops: new(op.Ops),
25 Constraints: layout.Exact(image.Pt(100, 100)),
26 Queue: &r,
27 }
28 29 // widget lays out two buttons on top of each other.
30 widget := func() {
31 // button2 completely covers button1, but PassOp allows pointer
32 // events to pass through to button1.
33 button1.Layout(gtx)
34 // PassOp is applied to the area defined by button1.
35 pointer.PassOp{Pass: true}.Add(gtx.Ops)
36 button2.Layout(gtx)
37 }
38 39 // The first layout and call to Frame declare the Clickable handlers
40 // to the input router, so the following pointer events are propagated.
41 widget()
42 r.Frame(gtx.Ops)
43 // Simulate one click on the buttons by sending a Press and Release event.
44 r.Queue(
45 pointer.Event{
46 Source: pointer.Mouse,
47 Buttons: pointer.ButtonPrimary,
48 Type: pointer.Press,
49 Position: f32.Pt(50, 50),
50 },
51 pointer.Event{
52 Source: pointer.Mouse,
53 Buttons: pointer.ButtonPrimary,
54 Type: pointer.Release,
55 Position: f32.Pt(50, 50),
56 },
57 )
58 // The second layout ensures that the click event is registered by the buttons.
59 widget()
60 61 if button1.Clicked() {
62 fmt.Println("button1 clicked!")
63 }
64 if button2.Clicked() {
65 fmt.Println("button2 clicked!")
66 }
67 68 // Output:
69 // button1 clicked!
70 // button2 clicked!
71 }
72