123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794 |
- //
- // CCMenuAccount.h
- // Nextcloud iOS
- //
- // Created by Marino Faggiana on 07/04/16.
- // Copyright (c) 2017 Marino Faggiana. All rights reserved.
- //
- // Author Marino Faggiana <marino.faggiana@nextcloud.com>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- //
- #import <Foundation/Foundation.h>
- #import <QuartzCore/QuartzCore.h>
- #import "CCMenuAccount.h"
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- @interface CCMenuOverlay : UIView
- @end
- @implementation CCMenuOverlay
- - (id)initWithFrame:(CGRect)frame maskSetting:(Boolean)mask
- {
- self = [super initWithFrame:frame];
-
- if (self) {
-
- if (mask) {
- self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.17];
- } else {
- self.backgroundColor = [UIColor clearColor];
- }
-
- UITapGestureRecognizer *gestureRecognizer;
- gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
- action:@selector(singleTap:)];
-
- [self addGestureRecognizer:gestureRecognizer];
- }
- return self;
- }
- // thank horaceho https://github.com/horaceho
- // for his solution described in https://github.com/kolyvan/kxmenu/issues/9
- - (void)singleTap:(UITapGestureRecognizer *)recognizer
- {
- for (UIView *v in self.subviews) {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wundeclared-selector"
- if ([v isKindOfClass:[CCMenuView class]] && [v respondsToSelector:@selector(dismissMenu:)]) {
- [v performSelector:@selector(dismissMenu:) withObject:@(YES)];
- }
- #pragma clang diagnostic pop
- }
- }
- @end
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- @implementation CCMenuItem
- + (instancetype) menuItem:(NSString *)title argument:(NSString*)argument image:(UIImage *)image target:(id)target action:(SEL)action
- {
- return [[CCMenuItem alloc] init:title argument:argument image:image target:target action:action];
- }
- - (id)init:(NSString *)title argument:(NSString*)argument image:(UIImage *)image target:(id)target action:(SEL)action
- {
- NSParameterAssert(title.length || image);
-
- self = [super init];
- if (self) {
-
- _title = title;
- _argument = argument;
- _image = image;
- _target = target;
- _action = action;
- }
- return self;
- }
- - (BOOL)enabled
- {
- return _target != nil && _action != NULL;
- }
- - (void)performAction
- {
- __strong id target = self.target;
-
- if (target && [target respondsToSelector:_action]) {
-
- [target performSelectorOnMainThread:_action withObject:self waitUntilDone:YES];
- }
- }
- - (NSString *)description
- {
- return [NSString stringWithFormat:@"<%@ #%p %@>", [self class], self, _title];
- }
- @end
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- typedef enum {
-
- CCMenuViewArrowDirectionNone,
- CCMenuViewArrowDirectionUp,
- CCMenuViewArrowDirectionDown,
- CCMenuViewArrowDirectionLeft,
- CCMenuViewArrowDirectionRight,
-
- } CCMenuViewArrowDirection;
- @implementation CCMenuView {
-
- CCMenuViewArrowDirection _arrowDirection;
- CGFloat _arrowPosition;
- UIView *_contentView;
- NSArray *_menuItems;
- }
- - (id)init
- {
- self = [super initWithFrame:CGRectZero];
- if(self) {
-
- self.backgroundColor = [UIColor clearColor];
-
- self.opaque = YES;
- self.alpha = 0;
- }
-
- return self;
- }
- - (void)setupFrameInView:(UIView *)view fromRect:(CGRect)fromRect
- {
- const CGSize contentSize = _contentView.frame.size;
- const CGFloat outerWidth = view.bounds.size.width;
- const CGFloat rectXM = fromRect.origin.x + fromRect.size.width * 0.5f;
- const CGFloat widthHalf = contentSize.width * 0.5f;
- const CGFloat kMargin = 5.f;
- const CGFloat rectY = fromRect.origin.y;
-
- if (self.CCMenuViewOptions.shadowOfMenu) {
- self.layer.shadowOpacity = 0.5;
- self.layer.shadowOffset = CGSizeMake(2, 2);
- self.layer.shadowRadius = 2;
-
- self.layer.shadowColor = [[UIColor blackColor] CGColor];
- }
-
- _arrowDirection = CCMenuViewArrowDirectionUp;
-
- CGPoint point = (CGPoint){
- rectXM - widthHalf,
- rectY - 4
- };
-
- if (point.x < kMargin)
- point.x = kMargin;
-
- if ((point.x + contentSize.width + kMargin) > outerWidth)
- point.x = outerWidth - contentSize.width - kMargin;
-
- _arrowPosition = rectXM - point.x;
- _contentView.frame = (CGRect){CGPointZero, contentSize};
-
- self.frame = (CGRect) {
-
- point,
- contentSize.width,
- contentSize.height - self.CCMenuViewOptions.arrowSize
- };
- }
- - (void)showMenuInView:(UIView *)view fromRect:(CGRect)rect menuItems:(NSArray *)menuItems withOptions:(OptionalConfiguration)options
- {
-
- self.CCMenuViewOptions = options;
-
- _menuItems = menuItems;
-
- _contentView = [self mkContentView];
- [self addSubview:_contentView];
-
- [self setupFrameInView:view fromRect:rect];
-
- CCMenuOverlay *overlay = [[CCMenuOverlay alloc] initWithFrame:view.bounds maskSetting:self.CCMenuViewOptions.maskToBackground];
- [overlay addSubview:self];
- [view addSubview:overlay];
-
- _contentView.hidden = YES;
- const CGRect toFrame = self.frame;
- self.frame = (CGRect){self.arrowPoint, 1, 1};
-
- [UIView animateWithDuration:0.2
- animations:^(void) {
-
- self.alpha = 1.0f;
- self.frame = toFrame;
-
- } completion:^(BOOL completed) {
- _contentView.hidden = NO;
- }];
-
- }
- - (void)dismissMenu:(BOOL) noAnimated
- {
- if (self.superview) {
-
- if (!noAnimated) {
-
- const CGRect toFrame = (CGRect){self.arrowPoint, 1, 1};
- _contentView.hidden = YES;
-
- [UIView animateWithDuration:0.1
- animations:^(void) {
-
- self.alpha = 0;
- self.frame = toFrame;
-
- } completion:^(BOOL finished) {
-
- if ([self.superview isKindOfClass:[CCMenuOverlay class]])
- [self.superview removeFromSuperview];
- [self removeFromSuperview];
- }];
-
- } else {
-
- if ([self.superview isKindOfClass:[CCMenuOverlay class]])
- [self.superview removeFromSuperview];
- [self removeFromSuperview];
- }
- }
- }
- - (void)performAction:(id)sender
- {
- [self dismissMenu:YES];
-
- UIButton *button = (UIButton *)sender;
- CCMenuItem *menuItem = _menuItems[button.tag];
- [menuItem performAction];
- }
- - (UIView *)mkContentView
- {
- for (UIView *v in self.subviews) {
- [v removeFromSuperview];
- }
-
- if (!_menuItems.count)
- return nil;
-
- const CGFloat kMinMenuItemHeight = 32.f;
- const CGFloat kMinMenuItemWidth = 32.f;
- const CGFloat kMarginX = self.CCMenuViewOptions.marginXSpacing;
- const CGFloat kMarginY = self.CCMenuViewOptions.marginYSpacing;
-
- UIFont *titleFont = [CCMenuAccount titleFont];
- if (!titleFont) titleFont = [UIFont boldSystemFontOfSize:16];
-
- CGFloat maxImageWidth = 0;
- CGFloat maxItemHeight = 0;
- CGFloat maxItemWidth = 0;
-
- for (CCMenuItem *menuItem in _menuItems) {
-
- const CGSize imageSize = menuItem.image.size;
- if (imageSize.width > maxImageWidth)
- maxImageWidth = imageSize.width;
- }
-
- if (maxImageWidth) {
- maxImageWidth += kMarginX;
- }
-
- for (CCMenuItem *menuItem in _menuItems) {
-
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
- const CGSize titleSize = [menuItem.title sizeWithAttributes:@{NSFontAttributeName: titleFont}];
- #else
- const CGSize titleSize = [menuItem.title sizeWithFont:titleFont];
- #endif
- const CGSize imageSize = menuItem.image.size;
-
- const CGFloat itemHeight = MAX(titleSize.height, imageSize.height) + kMarginY * 2;
-
- const CGFloat itemWidth = ((!menuItem.enabled && !menuItem.image) ? titleSize.width : maxImageWidth + titleSize.width) + kMarginX * 2 + self.CCMenuViewOptions.intervalSpacing;
-
- if (itemHeight > maxItemHeight)
- maxItemHeight = itemHeight;
-
- if (itemWidth > maxItemWidth)
- maxItemWidth = itemWidth;
- }
-
- maxItemWidth = MAX(maxItemWidth, kMinMenuItemWidth);
- maxItemHeight = MAX(maxItemHeight, kMinMenuItemHeight);
-
- const CGFloat titleX = maxImageWidth + self.CCMenuViewOptions.intervalSpacing;
-
- const CGFloat titleWidth = maxItemWidth - titleX - kMarginX *2;
-
- UIImage *selectedImage = [CCMenuView selectedImage:(CGSize){maxItemWidth, maxItemHeight + 2}];
- int insets = 0;
-
- if (self.CCMenuViewOptions.seperatorLineHasInsets) {
- insets = 4;
- }
-
- UIImage *gradientLine = [CCMenuView gradientLine: (CGSize){maxItemWidth- kMarginX * insets, 0.4}];
-
- UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero];
- contentView.autoresizingMask = UIViewAutoresizingNone;
-
- contentView.backgroundColor = [UIColor clearColor];
-
- contentView.opaque = NO;
-
- CGFloat itemY = kMarginY * 2;
-
- NSUInteger itemNum = 0;
-
- for (CCMenuItem *menuItem in _menuItems) {
-
- const CGRect itemFrame = (CGRect){0, itemY-kMarginY * 2 + self.CCMenuViewOptions.menuCornerRadius, maxItemWidth, maxItemHeight};
-
- UIView *itemView = [[UIView alloc] initWithFrame:itemFrame];
- itemView.autoresizingMask = UIViewAutoresizingNone;
-
- itemView.opaque = NO;
-
- [contentView addSubview:itemView];
-
- if (menuItem.enabled) {
-
- UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
- button.tag = itemNum;
- button.frame = itemView.bounds;
- button.enabled = menuItem.enabled;
-
- button.backgroundColor = [UIColor clearColor];
-
- button.opaque = NO;
- button.autoresizingMask = UIViewAutoresizingNone;
-
- [button addTarget:self
- action:@selector(performAction:)
- forControlEvents:UIControlEventTouchUpInside];
-
- [button setBackgroundImage:selectedImage forState:UIControlStateHighlighted];
-
- [itemView addSubview:button];
- }
-
- if (menuItem.title.length) {
-
- CGRect titleFrame;
-
- if (!menuItem.enabled && !menuItem.image) {
-
- titleFrame = (CGRect){
- kMarginX * 2,
- kMarginY,
- maxItemWidth - kMarginX * 4,
- maxItemHeight - kMarginY * 2
- };
-
- } else {
-
- titleFrame = (CGRect){
- titleX,
- kMarginY,
- titleWidth,
- maxItemHeight - kMarginY * 2
- };
- }
-
- UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
- titleLabel.text = menuItem.title;
- titleLabel.font = titleFont;
- titleLabel.textAlignment = menuItem.alignment;
-
- //titleLabel.textColor = menuItem.foreColor ? menuItem.foreColor : [UIColor blackColor];
- titleLabel.textColor = [UIColor colorWithRed:self.CCMenuViewOptions.textColor.R green:self.CCMenuViewOptions.textColor.G blue:self.CCMenuViewOptions.textColor.B alpha:1];
-
- titleLabel.backgroundColor = [UIColor clearColor];
-
- titleLabel.autoresizingMask = UIViewAutoresizingNone;
-
- [itemView addSubview:titleLabel];
- }
-
- if (menuItem.image) {
-
- const CGRect imageFrame = {kMarginX * 2, kMarginY, maxImageWidth, maxItemHeight - kMarginY * 2};
- UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageFrame];
- imageView.image = menuItem.image;
- imageView.clipsToBounds = YES;
- imageView.contentMode = UIViewContentModeCenter;
- imageView.autoresizingMask = UIViewAutoresizingNone;
- [itemView addSubview:imageView];
- }
-
- if (itemNum < _menuItems.count - 1) {
-
- UIImageView *gradientView = [[UIImageView alloc] initWithImage:gradientLine];
-
- if (self.CCMenuViewOptions.seperatorLineHasInsets) {
- gradientView.frame = (CGRect){kMarginX * 2, maxItemHeight + 1, gradientLine.size};
- } else {
- gradientView.frame = (CGRect){0, maxItemHeight + 1 , gradientLine.size};
- }
-
- gradientView.contentMode = UIViewContentModeLeft;
-
- if (self.CCMenuViewOptions.hasSeperatorLine) {
- [itemView addSubview:gradientView];
- itemY += 2;
- }
-
- itemY += maxItemHeight;
- }
-
- ++itemNum;
- }
-
- itemY += self.CCMenuViewOptions.menuCornerRadius;
-
- contentView.frame = (CGRect){0, 0, maxItemWidth, itemY + kMarginY * 2 + 5.5 + self.CCMenuViewOptions.menuCornerRadius};
-
- return contentView;
- }
- - (CGPoint)arrowPoint
- {
- CGPoint point;
-
- if (_arrowDirection == CCMenuViewArrowDirectionUp) {
-
- point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMinY(self.frame) };
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionDown) {
-
- point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMaxY(self.frame) };
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionLeft) {
-
- point = (CGPoint){ CGRectGetMinX(self.frame), CGRectGetMinY(self.frame) + _arrowPosition };
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionRight) {
-
- point = (CGPoint){ CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame) + _arrowPosition };
-
- } else {
-
- point = self.center;
- }
-
- return point;
- }
- + (UIImage *)selectedImage:(CGSize)size
- {
- const CGFloat locations[] = {0,1};
- const CGFloat components[] = {
- 0.890,0.890,0.890,1,
- 0.890,0.890,0.890,1
- };
-
- return [self gradientImageWithSize:size locations:locations components:components count:2];
- }
- + (UIImage *)gradientLine:(CGSize)size
- {
- const CGFloat locations[5] = {0,0.2,0.5,0.8,1};
-
- const CGFloat R = 0.890f, G = 0.890f, B = 0.890f;
-
- const CGFloat components[20] = {
- R,G,B,1,
- R,G,B,1,
- R,G,B,1,
- R,G,B,1,
- R,G,B,1
- };
-
- return [self gradientImageWithSize:size locations:locations components:components count:5];
- }
- + (UIImage *)gradientImageWithSize:(CGSize)size locations:(const CGFloat [])locations components:(const CGFloat [])components count:(NSUInteger)count
- {
- UIGraphicsBeginImageContextWithOptions(size, NO, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
-
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
- CGColorSpaceRelease(colorSpace);
- CGContextDrawLinearGradient(context, colorGradient, (CGPoint){0, 0}, (CGPoint){size.width, 0}, 0);
- CGGradientRelease(colorGradient);
-
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return image;
- }
- - (void)drawRect:(CGRect)rect
- {
- [self drawBackground:self.bounds inContext:UIGraphicsGetCurrentContext()];
- }
- - (void)drawBackground:(CGRect)frame inContext:(CGContextRef)context
- {
- CGFloat R0 = self.CCMenuViewOptions.menuBackgroundColor.R, G0 = self.CCMenuViewOptions.menuBackgroundColor.G, B0 = self.CCMenuViewOptions.menuBackgroundColor.B;
-
- CGFloat R1 = R0, G1 = G0, B1 = B0;
-
- UIColor *tintColor = [CCMenuAccount tintColor];
- if (tintColor) {
-
- CGFloat a;
- [tintColor getRed:&R0 green:&G0 blue:&B0 alpha:&a];
- }
-
- CGFloat X0 = frame.origin.x;
- CGFloat X1 = frame.origin.x + frame.size.width;
- CGFloat Y0 = frame.origin.y;
- CGFloat Y1 = frame.origin.y + frame.size.height;
-
- // render arrow
-
- UIBezierPath *arrowPath = [UIBezierPath bezierPath];
-
- // fix the issue with gap of arrow's base if on the edge
- const CGFloat kEmbedFix = 3.f;
-
- if (_arrowDirection == CCMenuViewArrowDirectionUp) {
-
- const CGFloat arrowXM = _arrowPosition;
- const CGFloat arrowX0 = arrowXM - self.CCMenuViewOptions.arrowSize;
- const CGFloat arrowX1 = arrowXM + self.CCMenuViewOptions.arrowSize;
- const CGFloat arrowY0 = Y0;
- const CGFloat arrowY1 = Y0 + self.CCMenuViewOptions.arrowSize + kEmbedFix;
-
- [arrowPath moveToPoint: (CGPoint){arrowXM, arrowY0}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
- [arrowPath addLineToPoint: (CGPoint){arrowX0, arrowY1}];
- [arrowPath addLineToPoint: (CGPoint){arrowXM, arrowY0}];
-
-
- [[UIColor colorWithRed:R0 green:G0 blue:B0 alpha:1] set];
-
- Y0 += self.CCMenuViewOptions.arrowSize;
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionDown) {
-
- const CGFloat arrowXM = _arrowPosition;
- const CGFloat arrowX0 = arrowXM - self.CCMenuViewOptions.arrowSize;
- const CGFloat arrowX1 = arrowXM + self.CCMenuViewOptions.arrowSize;
- const CGFloat arrowY0 = Y1 - self.CCMenuViewOptions.arrowSize - kEmbedFix;
- const CGFloat arrowY1 = Y1;
-
- [arrowPath moveToPoint: (CGPoint){arrowXM, arrowY1}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
- [arrowPath addLineToPoint: (CGPoint){arrowX0, arrowY0}];
- [arrowPath addLineToPoint: (CGPoint){arrowXM, arrowY1}];
-
- [[UIColor colorWithRed:R1 green:G1 blue:B1 alpha:1] set];
-
- Y1 -= self.CCMenuViewOptions.arrowSize;
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionLeft) {
-
- const CGFloat arrowYM = _arrowPosition;
- const CGFloat arrowX0 = X0;
- const CGFloat arrowX1 = X0 + self.CCMenuViewOptions.arrowSize + kEmbedFix;
- const CGFloat arrowY0 = arrowYM - self.CCMenuViewOptions.arrowSize;;
- const CGFloat arrowY1 = arrowYM + self.CCMenuViewOptions.arrowSize;
-
- [arrowPath moveToPoint: (CGPoint){arrowX0, arrowYM}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
- [arrowPath addLineToPoint: (CGPoint){arrowX0, arrowYM}];
-
- [[UIColor colorWithRed:R0 green:G0 blue:B0 alpha:1] set];
-
- X0 += self.CCMenuViewOptions.arrowSize;
-
- } else if (_arrowDirection == CCMenuViewArrowDirectionRight) {
-
- const CGFloat arrowYM = _arrowPosition;
- const CGFloat arrowX0 = X1;
- const CGFloat arrowX1 = X1 - self.CCMenuViewOptions.arrowSize - kEmbedFix;
- const CGFloat arrowY0 = arrowYM - self.CCMenuViewOptions.arrowSize;;
- const CGFloat arrowY1 = arrowYM + self.CCMenuViewOptions.arrowSize;
-
- [arrowPath moveToPoint: (CGPoint){arrowX0, arrowYM}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
- [arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
- [arrowPath addLineToPoint: (CGPoint){arrowX0, arrowYM}];
-
- [[UIColor colorWithRed:R1 green:G1 blue:B1 alpha:1] set];
-
- X1 -= self.CCMenuViewOptions.arrowSize;
- }
-
- [arrowPath fill];
-
- // render body
-
- const CGRect bodyFrame = {X0, Y0, X1 - X0, Y1 - Y0};
-
- UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:bodyFrame cornerRadius:self.CCMenuViewOptions.menuCornerRadius];
-
- const CGFloat locations[] = {0, 1};
- const CGFloat components[] = {
- R0, G0, B0, 1,
- R1, G1, B1, 1,
- };
-
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, sizeof(locations)/sizeof(locations[0]));
- CGColorSpaceRelease(colorSpace);
-
- [borderPath addClip];
-
- CGPoint start, end;
-
- if (_arrowDirection == CCMenuViewArrowDirectionLeft ||
- _arrowDirection == CCMenuViewArrowDirectionRight) {
-
- start = (CGPoint){X0, Y0};
- end = (CGPoint){X1, Y0};
-
- } else {
-
- start = (CGPoint){X0, Y0};
- end = (CGPoint){X0, Y1};
- }
-
- CGContextDrawLinearGradient(context, gradient, start, end, 0);
-
- CGGradientRelease(gradient);
- }
- @end
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- static CCMenuAccount *gMenu;
- static UIColor *gTintColor;
- static UIFont *gTitleFont;
- @implementation CCMenuAccount {
-
- CCMenuView *_menuView;
- BOOL _observing;
- }
- + (instancetype)sharedMenu
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
-
- gMenu = [[CCMenuAccount alloc] init];
- });
- return gMenu;
- }
- - (id)init
- {
- NSAssert(!gMenu, @"singleton object");
-
- self = [super init];
- if (self) {
- }
- return self;
- }
- - (void)dealloc
- {
- if (_observing) {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- }
- }
- - (void)showMenuInView:(UIView *)view fromRect:(CGRect)rect menuItems:(NSArray *)menuItems withOptions:(OptionalConfiguration) options
- {
- NSParameterAssert(view);
- NSParameterAssert(menuItems.count);
-
- if (_menuView) {
-
- [_menuView dismissMenu:NO];
- _menuView = nil;
- }
-
- if (!_observing) {
-
- _observing = YES;
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
- }
-
-
- _menuView = [[CCMenuView alloc] init];
- [_menuView showMenuInView:view fromRect:rect menuItems:menuItems withOptions:options];
- }
- - (void)dismissMenu
- {
- if (_menuView) {
-
- [_menuView dismissMenu:NO];
- _menuView = nil;
- }
-
- if (_observing) {
-
- _observing = NO;
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- }
- }
- - (void)orientationWillChange: (NSNotification *) n
- {
- [self dismissMenu];
- }
- + (void)showMenuInView:(UIView *)view fromRect:(CGRect)rect menuItems:(NSArray *)menuItems withOptions:(OptionalConfiguration)options
- {
- [[self sharedMenu] showMenuInView:view fromRect:rect menuItems:menuItems withOptions:options];
- }
- + (void)dismissMenu
- {
- [[self sharedMenu] dismissMenu];
- }
- + (UIColor *)tintColor
- {
- return gTintColor;
- }
- + (void)setTintColor:(UIColor *)tintColor
- {
- if (tintColor != gTintColor) {
- gTintColor = tintColor;
- }
- }
- + (UIFont *)titleFont
- {
- return gTitleFont;
- }
- + (void)setTitleFont:(UIFont *)titleFont
- {
- if (titleFont != gTitleFont) {
- gTitleFont = titleFont;
- }
- }
- @end
|