polishing the cocoa ammomenu a little, still requires work
authorkoda
Sat, 09 Oct 2010 05:57:46 +0200
changeset 3933 1a873262f5dd
parent 3930 8b00b4f93242
child 3935 5ca27a0e9a63
polishing the cocoa ammomenu a little, still requires work
hedgewars/PascalExports.pas
project_files/HedgewarsMobile/Classes/AmmoMenuViewController.h
project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m
project_files/HedgewarsMobile/Classes/OverlayViewController.h
project_files/HedgewarsMobile/Classes/OverlayViewController.m
--- 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
--- 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
--- 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];
+}
--- 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;
--- 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();