Getting the State of Modifier Keys (ctrl/cmd, shift, alt)



  • This is a snippet I like to use for easily accessing the state of modifier keys when a user runs a script. I figured I would post it here as I couldn't easily track it down when I needed it today and thought it might be useful to other folks as well.

    def get_modifiers():
        """Returns state of modifier keys: ctrl, shift, alt
        
        Example Usage:
        ctrl, shift, alt = get_modifiers()
        """
    
        bc = c4d.BaseContainer()
        if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):
            ctrl = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL
            shift = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT
            alt = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QALT
            
        return ctrl, shift, alt
    


  • Not sure if I am right, but I think something changed in R20 (at least for C++).
    These are 2 code snippets of the same functionality in one of my plugins, which had to be changed in R20 to make it work as expected. Again ... not sure if this applies to Python.

    pre-R20

    	BaseContainer channels;
    	GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, channels);
    	Bool shiftModifier = channels.GetInt32(BFM_INPUT_QUALIFIER) & QSHIFT;
    	Bool ctrlModifier = channels.GetInt32(BFM_INPUT_QUALIFIER) & QCTRL;
    

    R20

    	BaseContainer channels;
    	GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, channels);
    	Bool shiftModifier = (channels.GetInt32(BFM_INPUT_QUALIFIER) & QSHIFT) != 0;
    	Bool ctrlModifier = (channels.GetInt32(BFM_INPUT_QUALIFIER) & QCTRL) != 0;
    


  • hello,

    I've moved this topic to this category.

    Thanks for sharing your snippet.

    I will probably go this way to have Boolean and not "value". Same in c++ check != 0 i will go with == QCTRL ans so on.

            ctrl = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL == c4d.QCTRL
            shift = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT == c4d.QSHIFT
            alt = bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QALT == c4d.QALT
    

    Regarding the pre-R20 and r20 code i don't have any idea instead that storing bool in a bool (0 or 1) make more sense.
    In your code pre-R20 you were sending value > 1 to a bool

    Cheers
    Manuel



  • @m_magalhaes said in Getting the State of Modifier Keys (ctrl/cmd, shift, alt):

    Regarding the pre-R20 and r20 code i don't have any idea instead that storing bool in a bool (0 or 1) make more sense.
    In your code pre-R20 you were sending value > 1 to a bool

    I see, I got it all wrong all those years.
    My implementation came from reading the examples users posted on the forum (now the legacy forum).
    Most uses of modifiers keys were checking inside an if-statement, as such I assumed I could move the checking outside of the if and assign it to a Bool instead, to then check on multiple locations in a function.

    Here's an example found in the legacy forum

    On 06/09/2005 at 12:55, xxxxxxxx wrote:
    
    Hi
    
    the qualifiers are combined bitwise. So you can check each one by
    
    if( key&QSHIFT; )
    {
    // shift down
    }
    if( key&CTRL; )
    {
    // ctrl down
    }
    ..
    

    Notice the original message is full of typos, but the idea is what it is. Similar solutions have been posted since, all with this same idea ... that's where I got the bad habit from.
    Thanks for clarifying the use. Will try to remember it for future plugins.



  • I'm not sure it's a bad habit or what's the difference. There's maybe type conversion, i don't know.

    Or maybe with the code optimization there's no difference at the end.

    I just wanted to add my 2 cents to have bool and not value xD

    Cheers
    Manuel


Log in to reply