• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Cocoa Custom NSCell Binding Issue
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Cocoa Custom NSCell Binding Issue


  • Subject: Re: Cocoa Custom NSCell Binding Issue
  • From: mmalcolm crawford <email@hidden>
  • Date: Tue, 17 Jan 2006 04:50:37 -0800


*As far as I can tell* (I need to clarify this with engineering to find out how accurate this is, but perhaps others may be able to make progress given the example), the main issue is:



You must not override

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag

unless you call super. If you rely on overriding this method, then you may have to modify your code somewhat...





As an example, take the ClockControl project from <file:///Developer/ Examples/AppKit/ClockControl/>, and modify the ClockCell class (defined in ClockControl.{h,m}) as follows:



In ClockControl.h

@interface ClockCell : NSActionCell {
    NSCalendarDate *time;
    NSRect trackingFrame; // add instance variable
}

// add this declaration
-(void)updateForMouseAtPoint:(NSPoint)point inView:(NSView *) controlView;





In ClockControl.m

replace the methods
- (BOOL)trackMouseForTimeChangeEvent:(NSEvent *)theEvent inRect: (NSRect)cellFrame ofView:(NSView *)controlView
and
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag


with

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag {

NSPoint locationInCellFrame = [controlView convertPoint: [theEvent locationInWindow] fromView:nil];

    if ( PointIsInClockFace(locationInCellFrame, cellFrame) ) {

trackingFrame = [controlView convertRect: cellFrame fromView:nil];

// If the mouse click happened on the clock face, drag the hour hand around.
[super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:flag];
} else {
// ... otherwise, just toggle, the AM/PM indication.
[self toggleAmPm:nil];
}
return YES;
}



- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView { [self updateForMouseAtPoint:startPoint inView:controlView]; return YES; }

- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
{
[self updateForMouseAtPoint:currentPoint inView:controlView];
return YES;
}


- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView: (NSView *)controlView mouseIsUp:(BOOL)flag
{
if ([self isEnabled]) {
[self updateForMouseAtPoint:stopPoint inView:controlView];
if (flag && (![self isContinuous])) {
[[self target] performSelector:[self action]
withObject:self];
}
}
[super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];
}



-(void)updateForMouseAtPoint:(NSPoint)point inView:(NSView *)controlView
{
float radius = MIN(NSWidth(trackingFrame), NSHeight (trackingFrame))/2.0;
float centerX = floor(NSMinX(trackingFrame)+radius+.5);
float centerY = floor(NSMinY(trackingFrame)+radius+.5);


    NSPoint centerPoint = NSMakePoint(centerX, centerY);
    float angleFromNorth = 0.0;

NSPoint mousePoint = [controlView convertPoint: point fromView:nil];

// For each movement, update the position of the hour hand by adjusting our time.
angleFromNorth = AngleFromNorth(centerPoint, mousePoint, NO);
[self setHourHandByAngleFromNorth:angleFromNorth];
[(NSControl *)controlView updateCell: self];
}





This should give you a ClockCell class that you can use in a table view with bindings.



Caveat: This approach works (modulo a glitch shared by the original...) for this example, but as noted at the outset I haven't verified that this is strictly correct or guaranteed to work for other cells (although I have created from scratch a test cell class that follows the same pattern, and it also works). The example is given solely as a pointer towards a possible solution...


In particular, note that the way you establish the binding is also important. Bindings established in Interface Builder are unlikely to work. Instead you establish them programmatically:

MyCell *myCell = [[[MyCell alloc] initImageCell:nil] autorelease];
NSTableColumn *myCellColumn = [tableView tableColumnWithIdentifier:@"myCell"];
[myCellColumn setDataCell:myCell];
[myCellColumn bind:@"value" toObject:arrayController withKeyPath:@"arrangedObjects.key" options:nil];


It may be that you *must not* establish any bindings for the column in Interface Builder, otherwise an option may be set for the column that prevents it from working for the custom cell.


mmalc


_______________________________________________ Do not post admin requests to the list. They will be ignored. Cocoa-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
  • Follow-Ups:
    • Re: Cocoa Custom NSCell Binding Issue
      • From: Sean Willson <email@hidden>
References: 
 >Re: Cocoa Custom NSCell Binding Issue (From: Hamish Allan <email@hidden>)

  • Prev by Date: Re: Q: "Linking" to mail messages?
  • Next by Date: Flash security within WebView
  • Previous by thread: Re: Cocoa Custom NSCell Binding Issue
  • Next by thread: Re: Cocoa Custom NSCell Binding Issue
  • Index(es):
    • Date
    • Thread