Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Hit testing and action sending

  • Loading branch information...
commit 9893037d86ed82860480c48f6227d2af75a5b7e6 1 parent 3a8c0c8
@ciaran ciaran authored
View
6 PBGitCommitController.h
@@ -9,14 +9,16 @@
#import <Cocoa/Cocoa.h>
#import "PBViewController.h"
+@class PBIconAndTextCell;
+
@interface PBGitCommitController : PBViewController {
NSMutableArray *files;
IBOutlet NSArrayController *unstagedFilesController;
IBOutlet NSArrayController *cachedFilesController;
- IBOutlet NSButtonCell* unstagedButtonCell;
- IBOutlet NSButtonCell* cachedButtonCell;
+ IBOutlet PBIconAndTextCell* unstagedButtonCell;
+ IBOutlet PBIconAndTextCell* cachedButtonCell;
}
@property (retain) NSMutableArray *files;
View
10 PBGitCommitController.m
@@ -81,9 +81,15 @@ - (void) readCachedFiles
}
}
-- (void) cellClicked:(id) sender
+- (void) cellClicked:(NSCell*) sender
{
- NSLog(@"Cell clicked: %@", sender);
+ NSTableView* tableView = [sender controlView];
+ if([tableView numberOfSelectedRows] == 1)
+ {
+ NSUInteger selectionIndex = [[tableView selectedRowIndexes] firstIndex];
+ id selectedItem = [[(([tableView tag] == 0) ? unstagedFilesController : cachedFilesController) arrangedObjects] objectAtIndex:selectionIndex];
+ NSLog(@"%s selectedItem: %@", _cmd, [selectedItem valueForKey:@"path"]);
+ }
}
- (void)tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(int)rowIndex
View
28 PBGitCommitView.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="48"/>
+ <integer value="54"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1057,6 +1057,22 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<int key="connectionID">179</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">cachedButtonCell</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="39450212"/>
+ </object>
+ <int key="connectionID">210</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">unstagedButtonCell</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="45690317"/>
+ </object>
+ <int key="connectionID">211</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -1439,7 +1455,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">209</int>
+ <int key="maxID">211</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1462,9 +1478,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSButtonCell</string>
+ <string>PBIconAndTextCell</string>
<string>NSArrayController</string>
- <string>NSButtonCell</string>
+ <string>PBIconAndTextCell</string>
<string>NSArrayController</string>
</object>
</object>
@@ -1476,10 +1492,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="IBPartialClassDescription">
<string key="className">PBIconAndTextCell</string>
<string key="superclassName">NSTextFieldCell</string>
- <object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">realObjectValue</string>
- <string key="NS.object.0">id</string>
- </object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">PBIconAndTextCell.h</string>
View
2  PBIconAndTextCell.h
@@ -12,6 +12,8 @@
@interface PBIconAndTextCell : NSTextFieldCell
{
NSImage *image;
+ BOOL mouseDownInButton;
+ BOOL mouseHoveredInButton;
}
@property (retain) NSImage *image;
View
57 PBIconAndTextCell.mm
@@ -64,4 +64,61 @@ - (NSSize)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
Please sign in to comment.
Something went wrong with that request. Please try again.