【问题标题】:NSColorPanel blocking mouse up eventsNSColorPanel 阻止鼠标向上事件
【发布时间】:2012-12-17 19:29:13
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: macos cocoa nscolorpanel


    【解决方案1】:

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

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

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

    【讨论】:

    • 我的问题显然不清楚。问题是我从未收到表明我已完成颜色编辑的事件,因此我无法知道何时结束撤消。目前,我对 NSColorWell 进行了子分类,并在它退出响应者时结束撤消分组。这允许撤消,但它与其他绘图行为不一致。通常,当使用鼠标绘制图形元素时,撤消是在鼠标抬起时提交的。我想从颜色井中获得类似的行为,以便记录多个“鼠标向上”提交而不必离开井。
    【解决方案2】:

    我发现,如果我们观察到 NSColorPanelcolor 键路径,我们会在鼠标上移事件中额外调用一次。这允许我们在鼠标左键按下时忽略来自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
    

    【讨论】:

    • 您也只需将 NSColorPanel 的 continous 属性更改为 NO。然后setAction: 消息只会在鼠标抬起时触发。
    【解决方案3】:

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

    [[NSColorPanel sharedColorPanel] setContinuous:NO];
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多