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

What it is :
A package of dynamic scene instant update (so you don’t have to shutdown Panda and reload it again and again everytime you make minor/major changes) and a little attempt to minimize Panda3D - IDE windows switch, if you have 1 small monitor like mine.
It’s a 1 application, 1 window solution.

Full reason why :

[color=red]What’s missing :
[-] line wrap
[-] unicode support
[-] code folding
[-] code browser
[-] and anything not mentioned down below…

FEATURES :
[+] create new file, open, save, and save duplicate
[+] error pinpoint
[+] output capture
[+] line:column bookmarks
[+] auto & smart indent
[+] repetitive characters insertion
[+] Python syntax highlight
[+] matching brackets highlight & selection
[+] 2-ways grow & shrink selection
[+] edit history
[+] color chooser
[+] macro recording, replaying, and editing (visually, so you don’t need macro editing manual) [1] [2]
Works with undo/redo during recording, the recorded actions are popped out/in upon undo/redo. The last recorded action type is displayed at status bar.
[+] find & replace, with Regular Expressions
Able to replace in all opened files, and selectable files under a directory.
[+] 3 mouse selection modes (character, word, line), switched by another mouse click
[+] easy launch of PStats server (on local machine) and auto-establish connection
[+] code completion
[+] save to snippets and its completion [1] [2] [3]
[+] import completion [Python] [Panda3D] [new Panda3D]
[+] call tips [Python functions] [Panda3D functions] [individual argument insertion]
[+] Preferences GUI [1] [2] [3] [4] [5] [6] [7]
[+] portable app (can live in removable media)
[+] single instance app, all files passed to IDE_STARTER or using the Welcome Screen will be opened by the running instance of IDE
[+] per-file CWD and arguments
[+] SceneGraph browser and Node Properties panel [1] [2]
[+] software auto-upgrade [1] [2] [3] [4]

[size=150]Dependency :[/size] wxPython

[size=150]Download:[/size]
Since v0.1, there is C++ extension to speed up text generation.
Source code : Text Drawer extension
Windows binaries : for Panda3D 1.5.3, 1.6.0, 1.6.2, 1.7.0, 1.7.2, 1.8.0.
NOTE : if you up/downgrade your Panda3D version, you should rebuild the extension, or it would be done in python, which is approx. 4x slower.
Read /TD/HOW_TO_USE.txt for further info.

IDE codes : OnscreenIDEdynamic.zip [UPDATED Jun/26/2012]
images : IDEimages.zip [UPDATED Aug/31/2011]
models : IDEmodels.zip [UPDATED 3/2/2010]
slider skins : IDEsliderSkins.zip [NEW 6/3/09]
test scene : testDynScene.zip [UPDATED 5/18/09]
fonts : IDEfonts.zip [UPDATED 12/09/08]
tab skins : IDEtabSkins.zip [NEW 07/27/08]
sounds : IDEsounds.zip [NEW 03/31/08]
Put all the .zip files in the directory of your choice and extract them, so that the fonts, models, sounds, images, and skins directories are at the same level with the IDE codes.
You can put the test scene somewhere else.

Screenshots :
(1st week)
(Oct 2008)
(June 2009)
See my later posts for more shots.

[size=150]KNOWN RESTRICTIONS & LIMITATIONS[/size] :
RESTRICTION <1> :
In your main script, you have to protect your World instantiation, because it’s done by the IDE.
This is a sample of it :

if __name__=='__main__':
   print '\n', '@'*10, "\n  I'M PROCESSED !!!\n", '@'*10
   if not hasattr(help,'IDE'):
      World()
   run()

So you must isolate World instantiation so it won’t be done twice each time you update the scene. The rest of your code will be executed normally.
World instantiation is done by the IDE, to isolate the instance, to ease the pain when searching for the must-be-destroyed class instances.
The run() call is safe and meaningless when you use the IDE, since it’s redirected to a dummy run() function.
The test scene is not already use this blocker, so add it yourself.

But, in case you need to instantiate it yourself, save the instance in global namespace as “winst”, like this :

if __name__=='__main__':
   winst = World( arg1,arg2,etc. )
   run()

RESTRICTION <2> :
If you leave World instantiation to the IDE, you should name the class “World”.
Note that you don’t need to have a World class to instantiate. If you’re trying some very simple modules, you can just do everything in module global namespace.

LIMITATION <1> :
The destructors are still very limited to the commonly used ones, so if you think some destructors need to be added (in myFinder.py), let me know.

[size=150]IDE START-UP INSTRUCTIONS[/size] :

  1. run IDE_STARTER.pyw
  2. for testing only :
    2a. select dyn1.py and (optional) all other test scene files to be edited
    2b. select the main script file : dyn1.py
    And the IDE will be opened in a new fresh Python session.

NOTE : the default key to open Preferences window is Shift-Ctrl-P

CRITICAL SITUATION (when it stops responding to any key) :
Alt-M         : print current mode
Shift-Alt-R   : restore to correct mode

Once you’re ready to update your scene, press your beloved F9. All edited documents will be saved, and all changes will be instantly updated.

PS. : code donation is always welcome :smiley:

PPS. : You don’t have to read my rant below this line.


The reason why :
this IDE is generally a pain killer for me, on both Panda and editing sides.

PANDA3D side :
If I use large models or textures, they’re loaded from disk only once at first, and the next scene updates will load them from the pools. So, I don’t have to waste my time waiting for my scene being loaded from disk, each time I want to see some changes. This saves lots of time when debuging or developing shaders.

EDITING side :
Every IDE I’ve tried has some unbelieveably unique ways in hurting me. I can’t do this or that, or have to do it in weird way. At the end I can only sighhhhhhhhh.
To mention some (in contrast with mine) :
[1] Very small range of recent files, and there is no way to adjust it.
[2] Some IDE’s don’t save bookmarks, and some forcefully save bookmarks even if I don’t want to save the file.
[3] I can’t easily stop at the edge when cycling over bookmarks, and some IDE’s simply forbid me to wrap to the other edge.
[4] So far, no IDE I’ve tried offers me easy macro editing. All of them force me to read the commands reference, since there is no completion for IDE commands itself. It sounds like slouuuuuu hell if I only need to fix my mistakes when recording it, since I’m very aware that I’m just a mistakes factory.
[5] So far, no IDE I’ve tried adjusts the recorded macro commands upon undo/redo, it just runs 1 way straight forward, blindfold without looking back, so I have to go through point (4) if I made mistakes.
[6] I don’t know if there is IDE which displays indentation helper line only when needed, i.e. when the alignment notch is off the screen. The worst thing is if it’s offscreen, I can’t even see what it is. So, why don’t I just close my eyes instead ? Opening my eyes wouldn’t change anything.
[7] I don’t know if there is IDE which shows me other than start-matched completion.
[8] Any other IDE’s do multiple lines operation only on lines which have at least 1 selected character in it.
Imagine this, I put the cursor at the 1st column, and then select 2 lines downward, the line on which the cursor is now, won’t be included in the process. Now imagine if I do that in a macro, and I don’t put the cursor first at the first column, the result will be different at macro replay time.
Case 1: cursor is at column #1, there will be 2 processed lines
Case 2: cursor is at column #2, there will be 3 processed lines !!!
[9] I don’t know any IDE which is able to insert the call arguments into the script easily. The worst thing is it’s mostly not even wrapped.

Can’t wait to try it one of these days (very busy right now.)
Screenshot? :slight_smile:

Done.
Found a bug already. I missed the rstrip(’\n’) in delLine, caused a havoc to the indentation.

QUICK UPDATE :

  1. able to load files, press Ctrl-O
  2. I don’t like filling my screen with files’ tabs, so I make the tabs draggable sideways. Use MMB to slide it, and Ctrl-MMB to close a file.

UPDATE :

  1. able to load files, create new file, and save file as
  2. supports case change, to uppercase, lowercase, and swapcase
  3. besides rebind process exceptions handling, now able to handle runtime continuous tasks exceptions too, done by wrapping taskMgr.run(), and if the faulty task is in the tasks list, it would be removed, so it wouldn’t halt Panda. Practically, you will never get dropped to Python prompt at all. To demonstrate this, I split the jacks into a separate module : jackClass.py. In there, I used doMethodLater, which will be called 5 seconds later, after the scene get started. That method uses Task, which is not imported, I commented out its import line (line #2). So after 5 seconds passes by, you’ll be alerted about the error, and the module file will be set as the active document, or if it’s not loaded, it will be loaded first.

more shots :

wow you are putting quite amount of work into this! Much better then the editor i made.

wow wow wow-wow-wow :smiley:

Looks amazing! :smiley:

Regards, Bigfoot29

UPDATE:

  1. dynamic updater : there was a super huge hole in my previous updater. I hadn’t thought about it earlier. It’s the old instances replacement. The way I recreated the new instances was simply by generally call realClass(). Of course, that doesn’t work for a class which receives init arguments, which is mostly the way you need it.
    So, how if I want to rebind such a class (say class B) ? I must find its host class instances (say class A), and crush them and recreate them, so all class B instances will be created correctly and treated naturally afterward by class A instances. But how if those class A instances are part of a larger environment, which is part of another larger one ? I have to do exactly the same thing for them.
    At the end, I might need to crush the whole World class instance and recreate it anyway. So, yes that’s what I do now, directly crush World instance and recreate it everytime after any rebind process. The major inconvenience of that is the whole thing get restarted from the very beginning.

  2. dynamic updater : if there is an error in a class during instantiation after rebind, and before that erroneous point, you have attached some nodes to scenegraph, registered some events, etc, they used to get left over, alive and don’t get rolled back. It means, the next time you update the scene, you’d get another set of duplicates, models, events, lights, and everything instantiated before the broken line. So the scene would look and behave just like hell, or trash bin, sooooo ugly.
    It’s because the broken class instance doesn’t get crushed. Previously, I hadn’t figured out how to crush it, since the broken class instance isn’t saved in the caller’s locals, but only in the broken class’ locals.
    But I have found a way to crush it, by tracking the real error until the end of tracebacks chain, saving it in the caller class instance, so it can be removed altogether. So there should not be any artifact left anymore during rebind-restart process.
    To demonstrate this, uncomment this line in dyn1.py :
    [color=darkred]# self.brokenInstance=BrokenClass()
    and update it (press F9).
    You should never see the teapot created before messItUp() call in BrokenClass. What would happen is, the instance of World class, which is responsible for creating BrokenClass instance, will be crushed altogether after saving BrokenClass instance temporarily as its attribute, to ensure safety, in case the expected BrokenClass instance is used in other part of it.

  3. code completion is available, works for live objects (everything exists in builtins), all imported modules, Python keywords, and class instance attributes (the last part is still experimental and not usable yet).
    Works as you type, with stop-typing-threshold .3 second.
    It’s enabled by default, press F4 to toggle.
    Press Ctrl-Space to force it to show up if you’re not typing but want to know more about the code your cursor is on.
    Use ArrowUp/Down, PageUp/Down, and Home/End to navigate through the list.
    Press F1 to toggle the description when highlighting the available code.
    Use Ctrl-arrow up/down to navigate through the description.
    Press Enter to use the highlighted code.
    Press Esc to cancel.
    The performance to render the available codes list is poor, since I use my own text builder, which is not optimized for fast render, it’s geared towards quick show, so the faster it’s generated, the better. For 422 list items, DirectButton takes 3 seconds, plus additional 1 mysterious second. DirectLabel takes 2.3 seconds. Then I decided to use my own text builder, as for the script’s text, since I don’t need any cosmetics part. The result is it takes only 0.15 second for the same 422 items. In the future, I might use RTT too for it, just like what I do for the code description, which uses 3 pages cameras.

  4. before I released this in the 1st place, I dropped pixel-perfect text rendering for a funny reason. Somehow, some letter’s vertical edge or corner vanished. I thought that was due to “nearest” texture filter. But recently I found out that it was due to something completely different, it’s the side effect of flattenStrong(). Somehow, some overlapping vertices of adjacent letters get welded, or its texcoord loses precission or so, I don’t know exactly. The good news is it’s easy to solve, only by enlarging each letter’s quad to avoid overlapping vertices. See if it’s better.

I can’t seem to get this to run.

Here is the output.

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\smartviz>cd Desktop

C:\Documents and Settings\smartviz\Desktop>cd "New Folder"

C:\Documents and Settings\smartviz\Desktop\New Folder>python IDE_STARTER.py
Warning: DirectNotify: category 'Interval' already exists
DirectStart: Starting the game.
:prc(warning): Invalid integer value for ConfigVariable win-size: 600,500
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:prc(warning): Invalid floating-point value for ConfigVariable background-color:
 .1,.1,.1,1
:display:windisplay(warning): Could not find icon filename icon.ico
:display:gsg:glgsg(warning): BlendEquation advertised as supported by OpenGL run
time, but could not get pointers to extension function.
:display:gsg:glgsg(warning): BlendColor advertised as supported by OpenGL runtim
e, but could not get pointers to extension function.
:audio(error):   LoadLibrary() failed, will use NullAudioManager
:audio(error):     Module not found
:util(warning): Adjusting global clock's real time by 5.5873e-006 seconds.
:util(warning): Adjusting global clock's real time by -0.0761046 seconds.
enteringFrame
exitingFrame
enteringFrame
exitingFrame
exitingFrame
########################################
STARTING.....
########################################

C:\Documents and Settings\smartviz\Desktop\New Folder>Warning: DirectNotify: cat
egory 'Interval' already exists
############### YOUR FILES ###############
C:\Documents and Settings\smartviz\Desktop\New Folder\2\dyn1.py
C:\Documents and Settings\smartviz\Desktop\New Folder\2\brokenClass.py
C:\Documents and Settings\smartviz\Desktop\New Folder\2\jackClass.py
C:\Documents and Settings\smartviz\Desktop\New Folder\2\pandaClass.py
C:\Documents and Settings\smartviz\Desktop\New Folder\2\smileyClass.py
##########################################
C:\Documents and Settings\smartviz\Desktop\New Folder\2\dyn1.py
C:\Documents and Settings\smartviz\Desktop\New Folder\2
DirectStart: Starting the game.
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:display:windisplay(warning): Could not find icon filename icon.ico
:display:gsg:glgsg(warning): BlendEquation advertised as supported by openGL run time, but could not get pointers to extension function.
:display:gsg:glgsg(warning): BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.
:audio(error):   LoadLibrary() failed, will use NullAudioManager
:audio(error):     Module not found
:util(warning): Adjusting global clock's real time by 4.74921e-006 seconds.
APP ['WorldInst', '__doc__', '__init__', '__module__', 'moduleName']
APP_modName : dyn1
APP_modName : dyn1
CC_TEMP CLEARED !!
:text(warning): No definition in Lucida Console Regular for character 13
:text(warning): No definition in Lucida Console Regular for character 11
:text(warning): No definition in Lucida Console Regular for character 12
['\x0c', ' ', '$', '(', ',', '0', '4', '8', '<', '@', 'D', 'H', 'L', 'P', 'T', '
X', '\\', '`', 'd', 'h', 'l', 'p', 't', 'x', '|', '\x0b', '#', "'", '+', '/', '3
', '7', ';', '?', 'C', 'G', 'K', 'O', 'S', 'W', '[', '_', 'c', 'g', 'k', 'o', 's
', 'w', '{', '\n', '"', '&', '*', '.', '2', '6', ':', '>', 'B', 'F', 'J', 'N', '
R', 'V', 'Z', '^', 'b', 'f', 'j', 'n', 'r', 'v', 'z', '~', '\t', '\r', '!', '%',
 ')', '-', '1', '5', '9', '=', 'A', 'E', 'I', 'M', 'Q', 'U', 'Y', ']', 'a', 'e',
 'i', 'm', 'q', 'u', 'y', '}']
100
IDE_normal_chars_maxWidth : 0.654545474052
IDE_normal_chars_maxHeight: 2.09090900421
:text(warning): No definition in Lucida Console Regular for character 13
:text(warning): No definition in Lucida Console Regular for character 11
:text(warning): No definition in Lucida Console Regular for character 12
['\x0c', ' ', '$', '(', ',', '0', '4', '8', '<', '@', 'D', 'H', 'L', 'P', 'T', '
X', '\\', '`', 'd', 'h', 'l', 'p', 't', 'x', '|', '\x0b', '#', "'", '+', '/', '3
', '7', ';', '?', 'C', 'G', 'K', 'O', 'S', 'W', '[', '_', 'c', 'g', 'k', 'o', 's
', 'w', '{', '\n', '"', '&', '*', '.', '2', '6', ':', '>', 'B', 'F', 'J', 'N', '
R', 'V', 'Z', '^', 'b', 'f', 'j', 'n', 'r', 'v', 'z', '~', '\t', '\r', '!', '%',
 ')', '-', '1', '5', '9', '=', 'A', 'E', 'I', 'M', 'Q', 'U', 'Y', ']', 'a', 'e',
 'i', 'm', 'q', 'u', 'y', '}']
100
IDE_bold_chars_maxWidth : 0.654545474052
IDE_bold_chars_maxHeight: 2.09090900421
IDE_textScale : Vec3(0.0366667, 1, 0.0366667)
:display(error): Window wouldn't open; abandoning window.
:display:wgldisplay(error): Could not share texture contexts between wglGraphics StateGuardians.

I’m not sure what is going on but the last 2 lines say something I think…

Oh ignore the audio errors the panda version I am using is compiled without FMOD and OpenAL

Robert

I’m not sure either, that’s very weird. Even the Config params are invalid.
The error is very similar to this :
discourse.panda3d.org/viewtopic.php … t=contexts
My own 1.4.2 build works just fine. Perhaps it’s 1.5.0 issue ?
[EDIT]:
I’ll try to replace makeTextureBuffer with makeOutput. I guess you can’t run teapot-on-tv sample too.

I have some (minor) improvements ready for update. I’ll UL it tonight.

I’ve used makeOutput, but still using different framebuffer properties. It might not work. I tried to use main window’s FBprops but the RTT result was funny, so I dropped it.

UPDATE :

  1. changed keys for moving line(s) and duplicating line. Instead of using modifier keys (Shift-Ctrl-Alt), now I use double Ctrl, so I only need to utilize 1 hand. Double Ctrl press threshold is .3 second.
  2. pausing the scene now correctly pauses all scene’s intervals and tasks (both oridinary and doLater tasks).
  3. upon rebind, all doLater tasks get removed to avoid unnecessary annoying assertion error due to operating on no-longer-exist objects.
  4. code completion : works a little more correct on imported stuff, temporarily imported upon module/document switch (or anytime a document is set to active). Class instance attributes now includes all of its methods, but still not properly usable yet.
  5. added destructor for sound

UPDATE :

  1. the last edited files list now always saved upon exit, and can be loaded in the next execution.
  2. integrated WxPython, mainly to replace the limited my own file dialog and create a welcome screen. Luckily, it also allows me to use a better IDE-OS clipboards management and interaction. It’s my 1st time using this cool serves-everything GUI lib, so there should be better ways in doing things.
  3. moved the IDE’s root to render2dp, to avoid it being affected by user’s need over render2d and aspect2d.
  4. added pools clears for models, textures, and shaders
  5. added destructors for collision traverser and handlerPhysical
  6. added collisions in the sample scene
    [EDIT 05/22/08]:
  7. any camera is preserved upon update

more shots :

Ok, still doesn’t run :frowning:

A few things…

may have to do with the WXPython version…

I downloaded: http://downloads.sourceforge.net/sourceforge/wxpython/wxPython2.6-win32-unicode-2.6.4.0-py25.exe

Firstly, when I clicked open / new There was an error saying that

Traceback (most recent call last):
  File "IDE_STARTER.pyw", line 265, in __init__
    self.SetTransparent(ALPHA_optionsScreen)
AttributeError: 'CreateNewFile' object has no attribute 'SetTransparent'

So I commented out these 2 lines

193 #self.SetTransparent(ALPHA_optionsScreen)
265 #self.SetTransparent(ALPHA_optionsScreen)

Then this error was raised after creating a new file.

PREVIEW UPDATED
Nothing was selected.
########################################
STARTING.....
########################################

C:\Documents and Settings\smartviz\Desktop\asdf>Warning: DirectNotify: category
'Interval' already exists
############### YOUR FILES ###############
C:\Documents and Settings\smartviz\Desktop\asdf\brt.py
##########################################
DirectStart: Starting the game.
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:display:windisplay(warning): Could not find icon filename icon.ico
:display:gsg:glgsg(warning): BlendEquation advertised as supported by OpenGL run
time, but could not get pointers to extension function.
:display:gsg:glgsg(warning): BlendColor advertised as supported by OpenGL runtim
e, but could not get pointers to extension function.
:audio(error):   LoadLibrary() failed, will use NullAudioManager
:audio(error):     Module not found
:util(warning): Adjusting global clock's real time by 8.66315e-006 seconds.
APP ['WorldInst', '__doc__', '__init__', '__module__', 'modDir', 'moduleName']
APP_modName : brt
APP_modName : brt
CC_TEMP CLEARED !!
Traceback (most recent call last):
  File "IDE.py", line 449, in <module>
    base.startWx()
AttributeError: ShowBase instance has no attribute 'startWx'
>>>

Again looks like the wxpython playing up, where / how did you install your wxpython / what os are you using?

Robert.

Why are you still using v.2.6 ? Here I use wx v2.8, the latest, and Panda 1.5.1. I don’t know since which version startWx was added to ShowBase.

self.SetTransparent :
self is CreateNewFile instance, derived from wx.Frame, so it’s a method of a wx.Frame.

It was developed on Windows. But I have just setup a Hardy box (I’m a 3 days linuxer :smiley:) with the latest NVIDIA driver, and I have Panda’s gutsy .deb v1.5.2, I’ll try it soon on Hardy.

rninne, what’s your graphics card ?
For the previous RTT problem you have, do the render-to-texture samples work ?
RTT setup is tricky, the result varies too much across graphics cards.

Well I chose v.2.6 because it said latest stable release :stuck_out_tongue: Ill try with v2.8

Welcome to Linux! I’m glad that you chose Ubuntu.

It is a Colorgraphic Xentera GT… dxdiag tells me it has 4 ATI mobility radeon 9000’s (shaders aren’t supported on this card… but I’m sure it is the drivers, since it is a specialist card and Colorgraphic have stopped supporting it it’s hard to get updates)

With regards to that I’ll try it on my other computer it has a more standard card (NVIDIA 7600 GS).

Robert.

Well, life must go on, and v2.6 is just too old.
You’d be better stick to your 7600 GS.

[EDIT]:
for the base.startWx, you can use the next lines (for creating the wx.App instance and the loop) in IDE.py instead of it.

I am currently trying to port the app to os x. While doing this i wanted to post one mayor problem of wxpython (under osx):

if using StaticBoxSizer, all objects that are added must be created after the StaticBoxSizer.

this:

WELCOME_openLastEditedFilesBtn = wx.Button(welcomeScreenPanel, -1, 'Open Last Edited Files',size=(0,50))
if os.path.exists('lastFiles') and os.stat('lastFiles')[6]>0:
   WELCOME_openLastEditedFilesBtn.Bind(wx.EVT_BUTTON,OpenLastEditedFiles)
else:
   WELCOME_openLastEditedFilesBtn.Disable()

WELCOME_openFilesBtn = wx.Button(welcomeScreenPanel, -1, 'Open Files',size=(0,50))
WELCOME_openFilesBtn.Bind(wx.EVT_BUTTON,OpenFiles)

WELCOME_createNewFileBtn = wx.Button(welcomeScreenPanel, -1, 'Create New File',size=(0,50))
WELCOME_createNewFileBtn.Bind(wx.EVT_BUTTON,CreateNewFile)

WELCOME_buttonsSizer = wx.StaticBoxSizer(wx.StaticBox(welcomeScreenPanel),wx.VERTICAL)
WELCOME_buttonsSizer.Add((250,0))
WELCOME_buttonsSizer.Add(WELCOME_openLastEditedFilesBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
WELCOME_buttonsSizer.Add(WELCOME_openFilesBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
WELCOME_buttonsSizer.Add(WELCOME_createNewFileBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)

must be changed to this:

WELCOME_buttonsSizer = wx.StaticBoxSizer(wx.StaticBox(welcomeScreenPanel),wx.VERTICAL)

WELCOME_openLastEditedFilesBtn = wx.Button(welcomeScreenPanel, -1, 'Open Last Edited Files',size=(0,50))
if os.path.exists('lastFiles') and os.stat('lastFiles')[6]>0:
   WELCOME_openLastEditedFilesBtn.Bind(wx.EVT_BUTTON,OpenLastEditedFiles)
else:
   WELCOME_openLastEditedFilesBtn.Disable()

WELCOME_openFilesBtn = wx.Button(welcomeScreenPanel, -1, 'Open Files',size=(0,50))
WELCOME_openFilesBtn.Bind(wx.EVT_BUTTON,OpenFiles)

WELCOME_createNewFileBtn = wx.Button(welcomeScreenPanel, -1, 'Create New File',size=(0,50))
WELCOME_createNewFileBtn.Bind(wx.EVT_BUTTON,CreateNewFile)

WELCOME_buttonsSizer.Add((250,0))
WELCOME_buttonsSizer.Add(WELCOME_openLastEditedFilesBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
WELCOME_buttonsSizer.Add(WELCOME_openFilesBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
WELCOME_buttonsSizer.Add(WELCOME_createNewFileBtn, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)

it would be great, if you could consider this, while you continue your work.

Great shot, Hypnos !
So, I guess the StaticBox doesn’t wrap all children defined before the StaticBoxSizer is created. Is that it ? How about BoxSizer, is it buggy too ?
Are there anything else I should be aware of ?

I got it mostly working in the meantime, i dont think anything else is affected. I could open files and start the ide (i have not checked if the BoxSizer is used in those parts).

I didnt really understand why StaticBoxSizer is not working correctly. It took me a while to figure out this solution from the messages i found on the internet. But it seems to be a known osx problem for wx-windows.


Another problem i have found, under osx is that os.execl does not work while using wx-windows. A possibility is to keep the window opened (by using os.spawnl)

    if sys.platform == "darwin":
        pythonExecutable = "/usr/bin/python" # i think thats the usual py2.5 from 10.5 (leopard)
        result = os.spawnlp( os.P_NOWAIT, pythonExecutable,' -i ', the_IDE, the_files, ' %i'%PStatsEnabled)
    else:
        os.execl(sys.executable.replace('pythonw','ppython'),' -i ',the_IDE,the_files,' %i'%PStatsEnabled)

I think adding sys.path.append(’.’) to IDE.py will fix a problem which can occur in APP_MODULE when importing modules from the loaded file. I think the path is somehow not set correctly when spawning the ide process.


Maybe a working directory should be defined when loading a file.
i sometimes use a filestructure like this:

- panda_function_lib_dir
  - __init__.py
  - file1.py
  - file2.py
- currect_project_dir
  - main.py
  - class2.py

Where main contains:

from panda_function_lib_dir import file1

This does not work with the current structure.


The APP_files is a list of ‘"/path/to/file"’, the filename should be stripped of "

APP_files_unstrip=sys.argv[1].split('::::')
APP_files = list()
for app in APP_files_unstrip:
    APP_files.append( app.strip('"') )

I have changed a lot of other things, but most of them related to the fact that i still use python 2.4 ("var = ‘x’ if a else ‘y’ does not exist in 2.4)

Sorry, it took me too long. My first 1.5.2 .deb was corrupt, so I had to DL it again, plus wxPython was not installed by default in Hardy 8.0.4, so I had to install GTK+2 and build wxWidgets myself. Got confused a bit, I did some parts of the build process a little differently and got stuck for a while. :S
After it was built, I moved wx’s /lib/* to /usr/lib and the built /wx to python2.5/site-packages. The demo works gorgeously, but when I tried the IDE, none of the threads work. I use new thread to display all dialog (except 1, the exit & save confirmation), since ShowModal never return. On Windows, that works fine, but not on Linux.
Any clue about that ? Could it be something wrong with my wx build ? Perhaps I missed something.

Other bad news on Linux :
The code-completion description’s RTT is at low res
the sort order of 2d nodes get scrambled
Perhaps they’re simply P3D version changes (serious !) issues, I use 1.5.1 on Windows, and 1.5.2 on Linux.
wx’s clipboard must be checked if it’s already opened, otherwise assertion error !
wx show event for the code preview panel in create-new-file step doesn’t fired at all, causes the preview never generated at all
I’ll take closer look at them soon.

Good news :

I have re-arranged all StaticBoxSizers.


Before migrated to execl recently, I’ve used to use spawnl P_NOWAIT, plus sys.exit.
The only reason is, on Windows, most of the time, using spawnl minimizes the python console, it’s kinda annoying. One thing you (might) miss was closing the welcome screen window (sys.exit after os.spawnl). I could be wrong, so what’s the difference of with and without sys.exit ? The problem is solved as soon as the new python session is spawned, isn’t it ?


In IDE.py, I already inserted the main script’s dir to the path :

IDE_lastBrowsePath=os.path.dirname(APP_mainFile)
sys.path.insert(0,IDE_lastBrowsePath)

at the beginning, before importing user’s app, and nothing went wrong on Linux. Moreover, I always stick to /root when running “python /path/to/IDE_STARTER.pyw” on terminal.


On Windows, I used to execute “python script.py” not from console, so the CWD is set automatically to script’s dir. But on Linux (so far I always start the IDE from terminal, still from /root), so the CWD isn’t changed.
I just added this to IDE_STARTER, so the panda image can be found :

# sets the working dir to the script's location, just to ease the pain
os.chdir( os.path.dirname(sys.argv[0]) )

but I haven’t tried adding that in IDE.py though.


On Windows it’s without double-quotes, since double-quotes are automatically stripped by the OS. I guess Unix uses single-quotes, isn’t it ?
Actually, sys.argv[1] is “/path/to/file1::::/path/to/file2::::/path/to/file3”, not “/path/to/file1”::::“/path/to/file2”::::“/path/to/file3”, so this works :

APP_files=sys.argv[1].strip('"').split('::::')

Thanks for your attention, Hypnos !
BTW, is there any delicious reason to stick to python 2.4 ? v2.5 offers some performance optimizations and more interesting things.