iOS: Replaced UIViewAlert with custom alert dialog
@@ -10,7 +10,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface AboutController : UIViewController <UIWebViewDelegate, UIAlertViewDelegate>
|
||||
@interface AboutController : UIViewController <UIWebViewDelegate>
|
||||
{
|
||||
NSString* last_link_clicked;
|
||||
UIWebView* webView;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#import "AboutController.h"
|
||||
#import "Utils.h"
|
||||
#import "BlockAlertView.h"
|
||||
|
||||
@implementation AboutController
|
||||
|
||||
@@ -76,24 +77,19 @@
|
||||
{
|
||||
[last_link_clicked release];
|
||||
last_link_clicked = [[[request URL] absoluteString] retain];
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"External Link", @"External Link Alert Title")
|
||||
message:[NSString stringWithFormat:NSLocalizedString(@"Open [%@] in Browser?", @"Open link in browser (with link as parameter)"), last_link_clicked]
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button")
|
||||
otherButtonTitles:NSLocalizedString(@"No", @"No Button"), nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
BlockAlertView *alert = [BlockAlertView alertWithTitle:NSLocalizedString(@"External Link", @"External Link Alert Title")
|
||||
message:[NSString stringWithFormat:NSLocalizedString(@"Open [%@] in Browser?", @"Open link in browser (with link as parameter)"), last_link_clicked]];
|
||||
|
||||
[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK Button") block:^{
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:last_link_clicked]];
|
||||
}];
|
||||
|
||||
[alert show];
|
||||
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark UIAlertView delegate
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (buttonIndex == 0)
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:last_link_clicked]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
@end
|
||||
|
||||
|
||||
@interface BookmarkEditorController : EditorBaseController <UIAlertViewDelegate>
|
||||
@interface BookmarkEditorController : EditorBaseController
|
||||
{
|
||||
@private
|
||||
ComputerBookmark* _bookmark;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#import "PerformanceEditorController.h"
|
||||
#import "CredentialsEditorController.h"
|
||||
#import "AdvancedBookmarkEditorController.h"
|
||||
#import "BlockAlertView.h"
|
||||
|
||||
@implementation BookmarkEditorController
|
||||
|
||||
@@ -338,18 +339,6 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - UIAlertViewDelegate methods
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
// clicked yes?
|
||||
if (buttonIndex == 0)
|
||||
{
|
||||
// cancel bookmark editing and return to previous view controller
|
||||
[[self navigationController] popViewControllerAnimated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Action Handlers
|
||||
|
||||
@@ -363,8 +352,13 @@
|
||||
{
|
||||
if ([[_bookmark label] length] == 0 || [[_params StringForKey:@"hostname"] length] == 0 || [_params intForKey:@"port"] == 0)
|
||||
{
|
||||
UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cancel without saving?", @"Incomplete bookmark error title") message:NSLocalizedString(@"Press 'Cancel' to abort!\nPress 'Continue' to specify the required fields!", @"Incomplete bookmark error message") delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel Button") otherButtonTitles:NSLocalizedString(@"Continue", @"Continue Button"), nil] autorelease];
|
||||
[alertView show];
|
||||
BlockAlertView* alertView = [BlockAlertView alertWithTitle:NSLocalizedString(@"Cancel without saving?", @"Incomplete bookmark error title") message:NSLocalizedString(@"Press 'Cancel' to abort!\nPress 'Continue' to specify the required fields!", @"Incomplete bookmark error message")];
|
||||
[alertView setCancelButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button") block:^{
|
||||
// cancel bookmark editing and return to previous view controller
|
||||
[[self navigationController] popViewControllerAnimated:YES];
|
||||
}];
|
||||
[alertView addButtonWithTitle:NSLocalizedString(@"Continue", @"Continue Button") block:nil];
|
||||
[alertView show];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#import "BookmarkEditorController.h"
|
||||
#import "Reachability.h"
|
||||
|
||||
@interface BookmarkListController : UIViewController <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate, BookmarkEditorDelegate>
|
||||
@interface BookmarkListController : UIViewController <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource, BookmarkEditorDelegate>
|
||||
{
|
||||
// custom bookmark and session table cells
|
||||
BookmarkTableCell* _bmTableCell;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#import "Toast+UIView.h"
|
||||
#import "Reachability.h"
|
||||
#import "GlobalDefaults.h"
|
||||
#import "BlockAlertView.h"
|
||||
|
||||
#define SECTION_SESSIONS 0
|
||||
#define SECTION_BOOKMARKS 1
|
||||
@@ -633,8 +634,17 @@
|
||||
// ask the user if he wants to save the bookmark
|
||||
NSString* title = NSLocalizedString(@"Save Connection Settings?", @"Save connection settings title");
|
||||
NSString* message = NSLocalizedString(@"Your Connection Settings have not been saved. Do you want to save them?", @"Save connection settings message");
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"Yes", @"Yes Button") otherButtonTitles:NSLocalizedString(@"No", @"No Button"), nil];
|
||||
BlockAlertView* alert = [BlockAlertView alertWithTitle:title message:message];
|
||||
[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button") block:^{
|
||||
if (_temporary_bookmark)
|
||||
{
|
||||
[_manual_bookmarks addObject:_temporary_bookmark];
|
||||
[_tableView reloadSections:[NSIndexSet indexSetWithIndex:SECTION_BOOKMARKS] withRowAnimation:UITableViewRowAnimationNone];
|
||||
[_temporary_bookmark autorelease];
|
||||
_temporary_bookmark = nil;
|
||||
}
|
||||
}];
|
||||
[alert show];
|
||||
}
|
||||
}
|
||||
@@ -649,21 +659,6 @@
|
||||
[[self view] makeToast:NSLocalizedString(@"Failed to connect to session!", @"Failed to connect error message") duration:ToastDurationNormal position:@"center"];
|
||||
}
|
||||
|
||||
#pragma mark - UIAlertView delegates
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
// yes clicked?
|
||||
if (buttonIndex == 0 && _temporary_bookmark)
|
||||
{
|
||||
[_manual_bookmarks addObject:_temporary_bookmark];
|
||||
[_tableView reloadSections:[NSIndexSet indexSetWithIndex:SECTION_BOOKMARKS] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
|
||||
[_temporary_bookmark autorelease];
|
||||
_temporary_bookmark = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Reachability notification
|
||||
- (void)reachabilityChanged:(NSNotification*)notification
|
||||
{
|
||||
|
||||
@@ -55,27 +55,4 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark UIWebView callbacks
|
||||
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
|
||||
{
|
||||
if([[request URL] isFileURL])
|
||||
return YES;
|
||||
|
||||
if(navigationType == UIWebViewNavigationTypeLinkClicked)
|
||||
{
|
||||
NSString* lastClickedLink = [[request URL] absoluteString];
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"External Link"
|
||||
message:[NSString stringWithFormat:@"Open [%@] in Browser?", lastClickedLink]
|
||||
delegate:self
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:@"No", nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#import "TouchPointerView.h"
|
||||
#import "AdvancedKeyboardView.h"
|
||||
|
||||
@interface RDPSessionViewController : UIViewController <RDPSessionDelegate, TouchPointerDelegate, AdvancedKeyboardDelegate, RDPKeyboardDelegate, UIScrollViewDelegate, UITextFieldDelegate, UIAlertViewDelegate>
|
||||
@interface RDPSessionViewController : UIViewController <RDPSessionDelegate, TouchPointerDelegate, AdvancedKeyboardDelegate, RDPKeyboardDelegate, UIScrollViewDelegate, UITextFieldDelegate>
|
||||
{
|
||||
// scrollview that hosts the rdp session view
|
||||
IBOutlet UIScrollView* _session_scrollview;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#import "ConnectionParams.h"
|
||||
#import "CredentialsInputController.h"
|
||||
#import "VerifyCertificateController.h"
|
||||
#import "BlockAlertView.h"
|
||||
|
||||
#define TOOLBAR_HEIGHT 30
|
||||
|
||||
@@ -415,8 +416,12 @@
|
||||
|
||||
- (void)showGoProScreen:(RDPSession*)session
|
||||
{
|
||||
UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Pro Version", @"Pro version dialog title")
|
||||
message:NSLocalizedString(@"Do you want to buy Thinstuff RDC Pro and enable the full RDP Experience", @"Pro version dialog message") delegate:self cancelButtonTitle:NSLocalizedString(@"No", @"No Button title") otherButtonTitles:NSLocalizedString(@"Yes", @"Yes button title"), nil] autorelease];
|
||||
BlockAlertView* alertView = [BlockAlertView alertWithTitle:NSLocalizedString(@"Unlicensed Client", @"Pro version dialog title") message:NSLocalizedString(@"You are connected to Thinstuff Remote Desktop Host (RDH). Do you want to purchase an access license for this client which allows you to connect to any computer running Thinstuff RDH?", @"Pro version dialog message")];
|
||||
|
||||
[alertView setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button title") block:nil];
|
||||
[alertView addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes button title") block:^ {
|
||||
}];
|
||||
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
@@ -556,16 +561,20 @@
|
||||
|
||||
- (void)onTransactionSuccess:(NSNotification*)notification
|
||||
{
|
||||
UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transaction Succeeded", @"Pro version bought dialog title")
|
||||
message:NSLocalizedString(@"Thanks for buying Thinstuff RDC Pro. In order for the purchase to take effect please reconnect your current session.", @"Pro version bought dialog message") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button title") otherButtonTitles:nil] autorelease];
|
||||
BlockAlertView* alertView = [BlockAlertView alertWithTitle:NSLocalizedString(@"Transaction Succeeded", @"Pro version bought dialog title")
|
||||
message:NSLocalizedString(@"Thanks for buying Thinstuff RDC Pro. In order for the purchase to take effect please reconnect your current session.", @"Pro version bought dialog message")];
|
||||
[alertView setCancelButtonWithTitle:NSLocalizedString(@"OK", @"OK Button title") block:nil];
|
||||
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
- (void)onTransactionFailed:(NSNotification*)notification
|
||||
{
|
||||
UIAlertView* alertView = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transaction Failed", @"Pro version buy failed dialog title")
|
||||
message:NSLocalizedString(@"The transaction did not complete successfully!", @"Pro version buy failed dialog message") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"OK Button title") otherButtonTitles:nil] autorelease];
|
||||
[alertView show];
|
||||
BlockAlertView* alertView = [BlockAlertView alertWithTitle:NSLocalizedString(@"Transaction Failed", @"Pro version buy failed dialog title")
|
||||
message:NSLocalizedString(@"The transaction did not complete successfully!", @"Pro version buy failed dialog message")];
|
||||
[alertView setCancelButtonWithTitle:NSLocalizedString(@"OK", @"OK Button title") block:nil];
|
||||
|
||||
[alertView show];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
BIN
client/iOS/Resources/alert-black-button.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
client/iOS/Resources/alert-black-button@2x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
client/iOS/Resources/alert-gray-button.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
client/iOS/Resources/alert-gray-button@2x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
client/iOS/Resources/alert-red-button.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
client/iOS/Resources/alert-red-button@2x.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
client/iOS/Resources/alert-window.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
client/iOS/Resources/alert-window@2x.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
28
client/iOS/Views/BlockAlertView.h
Executable file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// BlockAlertView.h
|
||||
//
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BlockAlertView : NSObject {
|
||||
@private
|
||||
UIView *_view;
|
||||
NSMutableArray *_blocks;
|
||||
CGFloat _height;
|
||||
}
|
||||
|
||||
+ (BlockAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message;
|
||||
|
||||
- (id)initWithTitle:(NSString *)title message:(NSString *)message;
|
||||
|
||||
- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block;
|
||||
|
||||
- (void)show;
|
||||
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated;
|
||||
|
||||
@property (nonatomic, readonly) UIView *view;
|
||||
|
||||
@end
|
||||
340
client/iOS/Views/BlockAlertView.m
Executable file
@@ -0,0 +1,340 @@
|
||||
//
|
||||
// BlockAlertView.m
|
||||
//
|
||||
//
|
||||
|
||||
#import "BlockAlertView.h"
|
||||
#import "BlockBackground.h"
|
||||
|
||||
@implementation BlockAlertView
|
||||
|
||||
@synthesize view = _view;
|
||||
|
||||
static UIImage *background = nil;
|
||||
static UIFont *titleFont = nil;
|
||||
static UIFont *messageFont = nil;
|
||||
static UIFont *buttonFont = nil;
|
||||
|
||||
#define kBounce 20
|
||||
#define kBorder 10
|
||||
#define kButtonHeight 44
|
||||
|
||||
#define kAlertFontColor [UIColor colorWithWhite:244.0/255.0 alpha:1.0]
|
||||
|
||||
#define kAlertViewBackground @"alert-window.png"
|
||||
#define kAlertViewBackgroundCapHeight 38
|
||||
|
||||
#pragma mark - init
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [BlockAlertView class])
|
||||
{
|
||||
background = [UIImage imageNamed:kAlertViewBackground];
|
||||
background = [[background stretchableImageWithLeftCapWidth:0 topCapHeight:kAlertViewBackgroundCapHeight] retain];
|
||||
titleFont = [[UIFont boldSystemFontOfSize:20] retain];
|
||||
messageFont = [[UIFont systemFontOfSize:18] retain];
|
||||
buttonFont = [[UIFont boldSystemFontOfSize:18] retain];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BlockAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message
|
||||
{
|
||||
return [[[BlockAlertView alloc] initWithTitle:title message:message] autorelease];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (id)initWithTitle:(NSString *)title message:(NSString *)message
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
BlockBackground* blockBackground = [BlockBackground sharedInstance];
|
||||
[blockBackground sizeToFill];
|
||||
[self setViewTransform:blockBackground forOrientation:blockBackground.orientation];
|
||||
|
||||
CGRect frame = blockBackground.bounds;
|
||||
frame.origin.x = (frame.size.width - background.size.width) * 0.5;
|
||||
frame.size.width = background.size.width;
|
||||
|
||||
_view = [[UIView alloc] initWithFrame:frame];
|
||||
_blocks = [[NSMutableArray alloc] init];
|
||||
_height = kBorder + 15;
|
||||
|
||||
if (title)
|
||||
{
|
||||
CGSize size = [title sizeWithFont:titleFont
|
||||
constrainedToSize:CGSizeMake(frame.size.width-kBorder*2, 1000)
|
||||
lineBreakMode:NSLineBreakByWordWrapping];
|
||||
|
||||
UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(kBorder, _height, frame.size.width-kBorder*2, size.height)];
|
||||
labelView.font = titleFont;
|
||||
labelView.numberOfLines = 0;
|
||||
labelView.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
labelView.textColor = kAlertFontColor;
|
||||
labelView.backgroundColor = [UIColor clearColor];
|
||||
labelView.textAlignment = NSTextAlignmentCenter;
|
||||
labelView.shadowColor = [UIColor blackColor];
|
||||
labelView.shadowOffset = CGSizeMake(0, -1);
|
||||
labelView.text = title;
|
||||
[_view addSubview:labelView];
|
||||
[labelView release];
|
||||
|
||||
_height += size.height + kBorder;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
CGSize size = [message sizeWithFont:messageFont
|
||||
constrainedToSize:CGSizeMake(frame.size.width-kBorder*2, 1000)
|
||||
lineBreakMode:NSLineBreakByWordWrapping];
|
||||
|
||||
UILabel *labelView = [[UILabel alloc] initWithFrame:CGRectMake(kBorder, _height, frame.size.width-kBorder*2, size.height)];
|
||||
labelView.font = messageFont;
|
||||
labelView.numberOfLines = 0;
|
||||
labelView.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
labelView.textColor = kAlertFontColor;
|
||||
labelView.backgroundColor = [UIColor clearColor];
|
||||
labelView.textAlignment = NSTextAlignmentCenter;
|
||||
labelView.shadowColor = [UIColor blackColor];
|
||||
labelView.shadowOffset = CGSizeMake(0, -1);
|
||||
labelView.text = message;
|
||||
[_view addSubview:labelView];
|
||||
[labelView release];
|
||||
|
||||
_height += size.height + kBorder;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_view release];
|
||||
[_blocks release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setViewTransform:(UIView*)view forOrientation:(UIInterfaceOrientation)orientation
|
||||
{
|
||||
switch(orientation)
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
view.transform = CGAffineTransformMakeRotation(0);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
view.transform = CGAffineTransformMakeRotation((-2) *M_PI/2);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
view.transform = CGAffineTransformMakeRotation(M_PI/2);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
view.transform = CGAffineTransformMakeRotation((-1) * M_PI/2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)addButtonWithTitle:(NSString *)title color:(NSString*)color block:(void (^)())block
|
||||
{
|
||||
[_blocks addObject:[NSArray arrayWithObjects:
|
||||
block ? [[block copy] autorelease] : [NSNull null],
|
||||
title,
|
||||
color,
|
||||
nil]];
|
||||
}
|
||||
|
||||
- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"gray" block:block];
|
||||
}
|
||||
|
||||
- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"black" block:block];
|
||||
}
|
||||
|
||||
- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block
|
||||
{
|
||||
[self addButtonWithTitle:title color:@"red" block:block];
|
||||
}
|
||||
|
||||
- (void)show
|
||||
{
|
||||
BOOL isSecondButton = NO;
|
||||
NSUInteger index = 0;
|
||||
for (NSUInteger i = 0; i < _blocks.count; i++)
|
||||
{
|
||||
NSArray *block = [_blocks objectAtIndex:i];
|
||||
NSString *title = [block objectAtIndex:1];
|
||||
NSString *color = [block objectAtIndex:2];
|
||||
|
||||
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"alert-%@-button.png", color]];
|
||||
image = [image stretchableImageWithLeftCapWidth:(int)(image.size.width+1)>>1 topCapHeight:0];
|
||||
|
||||
CGFloat maxHalfWidth = floorf((_view.bounds.size.width-kBorder*3)*0.5);
|
||||
CGFloat width = _view.bounds.size.width-kBorder*2;
|
||||
CGFloat xOffset = kBorder;
|
||||
if (isSecondButton)
|
||||
{
|
||||
width = maxHalfWidth;
|
||||
xOffset = width + kBorder * 2;
|
||||
isSecondButton = NO;
|
||||
}
|
||||
else if (i + 1 < _blocks.count)
|
||||
{
|
||||
// In this case there's another button.
|
||||
// Let's check if they fit on the same line.
|
||||
CGSize size = [title sizeWithFont:buttonFont
|
||||
minFontSize:10
|
||||
actualFontSize:nil
|
||||
forWidth:_view.bounds.size.width-kBorder*2
|
||||
lineBreakMode:NSLineBreakByClipping];
|
||||
|
||||
if (size.width < maxHalfWidth - kBorder)
|
||||
{
|
||||
// It might fit. Check the next Button
|
||||
NSArray *block2 = [_blocks objectAtIndex:i+1];
|
||||
NSString *title2 = [block2 objectAtIndex:1];
|
||||
size = [title2 sizeWithFont:buttonFont
|
||||
minFontSize:10
|
||||
actualFontSize:nil
|
||||
forWidth:_view.bounds.size.width-kBorder*2
|
||||
lineBreakMode:NSLineBreakByClipping];
|
||||
|
||||
if (size.width < maxHalfWidth - kBorder)
|
||||
{
|
||||
// They'll fit!
|
||||
isSecondButton = YES; // For the next iteration
|
||||
width = maxHalfWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
button.frame = CGRectMake(xOffset, _height, width, kButtonHeight);
|
||||
button.titleLabel.font = buttonFont;
|
||||
if ([button.titleLabel respondsToSelector:@selector(setMinimumScaleFactor:)])
|
||||
button.titleLabel.minimumScaleFactor = 10;
|
||||
button.titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
button.titleLabel.shadowOffset = CGSizeMake(0, -1);
|
||||
button.backgroundColor = [UIColor clearColor];
|
||||
button.tag = i+1;
|
||||
|
||||
[button setBackgroundImage:image forState:UIControlStateNormal];
|
||||
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
[button setTitle:title forState:UIControlStateNormal];
|
||||
button.accessibilityLabel = title;
|
||||
|
||||
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[_view addSubview:button];
|
||||
|
||||
if (!isSecondButton)
|
||||
_height += kButtonHeight + kBorder;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
CGRect frame = _view.frame;
|
||||
frame.origin.y = - _height;
|
||||
frame.size.height = _height;
|
||||
_view.frame = frame;
|
||||
|
||||
UIImageView *modalBackground = [[UIImageView alloc] initWithFrame:_view.bounds];
|
||||
modalBackground.image = background;
|
||||
modalBackground.contentMode = UIViewContentModeScaleToFill;
|
||||
[_view insertSubview:modalBackground atIndex:0];
|
||||
[modalBackground release];
|
||||
|
||||
[[BlockBackground sharedInstance] addToMainWindow:_view];
|
||||
|
||||
__block CGPoint center = _view.center;
|
||||
center.y = floorf([BlockBackground sharedInstance].bounds.size.height * 0.5) + kBounce;
|
||||
|
||||
[UIView animateWithDuration:0.4
|
||||
delay:0.0
|
||||
options:UIViewAnimationOptionCurveEaseOut
|
||||
animations:^{
|
||||
[BlockBackground sharedInstance].alpha = 1.0f;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[UIView animateWithDuration:0.1
|
||||
delay:0.0
|
||||
options:0
|
||||
animations:^{
|
||||
center.y -= kBounce;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:nil];
|
||||
}];
|
||||
|
||||
[self retain];
|
||||
}
|
||||
|
||||
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
|
||||
{
|
||||
if (buttonIndex >= 0 && buttonIndex < [_blocks count])
|
||||
{
|
||||
id obj = [[_blocks objectAtIndex: buttonIndex] objectAtIndex:0];
|
||||
if (![obj isEqual:[NSNull null]])
|
||||
{
|
||||
((void (^)())obj)();
|
||||
}
|
||||
}
|
||||
|
||||
if (animated)
|
||||
{
|
||||
[UIView animateWithDuration:0.1
|
||||
delay:0.0
|
||||
options:0
|
||||
animations:^{
|
||||
CGPoint center = _view.center;
|
||||
center.y += 20;
|
||||
_view.center = center;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[UIView animateWithDuration:0.4
|
||||
delay:0.0
|
||||
options:UIViewAnimationOptionCurveEaseIn
|
||||
animations:^{
|
||||
CGRect frame = _view.frame;
|
||||
frame.origin.y = -frame.size.height;
|
||||
_view.frame = frame;
|
||||
[[BlockBackground sharedInstance] reduceAlphaIfEmpty];
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[[BlockBackground sharedInstance] removeView:_view];
|
||||
[_view release]; _view = nil;
|
||||
[self autorelease];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[BlockBackground sharedInstance] removeView:_view];
|
||||
[_view release]; _view = nil;
|
||||
[self autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Action
|
||||
|
||||
- (void)buttonClicked:(id)sender
|
||||
{
|
||||
/* Run the button's block */
|
||||
int buttonIndex = [sender tag] - 1;
|
||||
[self dismissWithClickedButtonIndex:buttonIndex animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
24
client/iOS/Views/BlockBackground.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// BlockBackground.h
|
||||
// arrived
|
||||
//
|
||||
// Created by Gustavo Ambrozio on 29/11/11.
|
||||
// Copyright (c) 2011 N/A. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BlockBackground : UIWindow
|
||||
|
||||
+ (BlockBackground *) sharedInstance;
|
||||
|
||||
- (void)addToMainWindow:(UIView *)view;
|
||||
- (void)reduceAlphaIfEmpty;
|
||||
- (void)removeView:(UIView *)view;
|
||||
|
||||
- (UIInterfaceOrientation)orientation;
|
||||
- (CGFloat)statusBarHeight;
|
||||
|
||||
- (void)sizeToFill;
|
||||
|
||||
@end
|
||||
160
client/iOS/Views/BlockBackground.m
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// BlockBackground.m
|
||||
// arrived
|
||||
//
|
||||
// Created by Gustavo Ambrozio on 29/11/11.
|
||||
// Copyright (c) 2011 N/A. All rights reserved.
|
||||
//
|
||||
#import <math.h>
|
||||
#import "BlockBackground.h"
|
||||
|
||||
@implementation BlockBackground
|
||||
|
||||
static BlockBackground *_sharedInstance = nil;
|
||||
|
||||
+ (BlockBackground*)sharedInstance
|
||||
{
|
||||
if (_sharedInstance != nil) {
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
@synchronized(self) {
|
||||
if (_sharedInstance == nil) {
|
||||
[[[self alloc] init] autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
+ (id)allocWithZone:(NSZone*)zone
|
||||
{
|
||||
@synchronized(self) {
|
||||
if (_sharedInstance == nil) {
|
||||
_sharedInstance = [super allocWithZone:zone];
|
||||
return _sharedInstance;
|
||||
}
|
||||
}
|
||||
NSAssert(NO, @ "[BlockBackground alloc] explicitly called on singleton class.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone*)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)retain
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned)retainCount
|
||||
{
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
- (oneway void)release
|
||||
{
|
||||
}
|
||||
|
||||
- (id)autorelease
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sizeToFill
|
||||
{
|
||||
UIInterfaceOrientation o = [self orientation];
|
||||
|
||||
if(UIInterfaceOrientationIsPortrait(o))
|
||||
{
|
||||
CGRect r = [[UIScreen mainScreen] applicationFrame];
|
||||
|
||||
CGFloat portraitHeight = [[UIScreen mainScreen] bounds].size.height;
|
||||
CGFloat portraitWidth = [[UIScreen mainScreen] bounds].size.width;
|
||||
|
||||
CGFloat center_y = (r.size.height / 2) + [self statusBarHeight];
|
||||
CGFloat center_x = (r.size.width / 2);
|
||||
|
||||
self.bounds = CGRectMake(0, 0, portraitWidth, portraitHeight);
|
||||
self.center = CGPointMake(center_x, center_y);
|
||||
}
|
||||
else if(UIInterfaceOrientationIsLandscape(o))
|
||||
{
|
||||
CGFloat landscapeHeight = [[UIScreen mainScreen] bounds].size.height;
|
||||
CGFloat landscapeWidth = [[UIScreen mainScreen] bounds].size.width;
|
||||
CGFloat center_y = (landscapeHeight/2);
|
||||
CGFloat center_x = (landscapeWidth / 2);
|
||||
|
||||
self.bounds = CGRectMake(0, 0, landscapeHeight, landscapeWidth);
|
||||
self.center = CGPointMake(center_x, center_y);
|
||||
}
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithFrame:[[UIScreen mainScreen] applicationFrame]];
|
||||
if (self) {
|
||||
self.windowLevel = UIWindowLevelStatusBar;
|
||||
self.hidden = YES;
|
||||
self.userInteractionEnabled = NO;
|
||||
self.backgroundColor = [UIColor colorWithWhite:0.4 alpha:0.5f];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)orientation
|
||||
{
|
||||
return [UIApplication sharedApplication].statusBarOrientation;
|
||||
}
|
||||
|
||||
- (CGFloat)statusBarHeight
|
||||
{
|
||||
CGSize statusBarSize =[[UIApplication sharedApplication] statusBarFrame].size;
|
||||
return MIN(statusBarSize.height, statusBarSize.width);
|
||||
}
|
||||
|
||||
- (void)addToMainWindow:(UIView *)view
|
||||
{
|
||||
if (self.hidden)
|
||||
{
|
||||
self.alpha = 0.0f;
|
||||
self.hidden = NO;
|
||||
self.userInteractionEnabled = YES;
|
||||
[self makeKeyAndVisible];
|
||||
}
|
||||
|
||||
if (self.subviews.count > 0)
|
||||
{
|
||||
((UIView*)[self.subviews lastObject]).userInteractionEnabled = NO;
|
||||
}
|
||||
|
||||
[self addSubview:view];
|
||||
}
|
||||
|
||||
- (void)reduceAlphaIfEmpty
|
||||
{
|
||||
if (self.subviews.count == 1)
|
||||
{
|
||||
self.alpha = 0.0f;
|
||||
// 20120907JY - disabling this user interaction can cause issues with fast taps when showing alerts - thanks for finding Anagd.
|
||||
// self.userInteractionEnabled = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeView:(UIView *)view
|
||||
{
|
||||
[view removeFromSuperview];
|
||||
if (self.subviews.count == 0)
|
||||
{
|
||||
self.hidden = YES;
|
||||
[self resignKeyWindow];
|
||||
}
|
||||
else
|
||||
{
|
||||
((UIView*)[self.subviews lastObject]).userInteractionEnabled = YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||