[bmx] Multitouch Trackpad Events by N [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Multitouch Trackpad Events
Author : N
Posted : 1+ years ago

Description : If you didn't read the short description, this is only for Mac OS.

Note: doesn't work in fullscreen for some reason.  Not sure why, but it'd be easier to get it working to just put the event handling code into the BRL modules.

What this does is it takes a TGLGraphics instance and inserts a responder into the responder chain for the window or view associated with the graphics, and then passes along events to BlitzMax, which you can get at by polling for events or adding a hook for EmitEventHook.

The only important functions are CreateTrackpadHandler and DestroyTrackpadHandler.  The event constants are in the source, but only three of them are used, so don't bother checking for the ones marked 'unused.'

Example
SuperStrict

'buildopt:gui

?MacOS

Import "tracktouch.bmx"

SetGraphicsDriver(GLMax2DDriver())
' If you're using Max2D, you'll have to grab the inner TGraphics from the TMax2DGraphics like so:
Local gfx:TGraphics = TMax2DGraphics(Graphics(800,600,0))._graphics
Local handle:Int = CreateTrackpadHandler(gfx)

Local x:Float = GraphicsWidth()*.5
Local y:Float = GraphicsHeight()*.5
Local scale:Float = 1.0
Local rotation:Float = 0.0
Local color:Int = 0

Local Running:Int = True

' Some colors to swipe through
Local colors:Int[] = [255,255,255, 254,149,50, 85,85,238, 254,34,35, 200,232,7, 241,41,234, ..
                      144,204,76, 120,148,183, 155,127,79, 242,11,137, 184,69,74, 35,33,86, ..
                      30,95,104, 106,148,181]

While Running
Cls

While PollEvent()
Select CurrentEvent.id

' HANDLE TOUCH EVENTS

Case EVENT_TOUCH_MAGNIFY
Rem
Unfortunately, the only other way I could see a float being included in an event was
if I either subclassed TEvent or if I converted the float value to a string.  Neither
struck me as necessary, so float values are just packed into an integer.
EndRem
scale = Max(.25, scale * (1.0+Float Ptr(Varptr CurrentEvent.data)[0]))

Case EVENT_TOUCH_SWIPE
Local dir$ = Null
If CurrentEvent.y Then ' down = -1, up = 1
If CurrentEvent.y > 0 Then
dir = "up"
Else
dir = "down"
EndIf
ElseIf CurrentEvent.x Then ' right = -1, left = 1
If CurrentEvent.x < 0 Then
dir = "right"
Else
dir = "left"
EndIf
EndIf

DebugLog "Swiped "+dir

color = (color - CurrentEvent.x) Mod (colors.Length/3)
If color < 0 Then color :+ colors.Length/3

Case EVENT_TOUCH_ROTATE
' Same deal as magnification events
rotation :- Float Ptr(Varptr CurrentEvent.Data)[0]

' TOUCH EVENTS END HERE

Case EVENT_KEYDOWN
If CurrentEvent.data = KEY_ESCAPE Then
Running = False
ElseIf CurrentEvent.data = KEY_SPACE Then
' debugging bit to ensure the handler restores the responder chain on release
If handle Then
DestroyTrackpadHandler(handle)
handle = 0
Else
handle = CreateTrackpadHandler(gfx)
EndIf
EndIf

Case EVENT_APPTERMINATE
Running = False

End Select
Wend

SetOrigin(x,y)
SetColor(colors[color*3], colors[color*3+1], colors[color*3+2])
SetHandle(16,16)
SetScale(scale, scale)
SetRotation(rotation)
DrawRect(0, 0, 32, 32)

Flip
Wend

DestroyTrackpadHandler(handle)

EndGraphics

?Not MacOS
Notify("Wrong OS, mate")
?

tracktouch.m (required)
#import <Cocoa/Cocoa.h>
#import <brl.mod/blitz.mod/blitz.h>

#define EVENT_USEREVENTMASK (-2147483648)
enum {
EVENT_TOUCH_GESTURE = EVENT_USEREVENTMASK+88,
EVENT_TOUCH_MAGNIFY,
EVENT_TOUCH_SWIPE,
EVENT_TOUCH_ROTATE,
EVENT_TOUCH_BEGINGESTURE,
EVENT_TOUCH_ENDGESTURE
};

extern BBClass brl_event_TEvent;

typedef struct s_bbevent {
BBClass *clas;
int refs;

int id;
BBObject *source;
int data;
int mods;
int x;
int y;
BBObject *extra;
} bbevent_t;

extern int _brl_event_TEvent_Emit(bbevent_t*); // TEvent#Emit


#pragma mark -

typedef struct s_glgraphics { // the TGLGraphics structure
BBClass *clas;
int refs;
struct {
int _[7]; // stuff we're not interested in
        id __[2];
        NSOpenGLContext *context;
} *ctx;
} glgraphics_t;

/** The NSResponder subclass we'll use to intercept touch events **/
@interface CTrackpadHandler : NSResponder
{
    NSOpenGLContext *context;
}
@end


#pragma mark -

@implementation CTrackpadHandler
- (id)initWithGraphics:(glgraphics_t*)graphics
{
if((self = [super init])) {
        context = [graphics->ctx->context retain];
        NSView *view = [context view];
       
        NSResponder *responder = [[view nextResponder] retain];
        [self setNextResponder:responder];
        [view setNextResponder:self];
        [responder release];
}
return self;
}

-(void)removeHandler {
if ( [self nextResponder] ) {
        NSView *view = [context view];
       
        NSResponder *responder = [[self nextResponder] retain];
        [view setNextResponder:responder];
        [self setNextResponder:nil];
        [responder release];
       
        [context release];
        context = nil;
}
}

// redundancy!
-(void)finalize { // in the event that the GC is used...
[self removeHandler];
[super finalize];
}

-(void)dealloc { // regular behavior.
[self removeHandler];
[super dealloc];
}

/** handle events **/
-(void)magnifyWithEvent:(NSEvent*)event {
int data;
*(float*)&data = [event magnification];
[self emitEventWithID:EVENT_TOUCH_MAGNIFY data:data x:0 y:0];
[super magnifyWithEvent:event];
}

-(void)rotateWithEvent:(NSEvent*)event {
int data;
*(float*)&data = [event rotation];
[self emitEventWithID:EVENT_TOUCH_ROTATE data:data x:0 y:0];
    [super rotateWithEvent:event];
}

-(void)swipeWithEvent:(NSEvent*)event {
[self emitEventWithID:EVENT_TOUCH_SWIPE data:0 x:(int)[event deltaX] y:(int)[event deltaY]];
[super swipeWithEvent:event];
}

-(void)emitEventWithID:(int)id data:(int)data x:(int)x y:(int)y {
bbevent_t* bbevent = bbObjectNew(&brl_event_TEvent);
bbevent->id = id;
bbevent->data = data;
bbevent->x = x;
bbevent->y = y;
_brl_event_TEvent_Emit(bbevent);
}

@end


#pragma mark -

CTrackpadHandler *CreateTrackpadHandler(BBObject *graphics) {
CTrackpadHandler* handler = [[CTrackpadHandler alloc] initWithGraphics:graphics];
return (handler != nil ? handler : NULL);
}

int DestroyTrackpadHandler(CTrackpadHandler *handler) {
[handler removeHandler];
[handler release];
}


tracktouch.bmx (required) [/i]

Code :
Code (blitzmax) Select
SuperStrict

?MacOS
Import "tracktouch.m"

Extern "C"
Function CreateTrackpadHandler%(gfx:TGraphics)
Function DestroyTrackpadHandler%(handle:Int)
End Extern
?

Const EVENT_TOUCH_GESTURE:Int = EVENT_USEREVENTMASK+88 ' unused
Const EVENT_TOUCH_MAGNIFY:Int = EVENT_TOUCH_GESTURE+1
Const EVENT_TOUCH_SWIPE:Int = EVENT_TOUCH_MAGNIFY+1
Const EVENT_TOUCH_ROTATE:Int = EVENT_TOUCH_SWIPE+1
Const EVENT_TOUCH_BEGINGESTURE:Int = EVENT_TOUCH_ROTATE+1 ' unused
Const EVENT_TOUCH_ENDGESTURE:Int = EVENT_TOUCH_BEGINGESTURE+1 ' unused


Comments :


Romanski(Posted 1+ years ago)

 I just installed Cocoa by installing DevTools and also tried a cocoa-wrapper in my mods but still can't make it run on my system.it's having problems with "#Import <Cocoa/Cocoa.h>" in tracktouch.mI can't really find a lot of installion-guides for this. could you help me out pls?


N(Posted 1+ years ago)

 Could you provide the actual error from the compiler?  I assume you are running Mac OS, so which version of Mac OS do you have?


Romanski(Posted 1+ years ago)

 I have 10.5.7 .this is the error:Compile Error2: error: invalid preprocessing directive #Import


N(Posted 1+ years ago)

 Out of curiosity, are you pasting tracktouch.m into MaxIDE?


Romanski(Posted 1+ years ago)

 I pasted the code above in MAXIDE and saved it as tracktouch.m. yes....ups... I think I get it...


Romanski(Posted 1+ years ago)

 I did it now via xcode and get this error:Building sampleCompiling:tracktouch.m/Users/blabla/Documents/Blitzmax/Touchpad/tracktouch.m: In function '-[CTrackpadHandler magnifyWithEvent:]':/Users/blabla/Documents/Blitzmax/Touchpad/tracktouch.m:105: error: incompatible types in assignmentBuild Error: failed to compile /Users/blabla/Documents/Blitzmax/Touchpad/tracktouch.mProcess complete


N(Posted 1+ years ago)

 magnifyWithEvent: doesn't include line 105, nor does that line have any assignments.  Did you change anything?


Romanski(Posted 1+ years ago)

 no I didn't. cxode just added some lines in the beginning with blind text that's why you're confused about line 105.maxide selects this part from tracktouch.m :float*)&data = [event magnification];it doesn't like this one. with the reason "incompatible types in assignment".


N(Posted 1+ years ago)

 According to the documentation, NSEvent#magnification is only available in Mac OS 10.6, while my headers are showing they require a minimum of 10.5.2.  I suspect [event magnification] may be returning an id in your case.  So, I'm not entirely sure what's up (and I'm assuming the missing opening parenthesis is just your mistake in copying).You'll probably just have to fiddle with the code and see what works.


Romanski(Posted 1+ years ago)

 Ok Thank you very much Nilium. I will play around with it for a while. And maybe get a new OS.


MacSven(Posted 1+ years ago)

 I it a cool idea since i have bought a Magix Trackpad for my Mac Pro, but i get this error:Building exampleCompiling:tracktouch.m/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:1:2: error: invalid preprocessing directive #Import/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:2:2: error: invalid preprocessing directive #Import/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'BBClass'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:17: error: expected specifier-qualifier-list before 'BBClass'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:28: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Int'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:34: error: expected specifier-qualifier-list before 'BBClass'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:45: error: cannot find interface declaration for 'NSResponder', superclass of 'CTrackpadHandler'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:46: error: expected specifier-qualifier-list before 'NSOpenGLContext'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:48: error: stray '@' in program/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:53: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'implementation'/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:68: error: expected ';' before '{' token/Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.m:122: error: stray '@' in programBuild Error: failed to compile /Applications/BlitzMax/SourceFiles/TrackPad/tracktouch.mProzess abgeschlossenI am using MacOS X 10.6.8 and XCode 3.2.6.Any idea?


sendelbros(Posted 1+ years ago)

 Tried it with 10.9.5/XCode 6.1 and it's working after the first try without any problems.Thanks a lot. ;)