Какао не захватит модификатор сдвига? - PullRequest
3 голосов
/ 01 января 2009

У меня есть приложение, в котором я пытаюсь захватить модификатор клавиши Shift для выполнения действия, однако, когда я запускаю программу и нажимаю и нормальную клавишу без модификатора клавиши Shift, я получаю звуковой сигнал, и модификатор и клавиша не отправлено на мое событие keyDown. Соответствующий код:

NSString* eventChars = [theEvent charactersIgnoringModifiers];

if ([eventChars isEqualTo:@"w"]) {
    newPlayerRow++;
    direction = eUp;
} else if ([eventChars isEqualTo:@"x"]) {
    newPlayerRow--;
    direction = eDown;
} else if ([eventChars isEqualTo:@"a"]) {
    newPlayerCol--;
    direction = eLeft;
} else if ([eventChars isEqualTo:@"d"]) {
    newPlayerCol++;
    direction = eRight;
} else {
    [super keyDown:theEvent];
    return;
}

// handle the player firing a bullet
if (([theEvent modifierFlags] & (NSShiftKeyMask | NSAlphaShiftKeyMask)) != 0) {
    NSLog(@"Shift key");
    [self fireBulletAtColumn:newPlayerCol row:newPlayerRow inDirection:direction];
    [self setNeedsDisplay:YES];
} else {
    ...
}

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

РЕДАКТИРОВАТЬ: Также я использую клавиатуру MacBook, если это имеет какое-либо значение.

РЕДАКТИРОВАТЬ: Это определенно проблема, ориентированная на смену, поскольку изменение (NSShiftKeyMask | NSAlphaShiftKeyMask) на NSControlKeyMask действительно дает желаемый эффект.

Ответы [ 5 ]

5 голосов
/ 02 января 2009

Во-первых, -charactersIgnoringModifiers не игнорирует клавишу Shift, поэтому вы все равно получите сдвинутые символы (т. Е. UPPERCASE и!% # $% ^ & *), Возвращенные из него. Вероятно, что происходит в вашей функции: вы нажимаете shift-w, ваш -isEqualTo: возвращает false, потому что вы сравниваете строчные буквы 'w' и прописные буквы 'W' и возвращаетесь, прежде чем перейти к коду обнаружения сдвига в дно. Самое простое решение - просто проверить оба.

Однако, если вы хотите, например, чтобы арабские клавишники могли легко использовать ваше приложение, вам не следует жестко кодировать символы, которые могут даже не отображаться на клавиатуре пользователя. Значение, возвращаемое параметром -keyCode, относится к положению клавиши на клавиатуре, а не к представленному символу. Для начала, константы, начинающиеся с 'kVK_ANSI_' и 'kVK_' в Events.h (вам может понадобиться ссылка на Carbon.framework и #include для использования этих констант) можно сравнить с тем, что -keyCode возвращается, и они ссылаются на ключевые позиции, которые ожидает использующий QWERTY американец. Таким образом, вы можете быть (довольно) уверены, что независимо от раскладки клавиатуры коды клавиш 'wasd' (kVK_ANSI_W, kVK_ANSI_A и т. Д.) Будут ссылаться на этот треугольник в верхнем левом углу клавиатуры вашего пользователя.

4 голосов
/ 07 января 2009

Если вы просто хотите получать уведомления о нажатиях клавиши-модификатора без символьной клавиши, вам следует переопределить метод flagsChanged NSResponder.

- (void)flagsChanged:(NSEvent *)theEvent

3 голосов
/ 02 января 2009

Вы пробовали записывать значения eventChars и modifierFlags, используя NSLog? Возможно, это нечто иное, чем вы ожидали. Если оператор log не отображается в ваших выходных данных, то этот код вообще не работает, и у вас есть проблема где-то еще.

NSLog(@"Chars: %@, modifier flags: 0x%x", eventChars, [theEvent modifierFlags]);

Некоторые другие вещи, которые стоит отметить:

  1. isEqualTo: - оператор равенства AppleScript. Это должно работать, но не так эффективно, потому что оно проходит через compare:. Подходящим методом является либо isEqualToString:, либо более общий isEqual:, любой из которых может выполнять прямое сравнение на равенство.
  2. Традиционный набор клавиш перемещения в области букв QWERTY - это wsad, а не wxad. Это использует перевернутую-T договоренность. Возможно, вы также захотите поддерживать клавиши со стрелками, поскольку у многих из нас есть клавиатуры со стрелками в перевернутой букве T.

    Кроме того, вы должны сделать их настраиваемыми пользователем, и вам следует отвечать на коды клавиш , а не на буквы, потому что разные макеты (французский, дворак и т. Д.) Будут генерировать разные буквы. У меня есть таблица кодов клавиш, адаптированная из Inside Macintosh , на моем веб-сайте. Используйте символы только для отображения.

  3. Разве это не должно быть «fireBulletFromColumn:row:inDirection:»? Я не знаю о вас, но говоря, что метод запускает пулю в , клетка говорит мне (и скажет вам, после того как вы не просматривали код в течение года), что она запускает пуля к этой клетке; замена «At» на «From» позволяет избежать этой путаницы.
1 голос
/ 01 января 2009

Из вашего кода похоже, что код, который проверяет модификатор, никогда не достигается. Все, что не является "w, x, a, d", отправляется суперклассу (см. Ветку else).

Вы, вероятно, хотите переместить "[super keyDown: theEvent]; return;" в конце вашего метода keyDown.

0 голосов
/ 03 января 2009

Решение неотложной проблемы:

  1. Исходя из сказанного Боазом, -charactersIgnoringModifiers не включает клавишу Shift (см. Документацию ), а вернет заглавные буквы, когда клавиша Shift не нажата. Вот почему клавиша Control работала, а клавиша Shift - нет. Переключите строку на в нижнем регистре перед ее проверкой:

    eventChars = [[theEvent charactersIgnoringModifiers] lowercaseString];
    
  2. После этого (как предположил Питер) измените все значения isEqualTo: * на 1018 * isEqualToString: (помимо правильности это также задокументировано как более быстрое).

Тем не менее:

Если вы планируете выпустить это приложение для других людей, вам действительно следует использовать коды клавиш (как предложили Питер и Вооз), чтобы оно работало на максимально возможном количестве различных клавиатур и настроек.

Создайте представление в ваших предпочтениях с вводом для каждой имеющейся у вас команды и запишите код клавиши для клавиши, которую нажимает пользователь. Сохраните их в своих NSUserDefaults и проверьте их вместо жестко закодированных строк. Вы можете создать набор по умолчанию для ваших текущих ключей "wasd".

См. Проекты, такие как Shortcut Recorder , чтобы найти примеры того, как это сделать (или найдите своего друга ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...