Macos NSColorPanel阻止鼠标移动事件

Macos NSColorPanel阻止鼠标移动事件,macos,cocoa,nscolorpanel,Macos,Cocoa,Nscolorpanel,我正在使用一个设置为持续更新的NSColorWell。我需要知道用户何时完成从颜色面板中的颜色选择器编辑控件(鼠标向上) 我安装了一个事件监视器,并成功地接收到鼠标按下和鼠标移动的消息,但NSColorPanel似乎阻止了鼠标移动 底线是,我想将最终选定的颜色添加到撤消堆栈中,而不需要在用户选择其选择时生成所有中间颜色 有没有一种方法可以创建一个定制的NSColorPanel并替换共享面板,从而覆盖其鼠标并发送消息 在我的研究中,这个问题已经被提出过几次,但是我还没有读到一个成功的决议 问候,,

我正在使用一个设置为持续更新的NSColorWell。我需要知道用户何时完成从颜色面板中的颜色选择器编辑控件(鼠标向上)

我安装了一个事件监视器,并成功地接收到鼠标按下和鼠标移动的消息,但NSColorPanel似乎阻止了鼠标移动

底线是,我想将最终选定的颜色添加到撤消堆栈中,而不需要在用户选择其选择时生成所有中间颜色

有没有一种方法可以创建一个定制的NSColorPanel并替换共享面板,从而覆盖其鼠标并发送消息

在我的研究中,这个问题已经被提出过几次,但是我还没有读到一个成功的决议

问候,,
-George Lawrence Storm,Keencoyote发明服务公司

做你想做的事的正确方法是使用
NSUndoManager。所以你会这样做

[undoManager beginUndoGrouping];
// ... whatever code you need to show the color picker
// ...then when the color has been chosen
[undoManager endUndoGrouping];

撤销组的目的正是您试图实现的——将所有更改都变成一个撤销

我发现,如果我们观察
NSColorPanel
color
键路径,我们会在鼠标移动事件中被额外调用一次。这允许我们在鼠标左键按下时忽略来自
NSColorWell
的操作消息,并从keypath observer获取最终颜色

在此应用程序中,委托示例代码
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

在界面生成器中,选择颜色井,然后取消选中属性检查器中的“连续”复选框。此外,在适当的位置添加以下代码行,如
ApplicationIDFinishLaunching:
方法或
awakeFromNib
方法:

[[NSColorPanel sharedColorPanel] setContinuous:NO];

换句话说,共享颜色面板和您的颜色井都需要连续设置为
NO
,才能正常工作。

我的问题显然不清楚。问题是,我从未收到一个事件表明我已经完成了对颜色的编辑,因此我无法知道何时结束撤消。目前,我已经将NSColorWell细分为子类,并在它退出响应程序时结束撤销分组。这允许撤消,但与其他图形行为不一致。通常,当使用鼠标绘制图形元素时,撤消是在鼠标向上时提交的。我希望颜色井具有类似的行为,以便在不离开颜色井的情况下记录多个“鼠标向上”提交。您也可以简单地将NSColorPanel的
continuous
属性更改为
NO
。然后,
setAction:
消息仅在鼠标向上时触发。