Created
March 24, 2021 14:10
-
-
Save rickfillion/10d4d2ea2829880c2235f0e93c6e4088 to your computer and use it in GitHub Desktop.
Bodega Awning Window
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AwningWindow.m | |
// Bodega | |
// | |
// Created by Rick Fillion on 14/04/09. | |
// Copyright 2009 Centrix.ca. All rights reserved. | |
// | |
#import "AwningWindow.h" | |
#import "NSNotificationCenter+Bodega.h" | |
#include <tgmath.h> | |
@interface AwningWindow (Private) | |
- (NSEvent *)convertMouseEventToParentWindowEvent:(NSEvent *)event; | |
@end | |
@implementation AwningWindow | |
- (id) initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation | |
{ | |
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:FALSE]; | |
if (!self) { return nil; } | |
awningLeft = [[NSImage imageNamed:@"AwningLeft"] retain]; | |
awningRight = [[NSImage imageNamed:@"AwningRight"] retain]; | |
awningSlice = [[NSImage imageNamed:@"AwningSlice"] retain]; | |
[self setBackgroundColor: [self sizedBackground]]; | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[awningLeft release]; | |
[awningRight release]; | |
[awningSlice release]; | |
[super dealloc]; | |
} | |
- (NSColor *)sizedBackground | |
{ | |
NSSize windowSize = [self frame].size; | |
NSSize adjustedWindowSize = windowSize; | |
adjustedWindowSize.width += 100.0; // we add a bunch of whitespace here so that in Snow Leopard it doesn't show the wrap-around. | |
NSImage *awningCompositeImage = [[[NSImage alloc] initWithSize:adjustedWindowSize] autorelease]; | |
CGFloat sideSlices = 16; | |
CGFloat leftRightWidth = [awningLeft size].width + [awningRight size].width; | |
CGFloat remainingWidth = roundf(windowSize.width - leftRightWidth); | |
NSInteger sliceCount = ((NSInteger)remainingWidth) / ((NSInteger)[awningSlice size].width); | |
remainingWidth -= roundf(sliceCount * [awningSlice size].width); | |
CGFloat leftWidth = roundf([awningLeft size].width + (sideSlices / (sideSlices*2 + sliceCount)) * remainingWidth); | |
CGFloat rightWidth = roundf([awningRight size].width + (sideSlices / (sideSlices*2 + sliceCount)) * remainingWidth); | |
NSImage *slicesImage = nil; | |
if (sliceCount * [awningSlice size].width > 0) | |
{ | |
slicesImage = [[[NSImage alloc] initWithSize:NSMakeSize(sliceCount * [awningSlice size].width, [awningSlice size].height)] autorelease]; | |
NSRect sliceRect = NSMakeRect(0, 0, [awningSlice size].width, [awningSlice size].height); | |
[slicesImage lockFocus]; | |
for (NSInteger count = 0; count < sliceCount; count++) | |
{ | |
[awningSlice drawInRect:sliceRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | |
sliceRect.origin.x += round(sliceRect.size.width); | |
} | |
[slicesImage unlockFocus]; | |
} | |
[awningCompositeImage lockFocus]; | |
{ | |
if (leftWidth + rightWidth > windowSize.width) | |
{ | |
// there's no slices, and the images are just going to overlap cause the window's too small | |
leftWidth = roundf(windowSize.width/2); | |
rightWidth = roundf(windowSize.width - leftWidth); | |
} | |
if (!slicesImage && (leftWidth + rightWidth < windowSize.width)) | |
{ | |
// no slices, and the images don't quite take up enough room. make the left one bigger | |
leftWidth = roundf(windowSize.width - rightWidth); | |
} | |
NSRect leftRect = NSMakeRect(0, 0, leftWidth, [awningLeft size].height); | |
[awningLeft drawInRect:leftRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | |
NSRect slicesRect = NSMakeRect(leftWidth, 0, windowSize.width - leftWidth - rightWidth,[awningSlice size].height); | |
[slicesImage drawInRect:slicesRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | |
NSRect rightRect = NSMakeRect(windowSize.width-rightWidth, 0, rightWidth, [awningRight size].height); | |
[awningRight drawInRect:rightRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | |
} | |
[awningCompositeImage unlockFocus]; | |
return [NSColor colorWithPatternImage:awningCompositeImage]; | |
} | |
- (void)setFrame:(NSRect)windowFrame display:(BOOL)displayViews | |
{ | |
[self setBackgroundColor:[self sizedBackground]]; | |
[super setFrame:windowFrame display: YES]; | |
[self setBackgroundColor:[self sizedBackground]]; | |
} | |
- (void)setFrame:(NSRect)windowFrame display:(BOOL)displayViews animate:(BOOL)performAnimation | |
{ | |
[super setFrame:windowFrame display:NO animate:NO]; | |
[self setBackgroundColor:[self sizedBackground]]; | |
} | |
#pragma mark NSResponder | |
- (void)mouseDown:(NSEvent *)theEvent | |
{ | |
lastLocationInWindow = [theEvent locationInWindow]; | |
[[NSNotificationCenter defaultCenter] postNotificaitonAwningWindowDidStartMove]; | |
} | |
- (void)mouseDragged:(NSEvent*)theEvent | |
{ | |
NSWindow *mainWindow = [self parentWindow]; | |
CGFloat deltaX = lastLocationInWindow.x - [theEvent locationInWindow].x; | |
CGFloat deltaY = lastLocationInWindow.y - [theEvent locationInWindow].y; | |
NSRect frame = [mainWindow frame]; | |
frame.origin.x -= deltaX; | |
frame.origin.y -= deltaY; | |
[mainWindow setFrameOrigin:frame.origin]; | |
} | |
- (void)mouseUp:(NSEvent *)theEvent | |
{ | |
[[NSNotificationCenter defaultCenter] postNotificaitonAwningWindowDidEndMove]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment