diff options
Diffstat (limited to 'frontends/cocoa/ArrowBox.m')
-rw-r--r-- | frontends/cocoa/ArrowBox.m | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/frontends/cocoa/ArrowBox.m b/frontends/cocoa/ArrowBox.m new file mode 100644 index 000000000..6605fcca9 --- /dev/null +++ b/frontends/cocoa/ArrowBox.m @@ -0,0 +1,163 @@ +/* Copyright 2011 Sven Weidauer + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#import "ArrowBox.h" + +@implementation ArrowBox + +@synthesize arrowPosition; +@synthesize arrowSize; +@synthesize arrowEdge; +@synthesize cornerRadius; + +- (void) setArrowEdge: (ArrowEdge)newEdge +{ + if (arrowEdge == newEdge) { + return; + } + + arrowEdge = newEdge; + + [self setNeedsDisplay: YES]; + updateShadow = YES; +} + + +- (void) setArrowSize: (CGFloat)newSize +{ + arrowSize = newSize; + [self setNeedsDisplay: YES]; + updateShadow = YES; +} + + +- (void) setCornerRadius: (CGFloat)newRadius +{ + cornerRadius = newRadius; + [self setNeedsDisplay: YES]; + updateShadow = YES; +} + +- (void) setArrowPosition: (CGFloat)newPosition +{ + arrowPosition = newPosition; + + [self setNeedsDisplay: YES]; + updateShadow = YES; +} + + +- (id)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + arrowPosition = 50; + cornerRadius = 10; + arrowSize = 15; + } + return self; +} + +- (void)drawRect:(NSRect)dirtyRect +{ + [[NSColor clearColor] set]; + [NSBezierPath fillRect: dirtyRect]; + + NSBezierPath *path = [NSBezierPath bezierPath]; + + NSRect bounds = [self convertRectToBase: NSInsetRect( [self bounds], 2, 2 )]; + bounds.origin.x = floor( bounds.origin.x ); + bounds.origin.y = floor( bounds.origin.y ); + bounds.size.width = floor( bounds.size.width ); + bounds.size.height = floor( bounds.size.height ); + bounds = [self convertRectFromBase: bounds]; + + const CGFloat right = bounds.size.width - arrowSize; + const CGFloat top = bounds.size.height - arrowSize; + const CGFloat left = arrowSize; + const CGFloat bottom = arrowSize; + + [path setLineJoinStyle:NSRoundLineJoinStyle]; + + [path moveToPoint: NSMakePoint( right - cornerRadius, top )]; + + if (arrowEdge == ArrowTopEdge) { + [path lineToPoint: NSMakePoint( arrowPosition + arrowSize, top )]; + [path lineToPoint: NSMakePoint( arrowPosition, top + arrowSize )]; + [path lineToPoint: NSMakePoint( arrowPosition - arrowSize, top )]; + } + + [path appendBezierPathWithArcFromPoint: NSMakePoint( left, top ) + toPoint: NSMakePoint( left, top - cornerRadius ) + radius: cornerRadius]; + + if (arrowEdge == ArrowLeftEdge) { + [path lineToPoint: NSMakePoint( left, bottom + arrowPosition + arrowSize )]; + [path lineToPoint: NSMakePoint( left - arrowSize, bottom + arrowPosition )]; + [path lineToPoint: NSMakePoint( left, bottom + arrowPosition - arrowSize )]; + } + + [path appendBezierPathWithArcFromPoint: NSMakePoint( left, bottom ) + toPoint: NSMakePoint( left + cornerRadius, bottom ) + radius: cornerRadius]; + + if (arrowEdge == ArrowBottomEdge) { + [path lineToPoint: NSMakePoint( arrowPosition - arrowSize, bottom )]; + [path lineToPoint: NSMakePoint( arrowPosition, bottom - arrowSize )]; + [path lineToPoint: NSMakePoint( arrowPosition + arrowSize, bottom )]; + } + + [path appendBezierPathWithArcFromPoint: NSMakePoint( right, bottom ) + toPoint: NSMakePoint( right, bottom + cornerRadius ) + radius: cornerRadius]; + + if (arrowEdge == ArrowRightEdge) { + [path lineToPoint: NSMakePoint( right, bottom + arrowPosition - arrowSize )]; + [path lineToPoint: NSMakePoint( right + arrowSize, bottom + arrowPosition )]; + [path lineToPoint: NSMakePoint( right, bottom + arrowPosition + arrowSize )]; + } + + [path appendBezierPathWithArcFromPoint: NSMakePoint( right, top ) + toPoint: NSMakePoint( right - cornerRadius, top ) + radius: cornerRadius]; + [path closePath]; + + [[NSColor colorWithDeviceWhite: 1.0 alpha: 0.4] set]; + [[NSColor colorWithDeviceWhite: 0.0 alpha: 0.75] setFill]; + + NSAffineTransform *transform = [NSAffineTransform transform]; + [transform translateXBy: bounds.origin.x yBy: bounds.origin.y]; + [transform concat]; + + [path setLineWidth: 2.0]; + [path fill]; + [path stroke]; + + if (updateShadow) { + [[self window] invalidateShadow]; + [[self window] update]; + updateShadow = NO; + } +} + +@end |