Skip to content

Commit a35440f

Browse files
authored
Merge pull request #142 from JuliaGizmos/jbj/set-and-forget
Adds `set!` function
2 parents 7eeee40 + fd876d7 commit a35440f

File tree

2 files changed

+74
-18
lines changed

2 files changed

+74
-18
lines changed

src/widgets.jl

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ export slider, togglebutton, button,
33
checkbox, textbox, textarea,
44
radiobuttons, dropdown, selection,
55
togglebuttons, html, latex, hbox, vbox,
6-
progress, widget, selection_slider
6+
progress, widget, selection_slider,
7+
set!
78

89
const Empty = VERSION < v"0.4.0-dev" ? Nothing : Void
910

@@ -339,30 +340,23 @@ Options(view::Symbol, options::OptionDict;
339340
ow
340341
end
341342

342-
addoption!(opts, v::NTuple{2}) = opts[string(v[1])] = v[2]
343-
addoption!(opts, v) = opts[string(v)] = v
344343
function Options(view::Symbol,
345-
options::AbstractArray;
344+
options::Union{Associative, AbstractArray};
346345
kwargs...)
347-
opts = OrderedDict()
348-
for v in options
349-
addoption!(opts, v)
350-
end
351-
optdict = OptionDict(opts)
352-
Options(view, optdict; kwargs...)
346+
Options(view, getoptions(options); kwargs...)
353347
end
354348

355-
function Options(view::Symbol,
356-
options::Associative;
357-
kwargs...)
349+
function getoptions(options)
358350
opts = OrderedDict()
359-
for (k, v) in options
360-
opts[string(k)] = v
351+
for el in options
352+
addoption!(opts, el)
361353
end
362354
optdict = OptionDict(opts)
363-
Options(view, optdict; kwargs...)
364355
end
365356

357+
addoption!(opts, v::NTuple{2}) = opts[string(v[1])] = v[2]
358+
addoption!(opts, v) = opts[string(v)] = v
359+
366360
"""
367361
dropdown(choices; label="", value, typ, icons, tooltips, signal)
368362
@@ -481,3 +475,30 @@ widget(x::Associative, label="") = togglebuttons(x, label=label)
481475
widget(x::Bool, label="") = checkbox(x, label=label)
482476
widget(x::AbstractString, label="") = textbox(x, label=label, typ=AbstractString)
483477
widget{T <: Number}(x::T, label="") = textbox(typ=T, value=x, label=label)
478+
479+
### Set!
480+
481+
"""
482+
`set!(w::Widget, fld::Symbol, val)`
483+
484+
Set the value of a widget property and update all displayed instances of the
485+
widget. If `val` is a `Signal`, then updates to that signal will be reflected in
486+
widget instances/views.
487+
488+
If `fld` is `:value`, `val` is also `push!`ed to `signal(w)`
489+
"""
490+
function set!(w::Widget, fld::Symbol, val)
491+
fld == :value && push!(signal(w), val)
492+
setfield!(w, fld, val)
493+
update_view(w)
494+
w
495+
end
496+
497+
set!(w::Widget, fld::Symbol, valsig::Signal) = begin
498+
map(val -> set!(w, fld, val), valsig) |> preserve
499+
end
500+
501+
set!{T<:Options}(w::T, fld::Symbol, val::Union{Signal,Any}) = begin
502+
fld == :options && (val = getoptions(val))
503+
invoke(set!, (Widget, Symbol, typeof(val)), w, fld, val)
504+
end

test/notebooks/Interact Manual Tests.ipynb

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,15 @@
402402
"#Byo Signal and init value\n",
403403
"fx = Signal(0.0)\n",
404404
"x = slider(0:.1:2pi, label=\"x\")\n",
405-
"y = map(v -> slider(-1:.05:1, value=sin(v), signal=fx, label=\"f(x)\"), signal(x))\n",
405+
"y = map(v -> slider(-1:.05:1, value=sin(v), signal=fx, label=\"sin(x)\"), signal(x))\n",
406406
"#init value only\n",
407407
"z = map(a -> slider(-1:.05:1, value=sin(2a), label=\"sin(2x)\"), signal(x))\n",
408408
"ssz = flatten(map(zslider->signal(zslider), signal(z)))\n",
409409
"sinx = map(xv->round(sin(xv), 3), signal(x))\n",
410410
"sin2x = map(xv->round(sin(2xv), 3), signal(x))\n",
411-
"display.([x, y, z, signal(x), fx, sinx, ssz, sin2x]);"
411+
"#top 3 values should be the same as the slider readouts after you move x (but not the other 2 sliders)\n",
412+
"#next two should be ~= sliders 2 and 3 at all times\n",
413+
"display.([x, y, z, signal(x), sinx, sin2x, fx, ssz]);"
412414
]
413415
},
414416
{
@@ -427,6 +429,39 @@
427429
"display.([layout, map(signal, (cb,s1,s2))...]);"
428430
]
429431
},
432+
{
433+
"cell_type": "code",
434+
"execution_count": null,
435+
"metadata": {
436+
"collapsed": false
437+
},
438+
"outputs": [],
439+
"source": [
440+
"#sin and cos are types that are subtypes of Function, make sure Options can generalise inputs to be of type Function\n",
441+
"#clicking the buttons should update the \"sin (generic function with 10 methods)\" output\n",
442+
"using Interact\n",
443+
"t = togglebuttons([sin,cos])\n",
444+
"display.([t, signal(t), eltype(signal(t))])\n",
445+
"@show typeof.([sin,cos]);"
446+
]
447+
},
448+
{
449+
"cell_type": "code",
450+
"execution_count": null,
451+
"metadata": {
452+
"collapsed": false
453+
},
454+
"outputs": [],
455+
"source": [
456+
"sldmin = slider(0:.01:10.0, label=\"min value\")\n",
457+
"sldstep = slider(0.01:.01:1, label=\"step size\")\n",
458+
"sldmax = slider(10.0:.1:20.0, label=\"max value\")\n",
459+
"sldrange = map((vmin, vstep, vmax)->vmin:vstep:vmax, signal(sldmin), signal(sldstep), signal(sldmax))\n",
460+
"s1 = slider(.01:.5:15.0)\n",
461+
"set!(s1, :range, sldrange)\n",
462+
"display.([sldmin, sldstep, sldmax, s1, sldrange]);"
463+
]
464+
},
430465
{
431466
"cell_type": "code",
432467
"execution_count": null,

0 commit comments

Comments
 (0)