KeyMapper: a key-binding module, with GUI [Major update 5/2019]

Minor update, 26th of January, 2022

  • A fix, I believe, to KeyMapper not correctly identifying “wheel” events as being related to a “mouse” device.

Update! 4th of March, 2021

  • KeyMapper should now support international keyboards!
    • There may still be bugs, so please do report them if you encounter any!
  • A few tweaks have been made to the example game such that it’s more compatible with baseline Panda.

MAJOR UPDATE! 9th of May 2019:

  • KeyMapper now supports Panda3D’s additional devices! (Gamepads, etc.)
  • KeyMapper no longer requires GameSaver.
    • Instead, it is expected that developers will provide their own file-handling, as they prefer. See the documentation for details.
  • Error-handling is now a little better (I feel), with an error-dialogue that’s shown when trouble is encountered while saving or loading

It’s also now on GitHub, and should be found here:

And finally, there’s a new example mini-game to go along with it–a sort of Lander-style gem-collecting game.


About KeyMapper:

KeyMapper is a module intended to provide a simple-to-use key-binding system and GUI, allowing users to re-bind the controls of an application.

Specifically, it offers:

  • Simple key-handling, including support for re-bindable “held” keys and key-events
  • Support for near-transparent handling of Panda3D’s additional devices, such as gamepads. (Including axial inputs, like thumbsticks.)
  • A GUI interface, constructed in such a way as to enable alteration and customisation of the interface via sub-classing; the default GUI uses DirectGUI.

Current issues:

  • With some devices attached, the first attempt to bind a key may automatically end up bound to the mouse-button. This seems to be an engine-level issue, and has been reported!

  • The default UI is only navigable by mouse; implementing navigation by other devices is left to the developer, should it be desired.

  • Due to Panda not producing key-release events for key-combinations (that is, keys in combination with modifiers; “alt-r”, for example), support for key-combinations is somewhat broken and restricted via a default parameter that prevents them from being bound.

  • Support for binding mouse-buttons should work properly, but does involve a slight hack behind the scenes; this is a result of an odd issue in which DirectDialogue prevents mouse-press events from being sent–but not mouse-release, key-press or key-release events. This thread was created for this issue.

1 Like

I’ve made a minor change to the example game included with KeyMapper, specifically the addition of an explicit “continue” button in the shop screen. (Continuing on from the shop previously involved an invisible button laid over a backdrop element, but this may have been a little too unobvious, and fell prey to a bug that caused the window-size to be smaller than intended, pushing the door image off-screen and leaving the button rather unintitive to find.

(There should be not changes to KeyMapper itself in this version, so the version number is unchanged.)

The new version should be available via the link in the first post.

MAJOR UPDATE! Check the first post for more, but KeyMapper now supports Panda3D’s additional devices (gamepad, etc.), is available on GitHub, and comes with a new example-game.

Minor update: I’ve added a script with dummy save- and load- callbacks, and updated the tester- and example-game- programs to use them. This should mean that those programs no longer show error dialogues every time that a key is bound, while still giving warning that saving and loading haven’t been implemented.

A moderate update, including some significant bug-fixes, I believe:

  • Optional key-group IDs, allowing for sets of keys that don’t conflict
    • Note that as the “group IDs” take the form of bitmasks, keys can belong to multiple groups
  • The addition of an optional callback that can be sent when a key or axis is detected to have been pressed/released
  • Previously, button-events could be left in effect when loading a key-mapping; this should, hopefully, be fixed.
  • The error dialogue should no longer show up if the reason for an IO error is simply that the binding-file to be loaded doesn’t exist
  • A handful of minor bug-fixes

As before, the new version should be available on GitHub, and accessible via the link in the first post!

1 Like

A minor update, including the following fixes and changes, I believe:

  • Improved (I hope!) handling of event-callbacks from axial inputs.
  • Improved handling of “None” axes; in short, KeyMapper now ignores them.
  • Replaced “DirectOptionMenuAware” with “DirectOptionMenu”
    • The former is one of my own classes, and was likely included here by mistake.

Minor update:

  • The “dummy” save-load class was importing GameSaver, which isn’t included with KeyMapper, and is unused by the code, as far as I see. I’ve thus removed that importation.

The files for the example are missing.

You’re quite right! It looks like I included the “working files” for them (i.e. the Blender model-files), but not the final assets. Sorry about that!

I’ve just uploaded the files, so you should find now them in the repository!

[edit] I’ve also updated the licensing information in the repository. Code and documentation is still under the MIT license, but the assets are now under a Creative Commons license.

Still isnt working but I managed to make it work.

I had to comment out these lines:

            # item_pad = (0.4, 0.2),
            # item_frameColor = (0.15, 0.42, 0.18, 1),
            # item_clickSound = base.btnClickSound,

and missing import

from DirectOptionMenuAware import DirectOptionMenuAware

Anyways, in the example modifier combinations dont work. And more importantly also it seems it doesnt work with keys that generate unicode characters? Like in my case: ě š č ř …

Could you show me the error(s) that you got with those lines in place, please? They should work, being, I think, standard DirectGUI keyword-parameters.

Also, what version of Panda are you using?

Ah, that’s odd–I thought that I’d removed that!

Aaah, I see–I removed the file from the repository, but didn’t update the example game.

Okay, I’ve updated the game in the repository to instead use the base Panda “DirectOptionMenu” class!

Correct, in general they don’t, I’m afraid. :/

I believe that a fuller description is given in the documentation, under “Known issues”, but it’s related to the way that Panda handles such combinations.

It’s possibly something that’s fixable, but as it deals with Panda’s handling of key-events and as I don’t generally find myself using modifiers with my controls, I haven’t really had much inclination to delve into the matter, I’m afraid.

Ah, that’s a problem! I’m afraid that I don’t have such keys on my keyboard, so I never tested for them…

Are these characters generated by a single key? That is, do you have an “ě” on your keyboard?

And do events using these keys work with standard Panda key-events, as registered via “accept”?

(And thank you for pointing out these issues, by the way! I appreciate it. ^_^)

Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
Traceback (most recent call last):
  File "c:/Users/01/Desktop/KeyMapper-master/KeyMapperExampleGame.py", line 875, in <module>
    game = KeyMapperTestGame()
  File "c:/Users/01/Desktop/KeyMapper-master/KeyMapperExampleGame.py", line 689, in __init__
    self.keyMapper.setup()
  File "c:/Users/01/Desktop/KeyMapper-master/KeyMapperExampleGame.py", line 111, in setup
    KeyMapper.setup(self)
  File "c:\Users\01\Desktop\KeyMapper-master\KeyMapper.py", line 416, in setup
    self.buildMainGUI()
  File "c:/Users/01/Desktop/KeyMapper-master/KeyMapperExampleGame.py", line 199, in buildMainGUI
    KeyMapper.buildMainGUI(self)
  File "c:\Users\01\Desktop\KeyMapper-master\KeyMapper.py", line 502, in buildMainGUI
    self.buildProfileGUI()
  File "c:/Users/01/Desktop/KeyMapper-master/KeyMapperExampleGame.py", line 172, in buildProfileGUI
    popupMarker_relief = None)
  File "c:\Users\01\Desktop\KeyMapper-master\DirectOptionMenuAware.py", line 36, in __init__
    self.initialiseoptions(DirectOptionMenuAware)
  File "C:\Panda3D-1.10.7-x64\direct\gui\DirectGuiBase.py", line 275, in initialiseoptions
    '" for ' + myClass.__name__)
KeyError: 'Unknown options "item_pad, item_frameColor, item_clickSound" for DirectOptionMenuAware'

Panda3D-1.10.7-x64

And yeah, ě is a single key, panda generates raw-2 event for it. If you want to make your keybindings work on every keyboard then you have to use only raw-key events.

As to the error, ah! That seems to have been a bug related to “DirectOptionMenuAware”. Since I’ve switched the code in the repository to no longer use that class, it should be fine now.

As to the key-events, I’ll give that consideration, thank you; I’ve made a note of it as an issue to look into. (Although, thinking about it, it seems to me like a bug in Panda that normal key-events aren’t being generated.)

@Pignon: I’ve just uploaded an update to the KeyMapper repository. Would you do me the favour please of trying it out and letting me know whether the module now correctly supports the sort of keys that it wasn’t previously handling?

Again had to comment that 3 lines.
It shows that it binded the keys (it didnt before) but in the game they dont work. Also maybe its just the font but the ˇ above ě etc. is upside down and all the other letters are also incorrect. Can you include the font or check if it has the characters.

That’s very strange. Did you get the updated copy of the example-game? It should no longer be using DirectOptionMenuAware, and thus those parameters should work… o_0

Most frustrating! :/

[edit] Do you perhaps have a modified version of DirectOptionMenu, or any of the DirectGUI classes, in your build of Panda…? [/edit]

Ah, that’s a pity!

Okay, I’ll have to look into that further, I think. I’ll likely make a thread to ask after the issue, as I don’t seem to have a keyboard to hand that allows me to experiment with it myself.

But progress, at least!

I’m just using the default font, I believe–that is, it should be using whatever Panda uses when no font is specified, as I haven’t specified one. I’m not sure offhand of what font that is, I’m afraid.

You dont need special keyboard, you can change in your system keyboard to Czech and the 2-0 keys are some of the buttons that are the raw- only events.

And yeah DirectOptionMenu has the same issue.

KeyError: 'Unknown options "item_pad, item_frameColor, item_clickSound" for DirectOptionMenu'

I’ve tried that, I’m afraid: under Ubuntu, at least, Panda resolutely reports standard English key-presses, even when using non-raw events. I’ve tried changing my “input source” (i.e. which key-set I type in, e.g. Hangul) and using an on-screen keyboard. No apparent effect.

Hmm… Very odd. As far as I can tell, it should work.

Here, for example, is a thread in which “item_pad” was mentioned as being present:

Well, when I ctrl+F in DirectOptionMenu.py there are no results for item_pad, item_frameColor and item_clickSound.

On windows when I use multiple keyboards I have to swap them when an application is running because they tend to swap back to default one. Maybe its the same in Ubuntu? :smiley: No idea.

Unfortunately, DirectGUI’s handling of sub-component keywords is a little on the arcane side. There’s code that breaks down such keywords and passes them on to said sub-components, as I recall.

You won’t find mention of “popupMarker_image” (as mentioned in the docs), either, for example.

I’m pretty sure that I’ve tried that, I’m afraid. ^^; But I’ll give it another shot…

[edit] Nope, whether I switch “input sources” before or during a run, I just get English letters. :/