home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / Rhapsody / Graphics / Morph-2.0a / Editor.m < prev    next >
Encoding:
Text File  |  1998-01-25  |  9.9 KB  |  346 lines

  1. // Editor.m
  2. //
  3. // created by Martin Wennerberg on Sun 12-Nov-1995
  4. //
  5. // when        who    modification
  6.  
  7. #import "Editor.h"
  8. #import "MorphLine.h"
  9. #import "MorphDocument.h"
  10. #import "algebra.h"
  11. #import "NSBitmapImageRep_editing.h"
  12. #import "InspectorController.h"
  13.  
  14. static void drawLine (NSPoint startPt, NSPoint endPt)
  15. {
  16.     PSmoveto(startPt.x, startPt.y);
  17.     PSarc(startPt.x, startPt.y, 2.0, 0, 360.0);
  18.     PSmoveto(startPt.x, startPt.y);
  19.     PSlineto(endPt.x, endPt.y);
  20. }
  21.  
  22. static void drawKnob (NSPoint p)
  23. {
  24.     PSmoveto(p.x - 2, p.y - 2);
  25.     PSlineto(p.x - 2, p.y + 2);
  26.     PSlineto(p.x + 2, p.y + 2);
  27.     PSlineto(p.x + 2, p.y - 2);
  28.     PSlineto(p.x - 2, p.y - 2);
  29. }
  30.  
  31. @implementation Editor
  32. - (id)initWithFrame:(NSRect)rect;
  33. {
  34.     self = [super initWithFrame:rect];
  35.     [self registerForDraggedTypes:[NSImage imagePasteboardTypes]];
  36.     [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
  37.     [self setToolTip:NSLocalizedString (@"Editor. Drop an image here", @"Editor before image")];
  38.     [self setNeedsDisplay:YES];
  39.     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionChanged:) name:NOTIFICATION_SELECTION_CHANGED object:delegate];
  40.     return self;
  41. }
  42.  
  43. - (BOOL) isFlipped
  44. {
  45.     return NO;
  46. }
  47.  
  48. - (BOOL) acceptsFirstResponder
  49. {
  50.     return YES;
  51. }
  52.  
  53. - (void) dealloc
  54. {
  55.     [image release];
  56.     [super dealloc];
  57. }
  58.  
  59. - (NSImage *) image
  60. {
  61.     if (image == nil)
  62.         [self setImage:[delegate imageAtDelta:delta]];
  63.     return image;
  64. }
  65.  
  66. - (void) setImage:(NSImage *)im
  67. {
  68.     [image release];
  69.     image = [im retain];
  70.     [image setDataRetained:YES];
  71.     [image setScalesWhenResized:YES];
  72.     [image setSize:[self bounds].size];
  73.     [self setNeedsDisplay:YES];
  74.     if (image != nil)
  75.         [self setToolTip:NSLocalizedString (@"Editor. Drag mouse to draw lines to indicate similar sections.", @"Editor after image")];
  76.     [delegate setImage:image atDelta:delta];
  77. }
  78.  
  79. - (void) setDelta:(float)d
  80. {
  81.     delta = d;
  82.     [self setNeedsDisplay:YES];
  83. }
  84.  
  85. - (float) delta
  86. {
  87.     return delta;
  88. }
  89.  
  90. - (void) setEditingIsEnabled:(BOOL)yn
  91. {
  92.     editingIsEnabled = yn;
  93. }
  94.  
  95. - (BOOL) editingIsEnabled
  96. {
  97.     return editingIsEnabled;
  98. }
  99.  
  100. - (void)resizeWithOldSuperviewSize:(NSSize)oldSize
  101. {
  102.     [super resizeWithOldSuperviewSize:oldSize];
  103.     [[self image] setSize:[self bounds].size];
  104.     [self setNeedsDisplay:YES];
  105. }
  106.  
  107. - (void)keyDown:(NSEvent *)event
  108. {
  109.     NSEnumerator *lineEnum = [[delegate morphLines] objectEnumerator];
  110.     MorphLine     *line;
  111.     NSArray      *selectedLines = [delegate currentSelection];
  112.     int              c;
  113.  
  114.     c = [event keyCode];
  115.     while ((line = [lineEnum nextObject]))
  116.         if ([selectedLines containsObject:line])
  117.             switch (c)
  118.             {
  119.                 case 14:    // Backspace
  120.                 case 83:    // Delete
  121.                 case NSDeleteFunctionKey:
  122.                 case NSClearLineFunctionKey:
  123.                 case NSDeleteLineFunctionKey:
  124.                 case NSDeleteCharFunctionKey:
  125.                     [delegate deleteMorphLine:line];
  126.                     break;
  127.                 case NSUpArrowFunctionKey:
  128.                 case NSDownArrowFunctionKey:
  129.                 case NSLeftArrowFunctionKey:
  130.                 case NSRightArrowFunctionKey:
  131.                     // Implement moving here
  132.                 default:
  133.                     NSLog (@"Unknown keydown: %d", c);
  134.                     break;
  135.             }
  136. }
  137.  
  138. #define MOVE        0
  139. #define RESIZE_STARTPT    1
  140. #define RESIZE_ENDPT    2
  141. #define    CREATE        3
  142. #define DRAGGING_MASK (NSLeftMouseUpMask|NSLeftMouseDraggedMask)
  143.  
  144. - (void)mouseDown:(NSEvent *)event
  145. {
  146.     short         action;
  147.     NSEnumerator    *lineEnum;
  148.     MorphLine        *morphLine = nil;
  149.     MorphLine        *tmpLine;
  150.     NSPoint         startPt, endPt;
  151.     NSPoint         mousePt;
  152.     float         maxDist;
  153.     NSRect         oldRect;
  154.     float         xscale, yscale;
  155.     NSPoint             offset;
  156.     NSPoint         oldMousePt;
  157.     BOOL         shouldDeselect = (([event modifierFlags] & NSShiftKeyMask) == 0);
  158.  
  159.     xscale = NSWidth([self bounds]);
  160.     yscale = NSHeight([self bounds]);
  161.     maxDist = 9.0;
  162.     mousePt = [self convertPoint:[event locationInWindow] fromView:nil];
  163.     oldMousePt = mousePt;
  164.     
  165.     lineEnum = [[delegate morphLines] objectEnumerator];
  166.  
  167.     while ((tmpLine = [lineEnum nextObject]))
  168.     {
  169.         startPt = pt_scale([tmpLine startPointAtDelta:delta], xscale, yscale);
  170.         endPt = pt_scale([tmpLine endPointAtDelta:delta], xscale, yscale);
  171.         
  172.         if (line_dist2_to_point(startPt, endPt, mousePt) <= maxDist)
  173.         {
  174.             morphLine = tmpLine;
  175.             [delegate addToCurrentSelection:morphLine];
  176.         }
  177.         else if (shouldDeselect)
  178.             [delegate removeFromCurrentSelection:tmpLine];
  179.     }
  180.  
  181.     if (morphLine)
  182.     {
  183.         startPt = pt_scale([morphLine startPointAtDelta:delta], xscale, yscale);
  184.         endPt = pt_scale([morphLine endPointAtDelta:delta], xscale, yscale);
  185.  
  186.         if (pt_dist2(mousePt, startPt) <= maxDist)
  187.             action = RESIZE_STARTPT;
  188.         else if (pt_dist2(mousePt, endPt) <= maxDist)
  189.             action = RESIZE_ENDPT;
  190.         else
  191.             action = MOVE;
  192.     }
  193.     else
  194.     {
  195.         startPt = mousePt;
  196.         action = CREATE;
  197.     }
  198.     
  199.     [self lockFocus];
  200.  
  201.     oldRect = NSInsetRect(rectContainingPoints(startPt,endPt), -4.0, -4.0);
  202.  
  203.     while ([event type] != NSLeftMouseUp)
  204.     {
  205.         event = [[self window] nextEventMatchingMask:DRAGGING_MASK];
  206.         mousePt = [self convertPoint:[event locationInWindow] fromView:nil];
  207.  
  208.         switch (action)
  209.         {
  210.         case MOVE:
  211.             offset = pt_sub(mousePt, oldMousePt);
  212.             startPt = pt_sum(offset, pt_scale([morphLine startPointAtDelta:delta], xscale, yscale));
  213.             [morphLine setStartPoint:pt_scale(startPt,1.0/xscale,1.0/yscale) atDelta:delta];
  214.             endPt = pt_sum(offset, pt_scale([morphLine endPointAtDelta:delta], xscale, yscale));
  215.             [morphLine setEndPoint:pt_scale(endPt,1.0/xscale,1.0/yscale) atDelta:delta];
  216.             oldMousePt = mousePt;
  217.             break;
  218.         case RESIZE_ENDPT:
  219.             endPt = mousePt;
  220.             [morphLine setEndPoint:pt_scale(endPt,1.0/xscale,1.0/yscale) atDelta:delta];
  221.             break;
  222.         case RESIZE_STARTPT:
  223.             startPt = mousePt;
  224.             [morphLine setStartPoint:pt_scale(startPt,1.0/xscale,1.0/yscale) atDelta:delta];
  225.             break;
  226.         case CREATE:
  227.             endPt = mousePt;
  228.             break;
  229.         }
  230.         [self drawRect:oldRect];
  231.         drawLine (startPt, endPt);
  232.         [[NSColor greenColor] set];
  233.         PSsetlinewidth(2.0);
  234.         PSstroke();
  235.         [[self window] flushWindow];
  236.         oldRect = NSInsetRect(rectContainingPoints(startPt,endPt), -4.0, -4.0);
  237.     }
  238.     if (action == CREATE)
  239.     {
  240.         if (pt_dist(startPt, endPt) > 5.0)
  241.         {
  242.             morphLine = [[[MorphLine allocWithZone:[self zone]] init] autorelease];
  243.             [morphLine setStartPoint:pt_scale(startPt, 1.0/xscale, 1.0/yscale) atDelta:delta];
  244.             [morphLine setStartPoint:pt_scale(startPt, 1.0/xscale, 1.0/yscale) atDelta:1.0 - delta];
  245.             [morphLine setEndPoint:pt_scale(endPt, 1.0/xscale, 1.0/yscale) atDelta:delta];
  246.             [morphLine setEndPoint:pt_scale(endPt, 1.0/xscale, 1.0/yscale) atDelta:1.0 - delta];
  247.             [delegate addMorphLine:morphLine];
  248.             [delegate addToCurrentSelection:morphLine];
  249.         }
  250.     }
  251.     [self unlockFocus];
  252.     [[NSNotificationQueue defaultQueue] enqueueNotification:[NSNotification notificationWithName:NOTIFICATION_SELECTION_CHANGED object:self]
  253.                                 postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];
  254.  
  255.     [self setNeedsDisplay:YES];
  256. }
  257.  
  258. - (void) selectionChanged:(NSNotification *)notification
  259. {
  260.     [self setNeedsDisplay:YES];
  261. }
  262.  
  263. - (void)drawRect:(NSRect)rect
  264. {
  265.     NSArray      *selectedLines = [delegate currentSelection];
  266.     NSEnumerator *lineEnum;
  267.     MorphLine     *morphLine;
  268.     NSPoint          startPt;
  269.     NSPoint          endPt;
  270.     NSRect          lineBounds;
  271.     BOOL          containsLine = NO;
  272.     NSPoint          p;
  273.  
  274.     p.x = NSMinX(rect);
  275.     p.y = NSMaxY(rect);
  276.  
  277.     [[self image] compositeToPoint:rect.origin fromRect:rect operation:NSCompositeCopy];
  278.  
  279.     lineEnum = [[delegate morphLines] objectEnumerator];
  280.  
  281.     while ((morphLine = [lineEnum nextObject]))
  282.     {
  283.         startPt = [morphLine startPointAtDelta:delta];
  284.         endPt = [morphLine endPointAtDelta:delta];
  285.  
  286.         startPt = pt_scale (startPt, NSWidth([self bounds]), NSHeight([self bounds]));
  287.         endPt = pt_scale (endPt, NSWidth([self bounds]), NSHeight([self bounds]));
  288.         
  289.         // Find out if the line intersects the drawing rect
  290.         // and if it does not then skip it.
  291.         lineBounds = NSInsetRect(rectContainingPoints(startPt,endPt), -3.0, -3.0);
  292.         if (NSIntersectsRect(rect, lineBounds))
  293.         {
  294.             drawLine (startPt, endPt);
  295.             if ([selectedLines containsObject:morphLine])
  296.             {
  297.                 drawKnob (startPt);
  298.                 drawKnob (endPt);
  299.             }
  300.             containsLine = YES;
  301.         }
  302.     }
  303.     if (containsLine)
  304.     {
  305.         [[NSColor greenColor] set];
  306.         PSsetlinewidth(3.0);
  307.         PSstroke();
  308.     }
  309. }
  310. @end
  311.  
  312. @implementation Editor(Drag)
  313. - (unsigned int)draggingEntered:(id <NSDraggingInfo>)sender
  314. {
  315. //    NSPasteboard *pboard = [sender draggingPasteboard];
  316. //  if ([NSImage canInitWithPasteboard:pboard])
  317.     return NSDragOperationCopy;
  318. //    else
  319.     return NSDragOperationNone;
  320. }
  321.  
  322. - (unsigned int)draggingUpdated:(id <NSDraggingInfo>)sender
  323. {
  324.     return [self draggingEntered:sender];
  325. }
  326.  
  327. - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
  328. {
  329.     NSImage    *im;
  330.     NSString    *filename;
  331.     
  332. //    im = [[[NSImage allocWithZone:[self zone]] initWithPasteboard:[sender draggingPasteboard]] autorelease];
  333.  
  334.     filename = [[[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType] lastObject];
  335.     im = [[NSImage allocWithZone:[self zone]] initWithContentsOfFile:filename];
  336.     [im setScalesWhenResized:YES];
  337.     if (im)
  338.     {
  339.         [self setImage:[im autorelease]];
  340.         return YES;
  341.     }
  342.     else
  343.         return NO;
  344. }
  345. @end
  346.