# HG changeset patch # User koda # Date 1286596666 -7200 # Node ID 1a873262f5ddb097ebf8b60c95bc20dc6901f460 # Parent 8b00b4f932427f73e2ea9bf026f587b29fef1e3b polishing the cocoa ammomenu a little, still requires work diff -r 8b00b4f93242 -r 1a873262f5dd hedgewars/PascalExports.pas --- a/hedgewars/PascalExports.pas Thu Oct 07 02:16:29 2010 +0200 +++ b/hedgewars/PascalExports.pas Sat Oct 09 05:57:46 2010 +0200 @@ -297,8 +297,6 @@ var skipTurns : PByte; a : TAmmoType; begin - if (CurrentTeam^.ExtDriven) or (CurrentTeam^.Hedgehogs[0].BotLevel <> 0) then - exit(nil); GetMem(skipTurns,ord(High(TAmmoType))); FillChar(skipTurns^,ord(High(TAmmoType)),0); for a:= Low(TAmmoType) to High(TAmmoType) do diff -r 8b00b4f93242 -r 1a873262f5dd project_files/HedgewarsMobile/Classes/AmmoMenuViewController.h --- a/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.h Thu Oct 07 02:16:29 2010 +0200 +++ b/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.h Sat Oct 09 05:57:46 2010 +0200 @@ -23,11 +23,21 @@ @interface AmmoMenuViewController : UIViewController { - NSArray *imagesArray; + UIImage *weaponsImage; + NSArray *buttonsArray; + + unsigned char *delay; + CGPoint startingPoint; + BOOL isVisible; } -@property (nonatomic,retain) NSArray *imagesArray; +@property (nonatomic,retain) UIImage *weaponsImage; +@property (nonatomic,retain) NSArray *buttonsArray; +@property (assign) BOOL isVisible; -(void) buttonPressed:(id)sender; +-(void) updateVisuals:(NSNotification *)object; +-(void) appearInView:(UIView *)container; +-(void) disappear; @end diff -r 8b00b4f93242 -r 1a873262f5dd project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m --- a/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m Thu Oct 07 02:16:29 2010 +0200 +++ b/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m Sat Oct 09 05:57:46 2010 +0200 @@ -26,21 +26,66 @@ #import "PascalImports.h" @implementation AmmoMenuViewController -@synthesize imagesArray;; +@synthesize weaponsImage, buttonsArray, isVisible; -(void) viewDidLoad { [super viewDidLoad]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(updateVisuals:) + name:@"updateAmmoVisuals" + object:nil]; + self.view.frame = CGRectMake(0, 0, 480, 320); self.view.backgroundColor = [UIColor blackColor]; + self.view.layer.borderColor = [[UIColor whiteColor] CGColor]; + self.view.layer.borderWidth = 1.3f; [self.view.layer setCornerRadius:10]; [self.view.layer setMasksToBounds:YES]; + self.isVisible = NO; + delay = HW_getAmmoDelays(); + + UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + spinner.hidesWhenStopped = YES; + spinner.center = self.view.center; + [spinner startAnimating]; + [self.view addSubview:spinner]; + if (self.buttonsArray == nil) + [NSThread detachNewThreadSelector:@selector(loadAmmoStuff:) toTarget:self withObject:spinner]; + [spinner release]; +} + +-(void) viewWillAppear:(BOOL)animated { + if (self.buttonsArray != nil) + [self updateVisuals:nil]; + [super viewWillAppear:animated]; +} + +-(void) appearInView:(UIView *)container { + [self viewWillAppear:YES]; + [container addSubview:self.view]; + self.view.center = CGPointMake(container.center.y, container.center.x); + self.isVisible = YES; + [self viewDidAppear:YES]; +} + +-(void) disappear { + + [self.view removeFromSuperview]; + self.isVisible = NO; +} + +-(void) loadAmmoStuff:(id) object { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + UIActivityIndicatorView *spinner = (UIActivityIndicatorView *)object; + NSString *str = [NSString stringWithFormat:@"%@/AmmoMenu/Ammos.png",GRAPHICS_DIRECTORY()]; UIImage *ammoStoreImage = [[UIImage alloc] initWithContentsOfFile:str]; - NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:CURRENT_AMMOSIZE]; - for (int i = 0; i < CURRENT_AMMOSIZE; i++) { + NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:HW_getNumberOfWeapons()]; + for (int i = 0; i < HW_getNumberOfWeapons(); i++) { int x_src = ((i*32)/(int)ammoStoreImage.size.height)*32; int y_src = (i*32)%(int)ammoStoreImage.size.height; int x_dst = 10+(i%10)*44; @@ -49,44 +94,169 @@ if (i / 10 % 2 != 0) x_dst += 20; UIImage *img = [ammoStoreImage cutAt:CGRectMake(x_src, y_src, 32, 32)]; - UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x_dst, y_dst, 40, 40)]; - button.tag = i+1; + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.frame = CGRectMake(x_dst, y_dst, 40, 40); + button.tag = i; button.layer.borderWidth = 1; button.layer.borderColor = [UICOLOR_HW_YELLOW_TEXT CGColor]; [button.layer setCornerRadius:6]; [button.layer setMasksToBounds:YES]; - [button setImage:img forState:UIControlStateNormal]; + [button setBackgroundImage:img forState:UIControlStateNormal]; [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + [button setTitleColor:UICOLOR_HW_YELLOW_TEXT forState:UIControlStateNormal]; + button.titleLabel.backgroundColor = [UIColor blackColor]; + button.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + [button.titleLabel.layer setCornerRadius:3]; + [button.titleLabel.layer setMasksToBounds:YES]; + button.titleLabel.layer.borderColor = [[UIColor whiteColor] CGColor]; + button.titleLabel.layer.borderWidth = 1; [self.view addSubview:button]; [array addObject:button]; - [button release]; } - self.imagesArray = array; + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:array,@"array",ammoStoreImage,@"image",spinner,@"spinner",nil]; [array release]; [ammoStoreImage release]; + [self performSelectorOnMainThread:@selector(ready:) withObject:dict waitUntilDone:NO]; + + [pool drain]; +} + +-(void) ready:(id) object { + NSDictionary *dict = (NSDictionary *)object; + [[dict objectForKey:@"spinner"] stopAnimating]; + self.weaponsImage = [dict objectForKey:@"image"]; + self.buttonsArray = [dict objectForKey:@"array"]; + [self updateVisuals:nil]; } +-(void) updateVisuals:(NSNotification *) object { + unsigned char *loadout = HW_getAmmoCounts(); + int turns = HW_getTurnsForCurrentTeam(); + + if (self.buttonsArray == nil) { + UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + spinner.hidesWhenStopped = YES; + spinner.center = self.view.center; + [spinner startAnimating]; + [self.view addSubview:spinner]; + [NSThread detachNewThreadSelector:@selector(loadAmmoStuff:) toTarget:self withObject:spinner]; + [spinner release]; + } + + if (loadout == NULL) { + self.view.userInteractionEnabled = NO; + return; + } else + self.view.userInteractionEnabled = YES; + + for (int i = 0; i < HW_getNumberOfWeapons(); i++) { + UIButton *button = [self.buttonsArray objectAtIndex:i]; + if (loadout[i] > 0) { + /*if (button.enabled == NO) { + int x_src = ((i*32)/(int)self.weaponsImage.size.height)*32; + int y_src = (i*32)%(int)self.weaponsImage.size.height; + UIImage *img = [self.weaponsImage cutAt:CGRectMake(x_src, y_src, 32, 32)]; + [button setBackgroundImage:img forState:UIControlStateNormal]; + }*/ + button.enabled = YES; + button.layer.borderColor = [UICOLOR_HW_YELLOW_TEXT CGColor]; + } else { + /*if (button.enabled == YES) { + int x_src = ((i*32)/(int)self.weaponsImage.size.height)*32; + int y_src = (i*32)%(int)self.weaponsImage.size.height; + UIImage *img = [self.weaponsImage cutAt:CGRectMake(x_src, y_src, 32, 32)]; + [button setBackgroundImage:img forState:UIControlStateNormal]; + }*/ + button.enabled = NO; + button.layer.borderColor = [[UIColor darkGrayColor] CGColor]; + //NSLog(@"disabled: %d",button.tag); + } + + if (button.enabled == YES) { + if (delay[i]-turns >= 0) { + // NSLog(@"delayed(%d) %d",delay[i], button.tag); + button.layer.borderColor = [[UIColor lightGrayColor] CGColor]; + [button setTitle:[NSString stringWithFormat:@" %d ",delay[i]-turns+1] forState:UIControlStateNormal]; + } else { + // NSLog(@"enabled %d",button.tag); + button.layer.borderColor = [UICOLOR_HW_YELLOW_TEXT CGColor]; + [button setTitle:@"" forState:UIControlStateNormal]; + } + } + } +} + +#pragma mark - +#pragma mark user interaction -(void) buttonPressed:(id) sender { UIButton *theButton = (UIButton *)sender; HW_setWeapon(theButton.tag); + playSound(@"clickSound"); + [self disappear]; +} + +-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + /* + NSSet *allTouches = [event allTouches]; + + if ([touches count] == 1) { + self.view.layer.borderWidth = 3.5; + startingPoint = [[[allTouches allObjects] objectAtIndex:0] locationInView:self.view]; + } + */ +} + +-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + //self.view.layer.borderWidth = 1.3; } +-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + /* + NSSet *allTouches = [event allTouches]; + + if ([touches count] == 1) { + CGPoint touchedPoint = [[[allTouches allObjects] objectAtIndex:0] locationInView:self.view]; + CGFloat deltaX = touchedPoint.x - startingPoint.x; + CGFloat deltaY = touchedPoint.y - startingPoint.y; + + //startingPoint = touchedPoint; + self.view.frame = CGRectMake(self.view.frame.origin.x + deltaX, self.view.frame.origin.y + deltaY, + self.view.frame.size.width, self.view.frame.size.height); + } + */ +} + +-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + //[self touchesEnded:touches withEvent:event]; +} + +#pragma mark - +#pragma mark memory -(void) didReceiveMemoryWarning { - // Releases the view if it doesn't have a superview. + self.weaponsImage = nil; + self.buttonsArray = nil; + MSG_MEMCLEAN(); [super didReceiveMemoryWarning]; - // Release any cached data, images, etc that aren't in use. } -(void) viewDidUnload { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + self.weaponsImage = nil; + self.buttonsArray = nil; + delay = NULL; + MSG_DIDUNLOAD(); [super viewDidUnload]; - self.imagesArray = nil; } -(void) dealloc { - [imagesArray release]; + [weaponsImage release]; + [buttonsArray release]; [super dealloc]; } +@end -@end +void updateVisualsNewTurn (void) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"updateAmmoVisuals" object:nil]; +} diff -r 8b00b4f93242 -r 1a873262f5dd project_files/HedgewarsMobile/Classes/OverlayViewController.h --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.h Thu Oct 07 02:16:29 2010 +0200 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.h Sat Oct 09 05:57:46 2010 +0200 @@ -24,6 +24,7 @@ @class InGameMenuViewController; @class HelpPageViewController; +@class AmmoMenuViewController; @interface OverlayViewController : UIViewController { // the timer that dims the overlay @@ -37,6 +38,9 @@ // the help menu HelpPageViewController *helpPage; + // the objc ammomenu + AmmoMenuViewController *amvc; + // ths touch section CGFloat initialDistanceForPinching; CGPoint startingPoint; @@ -47,6 +51,7 @@ @property (nonatomic,retain) id popoverController; @property (nonatomic,retain) InGameMenuViewController *popupMenu; @property (nonatomic,retain) HelpPageViewController *helpPage; +@property (nonatomic,retain) AmmoMenuViewController *amvc; -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; diff -r 8b00b4f93242 -r 1a873262f5dd project_files/HedgewarsMobile/Classes/OverlayViewController.m --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m Thu Oct 07 02:16:29 2010 +0200 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sat Oct 09 05:57:46 2010 +0200 @@ -43,7 +43,7 @@ #define removeConfirmationInput() [[self.view viewWithTag:CONFIRMATION_TAG] removeFromSuperview]; @implementation OverlayViewController -@synthesize popoverController, popupMenu, helpPage; +@synthesize popoverController, popupMenu, helpPage, amvc; -(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation { return rotationManager(interfaceOrientation); @@ -162,10 +162,6 @@ [UIView setAnimationDuration:1]; self.view.alpha = 1; [UIView commitAnimations]; - - AmmoMenuViewController *amvc = [[AmmoMenuViewController alloc] init]; - amvc.view.center = self.view.center; - [self.view addSubview:amvc.view]; } -(void) showHelp:(id) sender { @@ -185,6 +181,10 @@ self.popupMenu = nil; if (self.helpPage.view.superview == nil) self.helpPage = nil; + if (((UIPopoverController *)self.popoverController).contentViewController.view.superview == nil) + self.popoverController = nil; + if (self.amvc.view.superview == nil) + self.amvc = nil; MSG_MEMCLEAN(); } @@ -192,6 +192,10 @@ // only objects initialized in viewDidLoad should be here [[NSNotificationCenter defaultCenter] removeObserver:self]; dimTimer = nil; + self.helpPage = nil; + [self dismissPopover]; + self.popoverController = nil; + self.amvc = nil; MSG_DIDUNLOAD(); [super viewDidUnload]; } @@ -200,6 +204,7 @@ [popupMenu release]; [helpPage release]; [popoverController release]; + [amvc release]; // dimTimer is autoreleased [super dealloc]; } @@ -302,6 +307,10 @@ case 10: playSound(@"clickSound"); HW_pause(); + if (amvc.isVisible) { + doDim(); + [amvc disappear]; + } removeConfirmationInput(); [self showPopover]; break; @@ -309,6 +318,19 @@ playSound(@"clickSound"); removeConfirmationInput(); HW_ammoMenu(); + + // TODO: removal and multimonitor experience + if (self.amvc == nil) + self.amvc = [[AmmoMenuViewController alloc] init]; + + if (self.amvc.isVisible) { + doDim(); + [self.amvc disappear]; + } else { + doNotDim(); + [self.amvc appearInView:self.view]; + } + break; default: DLog(@"Nope"); @@ -335,26 +357,26 @@ isPopoverVisible = YES; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - if (popupMenu == nil) - popupMenu = [[InGameMenuViewController alloc] initWithStyle:UITableViewStylePlain]; - if (popoverController == nil) { - popoverController = [[UIPopoverController alloc] initWithContentViewController:popupMenu]; - [popoverController setPopoverContentSize:CGSizeMake(220, 170) animated:YES]; - [popoverController setPassthroughViews:[NSArray arrayWithObject:self.view]]; + if (self.popupMenu == nil) + self.popupMenu = [[InGameMenuViewController alloc] initWithStyle:UITableViewStylePlain]; + if (self.popoverController == nil) { + self.popoverController = [[UIPopoverController alloc] initWithContentViewController:self.popupMenu]; + [self.popoverController setPopoverContentSize:CGSizeMake(220, 170) animated:YES]; + [self.popoverController setPassthroughViews:[NSArray arrayWithObject:self.view]]; } - [popoverController presentPopoverFromRect:CGRectMake(screen.size.height / 2, screen.size.width / 2, 1, 1) + [self.popoverController presentPopoverFromRect:CGRectMake(screen.size.height / 2, screen.size.width / 2, 1, 1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } else { - if (popupMenu == nil) - popupMenu = [[InGameMenuViewController alloc] initWithStyle:UITableViewStyleGrouped]; + if (self.popupMenu == nil) + self.popupMenu = [[InGameMenuViewController alloc] initWithStyle:UITableViewStyleGrouped]; [self.view addSubview:popupMenu.view]; - [popupMenu present]; + [self.popupMenu present]; } - popupMenu.tableView.scrollEnabled = NO; + self.popupMenu.tableView.scrollEnabled = NO; } // on ipad just dismiss it, on iphone transtion to the right @@ -365,10 +387,10 @@ HW_pause(); if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [(InGameMenuViewController *)popoverController.contentViewController removeChat]; - [popoverController dismissPopoverAnimated:YES]; + [(InGameMenuViewController *)[[self popoverController] contentViewController] removeChat]; + [self.popoverController dismissPopoverAnimated:YES]; } else { - [popupMenu dismiss]; + [self.popupMenu dismiss]; } [self buttonReleased:nil]; } @@ -387,6 +409,10 @@ if (isPopoverVisible) [self dismissPopover]; + if (amvc.isVisible) { + doDim(); + [self.amvc disappear]; + } // reset default dimming doDim();