Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 124 lines (103 sloc) 4.383 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
//
// PBIconAndTextCell.m
// GitX
//
// Created by Ciarán Walsh on 23/09/2008.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// Adopted from http://www.cocoadev.com/index.pl?NSTableViewImagesAndText

#import "PBIconAndTextCell.h"


@implementation PBIconAndTextCell
@synthesize image;

- (void)dealloc
{
self.image = nil;
[super dealloc];
}

- (id)copyWithZone:(NSZone *)zone
{
PBIconAndTextCell *cell = [super copyWithZone:zone];
cell.image = image;
return cell;
}

- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength
{
NSRect textFrame, imageFrame;
NSDivideRect (aRect, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEdge);
[super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength];
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
if (image) {
NSSize imageSize;
NSRect imageFrame;

imageSize = [image size];
NSDivideRect(cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMinXEdge);
if ([self drawsBackground]) {
[[self backgroundColor] set];
NSRectFill(imageFrame);
}
imageFrame.origin.x += 3;
imageFrame.size = imageSize;

if ([controlView isFlipped])
imageFrame.origin.y += floor((cellFrame.size.height + imageFrame.size.height) / 2);
else
imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);

[image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
}
[super drawWithFrame:cellFrame inView:controlView];
}

- (NSSize)cellSize
{
NSSize cellSize = [super cellSize];
cellSize.width += (image ? [image size].width : 0) + 3;
return cellSize;
}

// ===============
// = Hit testing =
// ===============
// Adopted from PhotoSearch Apple sample code

- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
{
NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];

NSRect textFrame, imageFrame;
NSDivideRect (cellFrame, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEdge);
if (NSMouseInRect(point, imageFrame, [controlView isFlipped]))
return NSCellHitContentArea | NSCellHitTrackableArea;

return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];
}

+ (BOOL)prefersTrackingUntilMouseUp
{
// NSCell returns NO for this by default. If you want to have trackMouse:inRect:ofView:untilMouseUp: always track until the mouse is up, then you MUST return YES. Otherwise, strange things will happen.
return YES;
}

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag
{
[self setControlView:controlView];

NSRect textFrame, imageFrame;
NSDivideRect (cellFrame, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEdge);
while ([theEvent type] != NSLeftMouseUp) {
// This is VERY simple event tracking. We simply check to see if the mouse is in the "i" button or not and dispatch entered/exited mouse events
NSPoint point = [controlView convertPoint:[theEvent locationInWindow] fromView:nil];
BOOL mouseInButton = NSMouseInRect(point, imageFrame, [controlView isFlipped]);
if (mouseDownInButton != mouseInButton) {
mouseDownInButton = mouseInButton;
[controlView setNeedsDisplayInRect:cellFrame];
}
if ([theEvent type] == NSMouseEntered || [theEvent type] == NSMouseExited)
[NSApp sendEvent:theEvent];
// Note that we process mouse entered and exited events and dispatch them to properly handle updates
theEvent = [[controlView window] nextEventMatchingMask:(NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask)];
}

// Another way of implementing the above code would be to keep an NSButtonCell as an ivar, and simply call trackMouse:inRect:ofView:untilMouseUp: on it, if the tracking area was inside of it.
if (mouseDownInButton) {
// Send the action, and redisplay
mouseDownInButton = NO;
[controlView setNeedsDisplayInRect:cellFrame];
if (self.action)
[NSApp sendAction:self.action to:self.target from:self];
}

// We return YES since the mouse was released while we were tracking. Not returning YES when you processed the mouse up is an easy way to introduce bugs!
return YES;
}

@end
Something went wrong with that request. Please try again.