diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2013-03-16 02:03:13 +0400 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2013-03-16 02:03:13 +0400 |
commit | 47bf012ab71a87732ce62c04951cd3f3503e8a1f (patch) | |
tree | 9c8977c9d025c525209a94944fd4b59d10bc34b4 | |
parent | c497749766fb0676d19bb4726ff736c6e0132719 (diff) |
MUActionSheet: add homegrown action sheet that works better in a popover.
18 files changed, 1027 insertions, 17 deletions
diff --git a/Mumble.xcodeproj/project.pbxproj b/Mumble.xcodeproj/project.pbxproj index b37f253..3bcbd74 100755 --- a/Mumble.xcodeproj/project.pbxproj +++ b/Mumble.xcodeproj/project.pbxproj @@ -111,6 +111,9 @@ 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 28ADA303148A3E3B00C55E51 /* MUAudioQualityPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28ADA302148A3E3B00C55E51 /* MUAudioQualityPreferencesViewController.m */; }; 28BF81D2139AFFD50078B722 /* MUCertificateDiskImportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28BF81D1139AFFD50078B722 /* MUCertificateDiskImportViewController.m */; }; + 28C1034716EFB1C100DECE08 /* MUActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C1034216EFB1C100DECE08 /* MUActionSheet.m */; }; + 28C1034816EFB1C100DECE08 /* MUActionSheetBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C1034416EFB1C100DECE08 /* MUActionSheetBackgroundView.m */; }; + 28C1034916EFB1C100DECE08 /* MUActionSheetButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C1034616EFB1C100DECE08 /* MUActionSheetButton.m */; }; 28C6EF0A11BBF38100E426C8 /* MUCountryServerListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C6EF0911BBF38100E426C8 /* MUCountryServerListController.m */; }; 28D963961639B9E4002A9E73 /* IconPad.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D963951639B9E4002A9E73 /* IconPad.png */; }; 28D963981639B9E8002A9E73 /* IconPad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 28D963971639B9E8002A9E73 /* IconPad@2x.png */; }; @@ -383,6 +386,12 @@ 28ADA302148A3E3B00C55E51 /* MUAudioQualityPreferencesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUAudioQualityPreferencesViewController.m; sourceTree = "<group>"; }; 28BF81D0139AFFD50078B722 /* MUCertificateDiskImportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUCertificateDiskImportViewController.h; sourceTree = "<group>"; }; 28BF81D1139AFFD50078B722 /* MUCertificateDiskImportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUCertificateDiskImportViewController.m; sourceTree = "<group>"; }; + 28C1034116EFB1C100DECE08 /* MUActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUActionSheet.h; sourceTree = "<group>"; }; + 28C1034216EFB1C100DECE08 /* MUActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUActionSheet.m; sourceTree = "<group>"; }; + 28C1034316EFB1C100DECE08 /* MUActionSheetBackgroundView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUActionSheetBackgroundView.h; sourceTree = "<group>"; }; + 28C1034416EFB1C100DECE08 /* MUActionSheetBackgroundView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUActionSheetBackgroundView.m; sourceTree = "<group>"; }; + 28C1034516EFB1C100DECE08 /* MUActionSheetButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUActionSheetButton.h; sourceTree = "<group>"; }; + 28C1034616EFB1C100DECE08 /* MUActionSheetButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUActionSheetButton.m; sourceTree = "<group>"; }; 28C6EF0911BBF38100E426C8 /* MUCountryServerListController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUCountryServerListController.m; sourceTree = "<group>"; }; 28D963951639B9E4002A9E73 /* IconPad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = IconPad.png; sourceTree = "<group>"; }; 28D963971639B9E8002A9E73 /* IconPad@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "IconPad@2x.png"; sourceTree = "<group>"; }; @@ -564,6 +573,7 @@ 2872F7C4124668880078C0B1 /* Certificates */, 28BF8E1C11D93A1900B72770 /* Database */, 2838EA0C1293165700035C5D /* Preferences */, + 28C1033F16EFB1B500DECE08 /* MUActionSheet */, 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 286A3CAE158CEB5A00C817D1 /* MainWindow~iPad.xib */, 2861C25D116BE905002B8514 /* MUApplicationDelegate.h */, @@ -809,6 +819,19 @@ name = Database; sourceTree = "<group>"; }; + 28C1033F16EFB1B500DECE08 /* MUActionSheet */ = { + isa = PBXGroup; + children = ( + 28C1034116EFB1C100DECE08 /* MUActionSheet.h */, + 28C1034216EFB1C100DECE08 /* MUActionSheet.m */, + 28C1034316EFB1C100DECE08 /* MUActionSheetBackgroundView.h */, + 28C1034416EFB1C100DECE08 /* MUActionSheetBackgroundView.m */, + 28C1034516EFB1C100DECE08 /* MUActionSheetButton.h */, + 28C1034616EFB1C100DECE08 /* MUActionSheetButton.m */, + ); + name = MUActionSheet; + sourceTree = "<group>"; + }; 28DC1C1213DE59120037CDC2 /* Resources */ = { isa = PBXGroup; children = ( @@ -1352,6 +1375,9 @@ 28F9E1BF15EBDF2400D52001 /* MURemoteControlServer.m in Sources */, 2813B1D115EBFDA90049A59A /* MURemoteControlPreferencesViewController.m in Sources */, 285D6B7116BEEFA700F239EB /* MUTextMessageProcessor.m in Sources */, + 28C1034716EFB1C100DECE08 /* MUActionSheet.m in Sources */, + 28C1034816EFB1C100DECE08 /* MUActionSheetBackgroundView.m in Sources */, + 28C1034916EFB1C100DECE08 /* MUActionSheetButton.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetBackgroundView.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetBackgroundView.pcvd Binary files differnew file mode 100644 index 0000000..0fc78e5 --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetBackgroundView.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonBlueHighlight.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonBlueHighlight.pcvd Binary files differnew file mode 100644 index 0000000..ed8fec8 --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonBlueHighlight.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonCancel.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonCancel.pcvd Binary files differnew file mode 100644 index 0000000..3b9efc6 --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonCancel.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonConstructive.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonConstructive.pcvd Binary files differnew file mode 100644 index 0000000..82a64ec --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonConstructive.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonDestructive.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonDestructive.pcvd Binary files differnew file mode 100644 index 0000000..fc92e22 --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonDestructive.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonGrayHighlight.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonGrayHighlight.pcvd Binary files differnew file mode 100644 index 0000000..680af64 --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonGrayHighlight.pcvd diff --git a/Resources/UIElements/MUActionSheet/MUActionSheetButtonNormal.pcvd b/Resources/UIElements/MUActionSheet/MUActionSheetButtonNormal.pcvd Binary files differnew file mode 100644 index 0000000..f02c56a --- /dev/null +++ b/Resources/UIElements/MUActionSheet/MUActionSheetButtonNormal.pcvd diff --git a/Source/Classes/MUActionSheet.h b/Source/Classes/MUActionSheet.h new file mode 100644 index 0000000..157c85b --- /dev/null +++ b/Source/Classes/MUActionSheet.h @@ -0,0 +1,19 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#import <Foundation/Foundation.h> + +@class MUActionSheet; + +@protocol MUActionSheetDelegate +- (void) actionSheet:(MUActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex; +@end + +@interface MUActionSheet : NSObject +- (id) initWithTitle:(NSString *)title delegate:(id<MUActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle constructiveButtonTitle:(NSString *)constructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; +- (void) showInViewController:(UIViewController *)viewController; +- (NSInteger) destructiveButtonIndex; +- (NSInteger) constructiveButtonIndex; +- (NSInteger) cancelButtonIndex; +@end diff --git a/Source/Classes/MUActionSheet.m b/Source/Classes/MUActionSheet.m new file mode 100644 index 0000000..cdbfba8 --- /dev/null +++ b/Source/Classes/MUActionSheet.m @@ -0,0 +1,310 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#import "MUActionSheet.h" +#import "MUActionSheetBackgroundView.h" +#import "MUActionSheetButton.h" + +@interface MUActionSheet () { + UIView *_fadeView; + MUActionSheetBackgroundView *_bgView; + UIViewController *_viewController; + NSString *_title; + + NSMutableArray *_otherButtons; + + MUActionSheetButton *_cancelButton; + NSInteger _cancelButtonIndex; + + MUActionSheetButton *_destructiveButton; + NSInteger _destructiveButtonIndex; + + MUActionSheetButton *_constructiveButton; + NSInteger _constructiveButtonIndex; + + BOOL _shouldReenableScroll; + + UIBarButtonItem *_oldLeftBarButtonItem; + UIBarButtonItem *_oldRightBarButtonItem; + + NSArray *_oldViewGestureRecognizers; + + id<MUActionSheetDelegate> _delegate; +} +@end + +@implementation MUActionSheet + +- (id) initWithTitle:(NSString *)title delegate:(id<MUActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle constructiveButtonTitle:(NSString *)constructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... { + if ((self = [super init])) { + _delegate = delegate; + _title = [title copy]; + + _otherButtons = [[NSMutableArray alloc] init]; + NSInteger idx = 0; + + { + va_list args; + va_start(args, otherButtonTitles); + for (NSString *title = otherButtonTitles; title != nil; title = va_arg(args, NSString *)) { + MUActionSheetButton *btn = [MUActionSheetButton buttonWithKind:MUActionSheetButtonKindNormal]; + [btn setTitle:title]; + [btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [_otherButtons addObject:btn]; + + idx++; + } + } + + _cancelButton = [[MUActionSheetButton buttonWithKind:MUActionSheetButtonKindCancel] retain]; + [_cancelButton setTitle:cancelButtonTitle ? cancelButtonTitle : @"Cancel"]; + [_cancelButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + _cancelButtonIndex = idx++; + + if (constructiveButtonTitle) { + _constructiveButton = [[MUActionSheetButton buttonWithKind:MUActionSheetButtonKindConstructive] retain]; + [_constructiveButton setTitle:constructiveButtonTitle]; + [_constructiveButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + _constructiveButtonIndex = idx++; + } else { + _constructiveButtonIndex = -1; + } + + if (destructiveButtonTitle) { + _destructiveButton = [[MUActionSheetButton buttonWithKind:MUActionSheetButtonKindDestructive] retain]; + [_destructiveButton setTitle:destructiveButtonTitle]; + [_destructiveButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; + _destructiveButtonIndex = idx++; + } else { + _destructiveButtonIndex = -1; + } + } + return self; +} + +- (void) dealloc { + [_title release]; + [_fadeView release]; + [_bgView release]; + [_otherButtons release]; + [_destructiveButton release]; + [_constructiveButton release]; + [_cancelButton release]; + + [super dealloc]; +} + +- (NSInteger) cancelButtonIndex { + return _cancelButtonIndex; +} + +- (NSInteger) destructiveButtonIndex { + return _destructiveButtonIndex; +} + +- (NSInteger) constructiveButtonIndex { + return _constructiveButtonIndex; +} + +- (void) buttonClicked:(id)sender { + NSInteger idx = -1; + if (sender == _cancelButton) { + idx = _cancelButtonIndex; + } else if (sender == _constructiveButton) { + idx = _constructiveButtonIndex; + } else if (sender == _destructiveButton) { + idx = _destructiveButtonIndex; + } else { + idx = [_otherButtons indexOfObject:sender]; + } + [self removeViewAndPerformBlock:^{ + [_delegate actionSheet:self didDismissWithButtonIndex:idx]; + }]; +} + +- (void) showInViewController:(UIViewController *)viewController { + _viewController = viewController; + [self addView]; +} + +- (void) hideNavigationItemButtons { + [_viewController.navigationItem setHidesBackButton:YES animated:YES]; + _oldLeftBarButtonItem = [[_viewController.navigationItem leftBarButtonItem] retain]; + [_viewController.navigationItem setLeftBarButtonItem:nil animated:YES]; + _oldRightBarButtonItem = [[_viewController.navigationItem rightBarButtonItem] retain]; + [_viewController.navigationItem setRightBarButtonItem:nil animated:YES]; +} + +- (void) showNavigationItemButtons { + [_viewController.navigationItem setHidesBackButton:NO animated:YES]; + [_viewController.navigationItem setRightBarButtonItem:_oldRightBarButtonItem animated:YES]; + [_oldRightBarButtonItem release]; + [_viewController.navigationItem setLeftBarButtonItem:_oldLeftBarButtonItem animated:NO]; + [_oldLeftBarButtonItem release]; +} + +- (CGFloat) _viewHeightForTitleLabelHeight:(CGFloat)titleHeight { + CGFloat padding = 10; + CGFloat buttonHeight = 48; + CGFloat viewHeight = 0; + + if (titleHeight > 0) { + viewHeight += 1; + } + + // Title adjustment + viewHeight += padding + titleHeight + padding; + + // Group buttons (without cancel button) + NSInteger numButtons = [_otherButtons count]; + if (_destructiveButton) { + numButtons++; + } + if (_constructiveButton) { + numButtons++; + } + viewHeight += ((buttonHeight + padding) * numButtons); + + // Cancel button + viewHeight += padding + buttonHeight + 2*padding; + + return viewHeight; +} + +- (void) addView { + const CGFloat padding = 10; + + // Add a reference, so consumers of + // the MUActionSheet can release it as soon + // it is shown, just like UIActionSheet. + [self retain]; + + // Disable scrolling if we're added to something + // that looks like a UIScrollView. + CGPoint scrollViewOffset = CGPointMake(0, 0); + if ([_viewController.view respondsToSelector:@selector(isScrollEnabled)]) { + UIScrollView *scrollView = (UIScrollView *)_viewController.view; + _shouldReenableScroll = [scrollView isScrollEnabled]; + [scrollView setScrollEnabled:NO]; + + scrollViewOffset = [scrollView contentOffset]; + } + + // Store the the gesture recognizers on the view controller's view. + // Gesture recognizers pass through even though we set exclusiveTouch + // on our action sheet UI elements. + _oldViewGestureRecognizers = [[[_viewController view] gestureRecognizers] retain]; + [[_viewController view] setGestureRecognizers:nil]; + + CGFloat titleLabelHeight = 0; + UILabel *titleLabel = nil; + if (_title) { + titleLabel = [[UILabel alloc] init]; + titleLabel.text = _title; + titleLabel.font = [UIFont systemFontOfSize:[UIFont systemFontSize]]; + titleLabel.textAlignment = NSTextAlignmentCenter; + titleLabel.textColor = [UIColor whiteColor]; + titleLabel.shadowColor = [UIColor blackColor]; + titleLabel.shadowOffset = CGSizeMake(0, -1); + titleLabel.opaque = NO; + titleLabel.backgroundColor = [UIColor clearColor]; + + CGRect textRect = [titleLabel textRectForBounds:CGRectMake(0, 0, 320, 640) limitedToNumberOfLines:1]; + titleLabelHeight = textRect.size.height; + } + + CGFloat viewHeight = [self _viewHeightForTitleLabelHeight:titleLabelHeight]; + + _fadeView = [[[UIView alloc] initWithFrame:_viewController.view.frame] autorelease]; + _fadeView.backgroundColor = [UIColor clearColor]; + [_fadeView setExclusiveTouch:YES]; + + _bgView = [[[MUActionSheetBackgroundView alloc] initWithFrame:CGRectMake(0, _viewController.view.frame.size.height, 320, viewHeight)] autorelease]; + [_bgView setExclusiveTouch:YES]; + + [_viewController.view addSubview:_fadeView]; + [_viewController.view addSubview:_bgView]; + + __block CGFloat ofs = padding; + + if (titleLabel) { + ofs += 1; + [titleLabel setFrame:CGRectMake(0, ofs, 320, titleLabelHeight)]; + [_bgView addSubview:titleLabel]; + } + + ofs += titleLabelHeight + padding; + + // Destructive button + if (_destructiveButton) { + [_destructiveButton setFrame:CGRectMake(20, ofs, 280, 48)]; + [_bgView addSubview:_destructiveButton]; + ofs += 48 + padding; + } + + [_otherButtons enumerateObjectsWithOptions:0 usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + MUActionSheetButton *btn = (MUActionSheetButton *)obj; + [btn setFrame:CGRectMake(20, ofs, 280, 48)]; + [_bgView addSubview:btn]; + ofs += 48 + padding; + }]; + + // Constructive button + if (_constructiveButton) { + [_constructiveButton setFrame:CGRectMake(20, ofs, 280, 48)]; + [_bgView addSubview:_constructiveButton]; + ofs += 48 + padding; + } + + // Cancel button + ofs += padding; + [_cancelButton setFrame:CGRectMake(20, ofs, 280, 48)]; + [_bgView addSubview:_cancelButton]; + + // Store old UINavigationItem button state + [self hideNavigationItemButtons]; + + __block UIView *parentView = _viewController.view; + [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{ + _bgView.frame = CGRectMake(0, (parentView.frame.size.height + scrollViewOffset.y) - viewHeight, 320, viewHeight); + [_bgView layoutIfNeeded]; + _fadeView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4f]; + } completion:^(BOOL isfinished) { + // ... + }]; +} + +- (void) removeViewAndPerformBlock:(void(^)())doneBlock { + __block UIView *parentView = _viewController.view; + + // Restore UINavigationItem button state. + [self showNavigationItemButtons]; + + [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{ + _bgView.frame = CGRectMake(0, parentView.frame.size.height, 320, _bgView.frame.size.height); + _fadeView.backgroundColor = [UIColor clearColor]; + } completion:^(BOOL finished) { + [_bgView removeFromSuperview]; + _bgView = nil; + [_fadeView removeFromSuperview]; + _fadeView = nil; + doneBlock(); + + // Check if we should try to re-enable scrolling. + if (_shouldReenableScroll) { + UIScrollView *scrollView = (UIScrollView *)_viewController.view; + [scrollView setScrollEnabled:YES]; + } + + // Restore the view's gesture recognizers. + [[_viewController view] setGestureRecognizers:_oldViewGestureRecognizers]; + [_oldViewGestureRecognizers release]; + + // Release the reference we added when + // showing the MUActionSheet. + [self release]; + }]; +} + +@end diff --git a/Source/Classes/MUActionSheetBackgroundView.h b/Source/Classes/MUActionSheetBackgroundView.h new file mode 100644 index 0000000..90fda56 --- /dev/null +++ b/Source/Classes/MUActionSheetBackgroundView.h @@ -0,0 +1,6 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +@interface MUActionSheetBackgroundView : UIView +@end diff --git a/Source/Classes/MUActionSheetBackgroundView.m b/Source/Classes/MUActionSheetBackgroundView.m new file mode 100644 index 0000000..83e1200 --- /dev/null +++ b/Source/Classes/MUActionSheetBackgroundView.m @@ -0,0 +1,114 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#import "MUActionSheetBackgroundView.h" + +@implementation MUActionSheetBackgroundView + +- (id) initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + // ... + } + return self; +} + +// Drawing code generated using 'Resources/UIElements/MUActionSheet/MUActionSheetBackgroundView.pcvd' +- (void)drawRect:(CGRect)rect { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* fillColor = [UIColor colorWithRed: 0.365 green: 0.365 blue: 0.365 alpha: 1]; + UIColor* strokeColor = [UIColor colorWithRed: 0.125 green: 0.125 blue: 0.125 alpha: 1]; + UIColor* shadowColor2 = [UIColor colorWithRed: 0.541 green: 0.541 blue: 0.541 alpha: 1]; + UIColor* gradientColor = [UIColor colorWithRed: 0.063 green: 0.063 blue: 0.063 alpha: 1]; + UIColor* gradientColor2 = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)fillColor.CGColor, + (id)[UIColor colorWithRed: 0.245 green: 0.245 blue: 0.245 alpha: 1].CGColor, + (id)strokeColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + NSArray* gradient2Colors = [NSArray arrayWithObjects: + (id)gradientColor.CGColor, + (id)[UIColor colorWithRed: 0.031 green: 0.031 blue: 0.031 alpha: 1].CGColor, + (id)gradientColor2.CGColor, nil]; + CGFloat gradient2Locations[] = {0, 0.89, 1}; + CGGradientRef gradient2 = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradient2Colors, gradient2Locations); + + //// Shadow Declarations + UIColor* shadow = shadowColor2; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + //// Background Drawing + UIBezierPath* backgroundPath = [UIBezierPath bezierPathWithRect: CGRectMake(CGRectGetMinX(frame) + floor((CGRectGetWidth(frame)) * 0.00000 + 0.5), CGRectGetMinY(frame), CGRectGetWidth(frame) - floor((CGRectGetWidth(frame)) * 0.00000 + 0.5), CGRectGetHeight(frame))]; + [[UIColor blackColor] setFill]; + [backgroundPath fill]; + + + //// BottomTopGradient Drawing + CGRect bottomTopGradientRect = CGRectMake(CGRectGetMinX(frame) + floor(CGRectGetWidth(frame) * 0.00000 + 0.5), CGRectGetMinY(frame) + 22, floor(CGRectGetWidth(frame) * 1.00000 + 0.5) - floor(CGRectGetWidth(frame) * 0.00000 + 0.5), 21); + UIBezierPath* bottomTopGradientPath = [UIBezierPath bezierPathWithRect: bottomTopGradientRect]; + CGContextSaveGState(context); + [bottomTopGradientPath addClip]; + CGContextDrawLinearGradient(context, gradient2, + CGPointMake(CGRectGetMidX(bottomTopGradientRect), CGRectGetMinY(bottomTopGradientRect)), + CGPointMake(CGRectGetMidX(bottomTopGradientRect), CGRectGetMaxY(bottomTopGradientRect)), + 0); + CGContextRestoreGState(context); + + + //// TopTopGradient Drawing + CGRect topTopGradientRect = CGRectMake(CGRectGetMinX(frame) + floor((CGRectGetWidth(frame)) * 0.00000 + 0.5), CGRectGetMinY(frame) + 1, CGRectGetWidth(frame) - floor((CGRectGetWidth(frame)) * 0.00000 + 0.5), 21); + UIBezierPath* topTopGradientPath = [UIBezierPath bezierPathWithRect: topTopGradientRect]; + CGContextSaveGState(context); + [topTopGradientPath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(topTopGradientRect), CGRectGetMinY(topTopGradientRect)), + CGPointMake(CGRectGetMidX(topTopGradientRect), CGRectGetMaxY(topTopGradientRect)), + 0); + CGContextRestoreGState(context); + + ////// TopTopGradient Inner Shadow + CGRect topTopGradientBorderRect = CGRectInset([topTopGradientPath bounds], -shadowBlurRadius, -shadowBlurRadius); + topTopGradientBorderRect = CGRectOffset(topTopGradientBorderRect, -shadowOffset.width, -shadowOffset.height); + topTopGradientBorderRect = CGRectInset(CGRectUnion(topTopGradientBorderRect, [topTopGradientPath bounds]), -1, -1); + + UIBezierPath* topTopGradientNegativePath = [UIBezierPath bezierPathWithRect: topTopGradientBorderRect]; + [topTopGradientNegativePath appendPath: topTopGradientPath]; + topTopGradientNegativePath.usesEvenOddFillRule = YES; + + CGContextSaveGState(context); + { + CGFloat xOffset = shadowOffset.width + round(topTopGradientBorderRect.size.width); + CGFloat yOffset = shadowOffset.height; + CGContextSetShadowWithColor(context, + CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)), + shadowBlurRadius, + shadow.CGColor); + + [topTopGradientPath addClip]; + CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(topTopGradientBorderRect.size.width), 0); + [topTopGradientNegativePath applyTransform: transform]; + [[UIColor grayColor] setFill]; + [topTopGradientNegativePath fill]; + } + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGGradientRelease(gradient2); + CGColorSpaceRelease(colorSpace); +} + +@end diff --git a/Source/Classes/MUActionSheetButton.h b/Source/Classes/MUActionSheetButton.h new file mode 100644 index 0000000..a21d668 --- /dev/null +++ b/Source/Classes/MUActionSheetButton.h @@ -0,0 +1,16 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +typedef enum { + MUActionSheetButtonKindNormal, + MUActionSheetButtonKindCancel, + MUActionSheetButtonKindDestructive, + MUActionSheetButtonKindConstructive, +} MUActionSheetButtonKind; + +@interface MUActionSheetButton : UIControl ++ (MUActionSheetButton *) buttonWithKind:(MUActionSheetButtonKind)kind; +- (NSString *) title; +- (void) setTitle:(NSString *)title; +@end diff --git a/Source/Classes/MUActionSheetButton.m b/Source/Classes/MUActionSheetButton.m new file mode 100644 index 0000000..e3633d0 --- /dev/null +++ b/Source/Classes/MUActionSheetButton.m @@ -0,0 +1,517 @@ +// Copyright 2013 The 'Mumble for iOS' Developers. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#import "MUActionSheetButton.h" + +@interface MUActionSheetButton () { + NSString *_title; + MUActionSheetButtonKind _kind; +} +- (id) initWithKind:(MUActionSheetButtonKind)kind; +- (void) drawBlueHighlightState; +- (void) drawGrayHighlightState; +- (void) drawCancelState; +- (void) drawNormalState; +- (void) drawConstructiveState; +@end + +@implementation MUActionSheetButton + ++ (MUActionSheetButton *) buttonWithKind:(MUActionSheetButtonKind)kind { + return [[[MUActionSheetButton alloc] initWithKind:kind] autorelease]; +} + +- (id) initWithKind:(MUActionSheetButtonKind)kind { + if ((self = [super initWithFrame:CGRectZero])) { + self.opaque = NO; + _kind = kind; + } + return self; +} + +- (void) dealloc { + [_title release]; + + [super dealloc]; +} + +- (void) setHighlighted:(BOOL)highlighted { + [super setHighlighted:highlighted]; + [self setNeedsDisplay]; +} + +- (void) setTitle:(NSString *)title { + [_title release]; + _title = [title copy]; +} + +- (NSString *) title { + return _title; +} + +- (void) drawRect:(CGRect)rect { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextClearRect(context, self.bounds); + + if (self.highlighted) { + [self drawGrayHighlightState]; + } else if (_kind == MUActionSheetButtonKindNormal) { + [self drawNormalState]; + } else if (_kind == MUActionSheetButtonKindCancel) { + [self drawCancelState]; + } else if (_kind == MUActionSheetButtonKindDestructive) { + [self drawDestructiveState]; + } else if (_kind == MUActionSheetButtonKindConstructive) { + [self drawConstructiveState]; + } +} + +// Drawing code generated using 'Resources/UIElements/MUActionSheet/MUActionSheetButtonBlueHighlight.pcvd' +- (void) drawBlueHighlightState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.031 green: 0.161 blue: 0.698 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 0.275 green: 0.38 blue: 0.816 alpha: 1]; + UIColor* textShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.516 green: 0.58 blue: 0.849 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.031 green: 0.161 blue: 0.698 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.153 green: 0.271 blue: 0.757 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + UIColor* textShadow = textShadowColor; + CGSize textShadowOffset = CGSizeMake(0.1, -1.1); + CGFloat textShadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, textShadowOffset, textShadowBlurRadius, textShadow.CGColor); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +// Drawing code generated using 'Resources/UIElements/MUActionSheet/MUActionSheetButtonGrayHighlight.pcvd' +- (void) drawGrayHighlightState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 0.654 green: 0.654 blue: 0.654 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.205 green: 0.198 blue: 0.198 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 0.303 green: 0.301 blue: 0.301 alpha: 1]; + UIColor* textShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.429 green: 0.426 blue: 0.426 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.205 green: 0.198 blue: 0.198 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.254 green: 0.25 blue: 0.25 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + UIColor* textShadow = textShadowColor; + CGSize textShadowOffset = CGSizeMake(0.1, -1.1); + CGFloat textShadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, textShadowOffset, textShadowBlurRadius, textShadow.CGColor); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +// Drawing code generated using 'Resources/MUActionSheet/MUActionSheetButtonCancel.pcvd' +- (void) drawCancelState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 0.706 green: 0.706 blue: 0.706 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.004 green: 0.004 blue: 0.004 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 0.232 green: 0.232 blue: 0.232 alpha: 1]; + UIColor* textShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.355 green: 0.355 blue: 0.355 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.004 green: 0.004 blue: 0.004 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.118 green: 0.118 blue: 0.118 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + UIColor* textShadow = textShadowColor; + CGSize textShadowOffset = CGSizeMake(0.1, -1.1); + CGFloat textShadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, textShadowOffset, textShadowBlurRadius, textShadow.CGColor); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +// Drawing code generated using 'Resources/MUActionSheet/MUActionSheetButtonNormal.pcvd' +- (void) drawNormalState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.765 green: 0.769 blue: 0.776 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.882 green: 0.884 blue: 0.888 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.765 green: 0.769 blue: 0.776 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.882 green: 0.884 blue: 0.888 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + + //// Frames + CGRect frame = self.bounds; + + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +// Drawing code generated using 'Resources/UIElements/MUActionSheet/MUActionSheetButtonDestructive.pcvd' +- (void) drawDestructiveState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.808 green: 0.051 blue: 0.071 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 0.768 green: 0.569 blue: 0.569 alpha: 1]; + UIColor* textShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 0.303]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.904 green: 0.525 blue: 0.535 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.808 green: 0.051 blue: 0.071 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.788 green: 0.31 blue: 0.32 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + UIColor* textShadow = textShadowColor; + CGSize textShadowOffset = CGSizeMake(0.1, -1.1); + CGFloat textShadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, textShadowOffset, textShadowBlurRadius, textShadow.CGColor); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +// Drawing code generated using 'Resources/UIElements/MUActionSheet/MUActionSheetButtonConstructive.pcvd' +- (void) drawConstructiveState { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* strokeColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; + UIColor* gradientStartColor = [UIColor colorWithRed: 0.685 green: 0.844 blue: 0.566 alpha: 1]; + UIColor* gradientMiddleColor = [UIColor colorWithRed: 0.182 green: 0.486 blue: 0.044 alpha: 1]; + UIColor* fontColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* gradientEndColor = [UIColor colorWithRed: 0.185 green: 0.353 blue: 0 alpha: 1]; + UIColor* textShadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 0.303]; + + //// Gradient Declarations + NSArray* gradientColors = [NSArray arrayWithObjects: + (id)gradientStartColor.CGColor, + (id)[UIColor colorWithRed: 0.433 green: 0.665 blue: 0.305 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.182 green: 0.486 blue: 0.044 alpha: 1].CGColor, + (id)gradientMiddleColor.CGColor, + (id)[UIColor colorWithRed: 0.183 green: 0.42 blue: 0.022 alpha: 1].CGColor, + (id)gradientEndColor.CGColor, nil]; + CGFloat gradientLocations[] = {0, 0.03, 0.67, 0.74, 0.83, 0.95, 1}; + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)gradientColors, gradientLocations); + + //// Shadow Declarations + UIColor* shadow = [UIColor whiteColor]; + CGSize shadowOffset = CGSizeMake(0.1, 1.1); + CGFloat shadowBlurRadius = 2; + UIColor* textShadow = textShadowColor; + CGSize textShadowOffset = CGSizeMake(0.1, -1.1); + CGFloat textShadowBlurRadius = 0; + + //// Frames + CGRect frame = self.bounds; + + + //// Abstracted Attributes + NSString* textContent = _title; + + + //// Rounded Rectangle Drawing + CGRect roundedRectangleRect = CGRectMake(CGRectGetMinX(frame) + 1.5, CGRectGetMinY(frame) + 1.5, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: roundedRectangleRect cornerRadius: 10]; + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor); + CGContextBeginTransparencyLayer(context, NULL); + [roundedRectanglePath addClip]; + CGContextDrawLinearGradient(context, gradient, + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMinY(roundedRectangleRect)), + CGPointMake(CGRectGetMidX(roundedRectangleRect), CGRectGetMaxY(roundedRectangleRect)), + 0); + CGContextEndTransparencyLayer(context); + CGContextRestoreGState(context); + + [strokeColor setStroke]; + roundedRectanglePath.lineWidth = 3; + [roundedRectanglePath stroke]; + + + //// Text Drawing + CGRect textRect = CGRectMake(CGRectGetMinX(frame) + 1, CGRectGetMinY(frame) + 2, CGRectGetWidth(frame) - 3, CGRectGetHeight(frame) - 5); + CGContextSaveGState(context); + CGContextSetShadowWithColor(context, textShadowOffset, textShadowBlurRadius, textShadow.CGColor); + [fontColor setFill]; + [textContent drawInRect: CGRectInset(textRect, 0, 9) withFont: [UIFont boldSystemFontOfSize: 20.5] lineBreakMode: UILineBreakModeWordWrap alignment: UITextAlignmentCenter]; + CGContextRestoreGState(context); + + + + //// Cleanup + CGGradientRelease(gradient); + CGColorSpaceRelease(colorSpace); +} + +@end diff --git a/Source/Classes/MUCertificatePreferencesViewController.h b/Source/Classes/MUCertificatePreferencesViewController.h index 1fae61a..4d1bed2 100644 --- a/Source/Classes/MUCertificatePreferencesViewController.h +++ b/Source/Classes/MUCertificatePreferencesViewController.h @@ -2,7 +2,5 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -@interface MUCertificatePreferencesViewController : UITableViewController <UIActionSheetDelegate> -- (id) init; -- (void) dealloc; +@interface MUCertificatePreferencesViewController : UITableViewController @end
\ No newline at end of file diff --git a/Source/Classes/MUCertificatePreferencesViewController.m b/Source/Classes/MUCertificatePreferencesViewController.m index 0370a8b..118e9bb 100644 --- a/Source/Classes/MUCertificatePreferencesViewController.m +++ b/Source/Classes/MUCertificatePreferencesViewController.m @@ -8,10 +8,11 @@ #import "MUCertificateViewController.h" #import "MUCertificateController.h" #import "MUCertificateDiskImportViewController.h" +#import "MUActionSheet.h" #import <MumbleKit/MKCertificate.h> -@interface MUCertificatePreferencesViewController () { +@interface MUCertificatePreferencesViewController () <MUActionSheetDelegate> { NSMutableArray *_certificateItems; BOOL _picker; NSUInteger _selectedIndex; @@ -165,23 +166,23 @@ - (void) addButtonClicked:(UIBarButtonItem *)addButton { NSString *showAllCerts = NSLocalizedString(@"Show All Certificates", nil); NSString *showIdentities = NSLocalizedString(@"Show Identities Only", nil); - UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil + MUActionSheet *sheet = [[MUActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) destructiveButtonTitle:nil + constructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Generate New Certificate", nil), _showAll ? showIdentities : showAllCerts, NSLocalizedString(@"Import From iTunes", nil), nil]; - [sheet setActionSheetStyle:UIActionSheetStyleBlackOpaque]; - [sheet showInView:[self tableView]]; + [sheet showInViewController:self]; [sheet release]; } #pragma mark - -#pragma mark UIActionSheet delegate +#pragma mark MUActionSheet delegate -- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)idx { +- (void) actionSheet:(MUActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)idx { if (idx == 0) { // Generate New Certificate UINavigationController *navCtrl = [[UINavigationController alloc] init]; navCtrl.modalPresentationStyle = UIModalPresentationCurrentContext; @@ -195,7 +196,7 @@ [[NSUserDefaults standardUserDefaults] setBool:_showAll forKey:@"CertificatesShowIntermediates"]; [self fetchCertificates]; [self.tableView reloadData]; - } else if (idx == 2) { // Import From Disk + } else if (idx == 2) { // Import From iTunes MUCertificateDiskImportViewController *diskImportViewController = [[MUCertificateDiskImportViewController alloc] init]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:diskImportViewController]; [[self navigationController] presentModalViewController:navController animated:YES]; diff --git a/Source/Classes/MUCertificateViewController.m b/Source/Classes/MUCertificateViewController.m index 55c800b..1962653 100644 --- a/Source/Classes/MUCertificateViewController.m +++ b/Source/Classes/MUCertificateViewController.m @@ -8,6 +8,7 @@ #import "MUCertificateChainBuilder.h" #import "MUColor.h" #import "MUImage.h" +#import "MUActionSheet.h" #import <MumbleKit/MKCertificate.h> @@ -17,7 +18,7 @@ static const NSUInteger CertificateViewSectionSHA1Fingerprint = 2; static const NSUInteger CertificateViewSectionSHA256Fingerprint = 3; static const NSUInteger CertificateViewSectionTotal = 4; -@interface MUCertificateViewController () <UIAlertViewDelegate, UIActionSheetDelegate> { +@interface MUCertificateViewController () <UIAlertViewDelegate, MUActionSheetDelegate> { NSInteger _curIdx; NSData *_persistentRef; NSArray *_certificates; @@ -448,18 +449,18 @@ static const NSUInteger CertificateViewSectionTotal = 4; NSString *delete = NSLocalizedString(@"Delete", nil); NSString *export = NSLocalizedString(@"Export to iTunes", @"iTunes export button text for certificate chain action sheet"); - UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil + MUActionSheet *sheet = [[MUActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:cancel destructiveButtonTitle:delete + constructiveButtonTitle:nil otherButtonTitles:export, nil]; - [sheet setActionSheetStyle:UIActionSheetStyleBlackOpaque]; - [sheet showInView:self.tableView]; + [sheet showInViewController:self]; [sheet release]; } -- (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { - if (buttonIndex == 1) { // Export +- (void) actionSheet:(MUActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { + if (buttonIndex == 0) { // Export NSString *title = NSLocalizedString(@"Export Certificate Chain", @"Title for certificate export alert view (with username and password field)"); NSString *cancel = NSLocalizedString(@"Cancel", nil); NSString *export = NSLocalizedString(@"Export", nil); @@ -475,7 +476,7 @@ static const NSUInteger CertificateViewSectionTotal = 4; [[alertView textFieldAtIndex:1] setPlaceholder:password]; [alertView show]; [alertView release]; - } else if (buttonIndex == 0) { // Delete + } else if (buttonIndex == [actionSheet destructiveButtonIndex]) { // Delete NSString *title = NSLocalizedString(@"Delete Certificate Chain", @"Certificate deletion warning title"); NSString *msg = NSLocalizedString(@"Are you sure you want to delete this certificate chain?\n\n" @"If you don't have a backup, this will permanently remove any rights associated with the certificate chain on any Mumble servers.", diff --git a/Source/Classes/MUWelcomeScreenPad.m b/Source/Classes/MUWelcomeScreenPad.m index 8f25020..0cc1bf1 100644 --- a/Source/Classes/MUWelcomeScreenPad.m +++ b/Source/Classes/MUWelcomeScreenPad.m @@ -39,6 +39,8 @@ - (void) viewWillAppear:(BOOL)animated { self.navigationItem.title = @"Mumble"; + self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; + UIBarButtonItem *aboutBtn = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"About", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(aboutButtonClicked:)]; self.navigationItem.rightBarButtonItem = aboutBtn; [aboutBtn release]; |