app: support iOS touch events
Change-Id: I6e8effb1da24e9073454dd2643efdd3c3b3a5ded Reviewed-on: https://go-review.googlesource.com/10480 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
6c1c490379
commit
c73f3e75b6
@ -27,6 +27,7 @@ import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/mobile/event"
|
||||
"golang.org/x/mobile/geom"
|
||||
"golang.org/x/mobile/gl"
|
||||
)
|
||||
@ -50,6 +51,7 @@ func run(callbacks []Callbacks) {
|
||||
log.Fatalf("app.Run called on thread %d, but app.init ran on %d", tid, initThreadID)
|
||||
}
|
||||
cb = callbacks
|
||||
close(mainCalled)
|
||||
C.runApp()
|
||||
}
|
||||
|
||||
@ -123,6 +125,55 @@ func initGL() {
|
||||
var cb []Callbacks
|
||||
var initGLOnce sync.Once
|
||||
|
||||
// touchIDs is the current active touches. The position in the array
|
||||
// is the ID, the value is the UITouch* pointer value.
|
||||
//
|
||||
// It is widely reported that the iPhone can handle up to 5 simultaneous
|
||||
// touch events, while the iPad can handle 11.
|
||||
var touchIDs [11]uintptr
|
||||
|
||||
var touchEvents struct {
|
||||
sync.Mutex
|
||||
pending []event.Touch
|
||||
}
|
||||
|
||||
//export sendTouch
|
||||
func sendTouch(touch uintptr, touchType int, x, y float32) {
|
||||
id := -1
|
||||
for i, val := range touchIDs {
|
||||
if val == touch {
|
||||
id = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if id == -1 {
|
||||
for i, val := range touchIDs {
|
||||
if val == 0 {
|
||||
touchIDs[i] = touch
|
||||
id = i
|
||||
break
|
||||
}
|
||||
}
|
||||
panic("out of touchIDs")
|
||||
}
|
||||
|
||||
ty := event.TouchType(touchType)
|
||||
if ty == event.TouchEnd {
|
||||
touchIDs[id] = 0
|
||||
}
|
||||
|
||||
touchEvents.Lock()
|
||||
touchEvents.pending = append(touchEvents.pending, event.Touch{
|
||||
ID: event.TouchSequenceID(id),
|
||||
Type: ty,
|
||||
Loc: geom.Point{
|
||||
X: geom.Pt(x / geom.PixelsPerPt),
|
||||
Y: geom.Pt(y / geom.PixelsPerPt),
|
||||
},
|
||||
})
|
||||
touchEvents.Unlock()
|
||||
}
|
||||
|
||||
//export drawgl
|
||||
func drawgl(ctx uintptr) {
|
||||
// The call to lockContext loads the OpenGL context into
|
||||
@ -134,6 +185,18 @@ func drawgl(ctx uintptr) {
|
||||
|
||||
initGLOnce.Do(initGL)
|
||||
|
||||
touchEvents.Lock()
|
||||
pending := touchEvents.pending
|
||||
touchEvents.pending = nil
|
||||
touchEvents.Unlock()
|
||||
for _, cb := range callbacks {
|
||||
if cb.Touch != nil {
|
||||
for _, e := range pending {
|
||||
cb.Touch(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO not here?
|
||||
gl.ClearColor(0, 0, 0, 1)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
|
@ -44,7 +44,9 @@ struct utsname sysInfo;
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
view.context = self.context;
|
||||
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
||||
view.multipleTouchEnabled = true; // TODO expose setting to user.
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
int w = [view drawableWidth];
|
||||
@ -53,6 +55,30 @@ struct utsname sysInfo;
|
||||
|
||||
drawgl((GoUintptr)self.context);
|
||||
}
|
||||
|
||||
#define TOUCH_START 0 // event.TouchStart
|
||||
#define TOUCH_MOVE 1 // event.TouchMove
|
||||
#define TOUCH_END 2 // event.TouchEnd
|
||||
|
||||
static void sendTouches(int ty, NSSet* touches) {
|
||||
CGFloat scale = [UIScreen mainScreen].scale;
|
||||
for (UITouch* touch in touches) {
|
||||
CGPoint p = [touch locationInView:touch.view];
|
||||
sendTouch((GoUintptr)touch, ty, p.x*scale, p.y*scale);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
sendTouches(TOUCH_START, touches);
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
sendTouches(TOUCH_MOVE, touches);
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
|
||||
sendTouches(TOUCH_END, touches);
|
||||
}
|
||||
@end
|
||||
|
||||
void runApp(void) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user