This is Editor.m in view mode; [Download] [Up]
// Editor.m // // created by Martin Wennerberg on Sun 12-Nov-1995 // // when who modification #import "Editor.h" #import "MorphLine.h" #import "MorphDocument.h" #import "algebra.h" #import "NSBitmapImageRep_editing.h" #import "InspectorController.h" static void drawLine (NSPoint startPt, NSPoint endPt) { PSmoveto(startPt.x, startPt.y); PSarc(startPt.x, startPt.y, 2.0, 0, 360.0); PSmoveto(startPt.x, startPt.y); PSlineto(endPt.x, endPt.y); } static void drawKnob (NSPoint p) { PSmoveto(p.x - 2, p.y - 2); PSlineto(p.x - 2, p.y + 2); PSlineto(p.x + 2, p.y + 2); PSlineto(p.x + 2, p.y - 2); PSlineto(p.x - 2, p.y - 2); } @implementation Editor - (id)initWithFrame:(NSRect)rect; { self = [super initWithFrame:rect]; [self registerForDraggedTypes:[NSImage imagePasteboardTypes]]; [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]]; [self setToolTip:NSLocalizedString (@"Editor. Drop an image here", @"Editor before image")]; [self setNeedsDisplay:YES]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionChanged:) name:NOTIFICATION_SELECTION_CHANGED object:delegate]; return self; } - (BOOL) isFlipped { return NO; } - (BOOL) acceptsFirstResponder { return YES; } - (void) dealloc { [image release]; [super dealloc]; } - (NSImage *) image { if (image == nil) [self setImage:[delegate imageAtDelta:delta]]; return image; } - (void) setImage:(NSImage *)im { [image release]; image = [im retain]; [image setDataRetained:YES]; [image setScalesWhenResized:YES]; [image setSize:[self bounds].size]; [self setNeedsDisplay:YES]; if (image != nil) [self setToolTip:NSLocalizedString (@"Editor. Drag mouse to draw lines to indicate similar sections.", @"Editor after image")]; [delegate setImage:image atDelta:delta]; } - (void) setDelta:(float)d { delta = d; [self setNeedsDisplay:YES]; } - (float) delta { return delta; } - (void) setEditingIsEnabled:(BOOL)yn { editingIsEnabled = yn; } - (BOOL) editingIsEnabled { return editingIsEnabled; } - (void)resizeWithOldSuperviewSize:(NSSize)oldSize { [super resizeWithOldSuperviewSize:oldSize]; [[self image] setSize:[self bounds].size]; [self setNeedsDisplay:YES]; } - (void)keyDown:(NSEvent *)event { NSEnumerator *lineEnum = [[delegate morphLines] objectEnumerator]; MorphLine *line; NSArray *selectedLines = [delegate currentSelection]; int c; c = [event keyCode]; while ((line = [lineEnum nextObject])) if ([selectedLines containsObject:line]) switch (c) { case 14: // Backspace case 83: // Delete case NSDeleteFunctionKey: case NSClearLineFunctionKey: case NSDeleteLineFunctionKey: case NSDeleteCharFunctionKey: [delegate deleteMorphLine:line]; break; case NSUpArrowFunctionKey: case NSDownArrowFunctionKey: case NSLeftArrowFunctionKey: case NSRightArrowFunctionKey: // Implement moving here default: NSLog (@"Unknown keydown: %d", c); break; } } #define MOVE 0 #define RESIZE_STARTPT 1 #define RESIZE_ENDPT 2 #define CREATE 3 #define DRAGGING_MASK (NSLeftMouseUpMask|NSLeftMouseDraggedMask) - (void)mouseDown:(NSEvent *)event { short action; NSEnumerator *lineEnum; MorphLine *morphLine = nil; MorphLine *tmpLine; NSPoint startPt, endPt; NSPoint mousePt; float maxDist; NSRect oldRect; float xscale, yscale; NSPoint offset; NSPoint oldMousePt; BOOL shouldDeselect = (([event modifierFlags] & NSShiftKeyMask) == 0); xscale = NSWidth([self bounds]); yscale = NSHeight([self bounds]); maxDist = 9.0; mousePt = [self convertPoint:[event locationInWindow] fromView:nil]; oldMousePt = mousePt; lineEnum = [[delegate morphLines] objectEnumerator]; while ((tmpLine = [lineEnum nextObject])) { startPt = pt_scale([tmpLine startPointAtDelta:delta], xscale, yscale); endPt = pt_scale([tmpLine endPointAtDelta:delta], xscale, yscale); if (line_dist2_to_point(startPt, endPt, mousePt) <= maxDist) { morphLine = tmpLine; [delegate addToCurrentSelection:morphLine]; } else if (shouldDeselect) [delegate removeFromCurrentSelection:tmpLine]; } if (morphLine) { startPt = pt_scale([morphLine startPointAtDelta:delta], xscale, yscale); endPt = pt_scale([morphLine endPointAtDelta:delta], xscale, yscale); if (pt_dist2(mousePt, startPt) <= maxDist) action = RESIZE_STARTPT; else if (pt_dist2(mousePt, endPt) <= maxDist) action = RESIZE_ENDPT; else action = MOVE; } else { startPt = mousePt; action = CREATE; } [self lockFocus]; oldRect = NSInsetRect(rectContainingPoints(startPt,endPt), -4.0, -4.0); while ([event type] != NSLeftMouseUp) { event = [[self window] nextEventMatchingMask:DRAGGING_MASK]; mousePt = [self convertPoint:[event locationInWindow] fromView:nil]; switch (action) { case MOVE: offset = pt_sub(mousePt, oldMousePt); startPt = pt_sum(offset, pt_scale([morphLine startPointAtDelta:delta], xscale, yscale)); [morphLine setStartPoint:pt_scale(startPt,1.0/xscale,1.0/yscale) atDelta:delta]; endPt = pt_sum(offset, pt_scale([morphLine endPointAtDelta:delta], xscale, yscale)); [morphLine setEndPoint:pt_scale(endPt,1.0/xscale,1.0/yscale) atDelta:delta]; oldMousePt = mousePt; break; case RESIZE_ENDPT: endPt = mousePt; [morphLine setEndPoint:pt_scale(endPt,1.0/xscale,1.0/yscale) atDelta:delta]; break; case RESIZE_STARTPT: startPt = mousePt; [morphLine setStartPoint:pt_scale(startPt,1.0/xscale,1.0/yscale) atDelta:delta]; break; case CREATE: endPt = mousePt; break; } [self drawRect:oldRect]; drawLine (startPt, endPt); [[NSColor greenColor] set]; PSsetlinewidth(2.0); PSstroke(); [[self window] flushWindow]; oldRect = NSInsetRect(rectContainingPoints(startPt,endPt), -4.0, -4.0); } if (action == CREATE) { if (pt_dist(startPt, endPt) > 5.0) { morphLine = [[[MorphLine allocWithZone:[self zone]] init] autorelease]; [morphLine setStartPoint:pt_scale(startPt, 1.0/xscale, 1.0/yscale) atDelta:delta]; [morphLine setStartPoint:pt_scale(startPt, 1.0/xscale, 1.0/yscale) atDelta:1.0 - delta]; [morphLine setEndPoint:pt_scale(endPt, 1.0/xscale, 1.0/yscale) atDelta:delta]; [morphLine setEndPoint:pt_scale(endPt, 1.0/xscale, 1.0/yscale) atDelta:1.0 - delta]; [delegate addMorphLine:morphLine]; [delegate addToCurrentSelection:morphLine]; } } [self unlockFocus]; [[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:NOTIFICATION_SELECTION_CHANGED object:self] postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil]; [self setNeedsDisplay:YES]; } - (void) selectionChanged:(NSNotification *)notification { [self setNeedsDisplay:YES]; } - (void)drawRect:(NSRect)rect { NSArray *selectedLines = [delegate currentSelection]; NSEnumerator *lineEnum; MorphLine *morphLine; NSPoint startPt; NSPoint endPt; NSRect lineBounds; BOOL containsLine = NO; NSPoint p; p.x = NSMinX(rect); p.y = NSMaxY(rect); [[self image] compositeToPoint:rect.origin fromRect:rect operation:NSCompositeCopy]; lineEnum = [[delegate morphLines] objectEnumerator]; while ((morphLine = [lineEnum nextObject])) { startPt = [morphLine startPointAtDelta:delta]; endPt = [morphLine endPointAtDelta:delta]; startPt = pt_scale (startPt, NSWidth([self bounds]), NSHeight([self bounds])); endPt = pt_scale (endPt, NSWidth([self bounds]), NSHeight([self bounds])); // Find out if the line intersects the drawing rect // and if it does not then skip it. lineBounds = NSInsetRect(rectContainingPoints(startPt,endPt), -3.0, -3.0); if (NSIntersectsRect(rect, lineBounds)) { drawLine (startPt, endPt); if ([selectedLines containsObject:morphLine]) { drawKnob (startPt); drawKnob (endPt); } containsLine = YES; } } if (containsLine) { [[NSColor greenColor] set]; PSsetlinewidth(3.0); PSstroke(); } } @end @implementation Editor(Drag) - (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender { // NSPasteboard *pboard = [sender draggingPasteboard]; // if ([NSImage canInitWithPasteboard:pboard]) return NSDragOperationCopy; // else return NSDragOperationNone; } - (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender { return [self draggingEntered:sender]; } - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender { NSImage *im; NSString *filename; // im = [[[NSImage allocWithZone:[self zone]] initWithPasteboard:[sender draggingPasteboard]] autorelease]; filename = [[[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType] lastObject]; im = [[NSImage allocWithZone:[self zone]] initWithContentsOfFile:filename]; [im setScalesWhenResized:YES]; if (im) { [self setImage:[im autorelease]]; return YES; } else return NO; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.