gpt4 book ai didi

cocoa - 自定义 NSCell 内的 NSButtonCell

转载 作者:行者123 更新时间:2023-12-03 16:05:14 24 4
gpt4 key购买 nike

在我的 cocoa 应用程序中,我需要一个用于 NSTableView 的自定义 NSCell。这个 NSCell 子类包含一个自定义 NSButtonCell 用于处理点击(以及两个或三个用于文本内容的 NSTextFieldCell)。您将在下面找到我的代码的简化示例。

@implementation TheCustomCell

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
// various NSTextFieldCells
NSTextFieldCell *titleCell = [[NSTextFieldCell alloc] init];
....
// my custom NSButtonCell
MyButtonCell *warningCell = [[MyButtonCell alloc] init];
[warningCell setTarget:self];
[warningCell setAction:@selector(testButton:)];
[warningCell drawWithFrame:buttonRect inView:controlView];
}

我遇到的问题是:让该 NSCell 内的按钮(更准确地说:NSButtonCell)正常工作的最佳/正确方法是什么?“工作”意味着:触发分配的操作消息并在单击时显示备用图像。开箱即用后,单击该按钮不会执行任何操作。

关于这个主题的信息/读物很难找到。我在网上找到的唯一帖子指出我要实现

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

这是正确的方法吗??? 在我包含的NSCell中实现trackMouse:?然后将事件转发到NSButtonCell?我本来希望 NSButtonCell 本身知道在被单击时要做什么(并且我看到了 trackMouse: 方法更多地与真正跟踪鼠标移动的结合 - 而不是作为“标准”单击行为的训练轮)。但当它包含在单元格本身中时,它似乎不会这样做......看来我还没有掌握自定义单元格的整体情况;-)

如果有人能够根据自己的经验回答这个问题(或向我指出一些教程等),并告诉我我是否走在正确的道路上,我会很高兴。

提前致谢,托比

最佳答案

最低要求是:

  • 在按钮上按下鼠标左键后,每当鼠标悬停在按钮上时,该按钮都必须显示为按下状态。
  • 如果鼠标在按钮上松开,您的单元格必须发送适当的操作消息。

要使按钮看起来被按下,您需要根据需要更新按钮单元格的 highlighted 属性。单独更改状态并不能实现此目的,但您想要的是当且仅当其状态为 NSOnState 时按钮才会突出显示。

要发送操作消息,您需要知道鼠标何时释放,然后使用 -[NSApplication sendAction:to:from:] 发送消息。

为了能够发送这些消息,您需要连接到 NSCell 提供的事件跟踪方法。请注意,除了最后一个 -stopTracking:... 方法之外,所有这些跟踪方法都会返回一个 bool 值来回答问题“您想继续接收跟踪消息吗?”

最后的转折点是,为了发送任何跟踪消息,您需要实现 -hitTestForEvent:inRect:ofView: 并返回 NSCellHit 的适当位掩码。 . 值。具体来说,如果返回的值中没有 NSCellHitTrackableArea 值,您将不会收到任何跟踪消息!

因此,从较高的层面来看,您的实现将类似于:

- (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];
}

关于cocoa - 自定义 NSCell 内的 NSButtonCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2280317/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com