Я создаю приложение для фортепиано (для OSX), которое имеет экранную клавиатуру, отображающую, что пользователь играет на своей синтезаторной клавиатуре. Все связано с каркасом CoreMIDI. Я создал некоторые пользовательские кнопки, подклассифицируя NSButton в классе под названием PianoKey. Класс можно посмотреть ниже:Пользовательский NSButton не работает с функцией обратного вызова CoreMIDI
#import "PianoKey.h"
@implementation PianoKey
//updates the core animation layer whenever it needs to be changed
- (BOOL)wantsUpdateLayer {
return YES;
}
- (void)updateLayer {
//tells you whether or not the button is pressed
if ([self.cell isHighlighted]) {
NSLog(@"BUTTON PRESSED");
self.layer.contents = [NSImage imageNamed:@"buttonpressed.png"];
}
else {
NSLog(@"BUTTON NOT PRESSED");
self.layer.contents = [NSImage imageNamed:@"button.png"];
}
}
@end
«PianoKeys» создаются программно. Когда они не нажаты, клавиши пианино синие, и когда они нажимаются, они являются розовыми (только темповые цвета). Цветовой переключатель работает отлично, если я нажимаю кнопки на экране, но они не меняются, когда я пытаюсь воспроизвести свою MIDI-клавиатуру.
Некоторые примечания: 1) Работает MIDI-клавиатура 2) Я успешно получаю MIDI-данные с клавиатуры.
а) Этот MIDI-данные передаются в функцию обратного вызова называется midiInputCallback, как показано ниже: [из класса AppController.m]
void midiInputCallback(const MIDIPacketList *list, void *procRef, void *srcRef) {
PianoKey *button = (__bridge PianoKey*)procRef;
UInt16 nBytes;
const MIDIPacket *packet = &list->packet[0]; //gets first packet in list
for(unsigned int i = 0; i < list->numPackets; i++) {
nBytes = packet->length; //number of bytes in a packet
handleMIDIStatus(packet, button);
packet = MIDIPacketNext(packet);
}
}
Объектом Кнопки является ссылкой на кнопку, Я создал программно, как определено в AppController.h как:
@property PianoKey *button; //yes, this is synthesized in AppController.m
б) функция обратного вызова вызывает кучу функций, которые Handl e данные MIDI. Если записка была обнаружена в воспроизводимой, это где я устанавливаю мой заказ кнопка подсвечивается ... это можно увидеть в функции ниже:
void updateKeyboardButtonAfterKeyPressed(PianoKey *button, int key, bool keyOn) {
if(keyOn)
[button highlight:YES];
else
[button highlight:NO];
[button updateLayer];
}
[кнопка updateLayer] вызывает метод мой updateLayer() от PianoKey, но это не изменяет изображение. Есть что-то, что мне не хватает? Кажется, что просмотр или окно не обновляются, хотя моя кнопка говорит, что она «подсвечена». Пожалуйста помоги! Спасибо заранее
Я не совсем уверен ... Я не думаю, что это главная тема того, что я читал. Опять же, в CoreMIDI не так много информации, поэтому я не знаю, что взять иногда как правду:/ Что вы хотите, чтобы я попытался вызвать метод обратного вызова? – 02fentym
Я только использовал CoreMidi в iOS, но из того, что я прочитал, проблема потока для обновления графического интерфейса - это то же самое. Сначала просто поместите инструкцию NSLog (или эквивалент какао) в свой метод 'updateLayer', чтобы узнать, вызвана ли она. Если это так, это проблема с потоком. В этом случае вы хотите использовать 'performSelectorOnMainThread'.Одно предостережение: поскольку обновление клавиатуры может происходить быстрее, чем частота обновления, может быть бессмысленно называть обновление для каждого. В iOS есть метод, который можно вызвать перед каждым обновлением экрана. Не знаю в OSX. Может быть, попробуйте выполнить 'performSelectorOnMainThread' первое объявление, если это работает –
Хорошо, я знаю, о чем вы сейчас говорите. В настоящее время у меня есть указатель на экземпляр кнопки, так как я передал его в свою функцию обратного вызова. Если бы у меня не было этой ссылки, она ничего не узнает о моем объекте кнопки. Итак, вы правы, это проблема с потоком. Как вы используете 'performSelectorOnMainThread'? Я все равно, но я быстро научусь (думаю). Должен ли я опубликовать это как новый вопрос? Кстати, если у меня есть экземпляр моей кнопки, и я могу назвать 'updatelayer', как будет' performSelectorOnMainThread'? – 02fentym