RectsView.m
/* |
File: RectsView.m |
Abstract: RectsView is the ruler view's client in this test app. It tries to handle most ruler operations. |
Version: 1.1 |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple |
Inc. ("Apple") in consideration of your agreement to the following |
terms, and your use, installation, modification or redistribution of |
this Apple software constitutes acceptance of these terms. If you do |
not agree with these terms, please do not use, install, modify or |
redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and |
subject to these terms, Apple grants you a personal, non-exclusive |
license, under Apple's copyrights in this original Apple software (the |
"Apple Software"), to use, reproduce, modify and redistribute the Apple |
Software, with or without modifications, in source and/or binary forms; |
provided that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the following |
text and disclaimers in all such redistributions of the Apple Software. |
Neither the name, trademarks, service marks or logos of Apple Inc. may |
be used to endorse or promote products derived from the Apple Software |
without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or |
implied, are granted by Apple herein, including but not limited to any |
patent rights that may be infringed by your derivative works or by other |
works in which the Apple Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
Copyright (C) 2012 Apple Inc. All Rights Reserved. |
*/ |
#import "RectsView.h" |
#import "ColorRect.h" |
#import "NestleView.h" |
/* These images are displayed as markers on the rulers. */ |
static NSImage *leftImage; |
static NSImage *rightImage; |
static NSImage *topImage; |
static NSImage *bottomImage; |
/* These strings are used to identify the markers. */ |
#define STR_LEFT @"Left Edge" |
#define STR_RIGHT @"Right Edge" |
#define STR_TOP @"Top Edge" |
#define STR_BOTTOM @"Bottom Edge" |
@implementation RectsView |
+ (void)initialize |
{ |
static BOOL beenHere = NO; |
NSBundle *mainBundle; |
NSString *path; |
NSArray *upArray; |
NSArray *downArray; |
if (beenHere) return; |
beenHere = YES; |
mainBundle = [NSBundle mainBundle]; |
path = [mainBundle pathForResource:@"EdgeMarkerLeft" ofType:@"tiff"]; |
leftImage = [[NSImage alloc] initByReferencingFile:path]; |
path = [mainBundle pathForResource:@"EdgeMarkerRight" ofType:@"tiff"]; |
rightImage = [[NSImage alloc] initByReferencingFile:path]; |
path = [mainBundle pathForResource:@"EdgeMarkerTop" ofType:@"tiff"]; |
topImage = [[NSImage alloc] initByReferencingFile:path]; |
path = [mainBundle pathForResource:@"EdgeMarkerBottom" ofType:@"tiff"]; |
bottomImage = [[NSImage alloc] initByReferencingFile:path]; |
upArray = [NSArray arrayWithObjects:[NSNumber numberWithDouble:2.0], nil]; |
downArray = [NSArray arrayWithObjects:[NSNumber numberWithDouble:0.5], |
[NSNumber numberWithDouble:0.2], nil]; |
[NSRulerView registerUnitWithName:@"Grummets" |
abbreviation:NSLocalizedString(@"gt", @"Grummets abbreviation string") |
unitToPointsConversionFactor:100.0 |
stepUpCycle:upArray stepDownCycle:downArray]; |
return; |
} |
- (id)initWithFrame:(NSRect)frameRect |
{ |
NSRect aRect; |
ColorRect *firstRect; |
self = [super initWithFrame:frameRect]; |
if (!self) return nil; |
[self setBoundsOrigin:NSMakePoint(-108.0, -108.0)]; |
rects = [[NSMutableArray alloc] init]; |
selectedItem = nil; |
aRect = NSMakeRect(30.0, 45.0, 57.0, 118.0); |
firstRect = [[ColorRect alloc] initWithFrame:aRect color:[NSColor blueColor]]; |
[rects addObject:firstRect]; |
[firstRect release]; |
return self; |
} |
- (void)setRulerOffsets |
{ |
NSScrollView *scrollView = [self enclosingScrollView]; |
NSRulerView *horizRuler; |
NSRulerView *vertRuler; |
NSView *docView; |
NSView *clientView; |
NSPoint zero; |
docView = [scrollView documentView]; |
clientView = self; |
if (!scrollView) return; |
horizRuler = [scrollView horizontalRulerView]; |
vertRuler = [scrollView verticalRulerView]; |
zero = [docView convertPoint:[clientView bounds].origin fromView:clientView]; |
[horizRuler setOriginOffset:zero.x - [docView bounds].origin.x]; |
[vertRuler setOriginOffset:zero.y - [docView bounds].origin.y]; |
return; |
} |
- (void)awakeFromNib |
{ |
NSScrollView *scrollView = [self enclosingScrollView]; |
if (!scrollView) return; |
[scrollView setHasHorizontalRuler:YES]; |
[scrollView setHasVerticalRuler:YES]; |
[self setRulerOffsets]; |
[self updateRulers]; |
[scrollView setRulersVisible:YES]; |
return; |
} |
- (BOOL)acceptsFirstResponder |
{ |
return YES; |
} |
- (BOOL)isFlipped |
{ |
return YES; |
} |
- (void)drawRect:(NSRect)aRect |
{ |
NSEnumerator *numer; |
ColorRect *thisRect; |
[[NSColor whiteColor] set]; |
NSRectFill(aRect); |
numer = [rects objectEnumerator]; |
while ((thisRect = [numer nextObject])) { |
if (NSIntersectsRect([thisRect frame], aRect)) { |
[thisRect drawRect:aRect selected:(thisRect == selectedItem)]; |
} |
} |
[[NSColor blackColor] set]; |
[NSBezierPath strokeLineFromPoint:NSMakePoint(-10.0, 0.0) toPoint:NSMakePoint(10.0, 0.0)]; |
[NSBezierPath strokeLineFromPoint:NSMakePoint(0.0, -10.0) toPoint:NSMakePoint(0.0, 10.0)]; |
return; |
} |
- (void)moveselectedItemWithEvent:(NSEvent *)theEvent mouseOffset:(NSPoint)mouseOffset |
{ |
NSRect oldRect, newRect, bounds; |
NSPoint mouseLoc; |
mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; |
bounds = [self bounds]; |
oldRect = newRect = [selectedItem frame]; |
newRect.origin.x = mouseLoc.x - mouseOffset.x; |
newRect.origin.y = mouseLoc.y - mouseOffset.y; |
if (NSMinX(newRect) < NSMinX(bounds)) { |
newRect.origin.x = NSMinX(bounds); |
} |
if (NSMaxX(newRect) > NSMaxX(bounds)) { |
newRect.origin.x = NSMaxX(bounds) - NSWidth(newRect); |
} |
if (NSMinY(newRect) < NSMinY(bounds)) { |
newRect.origin.y = NSMinY(bounds); |
} |
if (NSMaxY(newRect) > NSMaxY(bounds)) { |
newRect.origin.y = NSMaxY(bounds) - NSHeight(newRect); |
} |
[selectedItem setFrame:newRect]; |
[self updateRulerlinesWithOldRect:oldRect newRect:newRect]; |
[self setNeedsDisplayInRect:oldRect]; |
[self setNeedsDisplayInRect:newRect]; |
return; |
} |
- (void)mouseDown:(NSEvent *)theEvent |
{ |
NSEnumerator *numer; |
ColorRect *oldselectedItem = selectedItem; |
ColorRect *thisRect; |
NSPoint mouseLoc; |
NSPoint mouseOffset; |
NSUInteger eventMask; |
BOOL dragged = NO; |
BOOL timerOn = NO; |
NSEvent *autoscrollEvent = nil; |
selectedItem = nil; |
if (![[self window] makeFirstResponder:self]) return; |
mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; |
numer = [rects reverseObjectEnumerator]; |
while ((thisRect = [numer nextObject])) { |
if ([self mouse:mouseLoc inRect:[thisRect frame]]) { |
selectedItem = thisRect; |
break; |
} |
} |
if (oldselectedItem != selectedItem) { |
[self setNeedsDisplayInRect:[oldselectedItem frame]]; |
[self setNeedsDisplayInRect:[selectedItem frame]]; |
[self updateRulers]; |
} |
if (selectedItem == nil || [selectedItem isLocked]) return; |
mouseOffset.x = mouseLoc.x - [selectedItem frame].origin.x; |
mouseOffset.y = mouseLoc.y - [selectedItem frame].origin.y; |
eventMask = NSLeftMouseDraggedMask | NSLeftMouseUpMask | NSPeriodicMask; |
while ((theEvent = [[self window] nextEventMatchingMask:eventMask])) { |
NSRect visibleRect = [self visibleRect]; |
switch ([theEvent type]) { |
case NSPeriodic: |
if (autoscrollEvent) [self autoscroll:autoscrollEvent]; |
[self moveselectedItemWithEvent:autoscrollEvent |
mouseOffset:mouseOffset]; |
break; |
case NSLeftMouseDragged: |
if (!dragged) { |
[self drawRulerlinesWithRect:[selectedItem frame]]; |
} |
dragged = YES; |
mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; |
[self moveselectedItemWithEvent:theEvent mouseOffset:mouseOffset]; |
if (![self mouse:mouseLoc inRect:visibleRect]) { |
if (NO == timerOn) { |
[NSEvent startPeriodicEventsAfterDelay:0.1 withPeriod:0.1]; |
timerOn = YES; |
if (autoscrollEvent) [autoscrollEvent release]; |
autoscrollEvent = [theEvent retain]; |
} else { |
if (autoscrollEvent) [autoscrollEvent release]; |
autoscrollEvent = [theEvent retain]; |
} |
break; |
} else if (YES == timerOn) { |
[NSEvent stopPeriodicEvents]; |
timerOn = NO; |
if (autoscrollEvent) [autoscrollEvent release]; |
autoscrollEvent = nil; |
} |
[self displayIfNeeded]; |
break; |
case NSLeftMouseUp: |
if (YES == timerOn) { |
[NSEvent stopPeriodicEvents]; // No need to set timerOn = NO, since we are returning |
if (autoscrollEvent) [autoscrollEvent release]; |
autoscrollEvent = nil; |
} |
if (dragged) [self eraseRulerlinesWithRect:[selectedItem frame]]; |
[self updateRulers]; |
return; |
default: |
break; |
} |
} |
if (autoscrollEvent) [autoscrollEvent release]; |
return; |
} |
- (void)selectRect:(ColorRect *)aColorRect |
{ |
if (selectedItem == aColorRect) return; |
if (selectedItem) [self setNeedsDisplayInRect:[selectedItem frame]]; |
if (aColorRect == nil) selectedItem = nil; |
else if ([rects containsObject:aColorRect]) selectedItem = aColorRect; |
[self updateRulers]; |
if (selectedItem) [self setNeedsDisplayInRect:[selectedItem frame]]; |
return; |
} |
- (void)lock:(id)sender |
{ |
if (selectedItem) { |
[selectedItem setLocked:![selectedItem isLocked]]; |
[self setNeedsDisplayInRect:[selectedItem frame]]; |
} |
return; |
} |
#define ZOOMINFACTOR (2.0) |
#define ZOOMOUTFACTOR (1.0 / ZOOMINFACTOR) |
- (void)zoomIn:(id)sender |
{ |
NSRect tempRect; |
NSRect oldBounds; |
NSScrollView *scrollView = [self enclosingScrollView]; |
oldBounds = [self bounds]; |
tempRect = [self frame]; |
tempRect.size.width = ZOOMINFACTOR * NSWidth(tempRect); |
tempRect.size.height = ZOOMINFACTOR * NSHeight(tempRect); |
[self setFrame:tempRect]; |
[self setBoundsSize:oldBounds.size]; |
[self setBoundsOrigin:oldBounds.origin]; |
if (scrollView) [scrollView setNeedsDisplay:YES]; |
else [[self superview] setNeedsDisplay:YES]; |
return; |
} |
- (void)zoomOut:(id)sender |
{ |
NSRect tempRect; |
NSRect oldBounds; |
NSScrollView *scrollView = [self enclosingScrollView]; |
oldBounds = [self bounds]; |
tempRect = [self frame]; |
tempRect.size.width = ZOOMOUTFACTOR * NSWidth(tempRect); |
tempRect.size.height = ZOOMOUTFACTOR * NSHeight(tempRect); |
[self setFrame:tempRect]; |
[self setBoundsSize:oldBounds.size]; |
[self setBoundsOrigin:oldBounds.origin]; |
if (scrollView) [scrollView setNeedsDisplay:YES]; |
else [[self superview] setNeedsDisplay:YES]; |
return; |
} |
/* -nestle: slips a larger view between the enclosing NSClipView and the |
* receiver, and adjusts the ruler origin to lie at the same point in the |
* receiver. Apps that tile pages differently might want to do this when |
* an NSView representing a page is moved. */ |
- (void)nestle:(id)sender |
{ |
NSScrollView *enclosingScrollView = [self enclosingScrollView]; |
if (!enclosingScrollView) return; |
if ([[self superview] isKindOfClass:[NestleView class]]) { |
[enclosingScrollView setDocumentView:self]; |
} else { |
NSRect nFrame, rFrame; |
NestleView *nView; |
rFrame = [self frame]; |
nFrame = NSMakeRect(0.0, 0.0, rFrame.size.width + 64.0, |
rFrame.size.height + 64.0); |
nView = [[[NestleView alloc] initWithFrame:nFrame] autorelease]; |
[enclosingScrollView setDocumentView:nil]; // self vanishes without this! |
[nView addSubview:self]; |
rFrame.origin.x = rFrame.origin.y = 32.0; |
[self setFrame:rFrame]; |
[enclosingScrollView setDocumentView:nView]; |
} |
[[self window] makeFirstResponder:self]; |
[self setRulerOffsets]; |
[self updateRulers]; |
[enclosingScrollView setNeedsDisplay:YES]; |
return; |
} |
- (void)drawRulerlinesWithRect:(NSRect)aRect; |
{ |
NSScrollView *scrollView = [self enclosingScrollView]; |
NSRulerView *horizRuler; |
NSRulerView *vertRuler; |
NSRect convRect; |
if (!scrollView) return; |
horizRuler = [scrollView horizontalRulerView]; |
vertRuler = [scrollView verticalRulerView]; |
if (horizRuler) { |
convRect = [self convertRect:aRect toView:horizRuler]; |
[horizRuler moveRulerlineFromLocation:-1.0 |
toLocation:NSMinX(convRect)]; |
[horizRuler moveRulerlineFromLocation:-1.0 |
toLocation:NSMaxX(convRect)]; |
} |
if (vertRuler) { |
convRect = [self convertRect:aRect toView:vertRuler]; |
[vertRuler moveRulerlineFromLocation:-1.0 |
toLocation:NSMinY(convRect)]; |
[vertRuler moveRulerlineFromLocation:-1.0 |
toLocation:NSMaxY(convRect)]; |
} |
return; |
} |
- (void)updateRulerlinesWithOldRect:(NSRect)oldRect newRect:(NSRect)newRect |
{ |
NSScrollView *scrollView = [self enclosingScrollView]; |
NSRulerView *horizRuler; |
NSRulerView *vertRuler; |
NSRect convOldRect, convNewRect; |
if (!scrollView) return; |
horizRuler = [scrollView horizontalRulerView]; |
vertRuler = [scrollView verticalRulerView]; |
if (horizRuler) { |
convOldRect = [self convertRect:oldRect toView:horizRuler]; |
convNewRect = [self convertRect:newRect toView:horizRuler]; |
[horizRuler moveRulerlineFromLocation:NSMinX(convOldRect) |
toLocation:NSMinX(convNewRect)]; |
[horizRuler moveRulerlineFromLocation:NSMaxX(convOldRect) |
toLocation:NSMaxX(convNewRect)]; |
} |
if (vertRuler) { |
convOldRect = [self convertRect:oldRect toView:vertRuler]; |
convNewRect = [self convertRect:newRect toView:vertRuler]; |
[vertRuler moveRulerlineFromLocation:NSMinY(convOldRect) |
toLocation:NSMinY(convNewRect)]; |
[vertRuler moveRulerlineFromLocation:NSMaxY(convOldRect) |
toLocation:NSMaxY(convNewRect)]; |
} |
return; |
} |
- (void)eraseRulerlinesWithRect:(NSRect)aRect; |
{ |
NSScrollView *scrollView = [self enclosingScrollView]; |
NSRulerView *horizRuler; |
NSRulerView *vertRuler; |
if (!scrollView) return; |
horizRuler = [scrollView horizontalRulerView]; |
vertRuler = [scrollView verticalRulerView]; |
if (horizRuler) { |
[horizRuler setNeedsDisplay:YES]; |
} |
if (vertRuler) { |
[vertRuler setNeedsDisplay:YES]; |
} |
return; |
} |
- (void)updateHorizontalRuler |
{ |
NSScrollView *scrollView; |
NSRulerView *horizRuler; |
NSRulerMarker *leftMarker; |
NSRulerMarker *rightMarker; |
scrollView = [self enclosingScrollView]; |
if (!scrollView) return; |
horizRuler = [scrollView horizontalRulerView]; |
if (!horizRuler) return; |
if ([horizRuler clientView] != self) { |
[horizRuler setClientView:self]; |
[horizRuler setMeasurementUnits:@"Grummets"]; |
} |
if (!selectedItem) { |
[horizRuler setMarkers:nil]; |
return; |
} |
leftMarker = [[NSRulerMarker alloc] initWithRulerView:horizRuler |
markerLocation:NSMinX([selectedItem frame]) image:leftImage |
imageOrigin:NSMakePoint(0.0, 0.0)]; |
rightMarker = [[NSRulerMarker alloc] initWithRulerView:horizRuler |
markerLocation:NSMaxX([selectedItem frame]) image:rightImage |
imageOrigin:NSMakePoint(7.0, 0.0)]; |
[leftMarker setRemovable:YES]; |
[rightMarker setRemovable:YES]; |
[leftMarker setRepresentedObject:STR_LEFT]; |
[rightMarker setRepresentedObject:STR_RIGHT]; |
[horizRuler setMarkers:[NSArray arrayWithObjects:leftMarker, rightMarker, nil]]; |
[leftMarker release]; |
[rightMarker release]; |
return; |
} |
- (void)updateVerticalRuler |
{ |
NSScrollView *scrollView; |
NSRulerView *vertRuler; |
NSPoint thePoint; /* Just a temporary scratch variable */ |
CGFloat location; |
NSRulerMarker *topMarker; |
NSRulerMarker *bottomMarker; |
scrollView = [self enclosingScrollView]; |
if (!scrollView) return; |
vertRuler = [scrollView verticalRulerView]; |
if (!vertRuler) return; |
if ([vertRuler clientView] != self) { |
[vertRuler setClientView:self]; |
[vertRuler setMeasurementUnits:@"Grummets"]; |
} |
if (!selectedItem) { |
[vertRuler setMarkers:nil]; |
return; |
} |
if ([self isFlipped]) location = NSMaxY([selectedItem frame]); |
else location = NSMinY([selectedItem frame]); |
thePoint = NSMakePoint(8.0, 1.0); |
bottomMarker = [[NSRulerMarker alloc] initWithRulerView:vertRuler |
markerLocation:location image:bottomImage |
imageOrigin:thePoint]; |
[bottomMarker setRemovable:YES]; |
[bottomMarker setRepresentedObject:STR_BOTTOM]; |
if ([self isFlipped]) location = NSMinY([selectedItem frame]); |
else location = NSMaxY([selectedItem frame]); |
thePoint = NSMakePoint(8.0, 8.0); |
topMarker = [[NSRulerMarker alloc] initWithRulerView:vertRuler |
markerLocation:location image:topImage |
imageOrigin:thePoint]; |
[topMarker setRemovable:YES]; |
[topMarker setRepresentedObject:STR_TOP]; |
[vertRuler setMarkers:[NSArray arrayWithObjects:bottomMarker, topMarker, nil]]; |
[topMarker release]; |
[bottomMarker release]; |
return; |
} |
- (void)updateRulers |
{ |
[self updateHorizontalRuler]; |
[self updateVerticalRuler]; |
return; |
} |
- (void)updateSelectedRectFromRulers |
{ |
NSRulerView *horizRuler; |
NSRulerView *vertRuler; |
NSArray *markers; |
CGFloat m1Loc, m2Loc; |
NSRect newRect; |
if (!selectedItem) return; |
horizRuler = [[self enclosingScrollView] horizontalRulerView]; |
markers = [horizRuler markers]; |
if ([markers count] != 2) return; |
m1Loc = [[markers objectAtIndex:0] markerLocation]; |
m2Loc = [[markers objectAtIndex:1] markerLocation]; |
if (m1Loc < m2Loc) { |
newRect.origin.x = m1Loc; |
newRect.size.width = m2Loc - m1Loc; |
} else { |
newRect.origin.x = m2Loc; |
newRect.size.width = m1Loc - m2Loc; |
} |
vertRuler = [[self enclosingScrollView] verticalRulerView]; |
markers = [vertRuler markers]; |
if ([markers count] != 2) return; |
m1Loc = [[markers objectAtIndex:0] markerLocation]; |
m2Loc = [[markers objectAtIndex:1] markerLocation]; |
if (m1Loc < m2Loc) { |
newRect.origin.y = m1Loc; |
newRect.size.height = m2Loc - m1Loc; |
} else { |
newRect.origin.y = m2Loc; |
newRect.size.height = m1Loc - m2Loc; |
} |
[self setNeedsDisplayInRect:[selectedItem frame]]; |
[selectedItem setFrame:newRect]; |
[self setNeedsDisplayInRect:newRect]; |
return; |
} |
/*********** |
* NSRulerView client methods |
*/ |
- (BOOL)rulerView:(NSRulerView *)aRulerView |
shouldMoveMarker:(NSRulerMarker *)aMarker |
{ |
if (!selectedItem || [selectedItem isLocked]) return NO; |
return YES; |
} |
- (CGFloat)rulerView:(NSRulerView *)aRulerView |
willMoveMarker:(NSRulerMarker *)aMarker |
toLocation:(CGFloat)location |
{ |
NSEvent *currentEvent; |
NSUInteger eventFlags; |
BOOL shifted; |
NSRect rect, dirtyRect; |
NSString *theEdge = (NSString *)[aMarker representedObject]; |
if (!selectedItem) return location; |
rect = [selectedItem frame]; |
dirtyRect = rect; |
dirtyRect.size.width = NSWidth(rect) + 2.0; // fudge to counter hilite prob |
dirtyRect.size.height = NSHeight(rect) + 2.0; |
[self setNeedsDisplayInRect:dirtyRect]; |
currentEvent = [NSApp currentEvent]; |
eventFlags = [currentEvent modifierFlags]; |
shifted = (eventFlags & NSShiftKeyMask) ? YES : NO; |
#define MINSIZE (5.0) |
if (!shifted) { |
if ([theEdge isEqualToString:STR_LEFT]) { |
if (location > (NSMaxX(rect) - MINSIZE)) { |
location = (NSMaxX(rect) - MINSIZE); |
} |
rect.size.width = NSMaxX(rect) - location; |
rect.origin.x = location; |
} |
else if ([theEdge isEqualToString:STR_RIGHT]) { |
if (location < (NSMinX(rect) + MINSIZE)) { |
location = (NSMinX(rect) + MINSIZE); |
} |
rect.size.width = location - NSMinX(rect); |
} |
else if ([theEdge isEqualToString:STR_TOP]) { |
if ([self isFlipped]) { |
if (location > (NSMaxY(rect) - MINSIZE)) { |
location = (NSMaxY(rect) - MINSIZE); |
} |
rect.size.height = NSMaxY(rect) - location; |
rect.origin.y = location; |
} else { |
if (location < (NSMinY(rect) + MINSIZE)) { |
location = (NSMinY(rect) + MINSIZE); |
} |
rect.size.height = location - NSMinY(rect); |
} |
} |
else if ([theEdge isEqualToString:STR_BOTTOM]) { |
if ([self isFlipped]) { |
if (location < (NSMinY(rect) + MINSIZE)) { |
location = (NSMinY(rect) + MINSIZE); |
} |
rect.size.height = location - NSMinY(rect); |
} else { |
if (location > (NSMaxY(rect) - MINSIZE)) { |
location = (NSMaxY(rect) - MINSIZE); |
} |
rect.size.height = NSMaxY(rect) - location; |
rect.origin.y = location; |
} |
} /* if theEdge equal... */ |
} else { |
NSArray *markers = [aRulerView markers]; |
NSRulerMarker *otherMarker; |
otherMarker = [markers objectAtIndex:0]; |
if (otherMarker == aMarker) otherMarker = [markers objectAtIndex:1]; |
if ([theEdge isEqualToString:STR_LEFT]) { |
rect.origin.x = location; |
[otherMarker setMarkerLocation:NSMaxX(rect)]; |
} |
else if ([theEdge isEqualToString:STR_RIGHT]) { |
rect.origin.x = location - NSWidth(rect); |
[otherMarker setMarkerLocation:NSMinX(rect)]; |
} |
else if ([theEdge isEqualToString:STR_TOP]) { |
if ([self isFlipped]) { |
rect.origin.y = location; |
[otherMarker setMarkerLocation:NSMaxY(rect)]; |
} else { |
rect.origin.y = location - NSHeight(rect); |
[otherMarker setMarkerLocation:NSMinY(rect)]; |
} |
} |
else if ([theEdge isEqualToString:STR_BOTTOM]) { |
if ([self isFlipped]) { |
rect.origin.y = location - NSHeight(rect); |
[otherMarker setMarkerLocation:NSMinY(rect)]; |
} else { |
rect.origin.y = location; |
[otherMarker setMarkerLocation:NSMaxY(rect)]; |
} |
} |
} |
[selectedItem setFrame:rect]; |
[self setNeedsDisplayInRect:rect]; |
return location; |
} |
- (void)rulerView:(NSRulerView *)aRulerView |
didMoveMarker:(NSRulerMarker *)aMarker |
{ |
[self updateSelectedRectFromRulers]; |
return; |
} |
- (BOOL)rulerView:(NSRulerView *)aRulerView |
shouldRemoveMarker:(NSRulerMarker *)aMarker |
{ |
if (selectedItem && ![selectedItem isLocked]) return YES; |
return NO; |
} |
- (void)rulerView:(NSRulerView *)aRulerView |
didRemoveMarker:(NSRulerMarker *)aMarker |
{ |
if (!selectedItem) return; |
[self setNeedsDisplayInRect:[selectedItem frame]]; |
[rects removeObject:selectedItem]; |
selectedItem = nil; |
[self updateRulers]; |
return; |
} |
- (BOOL)rulerView:(NSRulerView *)aRulerView |
shouldAddMarker:(NSRulerMarker *)aMarker |
{ |
return YES; |
} |
- (CGFloat)rulerView:(NSRulerView *)aRulerView |
willAddMarker:(NSRulerMarker *)aMarker |
atLocation:(CGFloat)location |
{ |
return location; |
} |
static CGFloat frand(void) { return (CGFloat)rand() / (pow(2, 31)-1); } |
- (void)rulerView:(NSRulerView *)aRulerView |
didAddMarker:(NSRulerMarker *)aMarker |
{ |
NSRect visibleRect; |
CGFloat theOtherCoord; |
NSRect newRect; |
NSColor *newColor; |
ColorRect *newColorRect; |
visibleRect = [self visibleRect]; |
[aMarker setRemovable:YES]; |
if ([aRulerView orientation] == NSHorizontalRuler) { |
theOtherCoord = NSMaxY(visibleRect) - 165.0; |
newRect = NSMakeRect([aMarker markerLocation], theOtherCoord, 115.0, 115.0); |
} else { |
if ([self isFlipped]) { |
theOtherCoord = NSMinX(visibleRect) + 50; |
newRect = NSMakeRect(theOtherCoord, [aMarker markerLocation], |
115.0, 115.0); |
} else { |
theOtherCoord = NSMinX(visibleRect) + 50; |
newRect = NSMakeRect(theOtherCoord, [aMarker markerLocation] - 115.0, |
115.0, 115.0); |
} |
} |
newColor = [NSColor colorWithCalibratedRed:frand() green:frand() |
blue:frand() alpha:1.0]; |
newColorRect = [[ColorRect alloc] initWithFrame:newRect color:newColor]; |
[rects addObject:newColorRect]; |
[newColorRect release]; |
[self selectRect:newColorRect]; |
return; |
} |
- (void)rulerView:(NSRulerView *)aRulerView |
handleMouseDown:(NSEvent *)theEvent |
{ |
NSRulerMarker *newMarker; |
if ([aRulerView orientation] == NSHorizontalRuler) { |
newMarker = [[NSRulerMarker alloc] initWithRulerView:aRulerView |
markerLocation:0.0 image:leftImage imageOrigin:NSZeroPoint]; |
} else { |
newMarker = [[NSRulerMarker alloc] initWithRulerView:aRulerView |
markerLocation:0.0 image:topImage imageOrigin:NSMakePoint(8.0, 8.0)]; |
} |
[aRulerView trackMarker:newMarker withMouseEvent:theEvent]; |
[newMarker release]; |
return; |
} |
- (void)rulerView:(NSRulerView *)aRulerView |
willSetClientView:(NSView *)newClient |
{ |
return; |
} |
@end |
Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2012-06-07