NSColorPanel阻止鼠标事件

时间:2013-01-03 12:20:35

标签: macos cocoa nscolorpanel

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

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

最重要的是,我想在我的撤销堆栈中添加最终选定的颜色,而不会在用户选择其选择时生成所有中间颜色。

是否有办法创建自定义NSColorPanel并更改共享面板,并考虑覆盖其mouseUp并发送消息?

在我的研究中,这个问题已经在一些场合得到了解释,但我还没有看到成功的解决方案。

此致 - 乔治劳伦斯风暴,Keencoyote发明服务

3 个答案:

答案 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];

撤消组的目的正是您要完成的目标 - 将所有更改转换为单个撤消。