home *** CD-ROM | disk | FTP | other *** search
- // 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
-