Onscreen IDE & dynamic instant update [_v0.5.4_]

UPDATE :
[X] bugfix : auto-indent was accidentally broken
[X] startup:open file : add new file action now really appends files instead of replaces the old ones on the list.
[X] the recently closed files now inserted to the top of recent files list. So, if you accidentally close a file, it’s easier to load it back in.
[X] Panda’s default scenegraphs’ and main camera’s render state now correctly cleared. I tried it with the shadow sample, and then changed main module to no-light scene, and it works.
[X] the crusher now works too for classes derived from object type.
[X] all cameras (except Panda’s default and IDE’s code description RTT ones) and their graphics outputs will be removed. This works too for cameras which are not attached to Panda’s default scenegraphs. Once again, I did it by extending Camera class at runtime, so I can remove them simply by yelling at them using messenger.
[X] added buffer viewer toggle
[X] added jump to main module file
[X] added output redirection to a StringStream, displayed as log.txt in the IDE workspace. Use Ctrl-L to create/jump to it. It’s not created by default, but there is a config var you can change.
Here are its behavior :
+ if it’s already created and opened, but you’re editing other file, the log is still updated without interrupting anything you’re currently doing.
+ if you close it, its text display won’t be updated (until you open it again), though the output still fully recorded.
+ its scrolling behavior is similar to Linux’s terminal. If it’s scrolled to the end, upon output update it will be auto-scrolled, otherwise it’s not scrolled at all, so you can peacefully investigate the output without being annoyed by stupid auto-scroll as of Windows command prompt.
+ you can have it displayed too when you jump to scene. Not much you can do there, I only equipped it with the slider bar. I just don’t want to overwhelm your scene with more controls.
Unlike in IDE workspace, it’s displayed without the background layer, so you can see your scene’s real colors. And I don’t leave it rendered with only 1 color, that would make you hard to see it clearly over your colorful/dark/bright scene part. So, I created black halo around the white foreground color. This way, it remains readable no matter how your scene looks like. You can toggle show/hide it using F9.
The halo is created using PNMImage and the result is saved to disk and will be used at next runtime instead of creating it again.
The log file always saved to disk upon IDE shutdown.
[X] the files tab is skinned now.
The main module file tab label is colored green. I only created 5 skins, the 6th is only a combination of the others, showing that you can have asymetrical left-right edges. You can create your own skins, if you want.
The behavior of tab border :
1 if IDEtab_Rcorner.png exists, it will be used for right edge instead of the horizontally auto-flipped IDEtab_Lcorner.png
2 if IDEtab_mid.png exists, it will be used instead of U=1 (rightmost column) of IDEtab_Lcorner.png
The tab label skin has only behavior 1.
At runtime, you can cycle those skins using Ctrl-tilde. There is a config var for the default skin.

Possible problems :
[?] I couldn’t remove any shader, no matter what I tried. ShaderPool.releaseAllShaders() doesn’t work. So if I change a shader file, I couldn’t force it to be reloaded and compiled. I’m clueless, so I did it by hacking loader.loadShader. So, before sending the shader to ShaderPool, I temporarily alter its filename so it will be considered as new shader. That works great, but I believe it lets all old shaders floating around uselessly. I don’t know what to do about them.
[?] I couldn’t intercept Notify output in realtime. I monitor the output change only in a task, so all Notify output are accumulated at the end of frame, while Python’s print can be caught in realtime.