2
0
mirror of synced 2025-02-23 14:58:12 +00:00

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:
David Crawshaw 2015-05-26 14:33:20 -04:00
parent 6c1c490379
commit c73f3e75b6
2 changed files with 89 additions and 0 deletions

View File

@ -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)

View File

@ -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) {