diff options
Diffstat (limited to 'tikzit/src/gtk/GraphInputHandler.m')
-rw-r--r-- | tikzit/src/gtk/GraphInputHandler.m | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/tikzit/src/gtk/GraphInputHandler.m b/tikzit/src/gtk/GraphInputHandler.m deleted file mode 100644 index 02d39a1..0000000 --- a/tikzit/src/gtk/GraphInputHandler.m +++ /dev/null @@ -1,524 +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 "GraphInputHandler.h" -#import <gdk/gdkkeysyms.h> -#import "MainWindow.h" -#import "Edge+Render.h" - -static const InputMask unionSelectMask = ShiftMask; - -@interface GraphInputHandler (Notifications) -- (void) nodeSelectionChanged:(NSNotification*)n; -- (void) edgeSelectionChanged:(NSNotification*)n; -@end - -@implementation GraphInputHandler -- (id) initWithGraphRenderer:(GraphRenderer*)r { - return [self initWithGraphRenderer:r window:nil]; -} -- (id) initWithGraphRenderer:(GraphRenderer*)r window:(MainWindow*)w { - self = [super init]; - - if (self) { - window = w; - renderer = r; - mode = SelectMode; - state = QuietState; - edgeFuzz = 3.0f; - leaderNode = nil; - modifyEdge = nil; - selectionBoxContents = [[NSMutableSet alloc] initWithCapacity:10]; - currentResizeHandle = NoHandle; - // FIXME: listen only to the doc's PickSupport - // (need to track document changes) - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(nodeSelectionChanged:) - name:@"NodeSelectionChanged" object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(edgeSelectionChanged:) - name:@"EdgeSelectionChanged" object:nil]; - } - - return self; -} - -- (void) dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [selectionBoxContents release]; - - [super dealloc]; -} - -- (TikzDocument*) doc { - return [renderer document]; -} - -- (void) deselectAllNodes { - [[[self doc] pickSupport] deselectAllNodes]; -} - -- (void) deselectAllEdges { - [[[self doc] pickSupport] deselectAllEdges]; -} - -- (void) deselectAll { - [[[self doc] pickSupport] deselectAllNodes]; - [[[self doc] pickSupport] deselectAllEdges]; -} - -- (void) shiftNodesByMovingLeader:(Node*)leader to:(NSPoint)to { - Transformer *transformer = [renderer transformer]; - - NSPoint from = [transformer toScreen:[leader point]]; - //to = [[renderer grid] snapScreenPoint:to]; - float dx = to.x - from.x; - float dy = to.y - from.y; - - for (Node *node in [[[self doc] pickSupport] selectedNodes]) { - NSPoint p = [transformer toScreen:[node point]]; - p.x += dx; - p.y += dy; - p = [[renderer grid] snapScreenPoint:p]; - [node setPoint:[transformer fromScreen:p]]; - } -} - -- (float) edgeFuzz { - return edgeFuzz; -} - -- (void) setEdgeFuzz:(float)fuzz { - edgeFuzz = fuzz; -} - -- (InputMode) mode { - return mode; -} - -- (void) resetState { - state = QuietState; -} - -- (void) setMode:(InputMode)m { - if (mode != m) { - if (mode == BoundingBoxMode) { - [renderer setBoundingBoxHandlesShown:NO]; - [[renderer surface] setCursor:NormalCursor]; - } - mode = m; - [self deselectAll]; - if (mode == BoundingBoxMode) { - [renderer setBoundingBoxHandlesShown:YES]; - [window favourGraphControls]; - } else if (mode == CreateNodeMode) { - [window favourNodeControls]; - } else if (mode == DrawEdgeMode) { - [window favourEdgeControls]; - } else if (mode == HandMode) { - [window favourGraphControls]; - } else if (mode == SelectMode) { - // FIXME: also change on selection change - if ([[[[self doc] pickSupport] selectedNodes] count]) - [window favourNodeControls]; - else if ([[[[self doc] pickSupport] selectedEdges] count]) - [window favourEdgeControls]; - else - [window favourGraphControls]; - } - } -} - -- (BOOL) circleWithCenter:(NSPoint)c andRadius:(float)r containsPoint:(NSPoint)p { - return (NSDistanceBetweenPoints(c, p) <= r); -} - -- (void) lookForControlPointAt:(NSPoint)pos { - const float cpr = [Edge controlPointRadius]; - for (Edge *e in [[[self doc] pickSupport] selectedEdges]) { - NSPoint cp1 = [[renderer transformer] toScreen:[e cp1]]; - if ([self circleWithCenter:cp1 andRadius:cpr containsPoint:pos]) { - state = DragEdgeControlPoint1; - modifyEdge = e; - [[self doc] startModifyEdge:e]; - return; - } - NSPoint cp2 = [[renderer transformer] toScreen:[e cp2]]; - if ([self circleWithCenter:cp2 andRadius:cpr containsPoint:pos]) { - state = DragEdgeControlPoint2; - modifyEdge = e; - [[self doc] startModifyEdge:e]; - return; - } - } -} - -- (void) mousePressAt:(NSPoint)pos withButton:(MouseButton)button andMask:(InputMask)mask { - if (button != LeftButton) - return; - - dragOrigin = pos; - - // we should already be in a quiet state, but no harm in making sure - state = QuietState; - - if (mode == HandMode || mask == ControlMask) { - state = CanvasDragState; - oldOrigin = [[renderer transformer] origin]; - } else if (mode == DrawEdgeMode) { - leaderNode = [renderer anyNodeAt:pos]; - if (leaderNode != nil) { - state = EdgeDragState; - } - } else if (mode == BoundingBoxMode) { - state = BoundingBoxState; - currentResizeHandle = [renderer boundingBoxResizeHandleAt:pos]; - [[self doc] startChangeBoundingBox]; - if (currentResizeHandle == NoHandle) { - [[[self doc] graph] setBoundingBox:NSZeroRect]; - [renderer setBoundingBoxHandlesShown:NO]; - } - } else if (mode == SelectMode) { - modifyEdge = nil; - [self lookForControlPointAt:pos]; - - if (modifyEdge == nil) { - // we didn't find a control point - - BOOL unionSelect = (mask & unionSelectMask); - - leaderNode = [renderer anyNodeAt:pos]; - // if we hit a node, deselect other nodes (if Shift is up) and go to move mode - if (leaderNode != nil) { - BOOL alreadySelected = [[self doc] isNodeSelected:leaderNode]; - if (!unionSelect && !alreadySelected) { - [self deselectAllEdges]; - [self deselectAllNodes]; - } - if (unionSelect && alreadySelected) { - state = ToggleSelectState; - } else { - [[[self doc] pickSupport] selectNode:leaderNode]; - state = MoveSelectedNodesState; - oldLeaderPos = [leaderNode point]; - [[self doc] startShiftNodes:[[[self doc] pickSupport] selectedNodes]]; - } - } - - // if mouse did not hit a node, check if mouse hit an edge - if (leaderNode == nil) { - Edge *edge = [renderer anyEdgeAt:pos withFuzz:edgeFuzz]; - if (edge != nil) { - BOOL alreadySelected = [[self doc] isEdgeSelected:edge]; - if (!unionSelect) { - [self deselectAll]; - } - if (unionSelect && alreadySelected) { - [[[self doc] pickSupport] deselectEdge:edge]; - } else { - [[[self doc] pickSupport] selectEdge:edge]; - } - } else { - // if mouse did not hit anything, put us in box mode - if (!unionSelect) { - [self deselectAll]; - } - [selectionBoxContents removeAllObjects]; - state = SelectBoxState; - } - } - } - } -} - -- (void) mouseReleaseAt:(NSPoint)pos withButton:(MouseButton)button andMask:(InputMask)mask { - if (button != LeftButton) - return; - - if (state == SelectBoxState) { - BOOL shouldDeselect = !(mask & unionSelectMask); - if (shouldDeselect) { - [self deselectAllEdges]; - } - [[[self doc] pickSupport] selectAllNodes:selectionBoxContents - replacingSelection:shouldDeselect]; - [renderer clearSelectionBox]; - } else if (state == ToggleSelectState) { - [[[self doc] pickSupport] deselectNode:leaderNode]; - leaderNode = nil; - } else if (state == MoveSelectedNodesState) { - if (NSEqualPoints (oldLeaderPos, [leaderNode point])) { - [[self doc] cancelShiftNodes]; - } else { - [[self doc] endShiftNodes]; - } - leaderNode = nil; - } else if (state == DragEdgeControlPoint1 || state == DragEdgeControlPoint2) { - // FIXME: check if there was any real change - [[self doc] endModifyEdge]; - } else if (state == EdgeDragState) { - [renderer clearHalfEdge]; - Node *targ = [renderer anyNodeAt:pos]; - if (targ != nil) { - [[self doc] addEdgeFrom:leaderNode to:targ]; - } - } else if (state == QuietState && mode == CreateNodeMode) { - Transformer *transformer = [renderer transformer]; - NSPoint nodePoint = [transformer fromScreen:[[renderer grid] snapScreenPoint:pos]]; - [[self doc] addNodeAt:nodePoint]; - } else if (state == BoundingBoxState) { - [[self doc] endChangeBoundingBox]; - [renderer setBoundingBoxHandlesShown:YES]; - } - - state = QuietState; -} - -- (void) mouseDoubleClickAt:(NSPoint)pos withButton:(MouseButton)button andMask:(InputMask)mask { - if (button != LeftButton) - return; - - if (mode != SelectMode) { - return; - } - if (state != QuietState) { - return; - } - // convert bend mode on edge under mouse cursor - Edge *edge = [renderer anyEdgeAt:pos withFuzz:edgeFuzz]; - if (edge != nil) { - [[self doc] startModifyEdge:edge]; - if ([edge bendMode]==EdgeBendModeBasic) { - [edge convertBendToAngles]; - [edge setBendMode:EdgeBendModeInOut]; - } else { - [edge setBendMode:EdgeBendModeBasic]; - } - [[self doc] endModifyEdge]; - - [self deselectAllEdges]; - [[[self doc] pickSupport] selectEdge:edge]; - } -} - -- (void) mouseMoveTo:(NSPoint)pos withButtons:(MouseButton)buttons andMask:(InputMask)mask { - if (!(buttons & LeftButton)) - return; - - Transformer *transformer = [renderer transformer]; - - if (state == ToggleSelectState) { - state = MoveSelectedNodesState; - oldLeaderPos = [leaderNode point]; - [[self doc] startShiftNodes:[[[self doc] pickSupport] selectedNodes]]; - } - - if (state == SelectBoxState) { - NSRect selectionBox = NSRectAroundPoints(dragOrigin, pos); - [renderer setSelectionBox:selectionBox]; - - NSEnumerator *enumerator = [[self doc] nodeEnumerator]; - Node *node; - while ((node = [enumerator nextObject]) != nil) { - NSPoint nodePos = [transformer toScreen:[node point]]; - if (NSPointInRect(nodePos, selectionBox)) { - if (![selectionBoxContents member:node]) { - [selectionBoxContents addObject:node]; - [renderer invalidateNode:node]; - } - } else { - if ([selectionBoxContents member:node]) { - [selectionBoxContents removeObject:node]; - [renderer invalidateNode:node]; - } - } - } - } else if (state == MoveSelectedNodesState) { - if (leaderNode != nil) { - [self shiftNodesByMovingLeader:leaderNode to:pos]; - NSPoint shiftSoFar; - shiftSoFar.x = [leaderNode point].x - oldLeaderPos.x; - shiftSoFar.y = [leaderNode point].y - oldLeaderPos.y; - [[self doc] shiftNodesUpdate:shiftSoFar]; - } - } else if (state == DragEdgeControlPoint1 || state == DragEdgeControlPoint2) { - // invalidate once before we start changing it: we may be shrinking - // the control circles - [[self doc] modifyEdgeCheckPoint]; - if (state == DragEdgeControlPoint1) { - [modifyEdge moveCp1To:[transformer fromScreen:pos] - withWeightCourseness:0.1f - andBendCourseness:15 - forceLinkControlPoints:(mask & ControlMask)]; - } else { - [modifyEdge moveCp2To:[transformer fromScreen:pos] - withWeightCourseness:0.1f - andBendCourseness:15 - forceLinkControlPoints:(mask & ControlMask)]; - } - [[self doc] modifyEdgeCheckPoint]; - } else if (state == EdgeDragState) { - [renderer setHalfEdgeFrom:leaderNode to:pos]; - } else if (state == BoundingBoxState) { - Grid *grid = [renderer grid]; - Graph *graph = [[self doc] graph]; - if (currentResizeHandle == NoHandle) { - NSRect bbox = NSRectAroundPoints( - [grid snapScreenPoint:dragOrigin], - [grid snapScreenPoint:pos] - ); - [graph setBoundingBox:[transformer rectFromScreen:bbox]]; - } else { - NSRect bbox = [transformer rectToScreen:[graph boundingBox]]; - NSPoint p2 = [grid snapScreenPoint:pos]; - - if (currentResizeHandle == NorthWestHandle || - currentResizeHandle == NorthHandle || - currentResizeHandle == NorthEastHandle) { - - float dy = p2.y - NSMinY(bbox); - if (dy < bbox.size.height) { - bbox.origin.y += dy; - bbox.size.height -= dy; - } else { - bbox.origin.y = NSMaxY(bbox); - bbox.size.height = 0; - } - - } else if (currentResizeHandle == SouthWestHandle || - currentResizeHandle == SouthHandle || - currentResizeHandle == SouthEastHandle) { - - float dy = p2.y - NSMaxY(bbox); - if (-dy < bbox.size.height) { - bbox.size.height += dy; - } else { - bbox.size.height = 0; - } - } - - if (currentResizeHandle == NorthWestHandle || - currentResizeHandle == WestHandle || - currentResizeHandle == SouthWestHandle) { - - float dx = p2.x - NSMinX(bbox); - if (dx < bbox.size.width) { - bbox.origin.x += dx; - bbox.size.width -= dx; - } else { - bbox.origin.x = NSMaxX(bbox); - bbox.size.width = 0; - } - - } else if (currentResizeHandle == NorthEastHandle || - currentResizeHandle == EastHandle || - currentResizeHandle == SouthEastHandle) { - - float dx = p2.x - NSMaxX(bbox); - if (-dx < bbox.size.width) { - bbox.size.width += dx; - } else { - bbox.size.width = 0; - } - } - [graph setBoundingBox:[transformer rectFromScreen:bbox]]; - } - [[self doc] changeBoundingBoxCheckPoint]; - } else if (state == CanvasDragState) { - NSPoint newOrigin = oldOrigin; - newOrigin.x += pos.x - dragOrigin.x; - newOrigin.y += pos.y - dragOrigin.y; - [[renderer transformer] setOrigin:newOrigin]; - [renderer invalidateGraph]; - } - if (mode == BoundingBoxMode && state != BoundingBoxState) { - ResizeHandle handle = [renderer boundingBoxResizeHandleAt:pos]; - if (handle != currentResizeHandle) { - currentResizeHandle = handle; - Cursor c = NormalCursor; - switch (handle) { - case EastHandle: - c = ResizeRightCursor; - break; - case SouthEastHandle: - c = ResizeBottomRightCursor; - break; - case SouthHandle: - c = ResizeBottomCursor; - break; - case SouthWestHandle: - c = ResizeBottomLeftCursor; - break; - case WestHandle: - c = ResizeLeftCursor; - break; - case NorthWestHandle: - c = ResizeTopLeftCursor; - break; - case NorthHandle: - c = ResizeTopCursor; - break; - case NorthEastHandle: - c = ResizeTopRightCursor; - break; - default: - c = NormalCursor; - break; - } - [[renderer surface] setCursor:c]; - } - } -} - -- (void) mouseScrolledAt:(NSPoint)pos inDirection:(ScrollDirection)dir withMask:(InputMask)mask { - if (mask == ControlMask) { - if (dir == ScrollUp) { - [[renderer surface] zoomInAboutPoint:pos]; - } else if (dir == ScrollDown) { - [[renderer surface] zoomOutAboutPoint:pos]; - } - } -} - -@end - -@implementation GraphInputHandler (Notifications) -- (void) nodeSelectionChanged:(NSNotification*)n { - if (mode == SelectMode) { - if ([[[[self doc] pickSupport] selectedNodes] count]) - [window favourNodeControls]; - else if ([[[[self doc] pickSupport] selectedEdges] count]) - [window favourEdgeControls]; - else - [window favourGraphControls]; - } -} - -- (void) edgeSelectionChanged:(NSNotification*)n { - if (mode == SelectMode) { - if ([[[[self doc] pickSupport] selectedNodes] count]) - [window favourNodeControls]; - else if ([[[[self doc] pickSupport] selectedEdges] count]) - [window favourEdgeControls]; - else - [window favourGraphControls]; - } -} -@end - -// vim:ft=objc:ts=8:et:sts=4:sw=4 |