diff options
author | randomguy3 <randomguy3@7c02a99a-9b00-45e3-bf44-6f3dd7fddb64> | 2012-01-09 11:00:06 +0000 |
---|---|---|
committer | randomguy3 <randomguy3@7c02a99a-9b00-45e3-bf44-6f3dd7fddb64> | 2012-01-09 11:00:06 +0000 |
commit | e1cf0babff63e670e0d550b4072c22649a117fa7 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/linux/GraphRenderer.m | |
parent | 49393f6f445deb37e55a81798f88242e3e99d7a0 (diff) |
Re-make trunk
git-svn-id: https://tikzit.svn.sourceforge.net/svnroot/tikzit/trunk@364 7c02a99a-9b00-45e3-bf44-6f3dd7fddb64
Diffstat (limited to 'src/linux/GraphRenderer.m')
-rw-r--r-- | src/linux/GraphRenderer.m | 607 |
1 files changed, 0 insertions, 607 deletions
diff --git a/src/linux/GraphRenderer.m b/src/linux/GraphRenderer.m deleted file mode 100644 index c964f1b..0000000 --- a/src/linux/GraphRenderer.m +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright 2011 Alex Merry <alex.merry@kdemail.net> - * Copyright 2010 Chris Heunen - * - * This program 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 2 of - * the License, or (at your option) any later version. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#import "GraphRenderer.h" -#import "Edge+Render.h" -#import "Node+Render.h" - -static const float size = 5.0; - -float sideHandleTop(NSRect bbox) { - return (NSMinY(bbox) + NSMaxY(bbox) - size)/2.0f; -} - -float tbHandleLeft(NSRect bbox) { - return (NSMinX(bbox) + NSMaxX(bbox) - size)/2.0f; -} -void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); - -@interface GraphRenderer (Private) -- (BOOL) selectionBoxContainsNode:(Node*)node; -- (BOOL) halfEdgeIncludesNode:(Node*)node; -- (enum NodeState) nodeState:(Node*)node; -- (void) renderBoundingBoxWithContext:(id<RenderContext>)context; -- (void) renderSelectionBoxWithContext:(id<RenderContext>)context; -- (void) renderImpendingEdgeWithContext:(id<RenderContext>)context; -- (void) nodeNeedsRefreshing:(NSNotification*)notification; -- (void) edgeNeedsRefreshing:(NSNotification*)notification; -- (void) graphNeedsRefreshing:(NSNotification*)notification; -- (void) graphChanged:(NSNotification*)notification; -- (void) nodeStylePropertyChanged:(NSNotification*)notification; -- (void) edgeStylePropertyChanged:(NSNotification*)notification; -@end - -@implementation GraphRenderer - -- (id) initWithSurface:(NSObject <Surface> *)s { - self = [super init]; - - if (self) { - surface = [s retain]; - doc = nil; - grid = [[Grid alloc] initWithSpacing:1.0f subdivisions:4 transformer:[s transformer]]; - halfEdgeOrigin = nil; - [surface setRenderDelegate:self]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(nodeStylePropertyChanged:) - name:@"NodeStylePropertyChanged" - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(edgeStylePropertyChanged:) - name:@"EdgeStylePropertyChanged" - object:nil]; - } - - return self; -} - -- (id) initWithSurface:(NSObject <Surface> *)s document:(TikzDocument*)document { - self = [self initWithSurface:s]; - - if (self) { - [self setDocument:document]; - } - - return self; -} - -- (void) dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [doc release]; - [grid release]; - [surface release]; - - [super dealloc]; -} - -- (void) renderWithContext:(id<RenderContext>)context onSurface:(id<Surface>)surface { - [self renderWithContext:context]; -} - -- (void) renderWithContext:(id<RenderContext>)context { - // blank surface - [context paintWithColor:WhiteRColor]; - - // draw grid - [grid renderGridInContext:context]; - - // draw edges - NSEnumerator *enumerator = [doc edgeEnumerator]; - Edge *edge; - while ((edge = [enumerator nextObject]) != nil) { - [edge renderToSurface:surface withContext:context selected:[doc isEdgeSelected:edge]]; - } - - // draw nodes - enumerator = [doc nodeEnumerator]; - Node *node; - while ((node = [enumerator nextObject]) != nil) { - [node renderToSurface:surface withContext:context state:[self nodeState:node]]; - } - - [self renderBoundingBoxWithContext:context]; - [self renderSelectionBoxWithContext:context]; - [self renderImpendingEdgeWithContext:context]; -} - -- (void) invalidateGraph { - [surface invalidate]; -} - -- (void) invalidateNodes:(NSSet*)nodes { - for (Node *node in nodes) { - [self invalidateNode:node]; - } -} - -- (void) invalidateEdges:(NSSet*)edges { - for (Edge *edge in edges) { - [self invalidateEdge:edge]; - } -} - -- (void) invalidateNode:(Node*)node { - if (node == nil) { - return; - } - NSRect nodeRect = [node boundsWithLabelOnSurface:surface]; - nodeRect = NSInsetRect (nodeRect, -2.0f, -2.0f); - [surface invalidateRect:nodeRect]; -} - -- (void) invalidateEdge:(Edge*)edge { - if (edge == nil) { - return; - } - BOOL selected = [doc isEdgeSelected:edge]; - NSRect edgeRect = [edge renderedBoundsWithTransformer:[surface transformer] whenSelected:selected]; - edgeRect = NSInsetRect (edgeRect, -2.0f, -2.0f); - [surface invalidateRect:edgeRect]; -} - -- (void) invalidateNodesHitBy:(NSPoint)point { - NSEnumerator *enumerator = [doc nodeEnumerator]; - Node *node = nil; - while ((node = [enumerator nextObject]) != nil) { - if ([self point:point hitsNode:node]) { - [self invalidateNode:node]; - } - } -} - -- (BOOL) point:(NSPoint)p hitsNode:(Node*)node { - return [node hitByPoint:p onSurface:surface]; -} - -- (BOOL) point:(NSPoint)p fuzzyHitsNode:(Node*)node { - NSRect bounds = [node boundsOnSurface:surface]; - return NSPointInRect(p, bounds); -} - -- (BOOL) point:(NSPoint)p hitsEdge:(Edge*)edge withFuzz:(float)fuzz { - return [edge hitByPoint:p onSurface:surface withFuzz:fuzz]; -} - -- (Node*) anyNodeAt:(NSPoint)p { - NSEnumerator *enumerator = [doc nodeEnumerator]; - Node *node; - while ((node = [enumerator nextObject]) != nil) { - if ([self point:p hitsNode:node]) { - return node; - } - } - return nil; -} - -- (Edge*) anyEdgeAt:(NSPoint)p withFuzz:(float)fuzz { - // FIXME: is there an efficient way to find the "nearest" edge - // if the fuzz is the reason we hit more than one? - NSEnumerator *enumerator = [doc edgeEnumerator]; - Edge *edge; - while ((edge = [enumerator nextObject]) != nil) { - if ([self point:p hitsEdge:edge withFuzz:fuzz]) { - return edge; - } - } - return nil; -} - -- (id<Surface>) surface { - return surface; -} - -- (Transformer*) transformer { - return [surface transformer]; -} - -- (Grid*) grid { - return grid; -} - -- (PickSupport*) pickSupport { - return [doc pickSupport]; -} - -- (Graph*) graph { - return [doc graph]; -} - -- (TikzDocument*) document { - return doc; -} - -- (void) setDocument:(TikzDocument*)document { - if (doc == document) { - return; - } - - if (doc != nil) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:doc]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[doc pickSupport]]; - } - - [document retain]; - [doc release]; - doc = document; - - if (doc != nil) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphNeedsRefreshing:) - name:@"GraphReplaced" object:doc]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphChanged:) - name:@"GraphChanged" object:doc]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphChanged:) - name:@"GraphBeingChanged" object:doc]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphChanged:) - name:@"GraphChangeCancelled" object:doc]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(nodeNeedsRefreshing:) - name:@"NodeSelected" object:[doc pickSupport]]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(nodeNeedsRefreshing:) - name:@"NodeDeselected" object:[doc pickSupport]]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphNeedsRefreshing:) - name:@"NodeSelectionReplaced" object:[doc pickSupport]]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(edgeNeedsRefreshing:) - name:@"EdgeSelected" object:[doc pickSupport]]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(edgeNeedsRefreshing:) - name:@"EdgeDeselected" object:[doc pickSupport]]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(graphNeedsRefreshing:) - name:@"EdgeSelectionReplaced" object:[doc pickSupport]]; - } - [surface invalidate]; -} - -- (NSRect) selectionBox { - return selectionBox; -} - -- (void) setSelectionBox:(NSRect)box { - NSRect invRect = NSUnionRect (selectionBox, box); - selectionBox = box; - [surface invalidateRect:NSInsetRect (invRect, -2, -2)]; -} - -- (void) clearSelectionBox { - NSRect oldRect = selectionBox; - - NSRect emptyRect; - selectionBox = emptyRect; - - [surface invalidateRect:NSInsetRect (oldRect, -2, -2)]; -} - -- (void) invalidateHalfEdge { - if (halfEdgeOrigin != nil) { - NSRect invRect = NSRectAroundPoints(halfEdgeEnd, halfEdgeOriginPoint); - invRect = NSUnionRect(invRect, [halfEdgeOrigin boundsWithLabelOnSurface:surface]); - - NSEnumerator *enumerator = [doc nodeEnumerator]; - Node *node; - while ((node = [enumerator nextObject]) != nil) { - if ([self point:halfEdgeEnd fuzzyHitsNode:node]) { - invRect = NSUnionRect(invRect, [node boundsWithLabelOnSurface:surface]); - } - } - [surface invalidateRect:NSInsetRect (invRect, -2.0f, -2.0f)]; - } -} - -- (void) setHalfEdgeFrom:(Node*)origin to:(NSPoint)end { - [self invalidateHalfEdge]; - - if (halfEdgeOrigin != origin) { - [self invalidateNode:halfEdgeOrigin]; - halfEdgeOrigin = origin; - halfEdgeOriginPoint = [[surface transformer] toScreen:[origin point]]; - [self invalidateNode:origin]; - } - - if (origin != nil) { - halfEdgeEnd = end; - [self invalidateHalfEdge]; - } -} - -- (void) clearHalfEdge { - [self invalidateHalfEdge]; - halfEdgeOrigin = nil; -} - -- (BOOL) boundingBoxHandlesShown { - return showBoundingBoxHandles; -} - -- (void) setBoundingBoxHandlesShown:(BOOL)shown { - if (showBoundingBoxHandles != shown) { - showBoundingBoxHandles = shown; - [self invalidateGraph]; - } -} - -- (ResizeHandle) boundingBoxResizeHandleAt:(NSPoint)p { - NSRect bbox = [[surface transformer] rectToScreen:[[self graph] boundingBox]]; - if (p.x >= NSMaxX(bbox)) { - if (p.x <= NSMaxX(bbox) + size) { - if (p.y >= NSMaxY(bbox)) { - if (p.y <= NSMaxY(bbox) + size) { - return SouthEastHandle; - } - } else if (p.y <= NSMinY(bbox)) { - if (p.y >= NSMinY(bbox) - size) { - return NorthEastHandle; - } - } else { - float eastHandleTop = sideHandleTop(bbox); - if (p.y >= eastHandleTop && p.y <= (eastHandleTop + size)) { - return EastHandle; - } - } - } - } else if (p.x <= NSMinX(bbox)) { - if (p.x >= NSMinX(bbox) - size) { - if (p.y >= NSMaxY(bbox)) { - if (p.y <= NSMaxY(bbox) + size) { - return SouthWestHandle; - } - } else if (p.y <= NSMinY(bbox)) { - if (p.y >= NSMinY(bbox) - size) { - return NorthWestHandle; - } - } else { - float westHandleTop = sideHandleTop(bbox); - if (p.y >= westHandleTop && p.y <= (westHandleTop + size)) { - return WestHandle; - } - } - } - } else if (p.y >= NSMaxY(bbox)) { - if (p.y <= NSMaxY(bbox) + size) { - return SouthHandle; - } - } else if (p.y <= NSMinY(bbox)) { - if (p.y >= NSMinY(bbox) - size) { - return NorthHandle; - } - } - return NoHandle; -} - -- (NSRect) boundingBoxResizeHandleRect:(ResizeHandle)handle { - if (![[self graph] hasBoundingBox]) { - return NSZeroRect; - } - NSRect bbox = [[surface transformer] rectToScreen:[[self graph] boundingBox]]; - switch (handle) { - case EastHandle: - return NSMakeRect(NSMaxX(bbox), sideHandleTop(bbox), size, size); - case SouthEastHandle: - return NSMakeRect(NSMaxX(bbox), NSMaxY(bbox), size, size); - case SouthHandle: - return NSMakeRect(tbHandleLeft(bbox), NSMaxY(bbox), size, size); - case SouthWestHandle: - return NSMakeRect(NSMaxX(bbox), NSMinY(bbox) - size, size, size); - case WestHandle: - return NSMakeRect(NSMinX(bbox) - size, sideHandleTop(bbox), size, size); - case NorthWestHandle: - return NSMakeRect(NSMinX(bbox) - size, NSMinY(bbox) - size, size, size); - case NorthHandle: - return NSMakeRect(tbHandleLeft(bbox), NSMinY(bbox) - size, size, size); - case NorthEastHandle: - return NSMakeRect(NSMinX(bbox) - size, NSMaxY(bbox), size, size); - default: - return NSZeroRect; - } -} - -@end - -@implementation GraphRenderer (Private) -- (BOOL) selectionBoxContainsNode:(Node*)node { - return !NSIsEmptyRect (selectionBox) - && NSPointInRect([[surface transformer] toScreen:[node point]], selectionBox); -} -- (BOOL) halfEdgeIncludesNode:(Node*)node { - if (halfEdgeOrigin == nil) { - return FALSE; - } - return halfEdgeOrigin == node || [self point:halfEdgeEnd hitsNode:node]; -} -- (enum NodeState) nodeState:(Node*)node { - if ([doc isNodeSelected:node]) { - return NodeSelected; - } else if ([self selectionBoxContainsNode:node] || [self halfEdgeIncludesNode:node]) { - return NodeHighlighted; - } else { - return NodeNormal; - } -} - -- (void) renderBoundingBoxWithContext:(id<RenderContext>)context { - if ([[self graph] hasBoundingBox]) { - [context saveState]; - - NSRect bbox = [[surface transformer] rectToScreen:[[self graph] boundingBox]]; - - [context setAntialiasMode:AntialiasDisabled]; - [context setLineWidth:1.0]; - [context startPath]; - [context rect:bbox]; - [context strokePathWithColor:MakeSolidRColor (1.0, 0.7, 0.5)]; - - if ([self boundingBoxHandlesShown]) { - [context startPath]; - [context rect:[self boundingBoxResizeHandleRect:EastHandle]]; - [context rect:[self boundingBoxResizeHandleRect:SouthEastHandle]]; - [context rect:[self boundingBoxResizeHandleRect:SouthHandle]]; - [context rect:[self boundingBoxResizeHandleRect:SouthWestHandle]]; - [context rect:[self boundingBoxResizeHandleRect:WestHandle]]; - [context rect:[self boundingBoxResizeHandleRect:NorthWestHandle]]; - [context rect:[self boundingBoxResizeHandleRect:NorthHandle]]; - [context rect:[self boundingBoxResizeHandleRect:NorthEastHandle]]; - [context strokePathWithColor:MakeSolidRColor (0.5, 0.5, 0.5)]; - } - - [context restoreState]; - } -} - -- (void) renderSelectionBoxWithContext:(id<RenderContext>)context { - if (!NSIsEmptyRect (selectionBox)) { - [context saveState]; - - [context setAntialiasMode:AntialiasDisabled]; - [context setLineWidth:1.0]; - [context startPath]; - [context rect:selectionBox]; - RColor fColor = MakeRColor (0.8, 0.8, 0.8, 0.2); - RColor sColor = MakeSolidRColor (0.6, 0.6, 0.6); - [context strokePathWithColor:sColor andFillWithColor:fColor]; - - [context restoreState]; - } -} - -- (void) renderImpendingEdgeWithContext:(id<RenderContext>)context { - if (halfEdgeOrigin == nil) { - return; - } - [context saveState]; - - [context setLineWidth:1.0]; - [context startPath]; - [context moveTo:halfEdgeOriginPoint]; - [context lineTo:halfEdgeEnd]; - [context strokePathWithColor:MakeRColor (0, 0, 0, 0.5)]; - - [context restoreState]; -} - -- (void) nodeNeedsRefreshing:(NSNotification*)notification { - [self invalidateNode:[[notification userInfo] objectForKey:@"node"]]; -} - -- (void) edgeNeedsRefreshing:(NSNotification*)notification { - Edge *edge = [[notification userInfo] objectForKey:@"edge"]; - NSRect edgeRect = [edge renderedBoundsWithTransformer:[surface transformer] whenSelected:YES]; - edgeRect = NSInsetRect (edgeRect, -2, -2); - [surface invalidateRect:edgeRect]; -} - -- (void) graphNeedsRefreshing:(NSNotification*)notification { - [self invalidateGraph]; -} - -- (void) graphChanged:(NSNotification*)notification { - GraphChange *change = [[notification userInfo] objectForKey:@"change"]; - switch ([change changeType]) { - case GraphAddition: - case GraphDeletion: - [self invalidateNodes:[change affectedNodes]]; - [self invalidateEdges:[change affectedEdges]]; - break; - case NodePropertyChange: - if (!NSEqualPoints ([[change oldNode] point], [[change nwNode] point])) { - // if the node has moved, it may be affecting edges - [surface invalidate]; - } else { - // invalide both old and new (old node may be larger) - [self invalidateNode:[change oldNode]]; - [self invalidateNode:[change nwNode]]; - } - break; - case EdgePropertyChange: - // invalide both old and new (old bend may increase bounds) - [self invalidateEdge:[change oldEdge]]; - [self invalidateEdge:[change nwEdge]]; - [self invalidateEdge:[change edgeRef]]; - break; - case NodesPropertyChange: - { - NSEnumerator *enumerator = [[change oldNodeTable] keyEnumerator]; - Node *node = nil; - while ((node = [enumerator nextObject]) != nil) { - NSPoint oldPos = [[[change oldNodeTable] objectForKey:node] point]; - NSPoint newPos = [[[change nwNodeTable] objectForKey:node] point]; - if (NSEqualPoints (oldPos, newPos)) { - [self invalidateNode:[[change oldNodeTable] objectForKey:node]]; - [self invalidateNode:[[change nwNodeTable] objectForKey:node]]; - } else { - [surface invalidate]; - break; - } - } - } - break; - case NodesShift: - case NodesFlip: - case BoundingBoxChange: - [surface invalidate]; - break; - default: - // unknown change - [surface invalidate]; - break; - }; -} - -- (void) nodeStylePropertyChanged:(NSNotification*)notification { - if (![@"name" isEqual:[[notification userInfo] objectForKey:@"propertyName"]]) { - BOOL affected = NO; - for (Node *node in [[self graph] nodes]) { - if ([node style] == [notification object]) - affected = YES; - } - if (affected) - [surface invalidate]; - } -} - -- (void) edgeStylePropertyChanged:(NSNotification*)notification { - if (![@"name" isEqual:[[notification userInfo] objectForKey:@"propertyName"]]) { - BOOL affected = NO; - for (Edge *edge in [[self graph] edges]) { - if ([edge style] == [notification object]) - affected = YES; - } - if (affected) - [surface invalidate]; - } -} - -@end - -// vim:ft=objc:ts=8:et:sts=4:sw=4 |