JuliaGizmos / Interact.jl

Interactive widgets to play with your Julia code
Other
520 stars 75 forks source link

inner update of custom widget does not work with rangepicker #340

Open yakir12 opened 4 years ago

yakir12 commented 4 years ago

Sometimes I want to create some feedback control inside a custom widget: Say I have two rangepickers and I want to prevent the user from setting one of the slider to too high if the other slider is too low. So I want to build in to the widget a check that adjusts the sliders accordingly.

The following works in the sense that the resulting output from the widget is correct (so the feedback works), but the sliders themselves do not get updated and get stuck (they never again update):

function mywidget()
    p = rangepicker(1:10, value = [1])
    s = rangepicker(1:10, value = [1])
    on(p) do x
        Δ = x[1] - s[][1]
        if Δ < 0
            s[][1] += Δ
            s[] = s[]
        end
    end
    on(s) do x
        Δ = p[][1] - x[1]
        if Δ < 0
            p[][1] -= Δ
            p[] = p[]
        end
    end
    output = Interact.@map vcat(&p, &s)
    wdg = Widget(["p" => p, "s" => s], output = output)
    @layout! wdg vbox(pad(1em, hbox("Position", :p)), pad(1em, hbox("Size", :s)))
end
a = mywidget()
w = Window()
body!(w, a);

Note: With plain sliders (instead of rangepickers) this works flawlessly:

function mywidget()
    p = slider(1:10, value = 1)
    s = slider(1:10, value = 1)
    on(p) do x
        Δ = x - s[]
        if Δ < 0
            s[] += Δ
        end
    end
    on(s) do x
        Δ = p[] - x
        if Δ < 0
            p[] -= Δ
        end
    end
    output = Interact.@map vcat(&p, &s)
    wdg = Widget(["p" => p, "s" => s], output = output)
    @layout! wdg vbox(pad(1em, hbox("Position", :p)), pad(1em, hbox("Size", :s)))
end
a = mywidget()
w = Window()
body!(w, a);