Firstly please note that I'm using simply Dynamic
behavior to illustrate my question, I'm not asking how to move a Disk
or make a Slider
.
When defining custom functions that allow interactive changing of variables I have almost always gotten by with just setting the attribute HoldFirst
and giving the variable as a first argument and wrapping Dynamic
where appropriate in the code defining the controller for example:
SetAttributes[mySlider, HoldAll]
mySlider[var_, range_] := Slider[Dynamic[var], range]
DynamicModule[{a = 0.4},
{mySlider[a, {0, 1}], Dynamic[a]}
]
But I feel that this is somewhat clashing compared to the interfaces of the build-in controllers and would like to have a similar interface such as those, namely changing such a definition to:
mySlider2[var_Dynamic, range_] := Slider[var, range]
DynamicModule[{a = 0.4},
{mySlider2[Dynamic[a, Temporary], {0, 1}], Dynamic[a]}]
Which in a sense allows the full specification of Dynamic to be used, here showing for example the use of a Temporary
setter.
For this simple example the change is rather painless, however the problem arises in situations where the code doesn't just pass on variables but needs to split them out in some way, for instance this manual implementation of a movable disk:
myMovableDisk[Dynamic[r_, {fstart_, f_, fend_}]] :=
EventHandler[Dynamic@Disk[r, 1],{
{"MouseDown", 1} :> fstart[MousePosition["Graphics"], r],
{"MouseDragged", 1} :> f[MousePosition["Graphics"], r],
{"MouseUp", 1} :> fend[MousePosition["Graphics"], r]
}]
Now this matches the longest definition, but I would rather like not to have to provide multiple definitions for myMovableDisk[Dynamic[r_, { f_, fend_}]]
,myMovableDisk[Dynamic[r_, f_]]
and such. So my way of doing this was to set HoldAll
and just provide rewriting calls to other definitions:
myMovableDisk[Dynamic[r_]] := myMovableDisk[Dynamic[r, {None, Automatic, None}]]
myMovableDisk[Dynamic[r_, {f_}]] := myMovableDisk[Dynamic[r, {None, f, None}]]
myMovableDisk[Dynamic[r_, f_]] := myMovableDisk[Dynamic[r, {None, f, None}]]
myMovableDisk[Dynamic[r_, {f_, fend_}]] := myMovableDisk[Dynamic[r, {None, f, fend}]]
myMovableDisk[Dynamic[r_, Temporary]] := myMovableDisk[Dynamic[r, {None, Temporary, Automatic}]]
To me this seems like a less elegant solution to allow normal dynamic interactivity, and I have yet to actually define how for instance a Temporary setter should work. I was wondering if there was an easier way to carry out such definitions, something akin to just accepting a _Dynamic
argument and then query it to get the values of fstar
,f
and fend
in the code actually defining myMovableDisk
?
Additionally I wonder if there is a write up of something like an interface definition for Dynamic
, in essence answering what a function accepting Dynamic[var]
should live up to of expectations in order to mirror a build-in function, since I'm really just working against the help page.
f
,fend
,Temporary
, etc. in any way inside your function then I see no other way than writing different signatures for all cases, or combine them in one signature withDefault
andOptional
. Or I did not understand the question. $\endgroup$AbsoluteCurrentArgument[dynvar,fstart]
, since I could very easily have implemented my wanted flexibility iffstart
,fend
and f where Options. As for the special treatment needed forTemporary
that will of cause always be needed, however I think it's doable with a general pattern. $\endgroup$HoldAll
? (furthermore, you forgot "myMovableDisk` in yourSetAttributes
$\endgroup$SetAttributes
$\endgroup$