NSColorPanel блокирует события мыши

Я использую NSColorWell, который настроен на постоянное обновление. Мне нужно знать, когда пользователь завершит редактирование элемента управления (мышь вверх) из палитры цветов на цветовой панели.

Я установил монитор событий и успешно получаю сообщения мыши и мыши, но NSColorPanel, кажется, блокирует мышь вверх.

Суть в том, что я хочу добавить последний выбранный цвет в мой стек отмены без всех промежуточных цветов, сгенерированных, пока пользователь выбирает их выбор.

Есть ли способ создания пользовательской панели NSColorPanel и замены совместно используемой панели с мыслью переопределить ее mouseUp и отправить сообщение?

В моем исследовании эта проблема обсуждалась несколько раз, однако я не прочитал успешное решение.

С уважением, - Джордж Лоуренс Сторм, Служба изобретений Keencoyote

3 ответа

Я обнаружил, что если мы наблюдаем 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

В Интерфейсном Разработчике выберите свой цвет хорошо, и затем снимите флажок Непрерывный в Инспекторе Атрибутов. Кроме того, добавьте следующую строку кода где-то уместно, как в applicationDidFinishLaunching: метод или awakeFromNib метод:

[[NSColorPanel sharedColorPanel] setContinuous:NO];

Другими словами, как для общей цветовой панели, так и для вашего цвета необходимо постоянно устанавливать значение NO для того, чтобы это работало правильно.

Правильный способ сделать то, что вы хотите, это использовать NSUndoManager "s -begin/endUndoGrouping, Так что вы бы сделали что-то вроде этого

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

Цель групп отмены - именно то, чего вы пытаетесь достичь - превратить все изменения в одну отмену.

Другие вопросы по тегам