// // PBCommitList.m // GitX // // Created by Pieter de Bie on 9/11/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import "PBCommitList.h" #import "PBGitRevisionCell.h" #import "PBWebHistoryController.h" #import "PBHistorySearchController.h" @implementation PBCommitList @synthesize mouseDownPoint; @synthesize useAdjustScroll; - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL) local { return NSDragOperationCopy; } - (void)keyDown:(NSEvent *)event { NSString* character = [event charactersIgnoringModifiers]; // Pass on command-shift up/down to the responder. We want the splitview to capture this. if ([event modifierFlags] & NSShiftKeyMask && [event modifierFlags] & NSCommandKeyMask && ([event keyCode] == 0x7E || [event keyCode] == 0x7D)) { [self.nextResponder keyDown:event]; return; } if ([character isEqualToString:@" "]) { if (controller.selectedCommitDetailsIndex == 0) { if ([event modifierFlags] & NSShiftKeyMask) [webView scrollPageUp:self]; else [webView scrollPageDown:self]; } else [controller toggleQLPreviewPanel:self]; } else if ([character rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"jkcv"]].location == 0) [webController sendKey: character]; else [super keyDown: event]; } - (void) copy:(id)sender { [controller copyCommitInfo]; } - (void) copySHA:(id)sender { [controller copyCommitSHA]; } // !!! Andre Berg 20100330: Used from -scrollSelectionToTopOfViewFrom: of PBGitHistoryController // so that when the history controller udpates the branch filter the origin of the superview gets // shifted into multiples of the row height. Otherwise the top selected row will always be off by // a little bit depending on how much the bottom half of the split view is dragged down. - (NSRect)adjustScroll:(NSRect)proposedVisibleRect { //DLog(@"[%@ %s]: proposedVisibleRect: %@", [self class], _cmd, NSStringFromRect(proposedVisibleRect)); NSRect newRect = proposedVisibleRect; // !!! Andre Berg 20100330: only modify if -scrollSelectionToTopOfViewFrom: has set useAdjustScroll to YES // Otherwise we'd also constrain things like middle mouse scrolling. if (useAdjustScroll) { NSInteger rh = [self rowHeight]; NSInteger ny = (NSInteger)proposedVisibleRect.origin.y % (NSInteger)rh; NSInteger adj = rh - ny; // check the targeted row and see if we need to add or subtract the difference (if there is one)... NSRect sr = [self rectOfRow:[self selectedRow]]; // DLog(@"[%@ %s]: selectedRow %d, rect: %@", [self class], _cmd, [self selectedRow], NSStringFromRect(sr)); if (sr.origin.y > proposedVisibleRect.origin.y) { // DLog(@"[%@ %s] selectedRow.origin.y > proposedVisibleRect.origin.y. adding adj (%d)", [self class], _cmd, adj); newRect = NSMakeRect(newRect.origin.x, newRect.origin.y + adj, newRect.size.width, newRect.size.height); } else if (sr.origin.y < proposedVisibleRect.origin.y) { // DLog(@"[%@ %s] selectedRow.origin.y < proposedVisibleRect.origin.y. subtracting ny (%d)", [self class], _cmd, ny); newRect = NSMakeRect(newRect.origin.x, newRect.origin.y - ny , newRect.size.width, newRect.size.height); } else { // DLog(@"[%@ %s] selectedRow.origin.y == proposedVisibleRect.origin.y. leaving as is", [self class], _cmd); } } //DLog(@"[%@ %s]: newRect: %@", [self class], _cmd, NSStringFromRect(newRect)); return newRect; } - (void)mouseDown:(NSEvent *)theEvent { mouseDownPoint = [[self window] mouseLocationOutsideOfEventStream]; [super mouseDown:theEvent]; } - (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset { NSPoint location = [self convertPointFromBase:mouseDownPoint]; int row = [self rowAtPoint:location]; int column = [self columnAtPoint:location]; PBGitRevisionCell *cell = (PBGitRevisionCell *)[self preparedCellAtColumn:column row:row]; NSRect cellFrame = [self frameOfCellAtColumn:column row:row]; int index = [cell indexAtX:(location.x - cellFrame.origin.x)]; if (index == -1) return [super dragImageForRowsWithIndexes:dragRows tableColumns:tableColumns event:dragEvent offset:dragImageOffset]; NSRect rect = [cell rectAtIndex:index]; NSImage *newImage = [[NSImage alloc] initWithSize:NSMakeSize(rect.size.width + 3, rect.size.height + 3)]; rect.origin = NSMakePoint(0.5, 0.5); [newImage lockFocus]; [cell drawLabelAtIndex:index inRect:rect]; [newImage unlockFocus]; *dragImageOffset = NSMakePoint(rect.size.width / 2 + 10, 0); return newImage; } #pragma mark Row highlighting - (NSColor *)searchResultHighlightColorForRow:(NSInteger)rowIndex { // if the row is selected use default colors if ([self isRowSelected:rowIndex]) { if ([[self window] isKeyWindow]) { if ([[self window] firstResponder] == self) { return [NSColor alternateSelectedControlColor]; } return [NSColor selectedControlColor]; } return [NSColor secondarySelectedControlColor]; } // light blue color highlighting search results return [NSColor colorWithCalibratedRed:0.751f green:0.831f blue:0.943f alpha:0.800f]; } - (NSColor *)searchResultHighlightStrokeColorForRow:(NSInteger)rowIndex { if ([self isRowSelected:rowIndex]) return [NSColor colorWithCalibratedWhite:0.0f alpha:0.30f]; return [NSColor colorWithCalibratedWhite:0.0f alpha:0.05f]; } - (void)drawRow:(NSInteger)rowIndex clipRect:(NSRect)tableViewClipRect { NSRect rowRect = [self rectOfRow:rowIndex]; BOOL isRowVisible = NSIntersectsRect(rowRect, tableViewClipRect); // draw special highlighting if the row is part of search results if (isRowVisible && [searchController isRowInSearchResults:rowIndex]) { NSRect highlightRect = NSInsetRect(rowRect, 1.0f, 1.0f); float radius = highlightRect.size.height / 2.0f; NSBezierPath *highlightPath = [NSBezierPath bezierPathWithRoundedRect:highlightRect xRadius:radius yRadius:radius]; [[self searchResultHighlightColorForRow:rowIndex] set]; [highlightPath fill]; [[self searchResultHighlightStrokeColorForRow:rowIndex] set]; [highlightPath stroke]; } // draws the content inside the row [super drawRow:rowIndex clipRect:tableViewClipRect]; } - (void)highlightSelectionInClipRect:(NSRect)tableViewClipRect { // disable highlighting if the selected row is part of search results // instead do the highlighting in drawRow:clipRect: above if ([searchController isRowInSearchResults:[self selectedRow]]) return; [super highlightSelectionInClipRect:tableViewClipRect]; } @end