Hi everyone,
I've been working on a new interact system, inspired by a discussion
with William from this summer. I have a very rough proof-of-concept now
live on
aleph.sagemath.org. Here is an example of a few sliders and
areas which update in real-time as expressions change:
http://aleph.sagemath.org/?q=a8f94b77-6a95-4bb9-8d79-55578799704f&lang=sage
It is relatively easy to create new controls too. Here is an example of
a 2d point picker/dragger (drag the little box around in the big box).
It's not working perfectly, presumably because of some jqueryui/css
issues I haven't figured out yet, but you get the idea.
http://aleph.sagemath.org/?q=a52345e0-930e-4578-b444-7e1f823ca6c4&lang=sage
Basically, you need a python class that inherits from Control that has:
- __init__() method: that sets self.ns to an InteractiveNamespace
object (usually passed in at creation). An InteractiveNamespace is
basically a dictionary that will notify the front end whenever a key is
assigned a new value (i.e., when a variable is assigned)
- create() method: that sends a message to the javascript side to
create the control. The message has the format:
sys._sage_.display_message({'text/plain': '<short text description>',
'application/sage-interact-control': {'control_id':
self.id,
'control_type': '<javascript control identifier>',
'variable': [<list of variable names in namespace this control depends on],
'namespace':
self.ns.id}})
- variable_update() method: receives a dictionary from the javascript
side about variable names (keys) to update in self.ns
- control_update() method: sends the javascript control whatever
information it needs to update itself
On the javascript side, create a new object like thus:
mynewcontrol = sagecell.InteractControls.InteractControl();
then add:
- create() method: creates the javascript control and sets up a
handler to send messages about changes back to the python side
- update() method: when a variable this control depends on is
changed, this method is called to update the control. This usually will
involve sending a message back to the python side to get whatever
information is needed, then updating the html or javascript somehow
- register the control with the javascript identifier you used in the
create message from the python side.
Anyways, play with it if you want. It's still really rough, method
names probably will change, etc. But I think the foundation is there.
Thanks,
Jason
--
Jason Grout