From 1802977b95d29198f27535b1b731d1180c083667 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Wed, 11 Jan 2017 16:33:00 +0100 Subject: made new subdir --- tikzit/src/osx/GraphicsView.m | 1216 ----------------------------------------- 1 file changed, 1216 deletions(-) delete mode 100644 tikzit/src/osx/GraphicsView.m (limited to 'tikzit/src/osx/GraphicsView.m') diff --git a/tikzit/src/osx/GraphicsView.m b/tikzit/src/osx/GraphicsView.m deleted file mode 100644 index efa7ecb..0000000 --- a/tikzit/src/osx/GraphicsView.m +++ /dev/null @@ -1,1216 +0,0 @@ -// -// GraphicsView.m -// TikZiT -// -// Copyright 2010 Aleks Kissinger. All rights reserved. -// -// -// This file is part of TikZiT. -// -// TikZiT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// TikZiT is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with TikZiT. If not, see . -// - -#import "GraphicsView.h" -#import "util.h" -#import "CALayer+DrawLabel.h" - -#import "NodeSelectionLayer.h" -#import "NodeLayer.h" -#import "EdgeControlLayer.h" -#import "AppDelegate.h" -#import "TikzGraphAssembler.h" -#import "TikzSourceController.h" - -@interface GraphicsView (Private) -- (void)setupLayers; -- (void)addNodeLayers:(Node*)n; -- (void)addEdgeLayers:(Edge*)e; -- (void)removeNodeLayers:(Node*)n; -- (void)resetMainOrigin; -- (void)setMainOrigin:(NSPoint)o; -@end - -static CGColorRef cgGrayColor, cgWhiteColor, cgClearColor = nil; - - -@implementation GraphicsView - -@synthesize enabled, transformer, pickSupport, tikzSourceController; - -- (void)postGraphChange { - [[NSNotificationCenter defaultCenter] postNotificationName:@"GraphChanged" - object:self]; - [self postSelectionChange]; -} - -- (void)postSelectionChange { - [[NSNotificationCenter defaultCenter] postNotificationName:@"SelectionChanged" - object:self]; -} - -- (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { - if (cgClearColor == nil) { - cgClearColor = CGColorGetConstantColor(kCGColorClear); - cgGrayColor = CGColorCreateGenericGray(0.5f, 0.5f); - cgWhiteColor = CGColorCreateGenericRGB(1, 1, 1, 1); - } - - transformer = [[Transformer alloc] init]; - mouseMode = SelectMode; - grid = [Grid gridWithSpacing:1.0f - subdivisions:4 - transformer:transformer]; - [grid setSize:NSSizeFromCGSize([gridLayer bounds].size)]; - [transformer setScale:PIXELS_PER_UNIT]; - - [self setupLayers]; - - leaderNode = nil; - pickSupport = [[PickSupport alloc] init]; - frameMoveMode = NO; - - enabled = YES; - [self setGraph:[Graph graph]]; - } - return self; -} - -- (void)awakeFromNib { - AppDelegate *del = [application delegate]; - stylePaletteController = [del stylePaletteController]; - toolPaletteController = [del toolPaletteController]; - [self refreshLayers]; - [self postGraphChange]; -} - -- (void)setupLayers { - mainLayer = [CALayer layer]; - [mainLayer setBackgroundColor:cgWhiteColor]; - [mainLayer setFrame:CGRectIntegral(NSRectToCGRect([self bounds]))]; - [mainLayer setOpacity:1.0f]; - [self setLayer:mainLayer]; - [self resetMainOrigin]; - - gridLayer = [CALayer layer]; - [gridLayer setDelegate:grid]; - [gridLayer setOpacity:0.3f]; - [mainLayer addSublayer:gridLayer]; - - graphLayer = [CALayer layer]; - [graphLayer setDelegate:self]; - [mainLayer addSublayer:graphLayer]; - - hudLayer = [CALayer layer]; - [mainLayer addSublayer:hudLayer]; - - selectionLayer = [SelectBoxLayer layer]; - [mainLayer addSublayer:selectionLayer]; - - [transformer setOrigin:NSMakePoint(NSMidX([self bounds]),NSMidY([self bounds]))]; - oldBounds = [self bounds]; - [self refreshLayers]; -} - -// Lion resume feature -//- (void)encodeRestorableStateWithCoder:(NSCoder*)coder { -// NSLog(@"got encode request"); -//} -//- (void)restoreStateWithCoder:(NSCoder*)coder { -// NSLog(@"got decode request"); -//} - -- (void)registerUndo:(NSString*)oldTikz withActionName:(NSString*)nm { - [documentUndoManager registerUndoWithTarget:self - selector:@selector(undoGraphChange:) - object:oldTikz]; - [documentUndoManager setActionName:nm]; -} - -- (void)revertToTikz:(NSString*)tikz { - [tikzSourceController setTikz:tikz]; - [tikzSourceController tryParseTikz]; - [self refreshLayers]; - [self postGraphChange]; -} - - -- (void)undoGraphChange:(NSString*)oldTikz { - NSString *currentTikz = [graph tikz]; - [self revertToTikz:oldTikz]; - [documentUndoManager registerUndoWithTarget:self - selector:@selector(undoGraphChange:) - object:currentTikz]; -} - -- (void)setGraph:(Graph*)gr { - graph = gr; - - NSEnumerator *e; - CALayer *layer; - - e = [edgeControlLayers objectEnumerator]; - while (layer = [e nextObject]) [layer removeFromSuperlayer]; - edgeControlLayers = [NSMapTable mapTableWithStrongToStrongObjects]; - - - e = [nodeLayers objectEnumerator]; - while (layer = [e nextObject]) [layer removeFromSuperlayer]; - nodeLayers = [NSMapTable mapTableWithStrongToStrongObjects]; - - for (Node *n in [graph nodes]) { - [n attachStyleFromTable:[stylePaletteController nodeStyles]]; - [self addNodeLayers:n]; - } - - for (Edge *e in [graph edges]) { - [e setAttributesFromData]; - [e attachStyleFromTable:[stylePaletteController edgeStyles]]; - [self addEdgeLayers:e]; - } -} - -- (Graph*)graph { return graph; } - -- (void)setMainOrigin:(NSPoint)o { - o.x = round(o.x); - o.y = round(o.y); - CGRect rect = [mainLayer frame]; - rect.origin = NSPointToCGPoint(o); - [mainLayer setFrame:rect]; -} - -- (void)resetMainOrigin { - NSRect bds = [self bounds]; - bds.origin.x -= bds.size.width; - bds.origin.y -= bds.size.height; - bds.size.width *= 3; - bds.size.height *= 3; - [mainLayer setFrame:NSRectToCGRect([self bounds])]; -} - -- (void)refreshLayers { - [gridLayer setFrame:[mainLayer frame]]; - [graphLayer setFrame:[mainLayer frame]]; - [hudLayer setFrame:[mainLayer frame]]; - [selectionLayer setFrame:[mainLayer frame]]; - - if (enabled) { - [hudLayer setBackgroundColor:cgClearColor]; - } else { - [hudLayer setBackgroundColor:cgGrayColor]; - } - - [grid setSize:NSSizeFromCGSize([gridLayer bounds].size)]; - [gridLayer setNeedsDisplay]; - [graphLayer setNeedsDisplay]; - [hudLayer setNeedsDisplay]; - - NSEnumerator *e = [edgeControlLayers objectEnumerator]; - CALayer *layer; - while (layer = [e nextObject]) { - [layer setFrame:[graphLayer frame]]; - [layer setNeedsDisplay]; - } -} - - -- (void)viewDidEndLiveResize { - [super viewDidEndLiveResize]; - NSPoint o = [transformer origin]; - o.x += round(([self bounds].size.width - oldBounds.size.width)/2.0f); - o.y += round(([self bounds].size.height - oldBounds.size.height)/2.0f); - [transformer setOrigin:o]; - oldBounds = [self bounds]; - [self refreshLayers]; -} - -- (void)applyStyleToSelectedNodes:(NodeStyle*)style { - NSString *oldTikz = [graph tikz]; - - for (Node *n in [pickSupport selectedNodes]) { - [n setStyle:style]; - [[nodeLayers objectForKey:n] setNeedsDisplay]; - } - - [self registerUndo:oldTikz withActionName:@"Apply Style to Nodes"]; - [self refreshLayers]; - [self postGraphChange]; -} - -- (void)applyStyleToSelectedEdges:(EdgeStyle*)style { - NSString *oldTikz = [graph tikz]; - - for (Edge *e in [pickSupport selectedEdges]) { - [e setStyle:style]; - } - - [self registerUndo:oldTikz withActionName:@"Apply Style to Edges"]; - [self refreshLayers]; - [self postGraphChange]; -} - -- (void)addNodeLayers:(Node*)n { - // add a node to the graph - [graph addNode:n]; - - NSPoint pt = [transformer toScreen:[n point]]; - - // add a node layer - NodeLayer *nl = [[NodeLayer alloc] initWithNode:n transformer:transformer]; - [nl setCenter:pt]; - [nodeLayers setObject:nl forKey:n]; - [graphLayer addSublayer:nl]; - [nl setNeedsDisplay]; -} - -- (void)removeNodeLayers:(Node*)n { - [[nodeLayers objectForKey:n] removeFromSuperlayer]; - [nodeLayers removeObjectForKey:n]; -} - -- (void)addEdgeLayers:(Edge *)e { - [graph addEdge:e]; - EdgeControlLayer *ecl = [[EdgeControlLayer alloc] initWithEdge:e andTransformer:transformer]; - [edgeControlLayers setObject:ecl forKey:e]; - [ecl setFrame:CGRectMake(10, 10, 100, 100)]; - [hudLayer addSublayer:ecl]; - [ecl setNeedsDisplay]; -} - -- (void)removeEdgeLayers:(Edge*)e { - [[edgeControlLayers objectForKey:e] removeFromSuperlayer]; - [edgeControlLayers removeObjectForKey:e]; - [self refreshLayers]; -} - -- (BOOL)circleWithCenter:(NSPoint)center andRadius:(float)radius containsPoint:(NSPoint)p { - float dx = center.x - p.x; - float dy = center.y - p.y; - return (dx*dx + dy*dy) <= radius*radius; -} - -- (BOOL)node:(Node*)node containsPoint:(NSPoint)p { - NodeLayer *nl = [nodeLayers objectForKey:node]; - return [nl nodeContainsPoint:p]; -} - -- (BOOL)edge:(Edge*)edge containsPoint:(NSPoint)p { -// NSPoint center = [transformer toScreen:edge.mid]; -// float dx = center.x - p.x; -// float dy = center.y - p.y; -// float radius = 5.0f; // tolerence for clicks -// return (dx*dx + dy*dy) <= radius*radius; - - CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - - // Save the graphics state before doing the hit detection. - CGContextSaveGState(ctx); - - NSPoint src = [transformer toScreen:[edge tail]]; - NSPoint targ = [transformer toScreen:[edge head]]; - NSPoint cp1 = [transformer toScreen:[edge cp1]]; - NSPoint cp2 = [transformer toScreen:[edge cp2]]; - - CGContextSetLineWidth(ctx, 8.0f); - - CGContextMoveToPoint(ctx, src.x, src.y); - CGContextAddCurveToPoint(ctx, cp1.x, cp1.y, cp2.x, cp2.y, targ.x, targ.y); - - BOOL containsPoint = CGContextPathContainsPoint(ctx, NSPointToCGPoint(p), kCGPathStroke); - - CGContextSetRGBStrokeColor(ctx, 0, 0, 0, 0); - - CGContextStrokePath(ctx); - //CGContextFlush(ctx); - CGContextRestoreGState(ctx); - - return containsPoint; -} - -- (void)shiftNodes:(NSSet*)set from:(NSPoint)source to:(NSPoint)dest { - float dx = dest.x - source.x; - float dy = dest.y - source.y; - - for (Node *n in set) { - NSPoint p = [transformer toScreen:[n point]]; - p = [grid snapScreenPoint:NSMakePoint(p.x+dx, p.y+dy)]; - [n setPoint:[transformer fromScreen:p]]; - } -} - - -- (void)mouseDown:(NSEvent*)theEvent { - if (!enabled) return; - - [self updateMouseMode]; - - dragOrigin = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - dragTarget = dragOrigin; - - graphTikzOnMouseDown = [graph tikz]; - - if ([theEvent modifierFlags] & NSCommandKeyMask) { - oldTransformerOrigin = [transformer origin]; - oldMainOrigin = [self frame].origin; - frameMoveMode = YES; - return; - } - - if (mouseMode == SelectMode) { - [selectionLayer setActive:YES]; - [selectionLayer setSelectBox:NSRectAroundPoints(dragOrigin, dragOrigin)]; - [selectionLayer setNeedsDisplay]; - - modifyEdge = nil; - NSPoint cp1, cp2; - for (Edge *e in [pickSupport selectedEdges]) { - cp1 = [transformer toScreen:[e cp1]]; - cp2 = [transformer toScreen:[e cp2]]; - if ([self circleWithCenter:cp1 - andRadius:[EdgeControlLayer handleRadius] - containsPoint:dragOrigin]) - { - mouseMode = SelectEdgeBendMode; - modifyEdge = e; - firstControlPoint = YES; - break; - } else if ([self circleWithCenter:cp2 - andRadius:[EdgeControlLayer handleRadius] - containsPoint:dragOrigin]) - { - mouseMode = SelectEdgeBendMode; - modifyEdge = e; - firstControlPoint = NO; - break; - } - } - - if (modifyEdge == nil) { // skip all the rest if we're modifying an edge - - leaderNode = nil; - - // in first pass, try to find a leader node, under the mouse - for (Node* n in [graph nodes]) { - if ([self node:n containsPoint:dragOrigin]) { - leaderNode = n; - [gridLayer setOpacity:1.0f]; - break; - } - } - - // if we found one, deselect the others (if appropriate) and go to move mode - if (leaderNode != nil) { - startPoint = [leaderNode point]; - - // if we select a node, we should always deselect all edges: - for (Edge *e in [graph edges]) [[edgeControlLayers objectForKey:e] deselect]; - [pickSupport deselectAllEdges]; - - BOOL shouldDeselect = - !([theEvent modifierFlags] & NSShiftKeyMask) - && ![pickSupport isNodeSelected:leaderNode]; - for (Node *n in [graph nodes]) { - if (n != leaderNode && shouldDeselect) { - [pickSupport deselectNode:n]; - [[[nodeLayers objectForKey:n] selection] deselect]; - } - } - - // ensure the leader node is actually selected - if (![pickSupport isNodeSelected:leaderNode]) { - [pickSupport selectNode:leaderNode]; - [[[nodeLayers objectForKey:leaderNode] selection] select]; - } - - - // put us in move mode - mouseMode = SelectMoveMode; - } else { - mouseMode = SelectBoxMode; - - // if we didn't select a node, start hunting for an edge to select - BOOL shouldDeselect = !([theEvent modifierFlags] & NSShiftKeyMask); - - if (shouldDeselect) { - [pickSupport deselectAllEdges]; - for (Edge *e in graph.edges) [[edgeControlLayers objectForKey:e] deselect]; - } - - for (Edge* e in [graph edges]) { - // find the first node under the pointer, select it, show its controls - // and deselect all others if shift isn't down - if ([self edge:e containsPoint:dragOrigin]) { - for (Node *n in [pickSupport selectedNodes]) [[[nodeLayers objectForKey:n] selection] deselect]; - - [pickSupport deselectAllNodes]; - [pickSupport selectEdge:e]; - [[edgeControlLayers objectForKey:e] select]; - break; - } - } // end for e in [graph edges] - } // end if leaderNode == nil - } // end if modifyEdge == nil - - } else if (mouseMode == NodeMode) { - // do nothing... - } else if (mouseMode == EdgeMode) { - for (Node *n in [graph nodes]) { - if ([self node:n containsPoint:dragOrigin]) { - [[[nodeLayers objectForKey:n] selection] highlight]; - } - } - mouseMode = EdgeDragMode; - } else if (mouseMode == CropMode) { - if ([graph hasBoundingBox]) { - float fudge = 3; - - NSRect bb = [graph boundingBox]; - NSPoint bl = [transformer toScreen:bb.origin]; - NSPoint tr = [transformer - toScreen:NSMakePoint(bb.origin.x+bb.size.width, - bb.origin.y+bb.size.height)]; - if (dragOrigin.x > bl.x-fudge && dragOrigin.x < tr.x+fudge && - dragOrigin.y > tr.y-fudge && dragOrigin.y < tr.y+fudge) - { - bboxBottomTop = 1; - } else if (dragOrigin.x > bl.x-fudge && dragOrigin.x < tr.x+fudge && - dragOrigin.y > bl.y-fudge && dragOrigin.y < bl.y+fudge) - { - bboxBottomTop = -1; - } else { - bboxBottomTop = 0; - } - - if (dragOrigin.y > bl.y-fudge && dragOrigin.y < tr.y+fudge && - dragOrigin.x > tr.x-fudge && dragOrigin.x < tr.x+fudge) - { - bboxLeftRight = 1; - } else if (dragOrigin.y > bl.y-fudge && dragOrigin.y < tr.y+fudge && - dragOrigin.x > bl.x-fudge && dragOrigin.x < bl.x+fudge) - { - bboxLeftRight = -1; - } else { - bboxLeftRight = 0; - } - - if (bboxBottomTop != 0 || bboxLeftRight != 0) { - mouseMode = CropDragMode; - } - } - } else { - printf("WARNING: MOUSE DOWN IN INVALID MODE.\n"); - } - - [self refreshLayers]; -} - -- (void)mouseDragged:(NSEvent *)theEvent { - if (!enabled) return; - dragTarget = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - - if (frameMoveMode) { - NSPoint newTransOrigin, newMainOrigin; - NSPoint diff = NSMakePoint(dragTarget.x - dragOrigin.x, dragTarget.y - dragOrigin.y); - newTransOrigin.x = oldTransformerOrigin.x + diff.x; - newTransOrigin.y = oldTransformerOrigin.y + diff.y; - newMainOrigin.x = oldMainOrigin.x + diff.x; - newMainOrigin.y = oldMainOrigin.y + diff.y; - - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; - [self setMainOrigin:newMainOrigin]; - [CATransaction commit]; - - [transformer setOrigin:newTransOrigin]; - return; - } - - if (mouseMode == SelectBoxMode) { - [selectionLayer setSelectBox:NSRectAroundPoints(dragOrigin, dragTarget)]; - [selectionLayer setNeedsDisplay]; - - for (Node* n in [graph nodes]) { - if (NSPointInRect([transformer toScreen:[n point]], [selectionLayer selectBox])) { - [[[nodeLayers objectForKey:n] selection] highlight]; - } else if (!([theEvent modifierFlags] & NSShiftKeyMask)) { - [[[nodeLayers objectForKey:n] selection] unhighlight]; - } - } - } else if (mouseMode == SelectMoveMode) { - if (leaderNode != nil) { - [self shiftNodes:[pickSupport selectedNodes] - from:[transformer toScreen:[leaderNode point]] - to:dragTarget]; - } else { - printf("WARNING: LEADER NODE SHOULD NOT BE NIL.\n"); - } - - [self refreshLayers]; - } else if (mouseMode == SelectEdgeBendMode) { - NSPoint src = [transformer toScreen:[[modifyEdge source] point]]; - NSPoint targ = [transformer toScreen:[[modifyEdge target] point]]; - float dx1 = targ.x - src.x; - float dy1 = targ.y - src.y; - float dx2, dy2; - if (firstControlPoint) { - dx2 = dragTarget.x - src.x; - dy2 = dragTarget.y - src.y; - } else { - dx2 = dragTarget.x - targ.x; - dy2 = dragTarget.y - targ.y; - } - float base_dist = sqrt(dx1*dx1 + dy1*dy1); - float handle_dist = sqrt(dx2*dx2 + dy2*dy2); - float wcourseness = 0.1f; - - if (![modifyEdge isSelfLoop]) { - if (base_dist != 0) { - [modifyEdge setWeight:roundToNearest(wcourseness, handle_dist/base_dist)]; - //round(handle_dist / (base_dist*wcourseness)) * wcourseness; - } else { - [modifyEdge setWeight: - roundToNearest(wcourseness, [transformer scaleFromScreen:handle_dist])]; - } - } - - - float control_angle = good_atan(dx2, dy2); - - int bcourseness = 15; - - if ([modifyEdge bendMode] == EdgeBendModeBasic) { - float bnd; - float base_angle = good_atan(dx1, dy1); - if (firstControlPoint) { - bnd = base_angle - control_angle; - } else { - bnd = control_angle - base_angle + pi; - if (bnd > pi) bnd -= 2*pi; - } - - [modifyEdge setBend:round(bnd * (180.0f / pi) * - (1.0f / (float)bcourseness)) * - bcourseness]; - } else { - int bnd = round(control_angle * (180.0f / pi) * - (1.0f / (float)bcourseness)) * - bcourseness; - if (firstControlPoint) { - if ([theEvent modifierFlags] & NSAlternateKeyMask) { - if ([modifyEdge isSelfLoop]) { - [modifyEdge setInAngle:[modifyEdge inAngle] + - (bnd - [modifyEdge outAngle])]; - } else { - [modifyEdge setInAngle:[modifyEdge inAngle] - - (bnd - [modifyEdge outAngle])]; - } - } - - [modifyEdge setOutAngle:bnd]; - } else { - if (theEvent.modifierFlags & NSAlternateKeyMask) { - if ([modifyEdge isSelfLoop]) { - [modifyEdge setOutAngle:[modifyEdge outAngle] + - (bnd - [modifyEdge inAngle])]; - } else { - [modifyEdge setOutAngle:[modifyEdge outAngle] - - (bnd - [modifyEdge inAngle])]; - } - } - - [modifyEdge setInAngle:bnd]; - } - } - - [self refreshLayers]; - } else if (mouseMode == NodeMode) { - // do nothing... - } else if (mouseMode == EdgeDragMode) { - for (Node *n in [graph nodes]) { - if ([self node:n containsPoint:dragOrigin] || - [self node:n containsPoint:dragTarget]) - { - [[[nodeLayers objectForKey:n] selection] highlight]; - } else { - [[[nodeLayers objectForKey:n] selection] unhighlight]; - } - } - - [self refreshLayers]; - } else if (mouseMode == CropMode || mouseMode == CropDragMode) { - NSPoint p1 = [transformer fromScreen:[grid snapScreenPoint:dragOrigin]]; - NSPoint p2 = [transformer fromScreen:[grid snapScreenPoint:dragTarget]]; - - NSRect bbox; - if (mouseMode == CropDragMode) { - bbox = [graph boundingBox]; - if (bboxBottomTop == -1) { - float dy = p2.y - bbox.origin.y; - bbox.origin.y += dy; - bbox.size.height -= dy; - } else if (bboxBottomTop == 1) { - float dy = p2.y - (bbox.origin.y + bbox.size.height); - bbox.size.height += dy; - } - - if (bboxLeftRight == -1) { - float dx = p2.x - bbox.origin.x; - bbox.origin.x += dx; - bbox.size.width -= dx; - } else if (bboxLeftRight == 1) { - float dx = p2.x - (bbox.origin.x + bbox.size.width); - bbox.size.width += dx; - } - } else { - bbox = NSRectAroundPoints(p1, p2); - } - - [graph setBoundingBox:bbox]; - [self postGraphChange]; - [self refreshLayers]; - } else { - printf("WARNING: MOUSE DRAGGED IN INVALID MODE.\n"); - } -} - -- (void)mouseUp:(NSEvent*)theEvent { - if (!enabled) return; - - if (frameMoveMode) { - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; - [self resetMainOrigin]; - [self refreshLayers]; - [CATransaction commit]; - frameMoveMode = NO; - return; - } - - dragTarget = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - - if ((mouseMode & SelectMode) == SelectMode && [theEvent clickCount] == 2) { - for (Edge *e in [graph edges]) { - if ([self edge:e containsPoint:dragTarget]) { - if ([e bendMode] == EdgeBendModeBasic) { - [e convertBendToAngles]; - [e setBendMode:EdgeBendModeInOut]; - } else { - [e convertAnglesToBend]; - [e setBendMode:EdgeBendModeBasic]; - } - - [self registerUndo:graphTikzOnMouseDown withActionName:@"Change Edge Mode"]; - [self postGraphChange]; - break; - } - } - } - - if (mouseMode == SelectBoxMode) { - for (Node* n in [graph nodes]) { - if (NSPointInRect([transformer toScreen:[n point]], [selectionLayer selectBox])) { - [pickSupport selectNode:n]; - [[[nodeLayers objectForKey:n] selection] select]; - } else if (!([theEvent modifierFlags] & NSShiftKeyMask)) { - [pickSupport deselectNode:n]; - [[[nodeLayers objectForKey:n] selection] deselect]; - } - } - - [selectionLayer setActive:NO]; - [selectionLayer setNeedsDisplay]; - [self postSelectionChange]; - - mouseMode = SelectMode; - } else if (mouseMode == SelectMoveMode) { - [gridLayer setOpacity:0.3f]; - - if (dragTarget.x != dragOrigin.x || dragTarget.y != dragOrigin.y) { - [self registerUndo:graphTikzOnMouseDown withActionName:@"Shift Nodes"]; - } - - leaderNode = nil; - - [self postGraphChange]; - mouseMode = SelectMode; - } else if (mouseMode == SelectEdgeBendMode) { - [self registerUndo:graphTikzOnMouseDown withActionName:@"Adjust Edge"]; - [self postGraphChange]; - mouseMode = SelectMode; - modifyEdge = nil; - } else if (mouseMode == NodeMode) { - NSPoint coords = [transformer fromScreen:[grid snapScreenPoint:dragTarget]]; - Node *n = [Node nodeWithPoint:coords]; - [n setStyle:[stylePaletteController activeNodeStyle]]; - [graph addNode:n]; - - [self registerUndo:graphTikzOnMouseDown withActionName:@"Add Node"]; - - [self addNodeLayers:n]; - [self postGraphChange]; - } else if (mouseMode == EdgeDragMode) { - Node *src = nil; - Node *targ = nil; - BOOL found = NO; // don't break the loop until everything is unhighlighted - for (Node *n in [graph nodes]) { - [[[nodeLayers objectForKey:n] selection] unhighlight]; - if (!found) { - if ([self node:n containsPoint:dragOrigin]) src = n; - if ([self node:n containsPoint:dragTarget]) targ = n; - if (src != nil && targ != nil) { - Edge *e = [Edge edgeWithSource:src andTarget:targ]; - [e setStyle:[stylePaletteController activeEdgeStyle]]; - [graph addEdge:e]; - [self registerUndo:graphTikzOnMouseDown withActionName:@"Add Edge"]; - [self addEdgeLayers:e]; - found = YES; - } - } - } - - [self postGraphChange]; - mouseMode = EdgeMode; - } else if (mouseMode == CropMode || mouseMode == CropDragMode) { - if (dragOrigin.x == dragTarget.x && dragOrigin.y == dragTarget.y) { - [graph setBoundingBox:NSMakeRect(0, 0, 0, 0)]; - [self registerUndo:graphTikzOnMouseDown withActionName:@"Clear Bounding Box"]; - [self postGraphChange]; - } else { - [self registerUndo:graphTikzOnMouseDown withActionName:@"Change Bounding Box"]; - } - - mouseMode = CropMode; - } else { - if (! ([theEvent modifierFlags] & NSCommandKeyMask)) - printf("WARNING: MOUSE UP IN INVALID MODE.\n"); - } - - [self refreshLayers]; -} - -- (void)drawNode:(Node*)nd onLayer:(CALayer*)layer inContext:(CGContextRef)context { - NSPoint pt = [transformer toScreen:[nd point]]; - - NodeLayer *nl = [nodeLayers objectForKey:nd]; - //[nl setStrokeWidth:2.0f]; - [nl setCenter:pt andAnimateWhen:(mouseMode != SelectMoveMode)]; -} - -- (void)drawEdge:(Edge*)e onLayer:(CALayer*)layer inContext:(CGContextRef)context { - CGContextSaveGState(context); - NSPoint src = [transformer toScreen:[e tail]]; - NSPoint targ = [transformer toScreen:[e head]]; - NSPoint cp1 = [transformer toScreen:[e cp1]]; - NSPoint cp2 = [transformer toScreen:[e cp2]]; - - // all nodes have the same radius. this will need to be fixed - float sradius = 0;//(slayer.ghost) ? 0 : slayer.radius; - float tradius = 0;//(tlayer.ghost) ? 0 : tlayer.radius; - - float sdx = cp1.x - src.x; - float sdy = cp1.y - src.y; - float sdist = sqrt(sdx*sdx + sdy*sdy); - float sshortx = (sdist==0) ? 0 : sdx/sdist * sradius; - float sshorty = (sdist==0) ? 0 : sdy/sdist * sradius; - - float tdx = cp2.x - targ.x; - float tdy = cp2.y - targ.y; - float tdist = sqrt(tdx*tdx + tdy*tdy); - float tshortx = (tdist==0) ? 0 : tdx/tdist * tradius; - float tshorty = (tdist==0) ? 0 : tdy/tdist * tradius; - - CGContextMoveToPoint(context, src.x+sshortx, src.y+sshorty); - CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, targ.x+tshortx, targ.y+tshorty); - - - float lineWidth = [transformer scaleToScreen:0.04f]; - - CGContextSetLineWidth(context, lineWidth); - CGContextSetRGBStrokeColor(context, 0, 0, 0, 1); - CGContextSetRGBFillColor(context, 0, 0, 0, 1); - CGContextStrokePath(context); - - if ([e style] != nil) { - NSPoint p1,p2,p3; - - // draw edge decoration - switch ([[e style] decorationStyle]) { - case ED_None: - break; - case ED_Tick: - p1 = [transformer toScreen:[e leftNormal]]; - p2 = [transformer toScreen:[e rightNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextStrokePath(context); - break; - case ED_Arrow: - p1 = [transformer toScreen:[e leftNormal]]; - p2 = [transformer toScreen:[e midTan]]; - p3 = [transformer toScreen:[e rightNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextAddLineToPoint(context, p3.x, p3.y); - CGContextStrokePath(context); - break; - } - - // draw arrow head - switch ([[e style] headStyle]) { - case AH_None: - break; - case AH_Plain: - p1 = [transformer toScreen:[e leftHeadNormal]]; - p2 = [transformer toScreen:[e head]]; - p3 = [transformer toScreen:[e rightHeadNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextAddLineToPoint(context, p3.x, p3.y); - CGContextStrokePath(context); - break; - case AH_Latex: - p1 = [transformer toScreen:[e leftHeadNormal]]; - p2 = [transformer toScreen:[e head]]; - p3 = [transformer toScreen:[e rightHeadNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextAddLineToPoint(context, p3.x, p3.y); - CGContextClosePath(context); - CGContextFillPath(context); - break; - } - - // draw arrow tail - switch ([[e style] tailStyle]) { - case AH_None: - break; - case AH_Plain: - p1 = [transformer toScreen:[e leftTailNormal]]; - p2 = [transformer toScreen:[e tail]]; - p3 = [transformer toScreen:[e rightTailNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextAddLineToPoint(context, p3.x, p3.y); - CGContextStrokePath(context); - break; - case AH_Latex: - p1 = [transformer toScreen:[e leftTailNormal]]; - p2 = [transformer toScreen:[e tail]]; - p3 = [transformer toScreen:[e rightTailNormal]]; - CGContextMoveToPoint(context, p1.x, p1.y); - CGContextAddLineToPoint(context, p2.x, p2.y); - CGContextAddLineToPoint(context, p3.x, p3.y); - CGContextClosePath(context); - CGContextFillPath(context); - break; - } - } - - - CGContextRestoreGState(context); - - if ([e hasEdgeNode]) { - Node *en = [e edgeNode]; - NSPoint mid = [transformer toScreen:[e mid]]; - if (![[en label] isEqual:@""]) { - [layer drawLabel:[en label] - atPoint:mid - inContext:context - usingTrans:transformer]; - } - } - - EdgeControlLayer *ecl = [edgeControlLayers objectForKey:e]; - [ecl setNeedsDisplay]; -} - - -// draw the graph layer --(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context { - for (Edge* e in [graph edges]) [self drawEdge:e onLayer:layer inContext:context]; - - for (Node* n in [graph nodes]) [self drawNode:n onLayer:layer inContext:context]; - - if ([graph hasBoundingBox]) { - CGRect bbox = NSRectToCGRect(NSIntegralRect( - [transformer rectToScreen:[graph boundingBox]])); - CGContextSetRGBStrokeColor(context, 1.0f, 0.7f, 0.5f, 1.0f); - CGContextSetLineWidth(context, 1.0f); - CGContextSetShouldAntialias(context, NO); - CGContextStrokeRect(context, bbox); - CGContextSetShouldAntialias(context, YES); - } - - if (mouseMode == EdgeDragMode) { - CGContextMoveToPoint(context, dragOrigin.x, dragOrigin.y); - CGContextAddLineToPoint(context, dragTarget.x, dragTarget.y); - CGContextSetLineWidth(context, 2); - CGContextSetRGBStrokeColor(context, 0, 0, 1, 1); - CGContextStrokePath(context); - } -} - -// if enabled, suppress the default "bonk" behaviour on key presses -- (void)keyDown:(NSEvent *)theEvent { - if (!enabled) [super keyDown:theEvent]; -} - -- (void)delete:(id)sender { - BOOL didDelete = NO; - NSString *oldTikz = [graph tikz]; - - if ([[pickSupport selectedNodes] count] != 0) { - GraphChange *change = [graph removeNodes:[pickSupport selectedNodes]]; - for (Node *n in [change affectedNodes]) [self removeNodeLayers:n]; - for (Edge *e in [change affectedEdges]) [self removeEdgeLayers:e]; - - [self refreshLayers]; - [self postGraphChange]; - didDelete = YES; - } - - if ([[pickSupport selectedEdges] count] != 0) { - [graph removeEdges:[pickSupport selectedEdges]]; - for (Edge *e in [pickSupport selectedEdges]) [self removeEdgeLayers:e]; - [self refreshLayers]; - [self postGraphChange]; - didDelete = YES; - } - - [pickSupport deselectAllNodes]; - [pickSupport deselectAllEdges]; - - if (didDelete) [self registerUndo:oldTikz withActionName:@"Delete Nodes or Edges"]; -} - -- (void)keyUp:(NSEvent *)theEvent { - if (!enabled) return; - - id sender = self; - switch ([theEvent keyCode]) { - case 51: // delete - [self delete:sender]; // "self" is the sender - break; - case 1: // S - [toolPaletteController setSelectedTool:TikzToolSelect]; - break; - case 45: // N - case 9: // V - [toolPaletteController setSelectedTool:TikzToolNode]; - break; - case 14: // E - [toolPaletteController setSelectedTool:TikzToolEdge]; - //[self updateMouseMode]; - break; - case 40: // K - [toolPaletteController setSelectedTool:TikzToolCrop]; - break; - } - [self refreshLayers]; -} - - -- (void)deselectAll:(id)sender { - [pickSupport deselectAllNodes]; - [pickSupport deselectAllEdges]; - - for (Node *n in [graph nodes]) { - [[[nodeLayers objectForKey:n] selection] deselect]; - } - - for (Edge *e in [graph edges]) { - [[edgeControlLayers objectForKey:e] deselect]; - } - - [self postSelectionChange]; -} - -- (void)selectAll:(id)sender { - [pickSupport selectAllNodes:[NSSet setWithArray:[graph nodes]]]; - - for (Node *n in [graph nodes]) { - [[[nodeLayers objectForKey:n] selection] select]; - } - - [self postSelectionChange]; -} - - -- (void)updateMouseMode { - switch (toolPaletteController.selectedTool) { - case TikzToolSelect: - mouseMode = SelectMode; - break; - case TikzToolNode: - mouseMode = NodeMode; - break; - case TikzToolEdge: - mouseMode = EdgeMode; - break; - case TikzToolCrop: - mouseMode = CropMode; - break; - } -} - -- (void)setDocumentUndoManager:(NSUndoManager *)um { - documentUndoManager = um; -} - -- (void)copy:(id)sender { - if ([[pickSupport selectedNodes] count] != 0) { - Graph *clip = [graph copyOfSubgraphWithNodes:[pickSupport selectedNodes]]; - NSString *tikz = [clip tikz]; - NSData *data = [tikz dataUsingEncoding:NSUTF8StringEncoding]; - //NSLog(@"about to copy: %@", tikz); - NSPasteboard *cb = [NSPasteboard generalPasteboard]; - [cb declareTypes:[NSArray arrayWithObject:@"tikzpicture"] owner:self]; - [cb setData:data forType:@"tikzpicture"]; - } -} - -- (void)cut:(id)sender { - if ([[pickSupport selectedNodes] count] != 0) { - [self copy:sender]; - [self delete:sender]; - - // otherwise, menu will say "Undo Delete Graph" - [documentUndoManager setActionName:@"Cut Graph"]; - } -} - -- (void)paste:(id)sender { - NSPasteboard *cb = [NSPasteboard generalPasteboard]; - NSString *type = [cb availableTypeFromArray:[NSArray arrayWithObject:@"tikzpicture"]]; - if (type) { - NSData *data = [cb dataForType:type]; - NSString *tikz = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - //NSLog(@"pasting tikz:\n%@",tikz); - Graph *clip = [TikzGraphAssembler parseTikz:tikz]; - if (clip) { - //NSLog(@"tikz pasted:\n%@",tikz); - NSRect graphBounds = [graph bounds]; - NSRect clipBounds = [clip bounds]; - float dx = graphBounds.origin.x + - graphBounds.size.width - - clipBounds.origin.x + 0.5f; - [clip shiftNodes:[clip nodes] byPoint:NSMakePoint(dx, 0)]; - - if ([[clip nodes] count] != 0) { - NSString *oldTikz = [graph tikz]; - [self deselectAll:self]; - - // select everything from the clipboard - for (Node *n in [clip nodes]) { - [n attachStyleFromTable:[stylePaletteController nodeStyles]]; - [self addNodeLayers:n]; - [pickSupport selectNode:n]; - [[[nodeLayers objectForKey:n] selection] select]; - } - - for (Edge *e in [clip edges]) { - [e attachStyleFromTable:[stylePaletteController edgeStyles]]; - [self addEdgeLayers:e]; - } - - [graph insertGraph:clip]; - - [self registerUndo:oldTikz withActionName:@"Paste Graph"]; - [self refreshLayers]; - [self postGraphChange]; - } - } else { - NSLog(@"Error: couldn't parse tikz picture from clipboard."); - } - - } -} - -- (void)bringForward:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph bringNodesForward:[pickSupport selectedNodes]]; - [graph bringEdgesForward:[pickSupport selectedEdges]]; - [self registerUndo:oldTikz withActionName:@"Bring Forward"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)sendBackward:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph sendNodesBackward:[pickSupport selectedNodes]]; - [graph sendEdgesBackward:[pickSupport selectedEdges]]; - [self registerUndo:oldTikz withActionName:@"Send Backward"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)bringToFront:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph bringNodesToFront:[pickSupport selectedNodes]]; - [graph bringEdgesToFront:[pickSupport selectedEdges]]; - [self registerUndo:oldTikz withActionName:@"Bring to Front"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)sendToBack:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph sendNodesToBack:[pickSupport selectedNodes]]; - [graph sendEdgesToBack:[pickSupport selectedEdges]]; - [self registerUndo:oldTikz withActionName:@"Send to Back"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)flipHorizonal:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph flipHorizontalNodes:[pickSupport selectedNodes]]; - [self registerUndo:oldTikz withActionName:@"Flip Horizontal"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)flipVertical:(id)sender { - NSString *oldTikz = [graph tikz]; - [graph flipVerticalNodes:[pickSupport selectedNodes]]; - [self registerUndo:oldTikz withActionName:@"Flip Vertical"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (void)reverseEdgeDirection:(id)sender { - NSString *oldTikz = [graph tikz]; - - NSSet *es; - if ([[pickSupport selectedEdges] count] != 0) { - es = [pickSupport selectedEdges]; - } else { - es = [graph incidentEdgesForNodes:[pickSupport selectedNodes]]; - } - - for (Edge *e in es) [e reverse]; - - [self registerUndo:oldTikz withActionName:@"Flip Edge Direction"]; - [self postGraphChange]; - [self refreshLayers]; -} - -- (BOOL)acceptsFirstResponder { return YES; } -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return YES; } -- (BOOL)canBecomeKeyView { return YES; } - - -@end -- cgit v1.2.3