diff --git a/GitUpKit/Interface/GIGraphView.h b/GitUpKit/Interface/GIGraphView.h index c0d93f5a..3da23759 100644 --- a/GitUpKit/Interface/GIGraphView.h +++ b/GitUpKit/Interface/GIGraphView.h @@ -31,6 +31,7 @@ @property(nonatomic, weak) GINode* selectedNode; // Setting this property directly does not call the delegate @property(nonatomic, weak) GCHistoryCommit* selectedCommit; // Convenience method that wraps @selectedNode +@property(nonatomic, weak) GINode* lastSelectedNode; @property(nonatomic, readonly) NSSize minSize; diff --git a/GitUpKit/Interface/GIGraphView.m b/GitUpKit/Interface/GIGraphView.m index 40b25577..05c32a31 100644 --- a/GitUpKit/Interface/GIGraphView.m +++ b/GitUpKit/Interface/GIGraphView.m @@ -330,6 +330,11 @@ - (void)setSelectedNode:(GINode*)node { // We need to retain the underlying commit for later as GINode doesn't retain its commit - (void)_setSelectedNode:(GINode*)node display:(BOOL)display scroll:(BOOL)scroll notify:(BOOL)notify { XLOG_DEBUG_CHECK(!node.dummy); + if (display && _lastSelectedNode) { + NSPoint point = [self positionForNode:_lastSelectedNode]; + [self setNeedsDisplayInRect:SELECTED_NODE_BOUNDS(point.x, point.y)]; + } + _lastSelectedNode = nil; if (node != _selectedNode) { if (display && _selectedNode) { NSPoint point = [self positionForNode:_selectedNode]; @@ -467,7 +472,18 @@ - (void)mouseDown:(NSEvent*)event { node = nil; } } + + GINode* selectedNode = _selectedNode; + GINode* lastSelectedNode = _lastSelectedNode; [self _setSelectedNode:node display:YES scroll:NO notify:YES]; + if (event.modifierFlags & NSEventModifierFlagCommand) { + if (lastSelectedNode == nil) { + _lastSelectedNode = selectedNode; + } else { + _lastSelectedNode = lastSelectedNode; + } + } + if (scroll) { [self scrollToSelection]; } @@ -1693,6 +1709,19 @@ - (void)drawRect:(NSRect)dirtyRect { } } + // Draw selected node if any + if (_lastSelectedNode) { + CGFloat x = CONVERT_X(_lastSelectedNode.x); + CGFloat y = CONVERT_Y(offset - _lastSelectedNode.layer.y); + if (NSIntersectsRect(SELECTED_NODE_BOUNDS(x, y), dirtyRect)) { +#if __DEBUG_BOXES__ + CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.666); + CGContextFillRect(context, SELECTED_NODE_BOUNDS(x, y)); +#endif + _DrawSelectedNode(context, x, y, _lastSelectedNode, selectedAttributes1, selectedAttributes2, _dateFormatter, self.window.keyWindow && (self.window.firstResponder == self)); + } + } + // Restore graphics context CGContextRestoreGState(context); diff --git a/GitUpKit/Views/GIMapViewController.m b/GitUpKit/Views/GIMapViewController.m index a289fd83..7ffaf2f6 100644 --- a/GitUpKit/Views/GIMapViewController.m +++ b/GitUpKit/Views/GIMapViewController.m @@ -657,7 +657,8 @@ - (BOOL)validateUserInterfaceItem:(id)item { return (service != kGCHostingService_Unknown); } if ((item.action == @selector(diffSelectedCommitWithHEAD:)) || (item.action == @selector(externalDiffWithHEAD:))) { - return ![self.repository.history.HEADCommit isEqualToCommit:commit]; + GCHistoryCommit* headCommit = _graphView.lastSelectedNode.commit ?: self.repository.history.HEADCommit; + return ![headCommit isEqualToCommit:commit]; } if (editingDisabled) { @@ -799,7 +800,7 @@ - (IBAction)viewSelectedCommitInHostingService:(id)sender { } - (void)_diffSelectedCommitWithHEAD:(void (^)(GCHistoryCommit* commit, GCHistoryCommit* otherCommit))handler { - GCHistoryCommit* headCommit = self.repository.history.HEADCommit; + GCHistoryCommit* headCommit = _graphView.lastSelectedNode.commit ?: self.repository.history.HEADCommit; GCHistoryCommit* selectedCommit = _graphView.selectedCommit; switch ([selectedCommit.date compare:headCommit.date]) { case NSOrderedAscending: // Selected commit is older than HEAD commit