Page 1 of 1

Self-centering joystick mode for trackpad

Posted: Fri Jan 14, 2011 1:55 am
by colinh
Hi,

I've just started using Oolite on a MacBook (Air). (gosh, has it only been 23 yrs...)

Anyway, I've never managed to hit anything using the keyboard for manoeuvring. The trackpad is a bit closer to using a joystick - but it doesn't centre itself when you "let go". Wouldn't that be an improvement?



I'm guessing that:

[self setVirtualJoystick:0.0 :0.0];

in

- (void)mouseUp:(NSEvent *)theEvent

in

.../src/Cocoa/MyOpenGLView.m

might do the trick?

I'll try it out tomorrow, when I've got libpng etc. It's nearly 3 am now...

Re: Self-centering joystick mode for trackpad

Posted: Fri Jan 14, 2011 2:08 am
by JensAyton
That would require you to click to recentre. (Currently right-click does that, but of course that’s not terribly convenient for Mac trackpads.) The behaviour you want would require OS X 10.6 touch gesture support, although it’s not immediately clear whether one-finger “gestures” are supported.

Re: Self-centering joystick mode for trackpad

Posted: Sat Jan 15, 2011 10:15 pm
by colinh
Ah, OK - yes mouseDown and mouseUp are events generated by the a mouse button being clicked and released.

[irrelevant stuff removed]

Thanks for the prod in the right direction.

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 2:13 am
by colinh
Success! Sort of...

I got it working, but only in the NON full-screen mode! The mouse pointer jumps back to the centre of the sights when you lift your finger from the trackpad (on my MacBook Air). This feels quite close to using a joystick. Yes, the mouse pointer *is* visible. Perhaps it could be hidden when the Oolite app is active, or when the mouse pointer is within the Oolite window?

One has to set the target system as OS X 10.6, I'm afraid.



Then, in MyOpenGLView.m, in method - (id) initWithFrame:(NSRect)frameRect add

[self setAcceptsTouchEvents: TRUE]; // CDH only available from OS X 10.6

(obviously, somewhere after the self = [super initWithFrame:frameRect pixelFormat:pixelFormat]; line :-) )



And add a new method:

Code: Select all

- (void)touchesEndedWithEvent:(NSEvent *)event
{
	[self setVirtualJoystick:0.0 :0.0];	
	CGDisplayMoveCursorToPoint(kCGDirectMainDisplay,
						    CGPointMake([[self window] frame].origin.x + viewSize.width / 2,
									(900 - viewSize.height / 2 - [[self window] frame].origin.y)));
}
The 900 is the screen height of my MacBook Air. That needs to be set properly...


I wanted to add a

case NSEventTypeGesture:

to goFullScreen in GameController.m

This is the NSEvent that's generated for touch begin and end (intended for when it can't recognise a proper Gesture). But it's the same event type (and subtype) for both. And [event touchesMatchingPhase:NSTouchPhaseEnded inView:gameView]; isn't returning any NSTouch objects at all :-( so I can't detect when specifically a touch ends.

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 7:35 am
by JensAyton
colinh wrote:
One has to set the target system as OS X 10.6, I'm afraid.
We already have infrastructure for loading code for later OS versions. I’ll set up a Snow Leopard bundle this afternoon.

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 9:24 pm
by JensAyton
We don’t recentre the mouse in windowed mouse mode normally (which is why it’s officially unsupported). Ignoring the obvious fact that this sucks, is there a particular need to do it for touch events?

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 10:37 pm
by colinh
Hmmm. Not sure what you mean. What sucks?

I can't play this sort of game using the keyboard - it has to be a joystick, or something equivalent.

The normal mouse mode with pressing button 2 to centre is OK (I have the bottom right of the trackpad configured as Button 2) but it's kind of distracting when you're trying to shoot down missiles :-)

Surely having self-centring automatic (simply by lifting your finger from the trackpad, analogously to simply letting go of a joystick) - can't be what sucks?

The only way (AFAIK) to detect trackpad touched, finger moved, finger lifted, is by implementing the NSResponder methods invoked by the system for NSTouch events. Gesture events are what you get when you make one of the standard multi-touch (ie 2+ fingers) gestures (magnify, rotate, swipe - and scroll (which is signalled as a mouse event, I think)).

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 10:45 pm
by JensAyton
I am referring to the CGDisplayMoveCursorToPoint() call. For windowed-mode mouse control to work well, we’d need equivalent behaviour (only implemented completely differently, which is part of why I don’t want that there.) Does the trackpad control basically work without CGDisplayMoveCursorToPoint(), assuming you don’t hit the edge of the screen?

Re: Self-centering joystick mode for trackpad

Posted: Wed Jan 19, 2011 11:16 pm
by colinh
Ah, ok I think I see what you're getting at.

Except for the bit "does trackpad control basically work without..."

Well, I think one can get the absolute trackpad coordinates for touch events ie. touch began, moved and ended. (and then, obviously, use the motion relative to the coordinate of where the touch began).

So one could use that data instead of the mouse coordinates, but would you want the trackpad simply not to move the mouse when the oolite window is active? If so, I'm not sure how to do that.


Wouldn't it be easier to simply hide the mouse pointer (using [NSCursor hide] or whatever) when the oolite window is active?

... [ edit 2 mins later :-) ]

If one adds

[NSCursor hide];

after the

[self setAcceptsTouchEvents: TRUE]; // CDH only available from OS X 10.6

line in initWithFrame:(NSRect)frameRect in MyOpenGLView.m, that's precisely what happens. :-)

Re: Self-centering joystick mode for trackpad

Posted: Thu Jan 20, 2011 7:32 am
by JensAyton
colinh wrote:
[NSCursor hide];
That would be fine as long as the user didn’t try clicking anywhere.

But my point is that this is beyond the scope of touchpad improvements, because it applies to mouse control as well. As far as I can see, touchesEndedWithEvent: should be doing exactly the same thing as a right-click, i.e.:

Code: Select all

my_mouse_x = my_mouse_y = 0;
past_first_mouse_delta = NO;
[gameView setVirtualJoystick:0.0 :0.0];
Is there some reason this doesn’t work?