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];
Цель групп отмены - именно то, чего вы пытаетесь достичь - превратить все изменения в одну отмену.