我正在使用设置为不断更新的NSColorWell。我需要知道用户何时完成了从颜色面板中的颜色选择器编辑控件(鼠标向上)。
我安装了一个事件监视器,并成功接收了鼠标按下和鼠标移动的消息,但是NSColorPanel似乎阻止了鼠标移动。
最重要的是,我想在我的撤销堆栈中添加最终选定的颜色,而不会在用户选择其选择时生成所有中间颜色。
是否有办法创建自定义NSColorPanel并更改共享面板,并考虑覆盖其mouseUp并发送消息?
在我的研究中,这个问题已经在一些场合得到了解释,但我还没有看到成功的解决方案。
此致 - 乔治劳伦斯风暴,Keencoyote发明服务
答案 0 :(得分:4)
我发现,如果我们观察color
NSColorPanel
的{{1}}关键路径,我们就会在鼠标注册事件中再调用一次。这允许我们在鼠标左键按下时忽略来自NSColorWell
的动作消息,并从keypath观察者获取最终颜色。
在此应用程序中,委托示例代码colorChanged:
是NSColorWell
操作方法。
void* const ColorPanelColorContext = (void*)1001;
@interface AppDelegate()
@property (weak) NSColorWell *updatingColorWell;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
NSColorPanel *colorPanel = [NSColorPanel sharedColorPanel];
[colorPanel addObserver:self forKeyPath:@"color"
options:0 context:ColorPanelColorContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (context == ColorPanelColorContext) {
if (![self isLeftMouseButtonDown]) {
if (self.updatingColorWell) {
NSColorWell *colorWell = self.updatingColorWell;
[colorWell sendAction:[colorWell action] to:[colorWell target]];
}
self.updatingColorWell = nil;
}
}
}
- (IBAction)colorChanged:(id)sender {
if ([self isLeftMouseButtonDown]) {
self.updatingColorWell = sender;
} else {
NSColorWell *colorWell = sender;
[self updateFinalColor:[colorWell color]];
self.updatingColorWell = nil;
}
}
- (void)updateFinalColor:(NSColor*)color {
// Do something with the final color...
}
- (BOOL)isLeftMouseButtonDown {
return ([NSEvent pressedMouseButtons] & 1) == 1;
}
@end
答案 1 :(得分:2)
在Interface Builder中,选择您的颜色,然后取消选中Attributes Inspector中的Continuous复选框。另外,在applicationDidFinishLaunching:
方法或awakeFromNib
方法中添加以下适当的代码行:
[[NSColorPanel sharedColorPanel] setContinuous:NO];
换句话说,共享颜色面板和颜色井需要连续设置为NO
才能使其正常工作。
答案 2 :(得分:0)
执行所需操作的正确方法是使用NSUndoManager
的{{3}}。所以你会做这样的事情
[undoManager beginUndoGrouping];
// ... whatever code you need to show the color picker
// ...then when the color has been chosen
[undoManager endUndoGrouping];
撤消组的目的正是您要完成的目标 - 将所有更改转换为单个撤消。