Pergunta

When using NSEvent flagsChanged and ANDing the flags with various KeyMasks, how can you test themin an exclusive way? Currently, using a series of if else conditions whit the pattern:

if ((flags & someKeyMask) && (flags someOtherKeyMask))

This will match even if a third modifier key is down. Putting longer series of key masks earlier in the if else conditionals makes the behavior work as desired, but feels incomplete somehow. Is the a good way to say "only these modifier keys, not any others"?

Here is a more specific example where the first one matches before the others. I'm wondering if there is a way to add some logic to each one that says "only these modifier keys".

if ((flags & (NSCommandKeyMask|NSControlKeyMask))) {
                                               NSLog(@"one");
                                           }else if (((flags & NSCommandKeyMask) && (flags & NSAlternateKeyMask)) && (flags & NSControlKeyMask)) {
                                               NSLog(@"Command+Option+Control ");
                                           } else if ((flags & NSCommandKeyMask) && (flags & NSShiftKeyMask)) {
                                               NSLog(@"Command+Shift ");
                                           } else if ((flags & NSCommandKeyMask) && (flags & NSControlKeyMask)) {
                                               NSLog(@"Command+Control");
                                           } else if ((flags & NSCommandKeyMask) && (flags & NSAlternateKeyMask)) {
                                               NSLog(@"Command+Option ");
                                           } 

So the correct pattern I was looking for, as provided by Ken Thomases is: flags &= (<one or more masks bitwise OR'd together); if (flags == (<one or more masks bitwise OR'd together)) { // do something }

This gives exclusive matching.

Foi útil?

Solução

First, you need to be aware that the value returned from -modifierFlags includes some flags which do not exactly correspond to keys. You should construct a mask which includes all of the flags that you care about (whether you care that they are pressed or not pressed). Pass the flags value through that mask and then compare the result with exactly the combination you want.

For example, if you care about Command, Option, Shift, and Control, and you want to know if exactly Command and Shift are down but the others are not, you could use:

if ((flags & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) == (NSShiftKeyMask|NSCommandKeyMask))
    // do something

Update: Here's how to check a variety of combinations:

flags &= NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask;
if (flags == (NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask))
    NSLogs(@"Command+Option+Control");
else if (flags == (NSShiftKeyMask|NSCommandKeyMask))
    NSLog(@"Command+Shift ");
else if (flags == (NSControlKeyMask|NSCommandKeyMask))
    NSLog(@"Command+Control");
else if (flags == (NSAlternateKeyMask|NSCommandKeyMask))
   NSLog(@"Command+Option ");

Outras dicas

In order to catch just the combination pressed, you need to use the switch/break construction:

switch (flags) {
            case (NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask):
                [keystrokes appendString:@"cmd-alt-ctrl-"];
                break;
            case (NSShiftKeyMask|NSCommandKeyMask):
                [keystrokes appendString:@"cmd-shift-"];
                break;
            case (NSControlKeyMask|NSCommandKeyMask):
                [keystrokes appendString:@"cmd-ctrl-"];
                break;
            case (NSAlternateKeyMask|NSCommandKeyMask):
                [keystrokes appendString:@"cmd-alt-"];
                break;
            default:
                break;
        }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top