With Dynamic
and gui-constructs like Popup
I always have a problem:
when an expression takes a while to evaluate the Dynamic parts look bad and usually breaks. For example, imagine a PopupMenu showing choices whose data has yet to be downloaded. I tried using things like PrintTemporary
but they didn't achieve the in-place effect I'm looking for.
So, for an arbitrarily long running dynamic, inserting Activity Indicators (looped animations) seamlessly is what I'm after.
Here's my first attempt:
and the code:
assnMenu[f_,a_Association, title_:"Choose"] := Module[
{am,b,r,g},
blup=Style[Pane[Magnify[ProgressIndicator[Appearance->"Percolate"],2]
,Alignment->Center],Background->Transparent];
r=blup;
g:=(r=blup;r=f[#])&;
onValueChange[b, g];
am = Table[With[{i=i}, a[i]:>(b=i)], {i, Keys@a}];
b = First @ Keys[a];
Panel @ Grid[
{{ActionMenu[title, am, Method->"Queued"],
Dynamic[Style[a[b],FontFamily->"Arial Black",FontSize->14],UpdateInterval->1]},
{Dynamic[r, TrackedSymbols:>{r}],SpanFromLeft}},
Alignment->{Center,Center}
]
]
onValueChange[a_,f_] := Module[{},
a/:Set[a,x_]:=((OwnValues[a]={HoldPattern[a]:>x}; f[x]);a)
]
This almost achieves what I want, but has a few glitches:
- This seems too complicated to be the right way to do this.
- In the current form
assnMenu[slowFunc, <|10 -> "A", 5 -> "B"|>]
takes 10 seconds to evaluate, so there is leakage. - I couldn't get it to work with a
DynamicModule
, (which has the nice optionDynamicEvaluationTimeouts
), which would help a lot. - I probably overlooked some part of the docs, I feel like there should already be high level functionalities handling this sort of stuff.