cocoaTouch/iPad/OverlayViewController.m
changeset 3305 91074496d5c9
parent 3304 8690a3aa93b5
child 3306 fcdf6d85b042
equal deleted inserted replaced
3304:8690a3aa93b5 3305:91074496d5c9
     1 //
       
     2 //  overlayViewController.m
       
     3 //  HedgewarsMobile
       
     4 //
       
     5 //  Created by Vittorio on 16/03/10.
       
     6 //  Copyright 2010 __MyCompanyName__. All rights reserved.
       
     7 //
       
     8 
       
     9 #import "OverlayViewController.h"
       
    10 #import "SDL_uikitappdelegate.h"
       
    11 #import "PascalImports.h"
       
    12 #import "CGPointUtils.h"
       
    13 #import "SDL_mouse.h"
       
    14 #import "PopupMenuViewController.h"
       
    15 
       
    16 @implementation OverlayViewController
       
    17 @synthesize dimTimer, menuPopover;
       
    18 
       
    19 
       
    20 -(void) didReceiveMemoryWarning {
       
    21 	// Releases the view if it doesn't have a superview.
       
    22     [super didReceiveMemoryWarning];
       
    23 	
       
    24 	// Release any cached data, images, etc that aren't in use.
       
    25 }
       
    26 
       
    27 -(void) viewDidLoad {
       
    28     self.view.alpha = 0;
       
    29     
       
    30     // needed for rotation to work on os < 3.2
       
    31     self.view.center = CGPointMake(self.view.frame.size.height/2.0, self.view.frame.size.width/2.0);
       
    32     self.view.transform = CGAffineTransformRotate(self.view.transform, (M_PI/2.0));
       
    33 
       
    34     dimTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:6]
       
    35                                         interval:1000
       
    36                                           target:self
       
    37                                         selector:@selector(dimOverlay)
       
    38                                         userInfo:nil
       
    39                                          repeats:YES];
       
    40     
       
    41     // add timer too runloop, otherwise it doesn't work
       
    42     [[NSRunLoop currentRunLoop] addTimer:dimTimer forMode:NSDefaultRunLoopMode];
       
    43     // listen for dismissal of the popover (see below)x
       
    44     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissPopover) name:@"dismissPopover" object:nil];
       
    45     // present the overlay after 2 seconds
       
    46     [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showMenuAfterwards) userInfo:nil repeats:NO];
       
    47 }
       
    48 
       
    49 -(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
       
    50     return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
       
    51 }
       
    52 
       
    53 -(void) viewDidUnload {
       
    54 	[dimTimer invalidate];
       
    55     self.dimTimer = nil;
       
    56     menuPopover = nil;
       
    57     [super viewDidUnload];
       
    58 }
       
    59 
       
    60 -(void) dealloc {
       
    61     [menuPopover release];
       
    62     // dimTimer is autoreleased
       
    63     [super dealloc];
       
    64 }
       
    65 
       
    66 // draws the controller overlay after the sdl window has taken control
       
    67 -(void) showMenuAfterwards {
       
    68     [[SDLUIKitDelegate sharedAppDelegate].uiwindow bringSubviewToFront:self.view];
       
    69 
       
    70 	[UIView beginAnimations:@"showing overlay" context:NULL];
       
    71 	[UIView setAnimationDuration:1];
       
    72 	self.view.alpha = 1;
       
    73 	[UIView commitAnimations];
       
    74 }
       
    75 
       
    76 // dim the overlay when there's no more input for a certain amount of time
       
    77 -(IBAction) buttonReleased:(id) sender {
       
    78 	HW_allKeysUp();
       
    79     [dimTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:2.7]];
       
    80 }
       
    81 
       
    82 // nice transition for dimming
       
    83 -(void) dimOverlay {
       
    84     [UIView beginAnimations:@"overlay dim" context:NULL];
       
    85    	[UIView setAnimationDuration:0.6];
       
    86     self.view.alpha = 0.2;
       
    87 	[UIView commitAnimations];
       
    88 }
       
    89 
       
    90 // set the overlay visible and put off the timer for enough time
       
    91 -(void) activateOverlay {
       
    92     self.view.alpha = 1;
       
    93     [dimTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:1000]];
       
    94 }
       
    95 
       
    96 // issue certain action based on the tag of the button 
       
    97 -(IBAction) buttonPressed:(id) sender {
       
    98     [self activateOverlay];
       
    99     UIButton *theButton = (UIButton *)sender;
       
   100     
       
   101     switch (theButton.tag) {
       
   102         case 0:
       
   103             HW_walkLeft();
       
   104             break;
       
   105         case 1:
       
   106             HW_walkRight();
       
   107             break;
       
   108         case 2:
       
   109             HW_aimUp();
       
   110             break;
       
   111         case 3:
       
   112             HW_aimDown();
       
   113             break;
       
   114         case 4:
       
   115             HW_shoot();
       
   116             break;
       
   117         case 5:
       
   118             HW_jump();
       
   119             break;
       
   120         case 6:
       
   121             HW_backjump();
       
   122             break;
       
   123         case 7:
       
   124             HW_tab();
       
   125             break;
       
   126         default:
       
   127             NSLog(@"Nope");
       
   128             break;
       
   129     }
       
   130 }
       
   131 
       
   132 // present a further check before closing game
       
   133 -(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex {
       
   134 	if ([actionSheet cancelButtonIndex] != buttonIndex)
       
   135 	    HW_terminate(NO);
       
   136 	else
       
   137             HW_pause();		
       
   138 }
       
   139 
       
   140 // show up a popover containing a popupMenuViewController; we hook it with setPopoverContentSize
       
   141 -(IBAction) showPopover{
       
   142     PopupMenuViewController *popupMenu = [[PopupMenuViewController alloc] init];
       
   143     
       
   144     menuPopover = [[UIPopoverController alloc] initWithContentViewController:popupMenu];
       
   145     [menuPopover setPopoverContentSize:CGSizeMake(220, 170) animated:YES];
       
   146 
       
   147     [menuPopover presentPopoverFromRect:CGRectMake(960, 0, 220, 32) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
       
   148 }
       
   149 
       
   150 // because of the actionSheet, the popOver might not get dismissed, so we do it manually (through a NSNotification system, see above)
       
   151 -(void) dismissPopover {
       
   152     if (menuPopover.popoverVisible) 
       
   153         [menuPopover dismissPopoverAnimated:YES];
       
   154 }
       
   155 
       
   156 #pragma mark -
       
   157 #pragma mark Custom touch event handling
       
   158 
       
   159 #define kMinimumPinchDelta      50
       
   160 #define kMinimumGestureLength	10
       
   161 #define kMaximumVariance        3
       
   162 
       
   163 -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
       
   164 	NSArray *twoTouches;
       
   165 	UITouch *touch = [touches anyObject];
       
   166 	int width = [[UIScreen mainScreen] bounds].size.width;
       
   167     
       
   168 	switch ([touches count]) {
       
   169 		case 1:
       
   170 			gestureStartPoint = [touch locationInView:self.view];
       
   171 			initialDistanceForPinching = 0;
       
   172 			switch ([touch tapCount]) {
       
   173 				case 1:
       
   174 					NSLog(@"X:%d Y:%d", (int)gestureStartPoint.x, (int)gestureStartPoint.y );
       
   175 					SDL_WarpMouseInWindow([SDLUIKitDelegate sharedAppDelegate].window, 
       
   176 							      (int)gestureStartPoint.y, width - (int)gestureStartPoint.x);
       
   177 					HW_click();
       
   178 					break;
       
   179 				case 2:
       
   180 					HW_ammoMenu();
       
   181 					break;
       
   182 				default:
       
   183 					break;
       
   184 			}
       
   185 			break;
       
   186 		case 2:
       
   187 			if (2 == [touch tapCount]) {
       
   188 				HW_zoomReset();
       
   189 			}
       
   190 			
       
   191 			// pinching
       
   192 			twoTouches = [touches allObjects];
       
   193 			UITouch *first = [twoTouches objectAtIndex:0];
       
   194 			UITouch *second = [twoTouches objectAtIndex:1];
       
   195 			initialDistanceForPinching = distanceBetweenPoints([first locationInView:self.view], [second locationInView:self.view]);
       
   196 			break;
       
   197 		default:
       
   198 			break;
       
   199 	}
       
   200 
       
   201 }
       
   202 
       
   203 -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
       
   204 	initialDistanceForPinching = 0;
       
   205 	gestureStartPoint.x = 0;
       
   206 	gestureStartPoint.y = 0;
       
   207 	HW_allKeysUp();
       
   208 }
       
   209 
       
   210 -(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
       
   211 	// this can happen if the user puts more than 5 touches on the screen at once, or perhaps in other circumstances.
       
   212 	[self touchesEnded:touches withEvent:event];
       
   213 }
       
   214 
       
   215 -(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
       
   216 	NSArray *twoTouches;
       
   217 	CGPoint currentPosition;
       
   218 	UITouch *touch = [touches anyObject];
       
   219 	int width = [[UIScreen mainScreen] bounds].size.width;
       
   220 
       
   221 	switch ([touches count]) {
       
   222 		case 1:
       
   223 			currentPosition = [touch locationInView:self.view];
       
   224 			// panning
       
   225 			SDL_WarpMouseInWindow([SDLUIKitDelegate sharedAppDelegate].window, 
       
   226 							(int)gestureStartPoint.y, width - (int)gestureStartPoint.x);
       
   227 			// remember that we have x and y inverted
       
   228 			/* temporarily disabling hog movements for camera panning testing
       
   229 			CGFloat vertDiff = gestureStartPoint.x - currentPosition.x;
       
   230 			CGFloat horizDiff = gestureStartPoint.y - currentPosition.y;
       
   231 			CGFloat deltaX = fabsf(vertDiff);
       
   232 			CGFloat deltaY = fabsf(horizDiff);
       
   233 			
       
   234 			if (deltaY >= kMinimumGestureLength && deltaX <= kMaximumVariance) {
       
   235 				NSLog(@"Horizontal swipe detected, begX:%f curX:%f", gestureStartPoint.x, currentPosition.x);
       
   236 				if (horizDiff > 0) HW_walkLeft();
       
   237 				else HW_walkRight();
       
   238 			} else if (deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance){
       
   239 				NSLog(@"Vertical swipe detected, begY:%f curY:%f", gestureStartPoint.y, currentPosition.y);
       
   240 				if (vertDiff < 0) HW_aimUp();
       
   241 				else HW_aimDown();
       
   242 			}
       
   243 			*/
       
   244 			break;
       
   245 		case 2:
       
   246 			twoTouches = [touches allObjects];
       
   247 			UITouch *first = [twoTouches objectAtIndex:0];
       
   248 			UITouch *second = [twoTouches objectAtIndex:1];
       
   249 			CGFloat currentDistanceOfPinching = distanceBetweenPoints([first locationInView:self.view], [second locationInView:self.view]);
       
   250 			
       
   251 			if (0 == initialDistanceForPinching) 
       
   252 				initialDistanceForPinching = currentDistanceOfPinching;
       
   253 
       
   254 			if (currentDistanceOfPinching < initialDistanceForPinching + kMinimumPinchDelta)
       
   255 				HW_zoomOut();
       
   256 			else if (currentDistanceOfPinching > initialDistanceForPinching + kMinimumPinchDelta)
       
   257 				HW_zoomIn();
       
   258 
       
   259 			currentDistanceOfPinching = initialDistanceForPinching;
       
   260 			break;
       
   261 		default:
       
   262 			break;
       
   263 	}
       
   264 }
       
   265 
       
   266 
       
   267 @end