mirror of
https://github.com/thes3m/XNI
synced 2024-12-26 13:26:06 +01:00
238 lines
5.7 KiB
Objective-C
238 lines
5.7 KiB
Objective-C
//
|
|
// TouchPanel.m
|
|
// XNI
|
|
//
|
|
// Created by Matej Jan on 29.9.10.
|
|
// Copyright 2010 Retronator. All rights reserved.
|
|
//
|
|
|
|
#import "TouchPanel.h"
|
|
#import "TouchPanel+Internal.h"
|
|
|
|
#import "Retronator.Xni.Framework.h"
|
|
#import "Retronator.Xni.Framework.Input.Touch.h"
|
|
|
|
#import "GameView.h"
|
|
|
|
@interface XniTouchLocation : NSObject {
|
|
@public
|
|
int identifier;
|
|
Vector2 *position;
|
|
Vector2 *previousPosition;
|
|
TouchLocationState state;
|
|
int age;
|
|
}
|
|
|
|
- (id) initWithPosition:(Vector2*)thePosition;
|
|
|
|
- (void) update;
|
|
- (void) moveToPosition:(Vector2*)newPosition;
|
|
|
|
- (TouchLocation*) createTouchLocation;
|
|
|
|
@end
|
|
|
|
@implementation XniTouchLocation
|
|
|
|
static int nextID = 0;
|
|
|
|
- (id) initWithPosition:(Vector2*)thePosition
|
|
{
|
|
self = [super init];
|
|
if (self != nil) {
|
|
identifier = nextID++;
|
|
position = [[Vector2 alloc] initWithVector2:thePosition];
|
|
previousPosition = nil;
|
|
state = TouchLocationStatePressed;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) update {
|
|
[self moveToPosition:position];
|
|
age++;
|
|
}
|
|
|
|
- (void) moveToPosition:(Vector2*)newPosition {
|
|
if (!previousPosition) {
|
|
previousPosition = [[Vector2 alloc] init];
|
|
}
|
|
[previousPosition set:position];
|
|
[position set:newPosition];
|
|
state = TouchLocationStateMoved;
|
|
}
|
|
|
|
- (TouchLocation *) createTouchLocation {
|
|
return [[[TouchLocation alloc] initWithIdentifier:identifier
|
|
position:[Vector2 vectorWithVector:position]
|
|
previousPosition:previousPosition ? [Vector2 vectorWithVector:previousPosition] : nil
|
|
state:state] autorelease];
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[position release];
|
|
[previousPosition release];
|
|
[super dealloc];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation TouchPanel
|
|
|
|
static TouchPanel *instance;
|
|
|
|
- (id) init
|
|
{
|
|
self = [super init];
|
|
if (self != nil) {
|
|
addTouches = [[NSMutableSet alloc] init];
|
|
removeTouches = [[NSMutableSet alloc] init];
|
|
releaseTouches = [[NSMutableSet alloc] init];
|
|
lateReleaseTouches = [[NSMutableSet alloc] init];
|
|
|
|
touchLocations = (NSMutableDictionary*)CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
uiTouchesForLocations = (NSMutableDictionary*)CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
}
|
|
return self;
|
|
}
|
|
|
|
+ (void) initialize {
|
|
instance = [[TouchPanel alloc] init];
|
|
}
|
|
|
|
@synthesize displayWidth;
|
|
@synthesize displayHeight;
|
|
@synthesize displayOrientation;
|
|
@synthesize enabledGestures;
|
|
|
|
+ (TouchCollection*) getState {
|
|
return [instance getState];
|
|
}
|
|
|
|
+ (GestureSample*) readGesture {
|
|
return [instance readGesture];
|
|
}
|
|
|
|
|
|
+ (TouchPanel*) getInstance {
|
|
return instance;
|
|
}
|
|
|
|
- (void) setView:(GameView *)theView {
|
|
view = theView;
|
|
}
|
|
|
|
- (BOOL) isGestureAvailable{
|
|
return NO;
|
|
}
|
|
|
|
- (TouchCollection*) getState{
|
|
TouchCollection *collection = [[[TouchCollection alloc] init] autorelease];
|
|
for (XniTouchLocation *touch in [touchLocations allValues]) {
|
|
[collection addObject:[touch createTouchLocation]];
|
|
|
|
// After get state is done, all pressed touches should be moved.
|
|
[touch update];
|
|
if (touch->age > 200) {
|
|
UITouch *key = [uiTouchesForLocations objectForKey:touch];
|
|
[removeTouches addObject:key];
|
|
}
|
|
}
|
|
return collection;
|
|
}
|
|
|
|
- (GestureSample*) readGesture{
|
|
return nil;
|
|
}
|
|
|
|
// Internal methods
|
|
|
|
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
|
[addTouches unionSet:touches];
|
|
}
|
|
|
|
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
|
float scale = view.scale;
|
|
for (UITouch *touch in touches) {
|
|
XniTouchLocation *location = [touchLocations objectForKey:touch];
|
|
if (location) {
|
|
location->age = 0;
|
|
CGPoint position = [touch locationInView:view];
|
|
[location moveToPosition:[Vector2 vectorWithX:position.x * scale y:position.y * scale]];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
|
for (UITouch *touch in touches) {
|
|
if ([addTouches containsObject:touch]) {
|
|
[lateReleaseTouches addObject:touch];
|
|
} else {
|
|
[releaseTouches addObject:touch];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
|
// Just remove the touch locations so they dissapear from the state (without released happening).
|
|
for (UITouch *touch in touches) {
|
|
[touchLocations removeObjectForKey:touch];
|
|
}
|
|
}
|
|
|
|
- (void) update {
|
|
// Remove all previously released touches.
|
|
for (UITouch *touch in removeTouches) {
|
|
XniTouchLocation *location = [[touchLocations objectForKey:touch] retain];
|
|
[touchLocations removeObjectForKey:touch];
|
|
if (location) {
|
|
[uiTouchesForLocations removeObjectForKey:location];
|
|
[location release];
|
|
}
|
|
}
|
|
[removeTouches removeAllObjects];
|
|
|
|
// Set released touches.
|
|
for (UITouch *touch in releaseTouches) {
|
|
XniTouchLocation *location = [touchLocations objectForKey:touch];
|
|
if (location) {
|
|
location->state = TouchLocationStateReleased;
|
|
}
|
|
}
|
|
|
|
// Shift the pools.
|
|
NSMutableSet *temp = removeTouches;
|
|
removeTouches = releaseTouches;
|
|
releaseTouches = lateReleaseTouches;
|
|
lateReleaseTouches = temp;
|
|
|
|
// Add new touches
|
|
float scale = view.scale;
|
|
for (UITouch *touch in addTouches) {
|
|
CGPoint position = [touch locationInView:view];
|
|
XniTouchLocation *location = [[[XniTouchLocation alloc]
|
|
initWithPosition:[Vector2 vectorWithX:position.x * scale y:position.y * scale]] autorelease];
|
|
|
|
CFDictionaryAddValue((CFMutableDictionaryRef)touchLocations, touch, location);
|
|
CFDictionaryAddValue((CFMutableDictionaryRef)uiTouchesForLocations, location, touch);
|
|
}
|
|
[addTouches removeAllObjects];
|
|
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[addTouches release];
|
|
[removeTouches release];
|
|
[releaseTouches release];
|
|
[lateReleaseTouches release];
|
|
[touchLocations release];
|
|
[uiTouchesForLocations release];
|
|
[super dealloc];
|
|
}
|
|
|
|
|
|
|
|
@end
|