mirror of https://github.com/axmolengine/axmol.git
466 lines
14 KiB
Mathematica
466 lines
14 KiB
Mathematica
|
//
|
||
|
// SinaWeiboAuthorizeView.m
|
||
|
// sinaweibo_ios_sdk
|
||
|
//
|
||
|
// Created by Wade Cheng on 4/19/12.
|
||
|
// Copyright (c) 2012 SINA. All rights reserved.
|
||
|
//
|
||
|
|
||
|
#import "SinaWeiboAuthorizeView.h"
|
||
|
#import "SinaWeiboRequest.h"
|
||
|
#import "SinaWeibo.h"
|
||
|
#import "SinaWeiboConstants.h"
|
||
|
#import <QuartzCore/QuartzCore.h>
|
||
|
|
||
|
static CGFloat kBorderGray[4] = {0.3, 0.3, 0.3, 0.8};
|
||
|
static CGFloat kBorderBlack[4] = {0.3, 0.3, 0.3, 1};
|
||
|
static CGFloat kTransitionDuration = 0.3;
|
||
|
static CGFloat kPadding = 0;
|
||
|
static CGFloat kBorderWidth = 10;
|
||
|
|
||
|
@implementation SinaWeiboAuthorizeView
|
||
|
|
||
|
@synthesize delegate;
|
||
|
|
||
|
#pragma mark - Drawing
|
||
|
|
||
|
- (void)addRoundedRectToPath:(CGContextRef)context rect:(CGRect)rect radius:(float)radius
|
||
|
{
|
||
|
CGContextBeginPath(context);
|
||
|
CGContextSaveGState(context);
|
||
|
|
||
|
if (radius == 0)
|
||
|
{
|
||
|
CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
|
||
|
CGContextAddRect(context, rect);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rect = CGRectOffset(CGRectInset(rect, 0.5, 0.5), 0.5, 0.5);
|
||
|
CGContextTranslateCTM(context, CGRectGetMinX(rect)-0.5, CGRectGetMinY(rect)-0.5);
|
||
|
CGContextScaleCTM(context, radius, radius);
|
||
|
float fw = CGRectGetWidth(rect) / radius;
|
||
|
float fh = CGRectGetHeight(rect) / radius;
|
||
|
|
||
|
CGContextMoveToPoint(context, fw, fh/2);
|
||
|
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
|
||
|
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
|
||
|
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
|
||
|
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
|
||
|
}
|
||
|
|
||
|
CGContextClosePath(context);
|
||
|
CGContextRestoreGState(context);
|
||
|
}
|
||
|
|
||
|
- (void)drawRect:(CGRect)rect fill:(const CGFloat*)fillColors radius:(CGFloat)radius
|
||
|
{
|
||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||
|
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
||
|
|
||
|
if (fillColors)
|
||
|
{
|
||
|
CGContextSaveGState(context);
|
||
|
CGContextSetFillColor(context, fillColors);
|
||
|
if (radius)
|
||
|
{
|
||
|
[self addRoundedRectToPath:context rect:rect radius:radius];
|
||
|
CGContextFillPath(context);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CGContextFillRect(context, rect);
|
||
|
}
|
||
|
CGContextRestoreGState(context);
|
||
|
}
|
||
|
|
||
|
CGColorSpaceRelease(space);
|
||
|
}
|
||
|
|
||
|
- (void)strokeLines:(CGRect)rect stroke:(const CGFloat*)strokeColor
|
||
|
{
|
||
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||
|
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
||
|
|
||
|
CGContextSaveGState(context);
|
||
|
CGContextSetStrokeColorSpace(context, space);
|
||
|
CGContextSetStrokeColor(context, strokeColor);
|
||
|
CGContextSetLineWidth(context, 1.0);
|
||
|
|
||
|
{
|
||
|
CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y-0.5},
|
||
|
{rect.origin.x+rect.size.width, rect.origin.y-0.5}};
|
||
|
CGContextStrokeLineSegments(context, points, 2);
|
||
|
}
|
||
|
{
|
||
|
CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y+rect.size.height-0.5},
|
||
|
{rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height-0.5}};
|
||
|
CGContextStrokeLineSegments(context, points, 2);
|
||
|
}
|
||
|
{
|
||
|
CGPoint points[] = {{rect.origin.x+rect.size.width-0.5, rect.origin.y},
|
||
|
{rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height}};
|
||
|
CGContextStrokeLineSegments(context, points, 2);
|
||
|
}
|
||
|
{
|
||
|
CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y},
|
||
|
{rect.origin.x+0.5, rect.origin.y+rect.size.height}};
|
||
|
CGContextStrokeLineSegments(context, points, 2);
|
||
|
}
|
||
|
|
||
|
CGContextRestoreGState(context);
|
||
|
|
||
|
CGColorSpaceRelease(space);
|
||
|
}
|
||
|
|
||
|
- (void)drawRect:(CGRect)rect
|
||
|
{
|
||
|
[self drawRect:rect fill:kBorderGray radius:0];
|
||
|
|
||
|
CGRect webRect = CGRectMake(
|
||
|
ceil(rect.origin.x+kBorderWidth), ceil(rect.origin.y+kBorderWidth)+1,
|
||
|
rect.size.width-kBorderWidth*2, rect.size.height-(1+kBorderWidth*2));
|
||
|
|
||
|
[self strokeLines:webRect stroke:kBorderBlack];
|
||
|
}
|
||
|
|
||
|
#pragma mark - Memory management
|
||
|
|
||
|
- (id)init
|
||
|
{
|
||
|
if ((self = [super init]))
|
||
|
{
|
||
|
self.backgroundColor = [UIColor clearColor];
|
||
|
self.autoresizesSubviews = YES;
|
||
|
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||
|
self.contentMode = UIViewContentModeRedraw;
|
||
|
|
||
|
webView = [[UIWebView alloc] init];
|
||
|
webView.delegate = self;
|
||
|
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||
|
[self addSubview:webView];
|
||
|
[webView release];
|
||
|
|
||
|
UIImage* closeImage = [UIImage imageNamed:@"SinaWeibo.bundle/images/close.png"];
|
||
|
UIColor* color = [UIColor colorWithRed:167.0/255 green:184.0/255 blue:216.0/255 alpha:1];
|
||
|
closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||
|
[closeButton setImage:closeImage forState:UIControlStateNormal];
|
||
|
[closeButton setTitleColor:color forState:UIControlStateNormal];
|
||
|
[closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||
|
[closeButton addTarget:self action:@selector(cancel)
|
||
|
forControlEvents:UIControlEventTouchUpInside];
|
||
|
closeButton.titleLabel.font = [UIFont boldSystemFontOfSize:12];
|
||
|
closeButton.showsTouchWhenHighlighted = YES;
|
||
|
closeButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||
|
[self addSubview:closeButton];
|
||
|
|
||
|
indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:
|
||
|
UIActivityIndicatorViewStyleGray];
|
||
|
indicatorView.autoresizingMask =
|
||
|
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
|
||
|
| UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
|
||
|
[self addSubview:indicatorView];
|
||
|
|
||
|
modalBackgroundView = [[UIView alloc] init];
|
||
|
}
|
||
|
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
- (void)dealloc
|
||
|
{
|
||
|
[authParams release], authParams = nil;
|
||
|
[appRedirectURI release], appRedirectURI = nil;
|
||
|
[modalBackgroundView release], modalBackgroundView = nil;
|
||
|
|
||
|
[super dealloc];
|
||
|
}
|
||
|
|
||
|
- (id)initWithAuthParams:(NSDictionary *)params
|
||
|
delegate:(id<SinaWeiboAuthorizeViewDelegate>)_delegate
|
||
|
{
|
||
|
if ((self = [self init]))
|
||
|
{
|
||
|
self.delegate = _delegate;
|
||
|
authParams = [params copy];
|
||
|
appRedirectURI = [[authParams objectForKey:@"redirect_uri"] retain];
|
||
|
}
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
#pragma mark - View orientation
|
||
|
|
||
|
- (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation
|
||
|
{
|
||
|
if (orientation == previousOrientation)
|
||
|
{
|
||
|
return NO;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return orientation == UIInterfaceOrientationPortrait
|
||
|
|| orientation == UIInterfaceOrientationPortraitUpsideDown
|
||
|
|| orientation == UIInterfaceOrientationLandscapeLeft
|
||
|
|| orientation == UIInterfaceOrientationLandscapeRight;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (CGAffineTransform)transformForOrientation
|
||
|
{
|
||
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
||
|
if (orientation == UIInterfaceOrientationLandscapeLeft)
|
||
|
{
|
||
|
return CGAffineTransformMakeRotation(M_PI*1.5);
|
||
|
}
|
||
|
else if (orientation == UIInterfaceOrientationLandscapeRight)
|
||
|
{
|
||
|
return CGAffineTransformMakeRotation(M_PI/2);
|
||
|
}
|
||
|
else if (orientation == UIInterfaceOrientationPortraitUpsideDown)
|
||
|
{
|
||
|
return CGAffineTransformMakeRotation(-M_PI);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return CGAffineTransformIdentity;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (void)sizeToFitOrientation:(BOOL)transform
|
||
|
{
|
||
|
if (transform)
|
||
|
{
|
||
|
self.transform = CGAffineTransformIdentity;
|
||
|
}
|
||
|
|
||
|
CGRect frame = [UIScreen mainScreen].applicationFrame;
|
||
|
CGPoint center = CGPointMake(frame.origin.x + ceil(frame.size.width/2),
|
||
|
frame.origin.y + ceil(frame.size.height/2));
|
||
|
|
||
|
CGFloat scaleFactor = SinaWeiboIsDeviceIPad() ? 0.6f : 1.0f;
|
||
|
|
||
|
CGFloat width = floor(scaleFactor * frame.size.width) - kPadding * 2;
|
||
|
CGFloat height = floor(scaleFactor * frame.size.height) - kPadding * 2;
|
||
|
|
||
|
previousOrientation = [UIApplication sharedApplication].statusBarOrientation;
|
||
|
if (UIInterfaceOrientationIsLandscape(previousOrientation))
|
||
|
{
|
||
|
self.frame = CGRectMake(kPadding, kPadding, height, width);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.frame = CGRectMake(kPadding, kPadding, width, height);
|
||
|
}
|
||
|
self.center = center;
|
||
|
|
||
|
if (transform)
|
||
|
{
|
||
|
self.transform = [self transformForOrientation];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (void)updateWebOrientation
|
||
|
{
|
||
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
||
|
if (UIInterfaceOrientationIsLandscape(orientation))
|
||
|
{
|
||
|
[webView stringByEvaluatingJavaScriptFromString:
|
||
|
@"document.body.setAttribute('orientation', 90);"];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
[webView stringByEvaluatingJavaScriptFromString:
|
||
|
@"document.body.removeAttribute('orientation');"];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma mark - UIDeviceOrientationDidChangeNotification Methods
|
||
|
|
||
|
- (void)deviceOrientationDidChange:(id)object
|
||
|
{
|
||
|
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
|
||
|
if ([self shouldRotateToOrientation:orientation])
|
||
|
{
|
||
|
NSTimeInterval duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
|
||
|
|
||
|
[UIView beginAnimations:nil context:nil];
|
||
|
[UIView setAnimationDuration:duration];
|
||
|
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
|
||
|
[self sizeToFitOrientation:orientation];
|
||
|
[UIView commitAnimations];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma mark - Animation
|
||
|
|
||
|
- (void)bounce1AnimationStopped
|
||
|
{
|
||
|
[UIView beginAnimations:nil context:nil];
|
||
|
[UIView setAnimationDuration:kTransitionDuration/2];
|
||
|
[UIView setAnimationDelegate:self];
|
||
|
[UIView setAnimationDidStopSelector:@selector(bounce2AnimationStopped)];
|
||
|
self.transform = CGAffineTransformScale([self transformForOrientation], 0.9, 0.9);
|
||
|
[UIView commitAnimations];
|
||
|
}
|
||
|
|
||
|
- (void)bounce2AnimationStopped
|
||
|
{
|
||
|
[UIView beginAnimations:nil context:nil];
|
||
|
[UIView setAnimationDuration:kTransitionDuration/2];
|
||
|
self.transform = [self transformForOrientation];
|
||
|
[UIView commitAnimations];
|
||
|
}
|
||
|
|
||
|
#pragma mark Obeservers
|
||
|
|
||
|
- (void)addObservers
|
||
|
{
|
||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||
|
selector:@selector(deviceOrientationDidChange:)
|
||
|
name:@"UIDeviceOrientationDidChangeNotification" object:nil];
|
||
|
}
|
||
|
|
||
|
- (void)removeObservers
|
||
|
{
|
||
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||
|
name:@"UIDeviceOrientationDidChangeNotification" object:nil];
|
||
|
}
|
||
|
|
||
|
#pragma mark - Activity Indicator
|
||
|
|
||
|
- (void)showIndicator
|
||
|
{
|
||
|
[indicatorView sizeToFit];
|
||
|
[indicatorView startAnimating];
|
||
|
indicatorView.center = webView.center;
|
||
|
}
|
||
|
|
||
|
- (void)hideIndicator
|
||
|
{
|
||
|
[indicatorView stopAnimating];
|
||
|
}
|
||
|
|
||
|
#pragma mark - Show / Hide
|
||
|
|
||
|
- (void)load
|
||
|
{
|
||
|
NSString *authPagePath = [SinaWeiboRequest serializeURL:kSinaWeiboWebAuthURL
|
||
|
params:authParams httpMethod:@"GET"];
|
||
|
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:authPagePath]]];
|
||
|
}
|
||
|
|
||
|
- (void)showWebView
|
||
|
{
|
||
|
UIWindow* window = [UIApplication sharedApplication].keyWindow;
|
||
|
if (!window)
|
||
|
{
|
||
|
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
|
||
|
}
|
||
|
modalBackgroundView.frame = window.frame;
|
||
|
[modalBackgroundView addSubview:self];
|
||
|
[window addSubview:modalBackgroundView];
|
||
|
|
||
|
self.transform = CGAffineTransformScale([self transformForOrientation], 0.001, 0.001);
|
||
|
[UIView beginAnimations:nil context:nil];
|
||
|
[UIView setAnimationDuration:kTransitionDuration/1.5];
|
||
|
[UIView setAnimationDelegate:self];
|
||
|
[UIView setAnimationDidStopSelector:@selector(bounce1AnimationStopped)];
|
||
|
self.transform = CGAffineTransformScale([self transformForOrientation], 1.1, 1.1);
|
||
|
[UIView commitAnimations];
|
||
|
}
|
||
|
|
||
|
- (void)show
|
||
|
{
|
||
|
[self load];
|
||
|
[self sizeToFitOrientation:NO];
|
||
|
|
||
|
CGFloat innerWidth = self.frame.size.width - (kBorderWidth+1)*2;
|
||
|
[closeButton sizeToFit];
|
||
|
closeButton.frame = CGRectMake(2, 2, 29, 29);
|
||
|
|
||
|
webView.frame = CGRectMake(kBorderWidth+1, kBorderWidth+1, innerWidth,
|
||
|
self.frame.size.height - (1 + kBorderWidth*2));
|
||
|
|
||
|
[self showWebView];
|
||
|
[self showIndicator];
|
||
|
|
||
|
[self addObservers];
|
||
|
}
|
||
|
|
||
|
- (void)_hide
|
||
|
{
|
||
|
[self removeFromSuperview];
|
||
|
[modalBackgroundView removeFromSuperview];
|
||
|
}
|
||
|
|
||
|
- (void)hide
|
||
|
{
|
||
|
[self removeObservers];
|
||
|
|
||
|
[webView stopLoading];
|
||
|
|
||
|
[self performSelectorOnMainThread:@selector(_hide) withObject:nil waitUntilDone:NO];
|
||
|
}
|
||
|
|
||
|
- (void)cancel
|
||
|
{
|
||
|
[self hide];
|
||
|
[delegate authorizeViewDidCancel:self];
|
||
|
}
|
||
|
|
||
|
#pragma mark - UIWebView Delegate
|
||
|
|
||
|
- (void)webViewDidFinishLoad:(UIWebView *)aWebView
|
||
|
{
|
||
|
[self hideIndicator];
|
||
|
}
|
||
|
|
||
|
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
|
||
|
{
|
||
|
[self hideIndicator];
|
||
|
}
|
||
|
|
||
|
- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
|
||
|
{
|
||
|
NSString *url = request.URL.absoluteString;
|
||
|
NSLog(@"url = %@", url);
|
||
|
|
||
|
NSString *siteRedirectURI = [NSString stringWithFormat:@"%@%@", kSinaWeiboSDKOAuth2APIDomain, appRedirectURI];
|
||
|
|
||
|
if ([url hasPrefix:appRedirectURI] || [url hasPrefix:siteRedirectURI])
|
||
|
{
|
||
|
NSString *error_code = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_code"];
|
||
|
|
||
|
if (error_code)
|
||
|
{
|
||
|
NSString *error = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error"];
|
||
|
NSString *error_uri = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_uri"];
|
||
|
NSString *error_description = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_description"];
|
||
|
|
||
|
NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||
|
error, @"error",
|
||
|
error_uri, @"error_uri",
|
||
|
error_code, @"error_code",
|
||
|
error_description, @"error_description", nil];
|
||
|
|
||
|
[self hide];
|
||
|
[delegate authorizeView:self didFailWithErrorInfo:errorInfo];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
NSString *code = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"code"];
|
||
|
if (code)
|
||
|
{
|
||
|
[self hide];
|
||
|
[delegate authorizeView:self didRecieveAuthorizationCode:code];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NO;
|
||
|
}
|
||
|
|
||
|
return YES;
|
||
|
}
|
||
|
|
||
|
@end
|