NSButtonCell inside custom NSCell

转自:http://stackoverflow.com/questions/2280317/nsbuttoncell-inside-custom-nscell

The minimal requirements are:

  • After left mouse down on the button, it must appear pressed whenever the mouse is over it.
  • If the mouse then releases over the button, your cell must send the appropriate action message.

To make the button look pressed, you need to update the button cell's highlighted property as appropriate. Changing the state alone will not accomplish this, but what you want is for the button to be highlighted if, and only if, its states is NSOnState.

To send the action message, you need to be aware of when the mouse is released, and then use -[NSApplication sendAction:to:from:] to send the message.

In order to be in position to send these messages, you will need to hook into the event tracking methods provided by NSCell. Notice that all those tracking methods, except the final, -stopTracking:...method, return a Boolean to answer the question, "Do you want to keep receiving tracking messages?"

The final twist is that, in order to be sent any tracking messages at all, you need to implement -hitTestForEvent:inRect:ofView: and return an appropriate bitmask of NSCellHit... values. Specifically, if the value returned doesn't have the NSCellHitTrackableArea value in it, you won't get any tracking messages!

So, at a high level, your implementation will look something like:



- (NSUInteger)hitTestForEvent:(NSEvent *)event
                       inRect:(NSRect)cellFrame
                       ofView:(NSView *)controlView {
    NSUInteger hitType = [super hitTestForEvent:event inRect:cellFrame ofView:controlView];

    NSPoint location = [event locationInWindow];
    location = [controlView convertPointFromBase:location];
    // get the button cell's |buttonRect|, then
    if (NSMouseInRect(location, buttonRect, [controlView isFlipped])) {
        // We are only sent tracking messages for trackable areas.
        hitType |= NSCellHitTrackableArea;
    }
    return hitType;
}

+ (BOOL)prefersTrackingUntilMouseUp {
   // you want a single, long tracking "session" from mouse down till up
   return YES;
}

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView {
   // use NSMouseInRect and [controlView isFlipped] to test whether |startPoint| is on the button
   // if so, highlight the button
   return YES;  // keep tracking
}

- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView {
   // if |currentPoint| is in the button, highlight it
   // otherwise, unhighlight it
   return YES;  // keep on tracking
}

- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag {
   // if |flag| and mouse in button's rect, then
   [[NSApplication sharedApplication] sendAction:self.action to:self.target from:controlView];
   // and, finally,
   [buttonCell setHighlighted:NO];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值