From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/cocoa/ArrowWindow.m | 239 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 frontends/cocoa/ArrowWindow.m (limited to 'frontends/cocoa/ArrowWindow.m') diff --git a/frontends/cocoa/ArrowWindow.m b/frontends/cocoa/ArrowWindow.m new file mode 100644 index 000000000..8edc32e9f --- /dev/null +++ b/frontends/cocoa/ArrowWindow.m @@ -0,0 +1,239 @@ +/* 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 "ArrowWindow.h" +#import "ArrowBox.h" + +@implementation ArrowWindow + +@synthesize acceptsKey; + +- (id) initWithContentRect: (NSRect)contentRect styleMask: (NSUInteger)aStyle backing: (NSBackingStoreType)bufferingType defer: (BOOL)flag +{ + if ((self = [super initWithContentRect: contentRect styleMask: NSBorderlessWindowMask backing: bufferingType defer: flag]) == nil) { + return nil; + } + + [self setBackgroundColor: [NSColor clearColor]]; + [self setOpaque: NO]; + [self setHasShadow: YES]; + + return self; +} + +- (void) setContentView: (NSView *)aView +{ + if (aView == content) return; + + [content removeFromSuperview]; + content = aView; + + if (content == nil) return; + + if (box == nil) { + box = [[ArrowBox alloc] initWithFrame: NSZeroRect]; + [box setArrowEdge: ArrowTopEdge]; + [super setContentView: box]; + [box release]; + } + + [box addSubview: content]; + + NSRect frame = [self contentRectForFrameRect: [self frame]]; + frame.origin = [self convertScreenToBase: frame.origin]; + frame = [box convertRect: frame fromView: nil]; + + [content setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [content setFrame: frame]; +} + +- (void) setContentSize: (NSSize)aSize +{ + NSRect frame = [content frame]; + frame.size = aSize; + + frame = [box convertRect: frame toView: nil]; + frame.origin = [self convertBaseToScreen: frame.origin]; + frame = [self frameRectForContentRect: frame]; + + [self setFrame: frame display: YES]; +} + +static const CGFloat padding = 0; + +- (NSRect) contentRectForFrameRect: (NSRect)frameRect +{ + const CGFloat arrowSize = [box arrowSize]; + const CGFloat offset = 2 * (padding + arrowSize ); + + return NSInsetRect( frameRect, offset, offset ); +} + +- (NSRect) frameRectForContentRect: (NSRect)contentRect +{ + const CGFloat arrowSize = [box arrowSize]; + const CGFloat offset = -2 * (padding + arrowSize ); + + return NSInsetRect( contentRect, offset, offset ); +} + ++ (NSRect) frameRectForContentRect: (NSRect)cRect styleMask: (NSUInteger)aStyle +{ + const CGFloat DefaultArrowSize = 15; + const CGFloat offset = -2 * (padding + DefaultArrowSize); + + return NSInsetRect( cRect, offset, offset ); +} + +- (BOOL) canBecomeKeyWindow +{ + return acceptsKey; +} + +- (void) moveToPoint: (NSPoint) screenPoint +{ + switch ([box arrowEdge]) { + case ArrowNone: + screenPoint.x -= [box arrowSize]; + screenPoint.y += [box arrowSize]; + break; + + case ArrowTopEdge: + screenPoint.x -= [box arrowPosition]; + break; + + case ArrowBottomEdge: + screenPoint.x -= [box arrowPosition]; + screenPoint.y += NSHeight( [self frame] ); + break; + + case ArrowLeftEdge: + screenPoint.y += NSHeight( [self frame] ) - [box arrowPosition] - [box arrowSize]; + break; + + case ArrowRightEdge: + screenPoint.x -= NSWidth( [self frame] ); + screenPoint.y += NSHeight( [self frame] ) - [box arrowPosition] - [box arrowSize]; + break; + } + + [self setFrameTopLeftPoint: screenPoint]; +} + +static NSRect ScreenRectForView( NSView *view ) +{ + NSRect viewRect = [view bounds]; // in View coordinate system + viewRect = [view convertRect: viewRect toView: nil]; // translate to window coordinates + viewRect.origin = [[view window] convertBaseToScreen: viewRect.origin]; // translate to screen coordinates + return viewRect; +} + +- (void) attachToView: (NSView *) view +{ + if (nil != attachedWindow) [self detach]; + + NSRect viewRect = ScreenRectForView( view ); + NSPoint arrowPoint; + + switch ([box arrowEdge]) { + case ArrowLeftEdge: + arrowPoint = NSMakePoint( NSMaxX( viewRect ), + NSMidY( viewRect ) ); + break; + + case ArrowBottomEdge: + arrowPoint = NSMakePoint( NSMidX( viewRect ), + NSMaxY( viewRect ) ); + break; + + case ArrowRightEdge: + arrowPoint = NSMakePoint( NSMinX( viewRect ), + NSMidY( viewRect ) ); + break; + + case ArrowNone: + case ArrowTopEdge: + default: + arrowPoint = NSMakePoint( NSMidX( viewRect ), + NSMinY( viewRect ) ); + break; + + } + attachedWindow = [view window]; + [self moveToPoint: arrowPoint]; + [attachedWindow addChildWindow: self ordered: NSWindowAbove]; +} + +- (void) detach +{ + [attachedWindow removeChildWindow: self]; + [self close]; + attachedWindow = nil; +} + +//MARK: - +//MARK: Properties + +- (void) setArrowPosition: (CGFloat) newPosition +{ + [box setArrowPosition: newPosition]; +} + +- (CGFloat) arrowPosition +{ + return [box arrowPosition]; +} + +- (void) setArrowSize: (CGFloat)newSize +{ + NSRect contentRect = [self contentRectForFrameRect: [self frame]]; + [box setArrowSize: newSize]; + [self setFrame: [self frameRectForContentRect: contentRect] display: [self isVisible]]; +} + +- (CGFloat) arrowSize +{ + return [box arrowSize]; +} + +- (void) setArrowEdge: (ArrowEdge) newEdge +{ + [box setArrowEdge: newEdge]; +} + +- (ArrowEdge) arrowEdge +{ + return [box arrowEdge]; +} + +- (void) setCornerRadius: (CGFloat)newRadius +{ + [box setCornerRadius: newRadius]; +} + +- (CGFloat) cornerRadius +{ + return [box cornerRadius]; +} + +@end -- cgit v1.2.3