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.