Getting started on Hare (TurtleGraphics2) (A few little spike tests...)
Last update on .
Today I started work on making an IDE and/or rewriting Turtle graphics. I started with a few spike tests. The first was to see how to go about using the rsvg library to render SVG graphics. So far I'm disappointed (or, rather my disappointment is renewed), it does seem you can't get at the DOM representation, nor can you register for events on the various elements (i.e. do hit-testing to see what element in the SVG received a mouse event). In other words, to render in SVG you have to write a textual SVG file/string and the structures inside the SVG just disappear (it may as well be a bitmap, modulo scaling).
Okay, so probably go for straight GTK rendering to start, I started with the current Turtle graphics code. Refactored into a non-GUI-specific Turtle class that encapsulates the state and drawing code (and includes comments and documentation strings) and a back-end that does the GUI-specific drawing.
Of course, this being my first real GTK project, I'm somewhat floundering there (I normally use wxPython, PyGame or GLUT/GL, I seem to have messed up in isolating the "canvas" part of the Turtle graphics). Haven't found a portable FloatCanvas-like widget for GTK yet, I'd like something that allows us to draw to unlimited extents, but clips the actual drawing to the displayed area and allows for scrolling, zooming, etceteras. Haven't spent that long looking, though.
The new design should allow for children's code that looks like this:
TURN = 5
for i in range( 360/(TURN*2) ):
t.forward( 20 )
t.left( TURN )
t.arc( TURN, 5 )
where "t" is simply a Turtle object instantiated outside of the loop and provided in the execution name space for the code. The Turtle's queue of commands will then be used by the GUI back-end to draw (and/or animate) the commands. Should also allow for multiple simultaneous turtles should we decide to support that (no global state storage).
The idea is that the "Turtle Graphics" view of the IDE will automatically provide the turtle object that you can use to render, while a different view (possibly packaged as a different Activity) simply won't have the turtle object provided, as a result it won't provide a canvas onto which to draw (unless you define one yourself).
We'll probably want to use the sys.settrace operation to allow for break-point and debug operation, but the animation can be done simply by slicing the queue of graphics commands and rendering only the sub-set on a given iteration of the animation. It's the traditional debug-view and breakpointing that want the settrace stuff (though an animated "slow" debug would be pretty useful and cool).
I've also re-written the arc-drawing routine using step-based line rendering, so that kids looking at the code can see what's being done more readily than using a canvas-level primitive. Remembering back, one of the first things I ever programmed (when I was 7 or so) was a little drawing program on the Apple II+ and one of the first lessons from my dad was how to draw an arc (I couldn't figure it out in grade one).
The Turtle code itself is pretty simple, and the renderer only needs to know how to clear the screen and draw lines at this point (when we add things such as rendering text, filled shapes, bitmaps and svg graphics that will change). I've got a basic test-suite for the Turtle code (but not for the GUI renderer, that's well past my GTK mojo).
I'll need to figure out what I'm doing wrong in setting up the GTK context and get the GTK renderer working, then I can start into the really fun stuff (parsing, code generation and the visual representations of the code).
After that I'll have to read through some of the other IDE's source-code to see how they are handling running code, I would *like* to get the running code out of the IDE's process, but I think that would require an instrumented interpreter or some pretty icky hacking.
Also thinking about how to handle docstrings and localised variable/function names. I'm considering (with a great deal of trepidation) the possibility of having a tag at the start of the files that marks them as turtle-code (or even a different extension, or whatever).
With that tag in place, we'd do something nutty like translating utf-8-encoded local names into a 64-character encoding that only includes ascii upper and lower-case names. We'd store the code in the file using the insane format and then present it as localised text in the IDE (that is, you would edit the file as though Python supported unicode identifiers). Python is, IIRC scheduled to grow unicode identifier support at some point, but probably don't want to wait for that.
Comments are closed.
Pingbacks are closed.
André Roberge on 07/30/2007 11:40 p.m. #
I haven't followed all your posts, but I gather you are trying to design something for the XO (olpc). I have not look at Sugar at all and have only a very superficial knowledge of the XO. Still, if I may, I'd like to offer some suggestions.<br />
A while ago (last year?), Gregor Lindl came up with a new and improved version of the turtle module, named xturtle. Some information can be found here: http://www.rg16.asn-wien.ac.at/~python/xturtle/<br />
You may want to have a look at it, if only to get some more inspiration.<br />
Second, it is my understanding that the XO will include a browser based on XULrunner. If this browser support the tag, why not use it as your basis for drawing (rather than svg which you were looking at).<br />
Third - I'm a great believer in including lessons/examples/tutorials in a learning environment. This is what I originally did with my first project (rur-ple) which in turn totally influenced my second project (crunchy; found at http://code.google.com/p/crunchy). I have been thinking that I should (after version 1.0 is out) look at having a turtle module for crunchy. Crunchy already provides support for simple graphical animations (using the tag).<br />
My main focus in designing a learning environment has always been to think about providing a smooth transition from a "custom learning environment" to a "real life one". I believe that there is a real risk in designing a special IDE for children in creating an artificial barrier between learning that environment and being able to use the knowledge gained when trying to switch to an "adult" programming environment later on.<br />
Just some thoughts...
Mike Fletcher on 07/31/2007 6:56 a.m. #
Thanks for the input André. I'm actually hoping to make this IDE follow your idea of smoothing the transition from the "protected" space up to a fully-fledged IDE for developing applications.<br />
Although I am targeting the OLPC, I plan to make the program usable on normal Linux/MacOS and maybe even Windows desktops. Cross platform availability often helps adoption considerably.<br />
(I'm very aware of Crunchy, btw, you showed it to me at the last PyCon and I was very impressed. We were even discussing it at the last PyGTA). It would be interesting to see if we could adapt the LEO code-base's weaving and unweaving to get that kind of "literate" programming operation.<br />
XULRunner, yes, the XO's will have an XULRunner 1.9-based browser. Problem is that it is not readily available on other platforms (yet). If I read the API documentation and some of the code in the OLPC repository correctly it should be possible to use the browser with even SVG objects (it has DOM access), but then non-OLPC users can't contribute to the development as easily as with a simple GTK application.<br />
I'll take a look at xturtle as well.
André Roberge on 07/31/2007 11:52 a.m. #
Oops... I typed in the angled bracket around the word "canvas" as I wanted to refer to the "canvas tag" in my comment - but the "canvas" disappeared altogether!
Ian Bicking on 08/01/2007 11:14 a.m. #
Are you planning on not having automatic drawing? I would have expected your example to be preceded by t.penup() otherwise.<br />
Anyway, I'll note that this will be nice to use with PyLogo as well. You should be able to translate your example exactly as:<br />
tell :t [<br />
foreach range 360/(:turn*2) [<br />
forward 20<br />
left :turn<br />
arc :turn 5<br />
Basically "tell" means "for every function, first check if there's a method in :t with that name". So everything in that block (and actually continuing into Logo functions called by that block and so on) kind of inherits the active turtle. You could do the same thing with, say, a file-like object to effectively redirect stdout. But it's all mostly transparent to the Python code, which gets run fairly normally.
Mike Fletcher on 08/02/2007 10:16 a.m. #
Hmm, following the original code I am refactoring the turtle starts in "drawing" mode (pen down), so the idea was to have the turtle draw a little shape, pen-up would defeat the purpose of the code as I was intending it to operate.