summaryrefslogtreecommitdiff
path: root/frontends/cocoa/ArrowBox.m
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/cocoa/ArrowBox.m')
-rw-r--r--frontends/cocoa/ArrowBox.m180
1 files changed, 180 insertions, 0 deletions
diff --git a/frontends/cocoa/ArrowBox.m b/frontends/cocoa/ArrowBox.m
new file mode 100644
index 000000000..6d6911d9b
--- /dev/null
+++ b/frontends/cocoa/ArrowBox.m
@@ -0,0 +1,180 @@
+/* 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"
+
+#import "desktop/system_colour.h"
+#import "cocoa/plotter.h"
+
+@interface ArrowBox ()
+
+@property (nonatomic) NSColor *backgroundColor;
+
+@end
+
+@implementation ArrowBox
+
+@synthesize arrowPosition;
+@synthesize arrowSize;
+@synthesize arrowEdge;
+@synthesize cornerRadius;
+
+- (NSColor *)backgroundColor {
+ if (!_backgroundColor) {
+ colour fill_colour;
+ nserror res = ns_system_colour_char("Window", &fill_colour);
+ NSAssert(res == NSERROR_OK, @"Expect to find the window colour");
+ _backgroundColor = cocoa_convert_colour(fill_colour);
+ }
+
+ return _backgroundColor;
+}
+
+- (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.window convertRectToScreen: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.window convertRectFromScreen: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];
+ [self.backgroundColor 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