5 // Created by Pieter de Bie on 17-06-08.
6 // Copyright 2008 __MyCompanyName__. All rights reserved.
9 #import "PBGitRevisionCell.h"
11 #import "RoundedRectangle.h"
13 @implementation PBGitRevisionCell
16 - (id) initWithCoder: (id) coder
18 self = [super initWithCoder:coder];
19 textCell = [[NSTextFieldCell alloc] initWithCoder:coder];
25 return [NSArray arrayWithObjects:
26 [NSColor colorWithCalibratedRed: 0X4e/256.0 green:0X9A/256.0 blue: 0X06/256.0 alpha: 1.0],
27 [NSColor colorWithCalibratedRed: 0X20/256.0 green:0X4A/256.0 blue: 0X87/256.0 alpha: 1.0],
28 [NSColor colorWithCalibratedRed: 0XC4/256.0 green:0XA0/256.0 blue: 0 alpha: 1.0],
29 [NSColor colorWithCalibratedRed: 0X5C/256.0 green:0X35/256.0 blue: 0X66/256.0 alpha: 1.0],
30 [NSColor colorWithCalibratedRed: 0XA4/256.0 green:0X00/256.0 blue: 0X00/256.0 alpha: 1.0],
31 [NSColor colorWithCalibratedRed: 0XCE/256.0 green:0X5C/256.0 blue: 0 alpha: 1.0],
35 - (void) drawLineFromColumn: (int) from toColumn: (int) to inRect: (NSRect) r offset: (int) offset color: (int) c
39 NSPoint origin = r.origin;
41 NSPoint source = NSMakePoint(origin.x + columnWidth* from, origin.y + offset);
42 NSPoint center = NSMakePoint( origin.x + columnWidth * to, origin.y + r.size.height * 0.5 + 0.5);
44 // Just use red for now.
45 NSArray* colors = [self colors];
46 [[colors objectAtIndex: c % [colors count]] set];
48 NSBezierPath * path = [NSBezierPath bezierPath];
49 [path setLineWidth:2];
51 [path moveToPoint: source];
52 [path lineToPoint: center];
57 - (void) drawCircleInRect: (NSRect) r
60 int c = cellInfo.position;
62 NSPoint origin = r.origin;
63 NSPoint columnOrigin = { origin.x + columnWidth * c, origin.y};
65 NSRect oval = { columnOrigin.x - 5, columnOrigin.y + r.size.height * 0.5 - 5, 10, 10};
68 NSBezierPath * path = [NSBezierPath bezierPathWithOvalInRect:oval];
70 [[NSColor blackColor] set];
73 NSRect smallOval = { columnOrigin.x - 3, columnOrigin.y + r.size.height * 0.5 - 3, 6, 6};
74 [[NSColor whiteColor] set];
75 path = [NSBezierPath bezierPathWithOvalInRect:smallOval];
79 - (void) drawTriangleInRect: (NSRect) r sign: (char) sign
81 int c = cellInfo.position;
82 int columnHeight = 10;
87 top.x = round(r.origin.x) + 10 * c + 4;
89 top.x = round(r.origin.x) + 10 * c - 4;
92 top.y = r.origin.y + (r.size.height - columnHeight) / 2;
94 NSBezierPath * path = [NSBezierPath bezierPath];
96 [path moveToPoint: NSMakePoint(top.x, top.y)];
98 [path lineToPoint: NSMakePoint(top.x, top.y + columnHeight)];
100 [path lineToPoint: NSMakePoint(top.x - columnWidth, top.y + columnHeight / 2)];
104 [[NSColor whiteColor] set];
106 [[NSColor blackColor] set];
107 [path setLineWidth: 2];
111 - (NSMutableDictionary*) attributesForRefLabelSelected: (BOOL) selected
113 NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
114 NSMutableParagraphStyle* style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
116 [style setAlignment:NSCenterTextAlignment];
117 [attributes setObject:style forKey:NSParagraphStyleAttributeName];
118 [attributes setObject:[NSFont fontWithName:@"Helvetica" size:9] forKey:NSFontAttributeName];
121 // [attributes setObject:[NSColor alternateSelectedControlTextColor] forKey:NSForegroundColorAttributeName];
126 - (NSColor*) colorForRef: (PBGitRef*) ref
128 BOOL isHEAD = [ref.ref isEqualToString:[[[controller repository] headRef] simpleRef]];
131 return [NSColor colorWithCalibratedRed: 0Xfc/256.0 green:0Xa6/256.0 blue: 0X4f/256.0 alpha: 1.0];
133 NSString* type = [ref type];
134 if ([type isEqualToString:@"head"])
135 return [NSColor colorWithCalibratedRed: 0Xaa/256.0 green:0Xf2/256.0 blue: 0X54/256.0 alpha: 1.0];
136 else if ([type isEqualToString:@"remote"])
137 return [NSColor colorWithCalibratedRed: 0xb2/256.0 green:0Xdf/256.0 blue: 0Xff/256.0 alpha: 1.0];
138 else if ([type isEqualToString:@"tag"])
139 return [NSColor colorWithCalibratedRed: 0Xfc/256.0 green:0Xed/256.0 blue: 0X4f/256.0 alpha: 1.0];
141 return [NSColor yellowColor];
144 -(NSArray *)rectsForRefsinRect:(NSRect) rect;
146 NSMutableArray *array = [NSMutableArray array];
148 static const int ref_padding = 10;
149 static const int ref_spacing = 2;
151 NSRect lastRect = rect;
152 lastRect.origin.x = round(lastRect.origin.x) - 0.5;
153 lastRect.origin.y = round(lastRect.origin.y) - 0.5;
155 for (PBGitRef *ref in self.objectValue.refs) {
156 NSMutableDictionary* attributes = [self attributesForRefLabelSelected:NO];
157 NSSize textSize = [[ref shortName] sizeWithAttributes:attributes];
159 NSRect newRect = lastRect;
160 newRect.size.width = textSize.width + ref_padding;
161 newRect.size.height = textSize.height;
162 newRect.origin.y = rect.origin.y + (rect.size.height - newRect.size.height) / 2;
164 [array addObject:[NSValue valueWithRect:newRect]];
166 lastRect.origin.x += (int)lastRect.size.width + ref_spacing;
172 - (void) drawLabelAtIndex:(int)index inRect:(NSRect)rect
174 NSArray *refs = self.objectValue.refs;
175 PBGitRef *ref = [refs objectAtIndex:index];
177 NSMutableDictionary* attributes = [self attributesForRefLabelSelected:[self isHighlighted]];
178 NSBezierPath *border = [NSBezierPath bezierPathWithRoundedRect:rect cornerRadius: 2.0];
179 [[self colorForRef:ref] set];
182 [[ref shortName] drawInRect:rect withAttributes:attributes];
186 - (void) drawRefsInRect: (NSRect *)refRect
188 [[NSColor blackColor] setStroke];
192 for (NSValue *rectValue in [self rectsForRefsinRect:*refRect])
194 NSRect rect = [rectValue rectValue];
195 [self drawLabelAtIndex:index inRect:rect];
199 refRect->size.width -= lastRect.origin.x - refRect->origin.x + lastRect.size.width;
200 refRect->origin.x = lastRect.origin.x + lastRect.size.width;
203 - (void) drawWithFrame: (NSRect) rect inView:(NSView *)view
205 cellInfo = [self.objectValue lineInfo];
207 if (cellInfo && ![controller hasNonlinearPath]) {
208 float pathWidth = 10 + 10 * cellInfo.numColumns;
211 NSDivideRect(rect, &ownRect, &rect, pathWidth, NSMinXEdge);
214 struct PBGitGraphLine *lines = cellInfo.lines;
215 for (i = 0; i < cellInfo.nLines; i++) {
216 if (lines[i].upper == 0)
217 [self drawLineFromColumn: lines[i].from toColumn: lines[i].to inRect:ownRect offset: ownRect.size.height color: lines[i].colorIndex];
219 [self drawLineFromColumn: lines[i].from toColumn: lines[i].to inRect:ownRect offset: 0 color:lines[i].colorIndex];
222 if (cellInfo.sign == '<' || cellInfo.sign == '>')
223 [self drawTriangleInRect: ownRect sign: cellInfo.sign];
225 [self drawCircleInRect: ownRect];
229 if ([self.objectValue refs] && [[self.objectValue refs] count])
230 [self drawRefsInRect:&rect];
232 // Still use this superclass because of hilighting differences
233 //_contents = [self.objectValue subject];
234 //[super drawWithFrame:rect inView:view];
235 [textCell setObjectValue: [self.objectValue subject]];
236 [textCell setHighlighted: [self isHighlighted]];
237 [textCell drawWithFrame:rect inView: view];
240 - (void) setObjectValue: (PBGitCommit*)object {
241 [super setObjectValue:[NSValue valueWithNonretainedObject:object]];
244 - (PBGitCommit*) objectValue {
245 return [[super objectValue] nonretainedObjectValue];
248 - (int) indexAtX:(float)x
250 cellInfo = [self.objectValue lineInfo];
252 if (cellInfo && ![controller hasNonlinearPath])
253 pathWidth = 10 + 10 * cellInfo.numColumns;
256 NSRect refRect = NSMakeRect(pathWidth, 0, 1000, 10000);
257 for (NSValue *rectValue in [self rectsForRefsinRect:refRect])
259 NSRect rect = [rectValue rectValue];
260 if (x >= rect.origin.x && x <= (rect.origin.x + rect.size.width))
268 - (NSRect) rectAtIndex:(int)index
270 cellInfo = [self.objectValue lineInfo];
272 if (cellInfo && ![controller hasNonlinearPath])
273 pathWidth = 10 + 10 * cellInfo.numColumns;
274 NSRect refRect = NSMakeRect(pathWidth, 0, 1000, 10000);
276 return [[[self rectsForRefsinRect:refRect] objectAtIndex:index] rectValue];
279 # pragma mark context menu delegate methods
281 - (NSMenu *) menuForEvent:(NSEvent *)event inRect:(NSRect)rect ofView:(NSView *)view
283 if (!contextMenuDelegate)
286 int i = [self indexAtX:[view convertPointFromBase:[event locationInWindow]].x];
290 id ref = [[[self objectValue] refs] objectAtIndex:i];
294 NSArray *items = [contextMenuDelegate menuItemsForRef:ref commit:[self objectValue]];
295 NSMenu *menu = [[NSMenu alloc] init];
296 for (NSMenuItem *item in items)