Creating your own time slider
The Time slider — the red vertical marker that half-hides on the left hand side of the canvas — is a way of turning the canvas into a score: drag the slider around (or set it's position programmatically) and the visual elements that it crosses get executed. The Processing tutorial has some examples, and there are some handy conventions for writing code that starts, continues and stops as this red marker enters and exits boxes.
Sometimes, however, the global, single marker is insufficient — perhaps you'd like to make a little organization in one corner of the sheet out of just a few boxes; perhaps you'd like much more control over the scripting of the slider itself, without having to worry about accidently crossing boxes (and thus executing them) all over the sheet.
The solution is to create your own Time Sliders in code that a) operate only on a subset of the sheet and b) operate only when your code tells them to operate.
The Sub-Time slider
The connivence method for creating a slider is simply this:
TemporalSliderOverrides.newLocalTemporalSlider("sub1", _self, _self.frame.x, predicate)
This makes a new red bar that is called "sub1", thats a sub-element of this element, and is positioned at the left edge of this element. predicate is a function that says which elements should be executable by this red line, and thus which elements should be ignored.
Here's one typical definition:
def predicate(): return _self.subelements.values()
This just returns all of the elements that are subelements of this one. Remember, you which elements are subelements of what using the "modify dispatch" tool:
If we make a couple of child elements of this element we'll have something like this:
Here we're using the "Selection" palette to show the dispatch ordering:
Note how the red marker in this case tries to indicate, in red, the limited subset of the sheet that it's going to execute when it enters and exits.
Controlling execution
If you drag this slider over the boxes 'child' and 'child2' you'll find that nothing happens. To actually get the slider to execute things we'll need to add some more code.
First, let's actually keep track of the slider that we've created:
def pred(): return _self.subelements.values() if (not _self.subSlider_): _self.subSlider_, _self.runner_ = TemporalSliderOverrides.newLocalTemporalSlider("sub1", _self, _self.frame.x, pred)
newLocalTemporalSlider returns two things, the slider and the runner — the object responsible for sliding around, and the object responsible for actually executing things.
To run something, we need to update the runner:
_self.runner_.update(_self.subSlider_.frame.x)
Here we update the runner using the 'time' given by the position of the slider — by far the most usual case. You are free to actually call update any time that you like (or not at all).
That's it, we're basically done. Take a look at VisualElementLifecycles: everything still applies, both to the code that's in the sub-elements and to the code here that you might use to make _self.runner_.update run repeatedly.
One final note: you might want the main, default, time slider to ignore these child elements. To do so, execute this:
for x in predicate(): x.promiseExecution_ = _self.runner_
This overrides the object that is responsible for running things at a local level. In this case, even option-clicking wont do anything until the next call to _self.runner_.update( ... ) which is in some cases, exactly what you want to happen. Subclasses of BasicRunner have complete domain over the execution of visual elements — this is how the ProcessingPlugin is made for example, and we've also made subclasses that execute elements on remote machines.



