diff options
author | Alex Merry <alex.merry@cs.ox.ac.uk> | 2012-12-04 18:55:25 +0000 |
---|---|---|
committer | Alex Merry <dev@randomguy3.me.uk> | 2012-12-06 12:08:03 +0000 |
commit | f23a2d9daa1eb62b2afac8997f1d76eb881628f7 (patch) | |
tree | 378c1cc752b7aa1fd52f35da23bce7de855bef5d /tikzit/src/gtk/GraphRenderer.m | |
parent | 134de8169993f23f2c3a733a7bf96622965e7d7d (diff) |
Refactor GraphInputHandler into Tools
Diffstat (limited to 'tikzit/src/gtk/GraphRenderer.m')
-rw-r--r-- | tikzit/src/gtk/GraphRenderer.m | 249 |
1 files changed, 36 insertions, 213 deletions
diff --git a/tikzit/src/gtk/GraphRenderer.m b/tikzit/src/gtk/GraphRenderer.m index 3fc14d6..76fe551 100644 --- a/tikzit/src/gtk/GraphRenderer.m +++ b/tikzit/src/gtk/GraphRenderer.m @@ -20,24 +20,11 @@ #import "Edge+Render.h" #import "Node+Render.h" -static const float size = 8.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; @@ -53,9 +40,8 @@ void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); if (self) { surface = [s retain]; - doc = nil; grid = [[Grid alloc] initWithSpacing:1.0f subdivisions:4 transformer:[s transformer]]; - halfEdgeOrigin = nil; + highlightedNodes = [[NSMutableSet alloc] initWithCapacity:10]; [surface setRenderDelegate:self]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -85,11 +71,26 @@ void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); [[NSNotificationCenter defaultCenter] removeObserver:self]; [doc release]; [grid release]; + [highlightedNodes release]; [surface release]; [super dealloc]; } +- (id<RenderDelegate>) postRenderer { + return postRenderer; +} +- (void) setPostRenderer:(id<RenderDelegate>)r { + if (r == postRenderer) + return; + + [r retain]; + [postRenderer release]; + postRenderer = r; + + [self invalidateGraph]; +} + - (void) renderWithContext:(id<RenderContext>)context onSurface:(id<Surface>)surface { [self renderWithContext:context]; } @@ -116,14 +117,17 @@ void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); } [self renderBoundingBoxWithContext:context]; - [self renderSelectionBoxWithContext:context]; - [self renderImpendingEdgeWithContext:context]; + [postRenderer renderWithContext:context onSurface:surface]; } - (void) invalidateGraph { [surface invalidate]; } +- (void) invalidateRect:(NSRect)rect { + [surface invalidateRect:rect]; +} + - (void) invalidateNodes:(NSSet*)nodes { for (Node *node in nodes) { [self invalidateNode:node]; @@ -285,171 +289,34 @@ void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); [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)]; +- (BOOL) isNodeHighlighted:(Node*)node { + return [highlightedNodes containsObject:node]; } - -- (void) invalidateHalfEdge { - if (halfEdgeOrigin != nil) { - NSRect invRect = NSRectAroundPoints(halfEdgeEnd, halfEdgeOriginPoint); - invRect = NSUnionRect(invRect, [halfEdgeOrigin renderBoundsWithLabelForSurface:surface]); - - NSEnumerator *enumerator = [doc nodeEnumerator]; - Node *node; - while ((node = [enumerator nextObject]) != nil) { - if ([self point:halfEdgeEnd fuzzyHitsNode:node]) { - invRect = NSUnionRect(invRect, [node renderBoundsWithLabelForSurface: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) { - float southHandleLeft = tbHandleLeft(bbox); - if (p.x >= southHandleLeft && p.x <= (southHandleLeft + size)) { - return SouthHandle; - } +- (void) setNode:(Node*)node highlighted:(BOOL)h { + if (h) { + if (![highlightedNodes containsObject:node]) { + [highlightedNodes addObject:node]; + [self invalidateNode:node]; } - } else if (p.y <= NSMinY(bbox)) { - if (p.y >= NSMinY(bbox) - size) { - float northHandleLeft = tbHandleLeft(bbox); - if (p.x >= northHandleLeft && p.x <= (northHandleLeft + size)) { - return NorthHandle; - } + } else { + if ([highlightedNodes containsObject:node]) { + [highlightedNodes removeObject:node]; + [self invalidateNode:node]; } } - 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; - } +- (void) clearHighlightedNodes { + [self invalidateNodes:highlightedNodes]; + [highlightedNodes removeAllObjects]; } @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]) { + } else if ([self isNodeHighlighted:node]) { return NodeHighlighted; } else { return NodeNormal; @@ -468,54 +335,10 @@ void graph_renderer_expose_event(GtkWidget *widget, GdkEventExpose *event); [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"]]; } |