3

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

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

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

有没有办法创建自定义 NSColorPanel 并用覆盖其 mouseUp 并发送消息的想法替换共享面板?

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

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

4

3 回答 3

4

我发现,如果我们观察colorkeypath ,NSColorPanel我们会在鼠标向上事件中被调用一次。这使我们可以忽略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
于 2013-08-27T12:28:49.357 回答
2

在 Interface Builder 中,选择你的颜色,然后取消选中 Attributes Inspector 中的 Continuous 复选框。applicationDidFinishLaunching:此外,在方法或方法中的适当位置添加以下代码行awakeFromNib

[[NSColorPanel sharedColorPanel] setContinuous:NO];

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

于 2014-03-28T04:27:59.550 回答
0

做你想做的事情的正确方法是使用NSUndoManager's -begin/endUndoGrouping。所以你会做这样的事情

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

撤消组的目的正是您想要完成的 - 将所有更改都放在一个撤消中。

于 2013-01-03T15:54:43.080 回答