keyboard events, camera controls?

davidlallen

Deity
Joined
Apr 28, 2008
Messages
4,743
Location
California
Attached is a small chunk of python which gives the user finer control over the camera to make cool screenshots, via some keyboard bindings. I did not write this, and I don't know exactly where it came from, probably it has been around for a while. It would go into the vanilla CvEventManager.py in onKbdEvent.

I have some python on top of BUG using 3.19. I have hooked into a number of events like onEndGameTurn using the BUG event manager. I cannot quite figure out how to attach these keyboard bindings. I see addShortcutHandler, but it is not clear how to use it. I can hook a simple key like "a" but I cannot figure out how to hook arrow keys, and the ctrl and shift variants.

What is the right magic word to bind ctrl-left-arrow in addShortcutHandler?

Also, I see that somebody has already bound these keys, since they cause a selected unit to move around or to queue a move order. Will I be able to bind on top of these keys, or is somebody stronger than BUG already binding them?
 
CTRL + RIGHT / LEFT already rotate the camera 45 degrees, but hopefully you can intercept the shortcut and handle it yourself.

BUG's configuration XML has the <shortcut> element for defining keyboard shortcuts. It's a lot easier to do it in XML than in Python. The first step is to move that code out of CvEventManager into a new module, perhaps CameraShortcuts.py. Each action should be a separate function.

Code:
## CameraShortcuts.py

def rotateLeft(args):
    CyCamera().SetBaseTurn(CyCamera().GetBaseTurn() - 45.0)

def rotateLeftSmall(args):
    CyCamera().SetBaseTurn(CyCamera().GetBaseTurn() - 15.0)

def rotateRight(args):
    CyCamera().SetBaseTurn(CyCamera().GetBaseTurn() + 45.0)

...

def reset(args):
    CyCamera().SetBaseTurn(0)
    CyCamera().SetBasePitch(0)

Next hook up the shortcuts to the functions in a configuration XML file, CameraShortcuts.xml:

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
	Camera Shortcuts
-->
<mod id="CameraShortcuts" module="CameraShortcuts">
    <shortcut key="ctrl left" function="rotateLeft"/>
    <shortcut key="shift left" function="rotateLeftSmall"/>
    <shortcut key="ctrl right" function="rotateRight"/>
    ...
    <shortcut key="ctrl home" function="reset"/>
</mod>

That's it! If you complete it and get it working, I'll gladly include it in BUG.

Looking at CvCameraControls there is a lot of code to move the camera, but the handleInput() function is empty, so the call from CvEventManager does nothing. :confused:
 
Thanks, it was not obvious that "shift left" would be accepted. I wrote the code using these magic words and it is working. There is a philosophical question; so far I am going for the "one medium size file" approach for python in Dune Wars, rather than the "many distributed small files" approach. So I have added the shortcuts and camera code inside my existing DuneWars.py.

Since these keys are already overridden by something, it is probably not desirable to put this into BUG. Still, the code is there and you can easily add it if you have gotten other requests.

Thanks again for the help!
 
Yes, I need to create a list of all the key names in the module and on our documentation site.

BTW, one downside to making large modules is that you lose information. Whenever you change a file in SVN (I assume you have Dune Wars stored on SF.net or an SVN/CVS repository somewhere), it adds information.

If you modify the DuneWars.py file, it tells you only that the mod was changed.

If you modify the CameraShortcuts.py file, you don't even have to read the log entry or diff the file to know that the camera shortcut functions were modified. With many small files, reading the log output of an "SVN Update" command gives you a pretty good idea of what was changed and whether or not you need to pay closer attention.

If you're worried about performance, understand that having 1000 modules versus 1 at worst will cause a tiny slowdown during initialization (opening so many files). Parsing all the code won't take longer because it's the same amount of overall code.

And once it's parsed, 1 or 1,000 or 1,000,000 modules won't make a noticeable difference because hash tables are used for looking up modules and attributes. A hash table provides O(1) lookup time, meaning that it takes no longer to lookup a value if there are 1 or a million values in the table.

Finally, it's a lot easier to navigate small files than large ones. You don't have to have so many header comments to break the file apart, and it's easier to grok an entire file this way.

Anyway, that's just my opinion obviously, but I hate to see you paying a price with no real gain.
 
BTW, one downside to making large modules is that you lose information. Whenever you change a file in SVN (I assume you have Dune Wars stored on SF.net or an SVN/CVS repository somewhere), it adds information.

I wrote "medium size file" on purpose. For large scale projects when there already exist many tracked files, I agree that multiple small files may be better. But so far DW is at a medium size, with no CVS and 3-4 active developers, and only one active python developer (me).
 
I understand the desire to KISS, but I can say without hesitation that using a code repository--even when it was just myself doing the coding--has always been a very good thing. I have been burned by not using one earlier before (losing code and making changes that broke and wasting a lot of time trying to get back to a working version).

Working with SVN and SF.net is a snap with TortoiseSVN or Eclipse. While the latter is a bit heavy-handed, it is very nice with PyDev and SVN access in the tool.
 
I keep a sufficient number of backups. I am afraid that requiring others, especially non-programmers, to use an internet cvs facility would scare off potential contributors.
 
Back
Top Bottom