From 9bfccb5ea5d91411c4244ac75f689532eb936dbc Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 28 Aug 2008 17:29:34 +0200 Subject: [PATCH 1/7] Grapher: add first part of displaying refs This adds the "hasRef" boolean member in PBGitCellInfo which is set to true if the specific commit has symbolic refs. This is the first part in supporting labels just like gitk has. For now, commits with refs are just displayed with a red circle. Things that need to be done to support all refs: * Make the NSDictionary in PBGitRepository contain arrays of refs, not a single string * Make PBGitGrapher store all refs of a commit in the PBGitCellInfo * Figure out a nice way to display the labels in PBGitRevisionCell --- PBGitGrapher.h | 2 ++ PBGitGrapher.m | 14 +++++++++++++- PBGitRepository.h | 5 +++-- PBGitRepository.m | 20 +++++++++++--------- PBGitRevList.h | 2 +- PBGitRevList.m | 2 +- PBGitRevisionCell.m | 6 +++++- PBGraphCellInfo.h | 2 ++ PBGraphCellInfo.m | 2 +- 9 files changed, 39 insertions(+), 16 deletions(-) diff --git a/PBGitGrapher.h b/PBGitGrapher.h index 26741a4..2b46430 100644 --- a/PBGitGrapher.h +++ b/PBGitGrapher.h @@ -21,8 +21,10 @@ struct PBGitGraphColumn { @interface PBGitGrapher : NSObject { NSMutableArray* cellsInfo; + PBGitRepository* repository; } +- (id) initWithRepository: (PBGitRepository*) repo; - (void) parseCommits: (NSArray *) array; - (PBGraphCellInfo*) cellInfoForRow: (int) row; @end diff --git a/PBGitGrapher.m b/PBGitGrapher.m index a264f3b..a66369d 100644 --- a/PBGitGrapher.m +++ b/PBGitGrapher.m @@ -12,12 +12,21 @@ @implementation PBGitGrapher +- (id) initWithRepository: (PBGitRepository*) repo +{ + repository = repo; + return self; +} - (void) parseCommits: (NSArray *) commits { cellsInfo = [NSMutableArray arrayWithCapacity: [commits count]]; int row = 0; + NSDictionary* refs = nil; + if (repository) + refs = repository.refs; + PBGraphCellInfo* previous; NSMutableArray* previousLanes = [NSMutableArray array]; @@ -120,7 +129,10 @@ ++row; previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines]; - + + if (refs && [refs objectForKey:commit.sha]) + previous.hasRef = TRUE; + // If a parent was added, we have room to not indent. if (addedParent) previous.numColumns = [currentLanes count] - 1; diff --git a/PBGitRepository.h b/PBGitRepository.h index 22af9a5..98fe88e 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -15,6 +15,7 @@ extern NSString* PBGitRepositoryErrorDomain; PBGitRevList* revisionList; NSArray* branches; NSString* currentBranch; + NSDictionary* refs; } - (NSFileHandle*) handleForCommand:(NSString*) cmd; @@ -22,7 +23,7 @@ extern NSString* PBGitRepositoryErrorDomain; - (NSString*) outputForCommand:(NSString*) cmd; - (NSString*) outputForArguments:(NSArray*) args; -- (void) readBranches; +- (void) readRefs; - (void) readCurrentBranch; - (NSString*) parseSymbolicReference:(NSString*) ref; @@ -34,5 +35,5 @@ extern NSString* PBGitRepositoryErrorDomain; @property (readonly) PBGitRevList* revisionList; @property (assign) NSArray* branches; @property (assign) NSString* currentBranch; - +@property (assign) NSDictionary* refs; @end diff --git a/PBGitRepository.m b/PBGitRepository.m index fc7b66f..09327b2 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -17,7 +17,7 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; @implementation PBGitRepository -@synthesize revisionList, branches, currentBranch; +@synthesize revisionList, branches, currentBranch, refs; static NSString* gitPath; + (void) initialize @@ -112,7 +112,7 @@ static NSString* gitPath; } if (success) { - [self readBranches]; + [self readRefs]; [self readCurrentBranch]; revisionList = [[PBGitRevList alloc] initWithRepository:self andRevListParameters:[NSArray array]]; } @@ -139,21 +139,23 @@ static NSString* gitPath; [controller release]; } -- (void) readBranches +- (void) readRefs { - NSString* output = [PBEasyPipe outputForCommand:gitPath withArgs:[NSArray arrayWithObjects:@"for-each-ref", @"refs/heads", nil] inDir: self.fileURL.path]; + NSString* output = [PBEasyPipe outputForCommand:gitPath withArgs:[NSArray arrayWithObjects:@"for-each-ref", @"refs", nil] inDir: self.fileURL.path]; NSArray* lines = [output componentsSeparatedByString:@"\n"]; + NSMutableDictionary* newRefs = [NSMutableDictionary dictionary]; NSMutableArray* newBranches = [NSMutableArray array]; for (NSString* line in lines) { NSString* substr = [line substringWithRange: NSMakeRange(40,19)]; - if (![substr isEqualToString:@" commit\trefs/heads/"]) { - NSLog(@"Cannot parse branch %@. (%@)", line, substr); - continue; + if ([substr isEqualToString:@" commit\trefs/heads/"]) { + NSString* branch = [line substringFromIndex:59]; + [newBranches addObject: branch]; } - NSString* branch = [line substringFromIndex:59]; - [newBranches addObject: branch]; + NSArray* components = [line componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]]; + [newRefs setObject:[components objectAtIndex:2] forKey:[components objectAtIndex:0]]; } self.branches = newBranches; + self.refs = newRefs; } - (void) readCurrentBranch diff --git a/PBGitRevList.h b/PBGitRevList.h index 1417cac..60e96bf 100644 --- a/PBGitRevList.h +++ b/PBGitRevList.h @@ -18,7 +18,7 @@ } - initWithRepository:(id)repo andRevListParameters:(NSArray*) params; -- readCommits; +- (void) readCommits; @property(retain) NSArray* commits; @property(retain) id grapher; diff --git a/PBGitRevList.m b/PBGitRevList.m index a627326..631aa30 100644 --- a/PBGitRevList.m +++ b/PBGitRevList.m @@ -103,7 +103,7 @@ [self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES]; - PBGitGrapher* g = [[PBGitGrapher alloc] init]; + PBGitGrapher* g = [[PBGitGrapher alloc] initWithRepository: repository]; [g parseCommits: self.commits]; [self performSelectorOnMainThread:@selector(setGrapher:) withObject:g waitUntilDone:YES]; [self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES]; diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index 109a2ac..e57254e 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -63,7 +63,11 @@ - (void) drawCircleForColumn: (int) c inRect: (NSRect) r { - [[NSColor blackColor] set]; + if (!cellInfo.hasRef) + [[NSColor blackColor] set]; + else + [[NSColor redColor] set]; + int columnWidth = 10; NSPoint origin = r.origin; NSPoint columnOrigin = { origin.x + columnWidth * c, origin.y}; diff --git a/PBGraphCellInfo.h b/PBGraphCellInfo.h index 8f4b84b..8e6e464 100644 --- a/PBGraphCellInfo.h +++ b/PBGraphCellInfo.h @@ -14,9 +14,11 @@ int position; NSArray* lines; int numColumns; + BOOL hasRef; } @property(readonly) NSArray* lines; @property(assign) int position, numColumns; +@property(assign) BOOL hasRef; - (id)initWithPosition: (int) p andLines: (NSArray*) l; diff --git a/PBGraphCellInfo.m b/PBGraphCellInfo.m index f5e96b5..890ce7f 100644 --- a/PBGraphCellInfo.m +++ b/PBGraphCellInfo.m @@ -10,7 +10,7 @@ @implementation PBGraphCellInfo -@synthesize lines, position, numColumns; +@synthesize lines, position, numColumns, hasRef; - (id)initWithPosition: (int) p andLines: (NSArray*) l { position = p; From ae7d15a247d4968fe2a18c39da63b8033d48d58f Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 28 Aug 2008 17:46:54 +0200 Subject: [PATCH 2/7] Grapher: dereference annotated tags The for-each-ref construct used to return the tag sha for annotated tags. We're not really interested in that, so also display its referenced object. --- PBGitRepository.m | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/PBGitRepository.m b/PBGitRepository.m index 09327b2..c07ffda 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -141,18 +141,26 @@ static NSString* gitPath; - (void) readRefs { - NSString* output = [PBEasyPipe outputForCommand:gitPath withArgs:[NSArray arrayWithObjects:@"for-each-ref", @"refs", nil] inDir: self.fileURL.path]; + NSString* output = [PBEasyPipe outputForCommand:gitPath withArgs:[NSArray arrayWithObjects:@"for-each-ref", @"--format=%(refname) %(objecttype) %(objectname) %(*objectname)", @"refs", nil] inDir: self.fileURL.path]; NSArray* lines = [output componentsSeparatedByString:@"\n"]; NSMutableDictionary* newRefs = [NSMutableDictionary dictionary]; NSMutableArray* newBranches = [NSMutableArray array]; for (NSString* line in lines) { - NSString* substr = [line substringWithRange: NSMakeRange(40,19)]; - if ([substr isEqualToString:@" commit\trefs/heads/"]) { - NSString* branch = [line substringFromIndex:59]; + NSArray* components = [line componentsSeparatedByString:@" "]; + NSString* ref = [components objectAtIndex:0]; + NSString* type = [components objectAtIndex:1]; + NSString* sha; + if ([type isEqualToString:@"tag"] && [components count] == 4) + sha = [components objectAtIndex:3]; + else + sha = [components objectAtIndex:2]; + + if ([[ref substringToIndex:11] isEqualToString:@"refs/heads/"]) { + NSString* branch = [ref substringFromIndex:11]; [newBranches addObject: branch]; } - NSArray* components = [line componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]]; - [newRefs setObject:[components objectAtIndex:2] forKey:[components objectAtIndex:0]]; + + [newRefs setObject:ref forKey:sha]; } self.branches = newBranches; self.refs = newRefs; From b4d7816be770fdb4056073010b552844fa6b523b Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 28 Aug 2008 18:07:34 +0200 Subject: [PATCH 3/7] Grapher: draw ref names This simply draws the ref names in the cell, without any markup or correct rect. --- PBGitGrapher.m | 2 +- PBGitRepository.m | 6 +++++- PBGitRevisionCell.m | 15 ++++++++++++++- PBGraphCellInfo.h | 4 ++-- PBGraphCellInfo.m | 2 +- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/PBGitGrapher.m b/PBGitGrapher.m index a66369d..df7d87a 100644 --- a/PBGitGrapher.m +++ b/PBGitGrapher.m @@ -131,7 +131,7 @@ previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines]; if (refs && [refs objectForKey:commit.sha]) - previous.hasRef = TRUE; + previous.refs = [refs objectForKey:commit.sha]; // If a parent was added, we have room to not indent. if (addedParent) diff --git a/PBGitRepository.m b/PBGitRepository.m index c07ffda..458fb39 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -160,7 +160,11 @@ static NSString* gitPath; [newBranches addObject: branch]; } - [newRefs setObject:ref forKey:sha]; + NSMutableArray* curRefs; + if (curRefs = [newRefs objectForKey:sha]) + [curRefs addObject:ref]; + else + [newRefs setObject:[NSMutableArray arrayWithObject:ref] forKey:sha]; } self.branches = newBranches; self.refs = newRefs; diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index e57254e..01c2bec 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -63,7 +63,7 @@ - (void) drawCircleForColumn: (int) c inRect: (NSRect) r { - if (!cellInfo.hasRef) + if (!cellInfo.refs) [[NSColor blackColor] set]; else [[NSColor redColor] set]; @@ -86,6 +86,17 @@ [path fill]; } +- (void) drawRefsInRect: (NSRect*) rect +{ + int pathWidth = 40 * [cellInfo.refs count]; + NSRect ownRect; + NSDivideRect(*rect, &ownRect, rect, pathWidth, NSMinXEdge); + for (NSString* ref in cellInfo.refs) { + NSString* newRef = [[ref componentsSeparatedByString:@"/"] lastObject]; + [newRef drawInRect: ownRect withAttributes:nil]; + } +} + - (void) drawWithFrame: (NSRect) rect inView:(NSView *)view { if (!isReady) @@ -105,6 +116,8 @@ [self drawCircleForColumn: cellInfo.position inRect: ownRect]; + if (cellInfo.refs) + [self drawRefsInRect:&rect]; [super drawWithFrame:rect inView:view]; isReady = NO; diff --git a/PBGraphCellInfo.h b/PBGraphCellInfo.h index 8e6e464..c399441 100644 --- a/PBGraphCellInfo.h +++ b/PBGraphCellInfo.h @@ -14,11 +14,11 @@ int position; NSArray* lines; int numColumns; - BOOL hasRef; + NSArray* refs; } @property(readonly) NSArray* lines; +@property(retain) NSArray* refs; @property(assign) int position, numColumns; -@property(assign) BOOL hasRef; - (id)initWithPosition: (int) p andLines: (NSArray*) l; diff --git a/PBGraphCellInfo.m b/PBGraphCellInfo.m index 890ce7f..8beff21 100644 --- a/PBGraphCellInfo.m +++ b/PBGraphCellInfo.m @@ -10,7 +10,7 @@ @implementation PBGraphCellInfo -@synthesize lines, position, numColumns, hasRef; +@synthesize lines, position, numColumns, refs; - (id)initWithPosition: (int) p andLines: (NSArray*) l { position = p; From f631f54ddc25c08df968a4995513bb9b423ac850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciar=C3=A1n=20Walsh?= Date: Thu, 28 Aug 2008 20:54:48 +0100 Subject: [PATCH 4/7] Some minor cleanup of the commit-ref drawing. Proper calculation of the width required; each ref is given its own rounded box. --- PBGitRevisionCell.m | 84 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index 01c2bec..2f3f23b 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -9,6 +9,53 @@ #import "PBGitRevisionCell.h" +@implementation NSBezierPath (RoundedRectangle) ++ (NSBezierPath *)bezierPathWithRoundedRect: (NSRect) aRect cornerRadius: (double) cRadius +{ + double left = aRect.origin.x, bottom = aRect.origin.y, width = aRect.size.width, height = aRect.size.height; + + //now, crop the radius so we don't get weird effects + double lesserDim = width < height ? width : height; + if ( cRadius > lesserDim / 2 ) + { + cRadius = lesserDim / 2; + } + + //these points describe the rectangle as start and stop points of the + //arcs making up its corners --points c, e, & g are implicit endpoints of arcs + //and are unnecessary + NSPoint a = NSMakePoint( 0, cRadius ), b = NSMakePoint( 0, height - cRadius ), + d = NSMakePoint( width - cRadius, height ), f = NSMakePoint( width, cRadius ), + h = NSMakePoint( cRadius, 0 ); + + //these points describe the center points of the corner arcs + NSPoint cA = NSMakePoint( cRadius, height - cRadius ), + cB = NSMakePoint( width - cRadius, height - cRadius ), + cC = NSMakePoint( width - cRadius, cRadius ), + cD = NSMakePoint( cRadius, cRadius ); + + //start + NSBezierPath *bp = [NSBezierPath bezierPath]; + [bp moveToPoint: a ]; + [bp lineToPoint: b ]; + [bp appendBezierPathWithArcWithCenter: cA radius: cRadius startAngle:180 endAngle:90 clockwise: YES]; + [bp lineToPoint: d ]; + [bp appendBezierPathWithArcWithCenter: cB radius: cRadius startAngle:90 endAngle:0 clockwise: YES]; + [bp lineToPoint: f ]; + [bp appendBezierPathWithArcWithCenter: cC radius: cRadius startAngle:0 endAngle:270 clockwise: YES]; + [bp lineToPoint: h ]; + [bp appendBezierPathWithArcWithCenter: cD radius: cRadius startAngle:270 endAngle:180 clockwise: YES]; + [bp closePath]; + + //Transform path to rectangle's origin + NSAffineTransform *transform = [NSAffineTransform transform]; + [transform translateXBy: left yBy: bottom]; + [bp transformUsingAffineTransform: transform]; + + return bp; //it's already been autoreleased +} +@end + @implementation PBGitRevisionCell @synthesize cellInfo; @@ -88,13 +135,40 @@ - (void) drawRefsInRect: (NSRect*) rect { - int pathWidth = 40 * [cellInfo.refs count]; - NSRect ownRect; - NSDivideRect(*rect, &ownRect, rect, pathWidth, NSMinXEdge); - for (NSString* ref in cellInfo.refs) { + static const float ref_padding = 10.0f; + static const float ref_spacing = 2.0f; + + NSRect refRect = (NSRect){rect->origin, rect->size}; + + if([self isHighlighted]) + [[NSColor whiteColor] setStroke]; + else + [[NSColor blackColor] setStroke]; + + int index; + for (index = 0; index < [cellInfo.refs count]; ++index) { + NSString* ref = [cellInfo.refs objectAtIndex:index]; NSString* newRef = [[ref componentsSeparatedByString:@"/"] lastObject]; - [newRef drawInRect: ownRect withAttributes:nil]; + + NSSize refSize = [newRef sizeWithAttributes:nil]; + + refRect.size.width = refSize.width + ref_padding; + + NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease]; + NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + [style setAlignment:NSCenterTextAlignment]; + [attributes setObject:style forKey:NSParagraphStyleAttributeName]; + if([self isHighlighted]) + [attributes setObject:[NSColor alternateSelectedControlTextColor] forKey:NSForegroundColorAttributeName]; + [newRef drawInRect:refRect withAttributes:attributes]; + + [[NSBezierPath bezierPathWithRoundedRect:refRect cornerRadius:2.0f] stroke]; + + refRect.origin.x += refRect.size.width + ref_spacing; } + + rect->size.width -= refRect.origin.x - rect->origin.x; + rect->origin.x = refRect.origin.x; } - (void) drawWithFrame: (NSRect) rect inView:(NSView *)view From 8e949184bcd6cd9012c92ae152525993e88777bc Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 6 Sep 2008 22:28:44 +0200 Subject: [PATCH 5/7] Add a PBGitRef, a class to represent refs --- GitX.xcodeproj/project.pbxproj | 6 +++++ PBGitRef.h | 22 +++++++++++++++++ PBGitRef.m | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 PBGitRef.h create mode 100644 PBGitRef.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index a91ba82..c2bd34e 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ F58A8F280E043698007E3FC0 /* commits.css in Resources */ = {isa = PBXBuildFile; fileRef = F58A8F270E043698007E3FC0 /* commits.css */; }; F5945E170E02B0C200706420 /* PBGitRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = F5945E160E02B0C200706420 /* PBGitRepository.m */; }; F5B721C40E05CF7E00AF29DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5B721C20E05CF7E00AF29DC /* MainMenu.xib */; }; + F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C007740E731B48007B84B2 /* PBGitRef.m */; }; F5C6F68D0E65FF9300478D97 /* PBGitLane.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C6F68C0E65FF9300478D97 /* PBGitLane.m */; }; F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DFFA6B0E075D8800617813 /* PBEasyFS.m */; }; F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E170E0829C20006317A /* PBGitRevList.m */; }; @@ -107,6 +108,8 @@ F5945E150E02B0C200706420 /* PBGitRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRepository.h; sourceTree = ""; }; F5945E160E02B0C200706420 /* PBGitRepository.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRepository.m; sourceTree = ""; }; F5B721C30E05CF7E00AF29DC /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; + F5C007730E731B48007B84B2 /* PBGitRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRef.h; sourceTree = ""; }; + F5C007740E731B48007B84B2 /* PBGitRef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRef.m; sourceTree = ""; }; F5C6F68B0E65FF9300478D97 /* PBGitLane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitLane.h; sourceTree = ""; }; F5C6F68C0E65FF9300478D97 /* PBGitLane.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitLane.m; sourceTree = ""; }; F5DFFA6A0E075D8800617813 /* PBEasyFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyFS.h; sourceTree = ""; }; @@ -305,6 +308,8 @@ F5C6F6750E65FE2B00478D97 /* Graphing */ = { isa = PBXGroup; children = ( + F5C007730E731B48007B84B2 /* PBGitRef.h */, + F5C007740E731B48007B84B2 /* PBGitRef.m */, F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */, F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */, F56CC7270E65E0AD004307B4 /* PBGitGraphLine.h */, @@ -419,6 +424,7 @@ F56CC7290E65E0AD004307B4 /* PBGitGraphLine.m in Sources */, F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */, F5C6F68D0E65FF9300478D97 /* PBGitLane.m in Sources */, + F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitRef.h b/PBGitRef.h new file mode 100644 index 0000000..578b56e --- /dev/null +++ b/PBGitRef.h @@ -0,0 +1,22 @@ +// +// PBGitRef.h +// GitX +// +// Created by Pieter de Bie on 06-09-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PBGitRef : NSObject { + NSString* ref; +} + +- (NSString*) shortName; +- (NSString*) type; ++ (PBGitRef*) refFromString: (NSString*) s; +- (PBGitRef*) initWithString: (NSString*) s; +@property(readonly) NSString* ref; + +@end diff --git a/PBGitRef.m b/PBGitRef.m new file mode 100644 index 0000000..3dadf59 --- /dev/null +++ b/PBGitRef.m @@ -0,0 +1,44 @@ +// +// PBGitRef.m +// GitX +// +// Created by Pieter de Bie on 06-09-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "PBGitRef.h" + + +@implementation PBGitRef + +@synthesize ref; +- (NSString*) shortName +{ + if ([self type]) + return [ref substringFromIndex:[[self type] length] + 7]; + return ref; +} + +- (NSString*) type +{ + if ([ref hasPrefix:@"refs/heads"]) + return @"head"; + if ([ref hasPrefix:@"refs/tags"]) + return @"tag"; + if ([ref hasPrefix:@"refs/remotes"]) + return @"remote"; + return nil; +} + ++ (PBGitRef*) refFromString: (NSString*) s +{ + return [[PBGitRef alloc] initWithString:s]; +} + +- (PBGitRef*) initWithString: (NSString*) s +{ + ref = s; + return self; +} + +@end From 96917943b6bc54c778cbc072578f143b6c2c8b99 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 6 Sep 2008 22:29:18 +0200 Subject: [PATCH 6/7] Fix a crashing bug in PBGitRepository A ref might be less than 11 characters. In those cases, the substringToIndex would produce a fatal out-of-bounds. --- PBGitRepository.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PBGitRepository.m b/PBGitRepository.m index 458fb39..584a115 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -155,7 +155,7 @@ static NSString* gitPath; else sha = [components objectAtIndex:2]; - if ([[ref substringToIndex:11] isEqualToString:@"refs/heads/"]) { + if ([ref length] > 11 && [[ref substringToIndex:11] isEqualToString:@"refs/heads/"]) { NSString* branch = [ref substringFromIndex:11]; [newBranches addObject: branch]; } From 939a1079f98104dd1a946eb1529c43cddbca69d2 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 6 Sep 2008 22:31:10 +0200 Subject: [PATCH 7/7] Grapher: add coloring to ref labels --- PBGitRevisionCell.m | 59 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index 2f3f23b..2e65800 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -7,7 +7,7 @@ // #import "PBGitRevisionCell.h" - +#import "PBGitRef.h" @implementation NSBezierPath (RoundedRectangle) + (NSBezierPath *)bezierPathWithRoundedRect: (NSRect) aRect cornerRadius: (double) cRadius @@ -133,6 +133,34 @@ [path fill]; } +- (NSMutableDictionary*) attributesForRefLabelSelected: (BOOL) selected +{ + NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease]; + NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + + [style setAlignment:NSCenterTextAlignment]; + [attributes setObject:style forKey:NSParagraphStyleAttributeName]; + [attributes setObject:[NSFont fontWithName:@"Helvetica" size:9] forKey:NSFontAttributeName]; + + //if (selected) + // [attributes setObject:[NSColor alternateSelectedControlTextColor] forKey:NSForegroundColorAttributeName]; + + return attributes; +} + +- (NSColor*) colorForRef: (PBGitRef*) ref +{ + NSString* type = [ref type]; + if ([type isEqualToString:@"head"]) + return [NSColor yellowColor]; + else if ([type isEqualToString:@"remote"]) + return [NSColor greenColor]; + else if ([type isEqualToString:@"tag"]) + return [NSColor cyanColor]; + + return [NSColor yellowColor]; +} + - (void) drawRefsInRect: (NSRect*) rect { static const float ref_padding = 10.0f; @@ -147,24 +175,27 @@ int index; for (index = 0; index < [cellInfo.refs count]; ++index) { - NSString* ref = [cellInfo.refs objectAtIndex:index]; - NSString* newRef = [[ref componentsSeparatedByString:@"/"] lastObject]; - - NSSize refSize = [newRef sizeWithAttributes:nil]; + PBGitRef* ref = [PBGitRef refFromString:[cellInfo.refs objectAtIndex:index]]; + NSMutableDictionary* attributes = [self attributesForRefLabelSelected:[self isHighlighted]]; + NSSize refSize = [[ref shortName] sizeWithAttributes:attributes]; + refRect.size.width = refSize.width + ref_padding; + refRect.size.height = refSize.height; + refRect.origin.y += (rect->size.height - refRect.size.height) / 2; + + // Round rects to 0.5 pixels in order to draw only a single pixel + refRect.origin.x = round(refRect.origin.x) - 0.5; + refRect.origin.y = round(refRect.origin.y) - 0.5; - NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease]; - NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; - [style setAlignment:NSCenterTextAlignment]; - [attributes setObject:style forKey:NSParagraphStyleAttributeName]; - if([self isHighlighted]) - [attributes setObject:[NSColor alternateSelectedControlTextColor] forKey:NSForegroundColorAttributeName]; - [newRef drawInRect:refRect withAttributes:attributes]; + NSBezierPath *border = [NSBezierPath bezierPathWithRoundedRect:refRect cornerRadius: 2.0]; + [[self colorForRef: ref] set]; + [border fill]; - [[NSBezierPath bezierPathWithRoundedRect:refRect cornerRadius:2.0f] stroke]; + [[ref shortName] drawInRect:refRect withAttributes:attributes]; + [border stroke]; - refRect.origin.x += refRect.size.width + ref_spacing; + refRect.origin.x += (int)refRect.size.width + ref_spacing; } rect->size.width -= refRect.origin.x - rect->origin.x;