-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathinputLoop.go
168 lines (156 loc) · 6.07 KB
/
inputLoop.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package oak
import (
"github.com/oakmound/oak/v4/alg/intgeom"
"github.com/oakmound/oak/v4/event"
"github.com/oakmound/oak/v4/timing"
"github.com/oakmound/oak/v4/dlog"
okey "github.com/oakmound/oak/v4/key"
omouse "github.com/oakmound/oak/v4/mouse"
"golang.org/x/mobile/event/key"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/mouse"
"golang.org/x/mobile/event/size"
)
// The following block defines events generated by oak during scene execution
var (
// ViewportUpdate is triggered when the position of of the viewport changes
ViewportUpdate = event.RegisterEvent[intgeom.Point2]()
// OnStop is triggered when the engine is stopped, e.g. when a window's close
// button is clicked.
OnStop = event.RegisterEvent[struct{}]()
// FocusGain is triggered when a window gains focus
FocusGain = event.RegisterEvent[struct{}]()
// FocusLoss is triggered when a window loses focus
FocusLoss = event.RegisterEvent[struct{}]()
// InputChange is triggered when the most recent input device changes (e.g. keyboard to joystick or vice versa). It
// is only sent if Config.TrackInputChanges is true when Init is called.
InputChange = event.RegisterEvent[InputType]()
)
func (w *Window) inputLoop() {
for {
switch e := w.Window.NextEvent().(type) {
// We only currently respond to death lifecycle events.
case lifecycle.Event:
switch e.To {
case lifecycle.StageDead:
dlog.Info(dlog.WindowClosed)
<-event.TriggerOn(w.eventHandler, OnStop, struct{}{})
close(w.quitCh)
return
case lifecycle.StageFocused:
w.inFocus = true
// If you are in focused state, we don't care how you got there
w.DrawTicker.Reset(timing.FPSToFrameDelay(w.DrawFrameRate))
event.TriggerOn(w.eventHandler, FocusGain, struct{}{})
case lifecycle.StageVisible:
// If the last state was focused, this means the app is out of focus
// otherwise, we're visible for the first time
if e.From > e.To {
w.inFocus = false
w.DrawTicker.Reset(timing.FPSToFrameDelay(w.IdleDrawFrameRate))
event.TriggerOn(w.eventHandler, FocusLoss, struct{}{})
} else {
w.inFocus = true
w.DrawTicker.Reset(timing.FPSToFrameDelay(w.DrawFrameRate))
event.TriggerOn(w.eventHandler, FocusGain, struct{}{})
}
}
// Send key events
//
// Key events have two varieties:
// The "KeyDown" and "KeyUp" events, which trigger for all keys
// and specific "KeyDown$key", etc events which trigger only for $key.
// The specific key that is pressed is passed as the data interface for
// the former events, but not for the latter.
case key.Event:
switch e.Direction {
case key.DirPress:
w.TriggerKeyDown(okey.Event(e))
case key.DirRelease:
w.TriggerKeyUp(okey.Event(e))
default:
w.TriggerKeyHeld(okey.Event(e))
}
// Send mouse events
//
// Mouse events are parsed based on their button
// and direction into an event name and then triggered:
// 'MousePress', 'MouseRelease', 'MouseScrollDown', 'MouseScrollUp', and 'MouseDrag'
//
// The basic event name is meant for entities which
// want to respond to the mouse event happening -anywhere-.
//
// For events which have mouse collision enabled, they'll receive
// $eventName+"On" when the event occurs within their collision area.
//
// Mouse events all receive an x, y, and button string.
case mouse.Event:
button := omouse.Button(e.Button)
ev := omouse.GetEvent(e.Direction, e.Button)
// The event triggered for mouse events has the same scaling as the
// render and collision space. I.e. if the viewport is at 0, the mouse's
// position is exactly the same as the position of a visible entity
// on screen. When not at zero, the offset will be exactly the viewport.
mevent := omouse.NewEvent(
float64((((e.X - float32(w.windowRect.Min.X)) / float32(w.windowRect.Max.X-w.windowRect.Min.X)) * float32(w.ScreenWidth))),
float64((((e.Y - float32(w.windowRect.Min.Y)) / float32(w.windowRect.Max.Y-w.windowRect.Min.Y)) * float32(w.ScreenHeight))),
button,
ev,
)
w.TriggerMouseEvent(mevent)
// Size events update what we scale the screen to
case size.Event:
err := w.ChangeWindow(e.WidthPx, e.HeightPx)
dlog.ErrorCheck(err)
}
}
}
// TriggerKeyDown triggers a software-emulated keypress.
// This should be used cautiously when the keyboard is in use.
// From the perspective of the event handler this is indistinguishable
// from a real keypress.
func (w *Window) TriggerKeyDown(e okey.Event) {
w.State.SetDown(e.Code)
event.TriggerOn(w.eventHandler, okey.AnyDown, e)
event.TriggerOn(w.eventHandler, okey.Down(e.Code), e)
}
// TriggerKeyUp triggers a software-emulated key release.
// This should be used cautiously when the keyboard is in use.
// From the perspective of the event handler this is indistinguishable
// from a real key release.
func (w *Window) TriggerKeyUp(e okey.Event) {
w.State.SetUp(e.Code)
event.TriggerOn(w.eventHandler, okey.AnyUp, e)
event.TriggerOn(w.eventHandler, okey.Up(e.Code), e)
}
// TriggerKeyHeld triggers a software-emulated key hold signal.
// This should be used cautiously when the keyboard is in use.
// From the perspective of the event handler this is indistinguishable
// from a real key hold signal.
func (w *Window) TriggerKeyHeld(e okey.Event) {
event.TriggerOn(w.eventHandler, okey.AnyHeld, e)
event.TriggerOn(w.eventHandler, okey.Held(e.Code), e)
}
// TriggerMouseEvent triggers a software-emulated mouse event.
// This should be used cautiously when the mouse is in use.
// From the perspective of the event handler this is indistinguishable
// from a real key mouse press or movement.
func (w *Window) TriggerMouseEvent(mevent omouse.Event) {
w.LastMouseEvent = mevent
omouse.LastEvent = mevent
on, onOk := omouse.EventOn(mevent.EventType)
if onOk {
w.Propagate(on, mevent)
}
event.TriggerOn(w.eventHandler, mevent.EventType, &mevent)
if onOk {
rel, ok := omouse.EventRelative(on)
if ok {
relativeEvent := mevent
relativeEvent.Point2[0] += float64(w.viewPos[0])
relativeEvent.Point2[1] += float64(w.viewPos[1])
w.LastRelativeMouseEvent = relativeEvent
w.Propagate(rel, relativeEvent)
}
}
}