sdk-ameba-v4.0c_180328/tools/uart_adapter/app/iOS/uartadapter/KxMenu.m
2019-04-02 16:34:25 +08:00

889 lines
27 KiB
Objective-C
Executable file

//
// KxMenu.m
// kxmenu project
// https://github.com/kolyvan/kxmenu/
//
// Created by Kolyvan on 17.05.13.
//
/*
Copyright (c) 2013 Konstantin Bukreev. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Some ideas was taken from QBPopupMenu project by Katsuma Tanaka.
https://github.com/questbeat/QBPopupMenu
*/
#import "KxMenu.h"
#import <QuartzCore/QuartzCore.h>
const CGFloat kArrowSize = 12.f;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@interface KxMenuView : UIView
- (void)dismissMenu:(BOOL) animated;
@end
@interface KxMenuOverlay : UIView
@end
@implementation KxMenuOverlay
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
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) {
if ([v isKindOfClass:[KxMenuView class]] && [v respondsToSelector:@selector(dismissMenu:)]) {
[v performSelector:@selector(dismissMenu:) withObject:@(YES)];
}
}
}
@end
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@implementation KxMenuItem
+ (instancetype) menuItem:(NSString *) title
image:(UIImage *) image
target:(id)target
action:(SEL) action
{
return [[KxMenuItem alloc] init:title
image:image
target:target
action:action];
}
- (id) init:(NSString *) title
image:(UIImage *) image
target:(id)target
action:(SEL) action
{
NSParameterAssert(title.length || image);
self = [super init];
if (self) {
_title = title;
_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 {
KxMenuViewArrowDirectionNone,
KxMenuViewArrowDirectionUp,
KxMenuViewArrowDirectionDown,
KxMenuViewArrowDirectionLeft,
KxMenuViewArrowDirectionRight,
} KxMenuViewArrowDirection;
@implementation KxMenuView {
KxMenuViewArrowDirection _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;
self.layer.shadowOpacity = 0.5;
self.layer.shadowOffset = CGSizeMake(2, 2);
self.layer.shadowRadius = 2;
}
return self;
}
- (void) setupFrameInView:(UIView *)view
fromRect:(CGRect)fromRect
{
const CGSize contentSize = _contentView.frame.size;
const CGFloat outerWidth = view.bounds.size.width;
const CGFloat outerHeight = view.bounds.size.height;
const CGFloat rectX0 = fromRect.origin.x;
const CGFloat rectX1 = fromRect.origin.x + fromRect.size.width;
const CGFloat rectXM = fromRect.origin.x + fromRect.size.width * 0.5f;
const CGFloat rectY0 = fromRect.origin.y;
const CGFloat rectY1 = fromRect.origin.y + fromRect.size.height;
const CGFloat rectYM = fromRect.origin.y + fromRect.size.height * 0.5f;;
const CGFloat widthPlusArrow = contentSize.width + kArrowSize;
const CGFloat heightPlusArrow = contentSize.height + kArrowSize;
const CGFloat widthHalf = contentSize.width * 0.5f;
const CGFloat heightHalf = contentSize.height * 0.5f;
const CGFloat kMargin = 5.f;
if (heightPlusArrow < (outerHeight - rectY1)) {
_arrowDirection = KxMenuViewArrowDirectionUp;
CGPoint point = (CGPoint){
rectXM - widthHalf,
rectY1
};
if (point.x < kMargin)
point.x = kMargin;
if ((point.x + contentSize.width + kMargin) > outerWidth)
point.x = outerWidth - contentSize.width - kMargin;
_arrowPosition = rectXM - point.x;
//_arrowPosition = MAX(16, MIN(_arrowPosition, contentSize.width - 16));
_contentView.frame = (CGRect){0, kArrowSize, contentSize};
self.frame = (CGRect) {
point,
contentSize.width,
contentSize.height + kArrowSize
};
} else if (heightPlusArrow < rectY0) {
_arrowDirection = KxMenuViewArrowDirectionDown;
CGPoint point = (CGPoint){
rectXM - widthHalf,
rectY0 - heightPlusArrow
};
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 + kArrowSize
};
} else if (widthPlusArrow < (outerWidth - rectX1)) {
_arrowDirection = KxMenuViewArrowDirectionLeft;
CGPoint point = (CGPoint){
rectX1,
rectYM - heightHalf
};
if (point.y < kMargin)
point.y = kMargin;
if ((point.y + contentSize.height + kMargin) > outerHeight)
point.y = outerHeight - contentSize.height - kMargin;
_arrowPosition = rectYM - point.y;
_contentView.frame = (CGRect){kArrowSize, 0, contentSize};
self.frame = (CGRect) {
point,
contentSize.width + kArrowSize,
contentSize.height
};
} else if (widthPlusArrow < rectX0) {
_arrowDirection = KxMenuViewArrowDirectionRight;
CGPoint point = (CGPoint){
rectX0 - widthPlusArrow,
rectYM - heightHalf
};
if (point.y < kMargin)
point.y = kMargin;
if ((point.y + contentSize.height + 5) > outerHeight)
point.y = outerHeight - contentSize.height - kMargin;
_arrowPosition = rectYM - point.y;
_contentView.frame = (CGRect){CGPointZero, contentSize};
self.frame = (CGRect) {
point,
contentSize.width + kArrowSize,
contentSize.height
};
} else {
_arrowDirection = KxMenuViewArrowDirectionNone;
self.frame = (CGRect) {
(outerWidth - contentSize.width) * 0.5f,
(outerHeight - contentSize.height) * 0.5f,
contentSize,
};
}
}
- (void)showMenuInView:(UIView *)view
fromRect:(CGRect)rect
menuItems:(NSArray *)menuItems
{
_menuItems = menuItems;
_contentView = [self mkContentView];
[self addSubview:_contentView];
[self setupFrameInView:view fromRect:rect];
KxMenuOverlay *overlay = [[KxMenuOverlay alloc] initWithFrame:view.bounds];
[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) animated
{
if (self.superview) {
if (animated) {
_contentView.hidden = YES;
const CGRect toFrame = (CGRect){self.arrowPoint, 1, 1};
[UIView animateWithDuration:0.2
animations:^(void) {
self.alpha = 0;
self.frame = toFrame;
} completion:^(BOOL finished) {
if ([self.superview isKindOfClass:[KxMenuOverlay class]])
[self.superview removeFromSuperview];
[self removeFromSuperview];
}];
} else {
if ([self.superview isKindOfClass:[KxMenuOverlay class]])
[self.superview removeFromSuperview];
[self removeFromSuperview];
}
}
}
- (void)performAction:(id)sender
{
[self dismissMenu:YES];
UIButton *button = (UIButton *)sender;
KxMenuItem *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 = 10.f;
const CGFloat kMarginY = 5.f;
UIFont *titleFont = [KxMenu titleFont];
if (!titleFont) titleFont = [UIFont boldSystemFontOfSize:16];
CGFloat maxImageWidth = 0;
CGFloat maxItemHeight = 0;
CGFloat maxItemWidth = 0;
for (KxMenuItem *menuItem in _menuItems) {
const CGSize imageSize = menuItem.image.size;
if (imageSize.width > maxImageWidth)
maxImageWidth = imageSize.width;
}
if (maxImageWidth) {
maxImageWidth += kMarginX;
}
for (KxMenuItem *menuItem in _menuItems) {
NSDictionary *attributes = @{NSFontAttributeName:titleFont};
const CGSize titleSize = [menuItem.title sizeWithAttributes:attributes];
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 * 4;
if (itemHeight > maxItemHeight)
maxItemHeight = itemHeight;
if (itemWidth > maxItemWidth)
maxItemWidth = itemWidth;
}
maxItemWidth = MAX(maxItemWidth, kMinMenuItemWidth);
maxItemHeight = MAX(maxItemHeight, kMinMenuItemHeight);
const CGFloat titleX = kMarginX * 2 + maxImageWidth;
const CGFloat titleWidth = maxItemWidth - titleX - kMarginX * 2;
UIImage *selectedImage = [KxMenuView selectedImage:(CGSize){maxItemWidth, maxItemHeight + 2}];
UIImage *gradientLine = [KxMenuView gradientLine: (CGSize){maxItemWidth - kMarginX * 4, 1}];
UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero];
contentView.autoresizingMask = UIViewAutoresizingNone;
contentView.backgroundColor = [UIColor clearColor];
contentView.opaque = NO;
CGFloat itemY = kMarginY * 2;
NSUInteger itemNum = 0;
for (KxMenuItem *menuItem in _menuItems) {
const CGRect itemFrame = (CGRect){0, itemY, maxItemWidth, maxItemHeight};
UIView *itemView = [[UIView alloc] initWithFrame:itemFrame];
itemView.autoresizingMask = UIViewAutoresizingNone;
itemView.backgroundColor = [UIColor clearColor];
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 whiteColor];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.autoresizingMask = UIViewAutoresizingNone;
//titleLabel.backgroundColor = [UIColor greenColor];
[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];
gradientView.frame = (CGRect){kMarginX * 2, maxItemHeight + 1, gradientLine.size};
gradientView.contentMode = UIViewContentModeLeft;
[itemView addSubview:gradientView];
itemY += 2;
}
itemY += maxItemHeight;
++itemNum;
}
contentView.frame = (CGRect){0, 0, maxItemWidth, itemY + kMarginY * 2};
return contentView;
}
- (CGPoint) arrowPoint
{
CGPoint point;
if (_arrowDirection == KxMenuViewArrowDirectionUp) {
point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMinY(self.frame) };
} else if (_arrowDirection == KxMenuViewArrowDirectionDown) {
point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMaxY(self.frame) };
} else if (_arrowDirection == KxMenuViewArrowDirectionLeft) {
point = (CGPoint){ CGRectGetMinX(self.frame), CGRectGetMinY(self.frame) + _arrowPosition };
} else if (_arrowDirection == KxMenuViewArrowDirectionRight) {
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.216, 0.471, 0.871, 1,
0.059, 0.353, 0.839, 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.44f, G = 0.44f, B = 0.44f;
const CGFloat components[20] = {
R,G,B,0.1,
R,G,B,0.4,
R,G,B,0.7,
R,G,B,0.4,
R,G,B,0.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 = 0.267, G0 = 0.303, B0 = 0.335;
CGFloat R1 = 0.040, G1 = 0.040, B1 = 0.040;
UIColor *tintColor = [KxMenu 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 == KxMenuViewArrowDirectionUp) {
const CGFloat arrowXM = _arrowPosition;
const CGFloat arrowX0 = arrowXM - kArrowSize;
const CGFloat arrowX1 = arrowXM + kArrowSize;
const CGFloat arrowY0 = Y0;
const CGFloat arrowY1 = Y0 + kArrowSize + 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 += kArrowSize;
} else if (_arrowDirection == KxMenuViewArrowDirectionDown) {
const CGFloat arrowXM = _arrowPosition;
const CGFloat arrowX0 = arrowXM - kArrowSize;
const CGFloat arrowX1 = arrowXM + kArrowSize;
const CGFloat arrowY0 = Y1 - kArrowSize - 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 -= kArrowSize;
} else if (_arrowDirection == KxMenuViewArrowDirectionLeft) {
const CGFloat arrowYM = _arrowPosition;
const CGFloat arrowX0 = X0;
const CGFloat arrowX1 = X0 + kArrowSize + kEmbedFix;
const CGFloat arrowY0 = arrowYM - kArrowSize;;
const CGFloat arrowY1 = arrowYM + kArrowSize;
[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 += kArrowSize;
} else if (_arrowDirection == KxMenuViewArrowDirectionRight) {
const CGFloat arrowYM = _arrowPosition;
const CGFloat arrowX0 = X1;
const CGFloat arrowX1 = X1 - kArrowSize - kEmbedFix;
const CGFloat arrowY0 = arrowYM - kArrowSize;;
const CGFloat arrowY1 = arrowYM + kArrowSize;
[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 -= kArrowSize;
}
[arrowPath fill];
// render body
const CGRect bodyFrame = {X0, Y0, X1 - X0, Y1 - Y0};
UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:bodyFrame
cornerRadius:8];
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 == KxMenuViewArrowDirectionLeft ||
_arrowDirection == KxMenuViewArrowDirectionRight) {
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 KxMenu *gMenu;
static UIColor *gTintColor;
static UIFont *gTitleFont;
@implementation KxMenu {
KxMenuView *_menuView;
BOOL _observing;
}
+ (instancetype) sharedMenu
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
gMenu = [[KxMenu 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
{
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 = [[KxMenuView alloc] init];
[_menuView showMenuInView:view fromRect:rect menuItems:menuItems];
}
- (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
{
[[self sharedMenu] showMenuInView:view fromRect:rect menuItems:menuItems];
}
+ (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