What method should I call on my NSCell - objective-c

I am writing a custom NSControl with custom NSCells. It is a control, so it has to respond to the mouse. I created an NSTrackingArea over my control, implemented -mouseEntered:, -mouseExited: and -mouseMoved:. (And I will have to implement -mouseUp/Down:, but I have no idea what to do in there, so for now I haven't overridden those methods yet.) In these methods I successfully determine on which cell the mouse currently is. Now I have two questions:
Is this a good approach for tracking the mouse? If not, what should I do instead?
What method should I call on my NSCell on a mouse click, when the mouse enters the cell, when the mouse leaves the cell etc? Apple's docs are not very clear about this.
So, basically: When should I call what method on my NSCell to let it respond to mouse events?
EDIT:
Rereading the docs, I think I should call NSCell's -trackMouse:inRect:ofView:untilMouseUp: and override -startTrackingAt:inView:, -continueTracking:at:inView: and -stopTracking:at:inView:mouseIsUp:. Again two questions: 1) the docs give the impression these are only called when the mouse is down. Is that correct? Then what should I do instead? 2) Where/when should I call NSCell's -trackMouse:inRect:ofView:untilMouseUp:?

I ended up implementing my own mouse tracking mechanism:
// MyControl.m:
- (void)mouseDown:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
currentCell = cell;
[currentCell mouseDown:theEvent];
}
}
- (void)mouseUp:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
[cell mouseUp:theEvent];
}
}
- (void)mouseEntered:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
currentCell = cell;
[currentCell mouseEntered:theEvent];
}
}
- (void)mouseExited:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
if (currentCellIndex < [cells count]) {
MKListCell *cell = [cells objectAtIndex:currentCellIndex];
[cell mouseExited:theEvent];
currentCell = nil;
}
}
- (void)mouseMoved:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
MKListCell *cell;
if (currentCellIndex < [cells count]) {
cell = [cells objectAtIndex:currentCellIndex];
}
if (currentCell != cell) {
[currentCell mouseExited:theEvent];
[cell mouseEntered:theEvent];
currentCell = cell;
}
else {
[currentCell mouseMoved:theEvent];
}
}
- (void)mouseDragged:(NSEvent *)theEvent {
int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
MKListCell *cell = nil;
if (currentCellIndex < [cells count]) {
cell = [cells objectAtIndex:currentCellIndex];
}
if (currentCell != cell) {
[currentCell mouseExited:theEvent];
[cell mouseEntered:theEvent];
currentCell = cell;
}
else {
[currentCell mouseMoved:theEvent];
}
}
- (int)indexOfCellAtPoint:(NSPoint)p {
int cellIndex = (self.bounds.size.height - p.y) / cellHeight;
return cellIndex;
}
And of course, in MyCell.h:
- (void)mouseDown:(NSEvent *)event;
- (void)mouseUp:(NSEvent *)event;
- (void)mouseMoved:(NSEvent *)event;
- (void)mouseEntered:(NSEvent *)event;
- (void)mouseExited:(NSEvent *)event;
With an empty implementation for those methods (so the compiler doesn't complain and I can leave the implementation of the mouse handling methods to subclasses).

Related

How do I cancel touches after long press?

I'm got a tableview that displays custom view cells. In viewWillAppear i've setup a long press gesture recognizer that is on the UITableView. My long press is firing and displaying the info about the cell that has been long pressed upon. However when I let go of the press the didSelectRowAtIndexPath method is firing. Is there a way to cancel the touch after the long press fires, so that the select row doesn't get triggered?
I've seen didSelectRowAtIndexPath called after long press and that question does not seem to have an adequate answer as to how to fix the problem.
#implementation ViewController
UILongPressGestureRecognizer *lpgr;
.
.
.
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// setup long press
lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 0.5; //seconds
lpgr.delegate = self;
lpgr.cancelsTouchesInView = true;
[self.myTableview addGestureRecognizer:lpgr];
[self.myTableview.panGestureRecognizer requireGestureRecognizerToFail:lpgr]; ...
.
.
.
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gestureRecognizer locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(#"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.myTableview cellForRowAtIndexPath:indexPath];
CensusData *currentUser;
if(self.isFiltered){
currentUser = (CensusData*)[self.filteredTableData objectAtIndex:indexPath.row];
}else{
currentUser = (CensusData*)[self.dataArray objectAtIndex:indexPath.row];
}
NSLog(#"CURRENT ROW WITH LONG PRESS: %#", currentUser.friendlyName);
}
}
}
.
.
.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
While the gesture is active (begun but not ended) disable selection on the table view...
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.myTableview.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.myTableview.allowsSelection = YES;
}
}
No need to set the delegate, set cancelsTouches, or implement shouldRecognize... (unless you need these for something else).
EDIT This vc is a minimally complete test. It requires a storyboard with a table view wired to the outlet and the vc as the datasource and delegate...
#import "ViewController.h"
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property(weak,nonatomic) IBOutlet UITableView *tableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[self.tableView addGestureRecognizer:gr];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"Row %ld", indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"selected %#", indexPath);
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
NSLog(#"long press began");
self.tableView.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
NSLog(#"long press ended");
self.tableView.allowsSelection = YES;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You can disable tableview then only longGesture is working properly
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(onLongPress:)];
[self.myTableview addGestureRecognizer:longPressRecognizer];
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{
if (pGesture.state == UIGestureRecognizerStateRecognized)
{
//Do something to tell the user!
}
if (pGesture.state == UIGestureRecognizerStateEnded)
{
CGPoint p = [pGesture locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:self.myTableview]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}

Hide tableview sections on tap gesture of section header

I want to hide the NSArrays (menuItems, about, and charting) on the click for the specific section header for the tableview cell arrays. I got the section header to highlight and de-highlight depending on tap gesture recognizer count but I can not get the tableview cells to hide when that specific section header is clicked. Can someone please help? Thank you! Here is my .m code. My GCF float method is located at the bottom of the .m.
#interface SidebarTableViewController ()
#end
#implementation SidebarTableViewController {
NSArray *menuItems;
NSArray *about;
NSArray *charting;
}
- (void)viewDidLoad {
[super viewDidLoad];
menuItems = #[#"Home",#"Field Goal", #"Punt", #"Kick Off", #"Snapper", #"Punter"];
about = #[#"Home",#"About Us", #"Tutorial"];
charting = #[#"Home",#"Charting"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.section==0) {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
else if(indexPath.section==1) {
NSString *CellIdentifier2 = [charting objectAtIndex:indexPath.row];
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
return cell2;
}
else {
NSString *CellIdentifier1 = [about objectAtIndex:indexPath.row];
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
return cell1;
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section==0)
{
return [menuItems count];
}
else if(section==1)
{
return [charting count];
}
else{
return [about count];
}
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section
{
UILabel *headerLabel = [[UILabel alloc]init];
headerLabel.tag = section;
headerLabel.userInteractionEnabled = YES;
headerLabel.backgroundColor = [UIColor grayColor];
if(section == 0){
headerLabel.text = [NSString stringWithFormat:#"Timers Without Charting"];
}
else if(section==1)
{
headerLabel.text = [NSString stringWithFormat:#"Charting with Timers"];
}
else{
headerLabel.text = [NSString stringWithFormat:#"About Us/Tutorial"];
}
headerLabel.frame = CGRectMake(0, 0, tableView.tableHeaderView.frame.size.width, tableView.tableHeaderView.frame.size.height);
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(catchHeaderGesture:)];
tapGesture.cancelsTouchesInView = NO;
[headerLabel addGestureRecognizer:tapGesture];
return headerLabel;
//return nil;
}
-(void)catchHeaderGesture:(UIGestureRecognizer*)sender
{
border ++;
if (border == 1)
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor yellowColor].CGColor;
caughtLabel.layer.borderWidth = 2;
}
if (border == 2 )
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor clearColor].CGColor;
caughtLabel.layer.borderWidth = 2;
border = 0;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
border ++;
if (border == 1)
{
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
return 40.0;
}
if (border == 2 )
{ border = 0;
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
}
return 0;
}
#end
You need a few couple things to make this work.
section headers that respond to taps.
a method for expanding or collapsing a section.
some way to track which sections are collapsed.
The first is trivial. Return a UIView for the header, and attach a UITapGestureRecognizer to it. You'll need a method to figure out which section it is. You can use the tag property, or you can store the views in an NSMutableArray.
In tableView:numberOfRowsInSection: you return 0 if the section is collapsed, or the actual number, if not.
In the handler for the gesture recognizer, you toggle the collapsed/expanded state, and then you call `[self.tableView reloadSections:withRowAnimation:] to update the visuals.
(I do see in your posted code that you already handle part of this.)

UICollection View Deleting Section

I have searched a lot to find a solution to delete section's in a UICollectionView
but all the proposed solutions leading to a crash.
The code is I have used is:
[categoryCollection performBatchUpdates:^{
NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, keys.count-1)];
[categoryCollection deleteSections:indexSet];
} completion:nil];
Update:
#implementation BooksLayout
- (void)prepareLayout {
// Registers my decoration views.
[self registerClass:[ShelfView class] forDecorationViewOfKind:[ShelfView kind]];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath {
// Prepare some variables.
NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:indexPath.row+1 inSection:indexPath.section];
UICollectionViewLayoutAttributes *cellAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
UICollectionViewLayoutAttributes *nextCellAttributes = [self layoutAttributesForItemAtIndexPath:nextIndexPath];
UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];
CGRect baseFrame = cellAttributes.frame;
CGRect nextFrame = nextCellAttributes.frame;
CGFloat strokeWidth = 8;
CGFloat spaceToNextItem = 0;
if (nextFrame.origin.y == baseFrame.origin.y)
spaceToNextItem = (nextFrame.origin.x - baseFrame.origin.x - baseFrame.size.width);
// Positions the horizontal line for this item.
layoutAttributes.frame = CGRectMake(10,
baseFrame.origin.y + baseFrame.size.height,
300,
strokeWidth);
layoutAttributes.zIndex = 1;
return layoutAttributes;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *baseLayoutAttributes = [super layoutAttributesForElementsInRect:rect];
NSMutableArray * layoutAttributes = [baseLayoutAttributes mutableCopy];
for (UICollectionViewLayoutAttributes *thisLayoutItem in baseLayoutAttributes) {
if (thisLayoutItem.representedElementCategory == UICollectionElementCategoryCell) {
UICollectionViewLayoutAttributes *newHorizontalLayoutItem = [self layoutAttributesForDecorationViewOfKind:[ShelfView kind] atIndexPath:thisLayoutItem.indexPath];
[layoutAttributes addObject:newHorizontalLayoutItem];
}
}
return layoutAttributes;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
if([sortString isEqualToString:#"title"]){
NSArray *keys=[bookObj.orderedBooks allKeys];
keys = [keys sortedArrayUsingSelector:
#selector(localizedCaseInsensitiveCompare:)];
return [[bookObj.orderedBooks objectForKey:[keys objectAtIndex:section]] count];
}
else
return bookObj.booksArray.count;
}

Mouse tracking with modifier keys in table view cell

I have a NSTextFieldCell in a column of a cell-based NSTableView. This cell should handle clicks. This works fine when no modifier keys are pressed. If I hold the shift or command keys, the table view swallows the mouseDown event in an attempt to handle row selection.
Is there a way to completely disable row selection in NSTableView?
Is there a way to have NSTableView pass through all events?
My cell subclass is derived from the LinkTextFieldCell in the TableViewLinks sample code. It implements:
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag
Since I don't want row selection, my table view delegate implements:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex
{
return NO;
}
- (BOOL)tableView:(NSTableView *)tableView shouldTrackCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
return YES;
}
My delegate methods are called from -[NSTableView mouseDown:]. The mouse tracking code is called when no modifier keys are pressed.
Is there a better way to fix this than subclassing NSTableView to override -[NSTableView mouseDown:]?
I have implemented a solution where I override mouseDown:. I don't really like it. But it works. Still hoping for better ideas.
- (void)mouseDown:(NSEvent *)theEvent
{
if (! [self handleMouseDown:theEvent]) {
[super mouseDown:theEvent];
}
}
- (BOOL)handleMouseDown:(NSEvent *)theEvent
{
NSInteger clickCount = [theEvent clickCount];
if (clickCount != 1) {
return NO;
}
NSPoint locationInWindow = [theEvent locationInWindow];
NSPoint locationInView = [self convertPoint:locationInWindow fromView:nil];
NSInteger clickedRow = [self rowAtPoint:locationInView];
NSInteger clickedColumn = [self columnAtPoint:locationInView];
if ((clickedRow < 0) || (clickedColumn < 0)) {
return NO;
}
if ((clickedRow >= [self numberOfRows]) || (clickedColumn >= [self numberOfColumns])) {
return NO;
}
NSArray *tableColumns = [self tableColumns];
NSTableColumn *tableColumn = [tableColumns objectAtIndex:clickedColumn];
NSCell *cell = [tableColumn dataCellForRow:clickedRow];
id <NSTableViewDelegate> delegate = [self delegate];
BOOL shouldTrackCell = NO;
if ([delegate respondsToSelector:#selector(tableView:shouldTrackCell:forTableColumn:row:)]) {
shouldTrackCell = [delegate tableView:self shouldTrackCell:cell forTableColumn:tableColumn row:clickedRow];
}
if (! shouldTrackCell) {
return NO;
}
BOOL prefersTrackingUntilMouseUp = [[cell class] prefersTrackingUntilMouseUp];
NSRect cellFrame = [self frameOfCellAtColumn:clickedColumn row:clickedRow];
return [cell trackMouse:theEvent inRect:cellFrame ofView:self untilMouseUp:prefersTrackingUntilMouseUp];
}

NSPathControl with popups for each component of the path?

From Apple's sample code and reading the docs I can see no way configuring the NSPathControl to behave similarly to e.g. the 'jump bar' in the Xcode Editor window:
I.e. have it represent a path (or other kind of hierarchy) and make each component of the path a clickable popup to navigate the hierarchy..?
Anybody having luck faking such behaviour using a NSPathControlDelegate listening to clicks and showing a menu in a temporary window?
Seems like a common design where one would even expect some OSS implementation - but no such luck yet googling for it..
I made a subclass of NSPathControl so that I can use mouseDown: to popup the context menus of the component cells at the right position. I added also a delegate to the menu to create deeper menus on demand.
- (void)mouseDown:(NSEvent *)event {
NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
NSPathCell *cell = self.cell;
NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point
withFrame:self.bounds
inView:self];
NSRect componentRect = [cell rectOfPathComponentCell:componentCell
withFrame:self.bounds
inView:self];
NSMenu *menu = [componentCell menuForEvent:event
inRect:componentRect
ofView:self];
if (menu.numberOfItems > 0) {
NSUInteger selectedMenuItemIndex = 0;
for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) {
if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) {
selectedMenuItemIndex = menuItemIndex;
break;
}
}
NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex];
[menu popUpMenuPositioningItem:selectedMenuItem
atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2)
inView:self];
}
}
- (NSMenu *)menuForEvent:(NSEvent *)event {
if (event.type != NSLeftMouseDown) {
return nil;
}
return [super menuForEvent:event];
}
I extended Stephan's answer slightly to accommodate for lazily loading the menu items. I created a small protocol to call for the menu rather than having to build the menu's ahead of time for each cell:
NSPathControlExtended.h
#protocol NSPathControlExtendedDelegate <NSPathControlDelegate>
#required
- (NSMenu *)pathControl:(NSPathControl *)pathControl menuForCell:(NSPathComponentCell *)cell;
#end
#interface NSPathControlExtended : NSPathControl
#property (weak) id <NSPathControlExtendedDelegate> delegate;
#end
NSPathControlExtended.m
#import "NSPathControlExtended.h"
#implementation NSPathControlExtended
#synthesize delegate;
- (instancetype)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
}
- (void)mouseDown:(NSEvent *)event {
NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
NSPathCell *cell = self.cell;
NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point
withFrame:self.bounds
inView:self];
NSRect componentRect = [cell rectOfPathComponentCell:componentCell
withFrame:self.bounds
inView:self];
NSMenu *menu = [delegate pathControl:self menuForCell:componentCell];
if (menu.numberOfItems > 0) {
NSUInteger selectedMenuItemIndex = 0;
for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) {
if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) {
selectedMenuItemIndex = menuItemIndex;
break;
}
}
NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex];
[menu popUpMenuPositioningItem:selectedMenuItem
atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2)
inView:self];
}
}
- (NSMenu *)menuForEvent:(NSEvent *)event {
if (event.type != NSLeftMouseDown) {
return nil;
}
return [super menuForEvent:event];
}
#end