NSColorPanel阻止鼠标事件

问题描述:

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

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

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

有没有办法创建一个自定义的NSColorPanel并替换共享面板的想法重写其mouseUp和发送消息?

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

问候, - 乔治·劳伦斯风暴,Keencoyote发明服务

正确的方法做你想做的就是用NSUndoManager-begin/endUndoGrouping。所以,你会做这样的事

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

撤消组的目的是你想要什么来完成 - 使所有更改成一个单一的撤消。

+0

我显然不清楚我的问题。问题是,我从来没有收到一个事件,表明我已经完成了编辑颜色,因此我无法知道何时结束撤消。目前我有NSColorWell子类,并结束撤消分组时响应者。这允许撤消,但与其他绘图行为不一致。通常,当使用鼠标绘制图形元素时,撤销在鼠标上被提交。我希望从颜色上有类似的行为,以便记录多次“鼠标向上”提交而不必离开井。 –

我发现如果我们观察color关键路径NSColorPanel,我们会在鼠标事件中调用一次额外的时间。这允许我们在鼠标左键关闭时忽略来自NSColorWell的操作消息并从关键路径观察者获得最终颜色。

在此应用程序代表示例代码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 
+0

您也简单地将NSColorPanel的“连续”属性更改为“否”。然后'setAction:'消息只在鼠标点亮时触发。 – zakdances

在Interface Builder中,选择您的颜色,然后取消选中属性检查器中的连续复选框。此外,添加的以下代码行适当地方,比如在applicationDidFinishLaunching:方法或awakeFromNib方法:

[[NSColorPanel sharedColorPanel] setContinuous:NO]; 

换言之,二者共享的彩色面板和您的颜色以及需要有连续的一组到NO为了使这种正常工作。