On 01/21/2013 09:46 PM, Jonathan Wilkes wrote:
----- Original Message -----
From: Hans-Christoph Steiner hans@at.or.at To: Martin Peach martin.peach@sympatico.ca Cc: PD List pd-list@iem.at Sent: Monday, January 21, 2013 5:48 PM Subject: Re: [PD] GUI toolkits and custom GUIs WAS: Integra Live 1.5 released
Sounds like a good idea, but I don't think that should block anyone from starting. And having a real example to work with will make it much easier to figure out how to convert the Tcl into something more generic. The graphic ideas in Pd are almost all really simple: draw an object box, draw a message box, draw an array, draw connections. And indeed I think the communications between pd and pd-gui should be logical rather than graphical, i.e. "connect 0 1 2 5" instead of a line draw command.
(Here's a modest proposal, additions, revisions, critiques welcome)
To that end I think the best way to move is by leveraging the tcl "rename" command, which is what the DesireData devs were using to try out the tkzinc canvas (a gui canvas library which I don't recommend).
Basically, someone just needs to write a gui-plugin that renames the procs that are called from sys_gui and sys_vgui. This can be done incrementally. Basically the process would be to write new versions of those procs which a) call the old procs and b) send a FUDI-style message to a proc named something like "forward_mess".
Then, inside proc "forward_mess", write the tcl bindings for the gui toolkit of your choice to send that FUDI message to your alternate gui.
Example: Tooltips
For this example, we'll just consider "manual" tips, which get triggered from within Pd and are thus simple to describe:
[namecanvas foo]
[loadbang] | [tip 1 Hello World( | [s foo]
This will print "Hello World" in a little label in the bottom right-hand corner of a canvas. (Let's assume we've already got canvases working in the alternate gui.)
In the function canvas_tip from g_editor.c, sys_vgui is used to call the proc "pdtk_tip", where the first arg is the .x%lx.c canvas name, the second arg is the number "1" to signify a "manual" tip generated from pd (instead of an autotip from hovering over an object with the mouse). The rest of the args are the user's message, which is "1 Hello World" above (the initial float controls the message display-- nonzero for "on", zero for "off").
Armed with this information, how do we send a tip to our alternate gui? We use the "rename" command from tcl to hijack message from Pd to the pdtk_tip proc:
rename pdtk_tip pdtk_tip_old
Now pdtk_tip has been aliased to pdtk_tip_old, which frees us up to build our own pdtk_tip that will perform a "friendly" MITM attack on Pd:
proc pdtk_tip {w fromc show args} { pdtk_tip_old $w $fromc $show $args forward_mess [list $w "tip" $fromc $show [join $args]] }
And finally, inside forward_mess, put your code to forward the FUDI message to your alternate_gui:
proc forward_mess {args} { # actual command names may vary... ::alternate_gui_bindings::send $args }
Now, if I wrote all my tcl correctly, your alternate_gui will receive the message: .x%lx.c tip 1 1 Hello World
(Note-- this is not the same message that was sent within Pd that ultimately
calls the canvas_tip function. Is the aim to use the _exact_ same FUDI message in the GUI that gets passed within the "c" part of Pd? Or is it just to have _a_ message in FUDI form?)
Then in your alternate_gui you parse that message in the same way you would parse everything your alternate gui receives-- take the selector to refer to the object, the 1st arg as a method of that object, and the remaining args as the args to that method.
I still don't understand the details, but the last release of DesireData it looks like poe.tcl was matju's object-oriented tcl system for handling the gui side of things in a way something like what I describe above. His classes seem to mimic the way things look in Pd, though I could be wrong because I still don't understand exactly how it works.
Anyway, the benefits to this approach:
- incremental-- you can build the new gui one piece at a time
- runs alongside tcl gui, so you can compare your incremental results to
the original gui which is still in tact
- your alternate_gui could be an object-oriented tcl/tk gui which processes
FUDI messages instead of raw tcl procs (and can be developed next to the old, fully-functional tcl gui)
- you can have one gui-plugin to rename all the procs and send FUDI
messages to forward_mess, and another set of gui-plugins for each GUI toolkit people want to test out that just loads the tcl binding package for that toolkit and defines forward_mess to send the FUDI messages to it
- once we get some fully functioning guis in other toolkits (or one in
tcl that processes FUDI messages), the sys_vgui stuff in Pd can be changed to send FUDI messages-- then you just remove the plugins and forward the messages straight to the alternate_gui with (or without) tcl as the middleman.
In fact, even before considering other toolkits, we can make the gui-plugin to rename procs to lay the groundwork for this, or someone smarter than me can make a proc that automates the process of renaming procs if that's even possible.
-Jonathan
I think most of the time it will just be better to modify the C code to make it send generic pd messages. But this hack could be a workaround if someone wanted to go that way.
.hc