Skip to content

Commit

Permalink
fix manipulate for observables
Browse files Browse the repository at this point in the history
  • Loading branch information
Pietro Vertechi committed Jun 6, 2018
1 parent 400e103 commit e77483e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/manipulate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ macro manipulate(expr)
end

widget(x, label="") = x
widget(x::Observable, label="") = Widget{:observable}(flex_row(label, x), x)
widget(x::Range, label="") = slider(x; label=label)
widget(x::AbstractVector, label="") = togglebuttons(x, label=label) # slider(x; label=label) ?
widget(x::Associative, label="") = togglebuttons(x, label=label)
Expand Down
16 changes: 11 additions & 5 deletions src/widget.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export observe, Widget

mutable struct Widget{T}
mutable struct Widget{T, S<:Union{WebIO.Scope, Void}}
node::Union{WebIO.Scope, WebIO.Node}
primary_scope::WebIO.Scope
primary_scope::S
primary_obs::Observable
Widget{T}(n::Union{WebIO.Scope, WebIO.Node}, s::S, o::Observable) where {T, S<:Union{WebIO.Scope, Void}} =
new{T,S}(n, s, o)
end

Widget{T}(primary_scope::Scope, primary_obs::Observable) where {T} = Widget{T}(primary_scope, primary_scope, primary_obs)
Widget{T}(widget::Widget, obs::Observable=widget.primary_obs) where {T} = Widget{T}(widget.node, widget.primary_scope, obs)
Widget{T}(scope, obs::AbstractString) where {T} = Widget{T}(scope, scope[obs])
Widget{T}(node::WebIO.Node, primary_obs::Observable) where {T} = Widget{T}(node, nothing, primary_obs)
Widget{T}(primary_scope::Scope, primary_obs) where {T} = Widget{T}(primary_scope, primary_scope, primary_obs)
Widget{T}(widget::Widget, obs=widget.primary_obs) where {T} = Widget{T}(widget.node, widget.primary_scope, obs)
Widget{T}(node, scope, obs::AbstractString) where {T} = Widget{T}(node, scope, scope[obs])

widgettype(::Widget{T}) where {T} = T
Expand All @@ -19,18 +21,22 @@ Base.show(io::IO, m::MIME"text/plain", x::Widget) = show(io, m, x.node)
# mapping from widgets to respective scope
scope(widget::Scope) = widget
scope(widget::Widget) = widget.primary_scope
hasscope(widget::Widget) = true
hasscope(widget::Widget{<:Any, Void}) = false

# users access a widgest's Observable via this function
observe(x::Observable) = x
observe(widget::Widget) = widget.primary_obs
observe(widget, i) = getindex(widget, i)

Base.getindex(widget::Widget, x) = getindex(scope(widget), x)
Base.getindex(widget::Widget{<:Any, Void}, x) = error("Indexing is only implemented for widgets with a primary scope")

"""
sets up a primary scope for widgets
"""
function primary_scope!(w::Widget, sc)
hasscope(w) || error("primary_scope! can only be called on widgets with a primary scope")
w.primary_scope = sc
end

Expand Down
4 changes: 4 additions & 0 deletions test/test_observables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ end
@test w["value"][] == 12
InteractBase.primary_obs!(w, "value")
@test observe(w)[] == 12

w = InteractBase.widget(Observable(1))
@test !InteractBase.hasscope(w)
@test_throws ErrorException w["value"]
end

@testset "katex" begin
Expand Down
3 changes: 2 additions & 1 deletion test/test_widgets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ ui = @manipulate for nsamples in 1:200,
sample_step in slider(0.01:0.01:1.0, value=0.1, label="sample step"),
phase in slider(0:0.1:2pi, value=0.0, label="phase"),
radii in 0.1:0.1:60,
show in true
show in true,
s in Observable(true)
cxs_unscaled = [i*sample_step + phase for i in 1:nsamples]
cys = sin.(cxs_unscaled) .* height/3 .+ height/2
cxs = cxs_unscaled .* width/4pi
Expand Down

0 comments on commit e77483e

Please sign in to comment.