Detect calling plugin via shortcut or menu

On 25/06/2018 at 22:48, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R19 
Platform:   Windows  ;   
Language(s) :     C++  ;

Hi again,

I have this silly question, which I probably already know the answer to, but I ask it anyway hoping it might provide some unexpected answers I didn't yet consider ...

Is there a way for a plugin (let's say a CommandData) to know if it was called from user action selecting from the plugin menu, or when user pressed the shortcut key assigned to the plugin.
The reason for this is that I want to display a widget in the viewport as a result of calling the plugin, and that the position of this widget would be taken from the current cursor position in the viewport (when activated from shortcut) or the center of the viewport (when selected from plugin menu).

As a result of the default location of the plugin menu and the viewport(s), when user selects a plugin from the menu the cursor usually ends up somewhere at the top right of a viewport, close to the top edge. Not really a good place for the widget to be positioned.
But since the cursor is detected having a valid viewport coordinate (i.e not being "outside") the widget would be displayed at that position ... while in this case it would be better of displaying it at the center of the viewport.

Edit: link added for informational completeness:

On 26/06/2018 at 07:57, xxxxxxxx wrote:


actually it sounds a bit like you are trying to imitate a ToolData workflow with a CommandData plugin.
Anyway, you can use GetInputState() inside of Execute() to check if a certain key or a combination of keys is pressed.

On 26/06/2018 at 10:11, xxxxxxxx wrote:

Hello Andreas,
Not really a ToolData workflow I had in mind.

Actually, the last thing I want to do, is make this plugin a tool.

While I understand you might consider this a tool, it really isn't ... or maybe you're right. It looks, feels and smells like a tool. But I really don't want to make it behave as a tool.

The fact a CommandData is used is only for the benefit of having a short-cut triggering the plugin.

Now that you bring up the GetInputState(), I recall the same answer from you on a question I had a few months ago. Some kind of deja vu feeling pops up. GetInputState() to the rescue, once again.


Edit: well, memory leaves to be desired ... it was actually Maxime who presented the GetInputState() response, and that was April 2018.

On 26/06/2018 at 12:37, xxxxxxxx wrote:

Well, I thought it was obvious but I cannot seem to get it working.

I put the following into the Execute of the CommandData, and while I can read out the qualifier key, I don't seem to be able to detect the actual key being pressed.

    BaseContainer keyChannels;  
  if (GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, keyChannels))  
      Int32 qualifier = keyChannels.GetInt32(BFM_INPUT_QUALIFIER);  
      //Bool shiftModifier = qualifier & QSHIFT;  
      //Bool ctrlModifier = qualifier & QCTRL;  
      //Bool altModifier = qualifier & QALT;  
      String str = keyChannels.GetString(BFM_INPUT_ASC);  
      Int32 val = keyChannels.GetInt32(BFM_INPUT_VALUE);  

GetString(BFM_INPUT_ASC) returns a nullptr, while GetInt32(BFM_INPUT_VALUE) returns 0

On 27/06/2018 at 08:02, xxxxxxxx wrote:

You need to check for the actual key.
Like so:

GetInputState(BFM_INPUT_KEYBOARD, 'x', keyChannels) // testing for x pressed

Then BFM_INPUT_VALUE will tell, if this key was pressed and BFM_INPUT_QUALIFIER delivers a qualifier pressed in parallel, if needed.

On 27/06/2018 at 12:13, xxxxxxxx wrote:

Oh, I actually first need to know which key I need to "listen" to in order to see if it is being pressed.
Mmmm, seems awkward.

Let's say I want to know if the shortcut key was pressed, I first need to find out what that shortcut key is, via FindShortcutsFromID(), then with that returned key (and qualifiers) I can perform a GetInputState()?

But a shortcut can consist of max 4 keys (+ qualifiers per key).
Since the CommandData::Execute is called by the shortcut, the current key the user would be holding down when the Execute is called is the last key of the shortcut, how to know the shortcut was pressed?

Since most single key shortcuts are already being taken up by native Cinema 4D tools,

assume a shortcut is assigned as CTRL+Q~SHIFT+A (two keys with qualifier).
The user presses CTRL+Q then presses SHIFT+A. This will call the CommandData::Execute.
Now, what will be the result of GetInputState in that Execute method? I would assume SHIFT+A, the current key combination being pressed.

Well, I just tested out the theory with the original (incorrect) code I posted above. It will print out "1" for qualifier, which means it did detect SHIFT ... no trace of the CTRL, however.
So, this means that only the last keystroke can be detected In Execute()

Or am I missing something? (except for the first keystroke ;)

On 29/06/2018 at 07:16, xxxxxxxx wrote:

No, I'm afraid you are not missing anything. To be honest I overlooked the possible complexity of our shortcuts and had thought this could be a solution for you problem.
The only other solution I have to offer is a bit more complex. Implement a SceneHook and use KeyboardInput() to catch all key presses...