Yesterday, I wanted to make an interact widget that showed an animation more complicated than the animate command allows. So, on a plane trip, I hacked up the following. It's a bit rough, and not a proper patch, etc. However, those who care can paste it into a notebook and check it out.
The idea is simple. You want your interact to get updated every second with some time dependence -- so add a timer, set the timeout to 1000 (milliseconds). Note, this isn't an interact widget. It only produces the HTML that a widget would -- so you can't actually use this in an interact yet -- but worry not, I'll probably hack that up on the way home. {{{ def html_timer(id, timeout, callback, wait_for_internet = True): # if wait_for_internet: # timeout = 'Math.max(%s,4*current_network_latency)'%timeout #TODO: keep track of network latency by recording AJAX response times # probably don't want to add overhead of recording every response, # so time the keep_alive pings or something. s = """ def html_timer(id, timeout, callback, wait_for_internet = True): # if wait_for_internet: # timeout = 'Math.max(%s,4*current_network_latency)'%timeout s = """ <input type='hidden' id='%s' value='off'> <input type='hidden' id='time_%s' value=0> <table><tr> <td><input type='button' value='start' id='start_%s' onClick='var timer = get_element("time_%s"); var control = get_element("%s"); if(control.value == "on") return; control.value = "on" timer.value = 0; timer.onClick(0);'></td> <td><input type='button' value='pause' id='stop_%s' onClick='get_element("%s").value="off";'></td> <td><input type='button' value='continue' id='continue_%s' onClick='var timer = get_element("time_%s"); var control = get_element("%s"); if(control.value == "on") return; control.value = "on" timer.onClick(eval(timer.value));'></td> </tr></table> """%(id,id,id,id,id,id,id,id,id,id) run_once = """ get_element("time_%s").onClick = function(time_last) { var TIMER = get_element("time_%s"); var CONTROL = get_element("%s"); if(CONTROL.value != "on") return; //quit! var time = eval(TIMER.value); if(time != time_last) return; //break extraneous time loops TIMER.value = time+1; %s setTimeout("get_element(\\'time_%s\\').onClick("+(time+1)+")", %s); } """%(id,id,id,callback,id,timeout) #convert lines to concatenated strings #warning -- we messed up the callback if it had single-quotes #in it. TODO: fix that run_once = "+".join("'"+r+"\\n'" for r in run_once.split("\n")) s+= """ <script>setTimeout(%s);</script> """%(run_once) return s }}} The following is the only reasonable example right now, since I haven't actually made the widget. Don't do alerts unless you want to crash your browser. {{{ t = "<span id='foo'></span>" t+= html_timer('timer-007',10,'get_element("foo").innerHTML = time;',False) print t print html(t) }}} Comments? I think that it'd be best to hide useless buttons (stop while already stopped, start & continue while running). Other than that, I like it. --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to sage-devel-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~----------~----~----~----~------~----~------~--~---