diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index e85deac..d6cc851 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ F56526240E03D85900F03B52 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56526230E03D85900F03B52 /* WebKit.framework */; }; F565262B0E03D89B00F03B52 /* PBWebGitController.m in Sources */ = {isa = PBXBuildFile; fileRef = F565262A0E03D89B00F03B52 /* PBWebGitController.m */; }; F565265A0E03E71B00F03B52 /* commit.html in Resources */ = {isa = PBXBuildFile; fileRef = F56526590E03E71B00F03B52 /* commit.html */; }; + F56CC7290E65E0AD004307B4 /* PBLine.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7280E65E0AD004307B4 /* PBLine.m */; }; + F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */; }; F57ABE0B0E0442DD00A088B8 /* commit.js in Resources */ = {isa = PBXBuildFile; fileRef = F57ABDDE0E0441DE00A088B8 /* commit.js */; }; F57ABE2B0E04435100A088B8 /* prototype.js in Resources */ = {isa = PBXBuildFile; fileRef = F57ABE180E04431D00A088B8 /* prototype.js */; }; F57CC3910E05DDF2000472E2 /* PBEasyPipe.m in Sources */ = {isa = PBXBuildFile; fileRef = F57CC3900E05DDF2000472E2 /* PBEasyPipe.m */; }; @@ -90,6 +92,10 @@ F56526290E03D89B00F03B52 /* PBWebGitController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebGitController.h; sourceTree = ""; }; F565262A0E03D89B00F03B52 /* PBWebGitController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebGitController.m; sourceTree = ""; }; F56526590E03E71B00F03B52 /* commit.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = commit.html; path = html/commit.html; sourceTree = ""; }; + F56CC7270E65E0AD004307B4 /* PBLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBLine.h; sourceTree = ""; }; + F56CC7280E65E0AD004307B4 /* PBLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBLine.m; sourceTree = ""; }; + F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGraphCellInfo.h; sourceTree = ""; }; + F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGraphCellInfo.m; sourceTree = ""; }; F57ABDDE0E0441DE00A088B8 /* commit.js */ = {isa = PBXFileReference; explicitFileType = sourcecode.javascript; fileEncoding = 4; name = commit.js; path = html/commit.js; sourceTree = ""; }; F57ABE180E04431D00A088B8 /* prototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = prototype.js; path = html/prototype.js; sourceTree = ""; }; F57CC38F0E05DDF2000472E2 /* PBEasyPipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyPipe.h; sourceTree = ""; }; @@ -232,6 +238,8 @@ F56174540E05887E001DCD79 /* Git */ = { isa = PBXGroup; children = ( + F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */, + F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */, F5FF4E780E082E440006317A /* PBGitGrapher.h */, F5FF4E790E082E440006317A /* PBGitGrapher.m */, F5945E150E02B0C200706420 /* PBGitRepository.h */, @@ -277,6 +285,8 @@ F513085A0E0740F2000C8BCD /* PBQLOutlineView.m */, F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */, F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */, + F56CC7270E65E0AD004307B4 /* PBLine.h */, + F56CC7280E65E0AD004307B4 /* PBLine.m */, ); name = Aux; sourceTree = ""; @@ -393,6 +403,8 @@ F5FF4E7A0E082E440006317A /* PBGitGrapher.m in Sources */, 911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */, 913D5E5F0E556A9300CECEA2 /* PBCLIProxy.mm in Sources */, + F56CC7290E65E0AD004307B4 /* PBLine.m in Sources */, + F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitGrapher.h b/PBGitGrapher.h index 3a421f2..58311ad 100644 --- a/PBGitGrapher.h +++ b/PBGitGrapher.h @@ -8,7 +8,8 @@ #import #import "PBGitCommit.h" - +#import "PBLine.h" +#import "PBGraphCellInfo.h" struct PBGitGraphColumn { NSString* commit; // Commit that we're looking for @@ -18,25 +19,10 @@ struct PBGitGraphColumn { #define PBGitMaxColumns 100 -struct PBGitGraphCellInfo { - struct PBGitGraphColumn columns[PBGitMaxColumns]; - int upperMapping[PBGitMaxColumns]; //How are the offsets compared to previous cell? - int lowerMapping[PBGitMaxColumns]; //How are the offsets compared to this cell? - int position; - NSString* commit; // Commit in cell - int numColumns; - int numNewColumns; -}; - -void add_commit_to_graph(struct PBGitGraphCellInfo* info, NSString* parent, int* mapping_index); - -typedef struct PBGitGraphCellInfo PBGitCellInfo; - - @interface PBGitGrapher : NSObject { - PBGitCellInfo* cellsInfo; + NSMutableArray* cellsInfo; } - (void) parseCommits: (NSArray *) array; -- (struct PBGitGraphCellInfo) cellInfoForRow: (int) row; +- (PBGraphCellInfo*) cellInfoForRow: (int) row; @end diff --git a/PBGitGrapher.m b/PBGitGrapher.m index e643807..1beff13 100644 --- a/PBGitGrapher.m +++ b/PBGitGrapher.m @@ -14,73 +14,67 @@ - (void) parseCommits: (NSArray *) commits { - cellsInfo = malloc(sizeof(struct PBGitGraphCellInfo) * [commits count]); - memset(cellsInfo, 0, sizeof(struct PBGitGraphCellInfo) * [commits count]); - + cellsInfo = [NSMutableArray arrayWithCapacity: [commits count]]; int row = 0; - struct PBGitGraphCellInfo *previous = nil; - for (PBGitCommit* commit in commits) { - struct PBGitGraphCellInfo *info = &(cellsInfo[row]); - info->commit = commit.sha; - info->numColumns = 0; + PBGraphCellInfo* previous; + NSMutableArray* previousLanes = [NSMutableArray array]; + for (PBGitCommit* commit in commits) { int i = 0, newPos = -1; - for (i = 0; i < PBGitMaxColumns; i++) { - info->lowerMapping[i] = -1; - info->upperMapping[i] = -1; - } - + NSMutableArray* currentLanes = [NSMutableArray array]; + NSMutableArray* lines = [NSMutableArray array]; BOOL didFirst = NO; + // First, iterate over earlier columns and pass through any that don't want this commit if (previous != nil) { // We can't count until numColumns here, as it's only used for the width of the cell. - for (i = 0; i < PBGitMaxColumns; i++) { - if ((previous->columns[i].commit) == nil) - continue; - + for (NSString* lane in previousLanes) { + i++; // This is our commit! We should do a "merge": move the line from // our upperMapping to their lowerMapping - if ([previous->columns[i].commit isEqualToString:info->commit]) { + if ([lane isEqualToString:commit.sha]) { if (!didFirst) { didFirst = YES; - info->position = info->numColumns++; - info->columns[info->position].commit = [commit.parents objectAtIndex:0]; + [currentLanes addObject: [commit.parents objectAtIndex:0]]; + newPos = [currentLanes count]; } - newPos = info->position; - info->upperMapping[i] = newPos; + [lines addObject: [PBLine upperLineFrom: i to: newPos]]; } else { // We are not this commit. // Try to find an earlier column for this commit. - int j; + int j = 0; BOOL found = NO; - for (j = 0; j < info->numColumns; j++) { - if (j == info->position) + for (NSString* column in currentLanes) { + j++; + // ??? what is this? + if (j == newPos) continue; - if ([previous->columns[i].commit isEqualToString: info->columns[j].commit]) { + if ([column isEqualToString: lane]) { // We already have a column for this commit. use it instead - newPos = j; - info->upperMapping[previous->lowerMapping[i]] = newPos; + [lines addObject: [PBLine lowerLineFrom: i to: j]]; found = YES; break; } } + // We need a new column for this. if (!found) { - if (previous->columns[i].color == 10) - continue; + // This was used as a hack to stop large lanes from drawing + //if (previous->columns[i].color == 10) + // continue; - newPos = info->numColumns++; - info->columns[newPos] = previous->columns[i]; - info->columns[newPos].color++; - info->upperMapping[newPos] = newPos; + [currentLanes addObject: lane]; + [lines addObject: [PBLine upperLineFrom: [currentLanes count] to: [currentLanes count]]]; + [lines addObject: [PBLine lowerLineFrom: [currentLanes count] to: [currentLanes count]]]; } } // For existing columns, we always just continue straight down - info->lowerMapping[newPos] = newPos; + // ^^ I don't know what that means anymore :( + [lines addObject:[PBLine lowerLineFrom:newPos to:newPos]]; } } @@ -88,9 +82,9 @@ // If we already did the first parent, don't do so again if (!didFirst) { - info->position = info->numColumns++; - info->columns[info->position].commit = [commit.parents objectAtIndex:0]; - info->lowerMapping[info->position] = info->position; + [currentLanes addObject: [commit.parents objectAtIndex:0]]; + newPos = [currentLanes count]; + [lines addObject:[PBLine lowerLineFrom: newPos to: newPos]]; } // Add all other parents @@ -100,39 +94,41 @@ BOOL addedParent = NO; for (NSString* parent in [commit.parents subarrayWithRange:NSMakeRange(1, [commit.parents count] -1)]) { - int i; + int i = 0; BOOL was_displayed = NO; - for (i = 0; i < info->numColumns; i++) - if ([info->columns[i].commit isEqualToString: parent]) { - // TODO! - // !!! BUG - // This overwrites an existing mapping. - // We should instead have the possibility - // to add multiple lower mappings - // As we don't have that now, pieces of the graph are missing - info->lowerMapping[i] = info->position; + for (NSString* column in currentLanes) { + i++; + if ([column isEqualToString: parent]) { + [lines addObject:[PBLine lowerLineFrom: i to: newPos]]; was_displayed = YES; break; } + } if (was_displayed) continue; // Really add this parent addedParent = YES; - info->columns[info->numColumns++].commit = parent; - info->lowerMapping[info->numColumns -1] = info->position; + [currentLanes addObject:parent]; + [lines addObject:[PBLine lowerLineFrom: [currentLanes count] to: newPos]]; } - // A parent was added, so we have room to not indent. - if (addedParent) - info->numColumns--; - previous = info; ++row; + previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines]; + + // If a parent was added, we have room to not indent. + if (addedParent) + previous.numColumns = [currentLanes count] - 1; + else + previous.numColumns = [currentLanes count]; + previousLanes = currentLanes; + [cellsInfo addObject: previous]; } } -- (struct PBGitGraphCellInfo) cellInfoForRow: (int) row + +- (PBGraphCellInfo*) cellInfoForRow: (int) row { - return cellsInfo[row]; + return [cellsInfo objectAtIndex: row]; } - (void) finalize diff --git a/PBGitRevisionCell.h b/PBGitRevisionCell.h index 8523b9c..def74c8 100644 --- a/PBGitRevisionCell.h +++ b/PBGitRevisionCell.h @@ -10,9 +10,9 @@ #import "PBGitGrapher.h" @interface PBGitRevisionCell : NSTextFieldCell { - PBGitCellInfo cellInfo; + PBGraphCellInfo* cellInfo; BOOL isReady; } -@property(assign) PBGitCellInfo cellInfo; +@property(assign) PBGraphCellInfo* cellInfo; @end diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index 3d960e2..e17013a 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -12,7 +12,7 @@ @implementation PBGitRevisionCell @synthesize cellInfo; --(void) setCellInfo: (PBGitCellInfo) info +-(void) setCellInfo: (PBGraphCellInfo*) info { isReady = YES; cellInfo = info; @@ -68,7 +68,7 @@ NSBezierPath * path = [NSBezierPath bezierPath]; path = [NSBezierPath bezierPathWithOvalInRect:oval]; - [[col objectAtIndex:cellInfo.columns[c].color] set]; + //[[col objectAtIndex:cellInfo.columns[c].color] set]; [path fill]; NSRect smallOval = { columnOrigin.x - 3, columnOrigin.y + r.size.height * 0.5 - 3, 6, 6}; @@ -90,16 +90,13 @@ // Adjust by removing the border ownRect.size.height += 2; ownRect.origin.y -= 1; - ownRect.origin.x += 10; - - int column = 0; + ownRect.origin.x += 0; - // We can't iterate over numColumns here, as there may be connections to be drawn outside our columns. - for (column = 0; column < PBGitMaxColumns; column++) { - if (cellInfo.upperMapping[column] !=-1) - [self drawLineFromColumn:column toColumn: cellInfo.upperMapping[column] inRect:ownRect offset: 0]; - if (cellInfo.lowerMapping[column] !=-1) - [self drawLineFromColumn: column toColumn: cellInfo.lowerMapping[column] inRect:ownRect offset: ownRect.size.height]; + for (PBLine* line in cellInfo.lines) { + if (line.upper == 0) + [self drawLineFromColumn: line.from toColumn: line.to inRect:ownRect offset: ownRect.size.height]; + else + [self drawLineFromColumn:line.from toColumn: line.to inRect:ownRect offset: 0]; } [self drawCircleForColumn: cellInfo.position inRect: ownRect]; diff --git a/PBGraphCellInfo.h b/PBGraphCellInfo.h new file mode 100644 index 0000000..8f4b84b --- /dev/null +++ b/PBGraphCellInfo.h @@ -0,0 +1,23 @@ +// +// PBGraphCellInfo.h +// GitX +// +// Created by Pieter de Bie on 27-08-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PBGraphCellInfo : NSObject +{ + int position; + NSArray* lines; + int numColumns; +} +@property(readonly) NSArray* lines; +@property(assign) int position, numColumns; + +- (id)initWithPosition: (int) p andLines: (NSArray*) l; + +@end \ No newline at end of file diff --git a/PBGraphCellInfo.m b/PBGraphCellInfo.m new file mode 100644 index 0000000..f5e96b5 --- /dev/null +++ b/PBGraphCellInfo.m @@ -0,0 +1,21 @@ +// +// PBGraphCellInfo.m +// GitX +// +// Created by Pieter de Bie on 27-08-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "PBGraphCellInfo.h" + + +@implementation PBGraphCellInfo +@synthesize lines, position, numColumns; +- (id)initWithPosition: (int) p andLines: (NSArray*) l +{ + position = p; + lines = l; + + return self; +} +@end \ No newline at end of file diff --git a/PBLine.h b/PBLine.h new file mode 100644 index 0000000..63859e4 --- /dev/null +++ b/PBLine.h @@ -0,0 +1,23 @@ +// +// PBLine.h +// GitX +// +// Created by Pieter de Bie on 27-08-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PBLine : NSObject +{ + int upper; + int from; + int to; +} +@property(readonly) int upper, from, to; +- (id)initWithUpper: (int) u From: (int) f to: (int) t; ++ (PBLine*) lowerLineFrom:(int) f to: (int) t; ++ (PBLine*) upperLineFrom:(int) f to: (int) t; + +@end \ No newline at end of file diff --git a/PBLine.m b/PBLine.m new file mode 100644 index 0000000..a0c2880 --- /dev/null +++ b/PBLine.m @@ -0,0 +1,32 @@ +// +// PBLine.m +// GitX +// +// Created by Pieter de Bie on 27-08-08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "PBLine.h" + + +@implementation PBLine +@synthesize upper, from, to; +- (id)initWithUpper: (int) u From: (int) f to: (int) t; +{ + upper = u; + from = f; + to = t; + + return self; +} + ++ (PBLine*) lowerLineFrom:(int) f to: (int) t +{ + return [[PBLine alloc] initWithUpper:0 From:f to:t]; +} + ++ (PBLine*) upperLineFrom:(int) f to: (int) t +{ + return [[PBLine alloc] initWithUpper:1 From:f to:t]; +} +@end