Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to update when releasing mouse button from slide #2228

Closed
wants to merge 9 commits into from
55 changes: 55 additions & 0 deletions docs/examples/blocks/slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ The currently selected value is in the attribute `value`.
Don't change this value manually, but use the function `set_close_to!(slider, value)`.
This is necessary to ensure the value is actually present in the `range` attribute.

If the slider value is used for a relatively slow task, it may be more effective to
use the attribute `value_dragstop` instead of `value`. The `value_dragstop` is only
updated when the mouse is released to conclude the slider drag operation. It is
is synchronized with `value` when calling `set_close_to!(slider, value)` or one a mouse
click or double click event.

You can double-click the slider to reset it (approximately) to the value present in `startvalue`.

If you set the attribute `snap = false`, the slider will move continously while dragging and only jump to the closest available value when releasing the mouse.
Expand Down Expand Up @@ -37,6 +43,55 @@ fig
\end{examplefigure}


This slightly more complicated example compares the behavior of the `value`
and `value_dragstop` slide attributes. There are two text fields displaying
the x value selected with the horizontal slider. However, one updates while the slider
is ddragged to show continuous updates but the other text only updates on mouse
release. The vertical slider and associated text fields behave the same way.
A more realistic application could use the the `value_dragstop` attribute to
trigger a slow computation only on the mouse release event.

\begin{examplefigure}{}
```julia
using GLMakie
GLMakie.activate!() # hide
fig = Figure()

ax = Axis(fig[1, 1])

sl_x = Slider(fig[2, 1], range = 0:0.5:10, startvalue = 3)
sl_y = Slider(fig[1, 2], range = 0:0.5:10, horizontal = false, startvalue = 6)

x_text = lift(sl_x.value) do x
"x slider value=$(x)"
end
x_text_stop = lift(sl_x.value_dragstop) do x
"mouse release x slider value=$(x)"
end
y_text = lift(sl_y.value) do y
"y slider value=$(y)"
end
y_text_stop = lift(sl_y.value_dragstop) do y
"mouse release y slider value=$(y)"
end

point = lift(sl_x.value, sl_y.value) do x, y
Point2f(x, y)
end

scatter!(point, color = :red, markersize = 20)
text!(2.5,9.5, text = x_text, align = (:center, :center))
text!(2.5,9.0, text = x_text_stop, align = (:center, :center))
text!(7.5,9.5, text = y_text, align = (:center, :center))
text!(7.5,9.0, text = y_text_stop, align = (:center, :center))

limits!(ax, 0, 10, 0, 10)

fig
```
\end{examplefigure}


## Labelled sliders and grids

The functions \apilink{labelslider!} and \apilink{labelslidergrid!} are deprecated, use \apilink{SliderGrid} instead.
Expand Down
38 changes: 30 additions & 8 deletions src/makielayout/blocks/slider.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ function initialize_block!(sl::Slider)

on(topscene, selected_index) do i
sl.value[] = sliderrange[][i]
if !dragging[]
sl.value_dragstop[] = sliderrange[][i]
end
end

# initialize slider value with closest from range
Expand Down Expand Up @@ -93,19 +96,16 @@ function initialize_block!(sl::Slider)

onmouseleftdrag(mouseevents) do event
dragging[] = true
dif = event.px - event.prev_px
fraction = clamp(if sl.horizontal[]
(event.px[1] - endpoints[][1][1]) / (endpoints[][2][1] - endpoints[][1][1])
else
(event.px[2] - endpoints[][1][2]) / (endpoints[][2][2] - endpoints[][1][2])
end, 0, 1)

fraction = current_sliderfraction(sl, event, endpoints, sliderrange)
displayed_sliderfraction[] = fraction

newindex = closest_fractionindex(sliderrange[], fraction)
if sl.snap[]
fraction = (newindex - 1) / (length(sliderrange[]) - 1)
end
displayed_sliderfraction[] = fraction

newindex = closest_fractionindex(sliderrange[], fraction)
if selected_index[] != newindex
selected_index[] = newindex
end
Expand All @@ -115,8 +115,11 @@ function initialize_block!(sl::Slider)

onmouseleftdragstop(mouseevents) do event
dragging[] = false
# selected_index should be set correctly in onmouseleftdrag
sl.value_dragstop = sliderrange[][selected_index[]]
# adjust slider to closest legal value
sliderfraction[] = sliderfraction[]
# This line is not necessary?
# sliderfraction[] = sliderfraction[]
linecolors[] = [sl.color_active_dimmed[], sl.color_inactive[]]
return Consume(true)
end
Expand All @@ -126,6 +129,7 @@ function initialize_block!(sl::Slider)
dim = sl.horizontal[] ? 1 : 2
frac = (pos[dim] - endpoints[][1][dim]) / (endpoints[][2][dim] - endpoints[][1][dim])
selected_index[] = closest_fractionindex(sliderrange[], frac)
sl.value_dragstop = sliderrange[][selected_index[]]
# linecolors[] = [color_active[], color_inactive[]]
return Consume(true)
end
Expand All @@ -151,6 +155,23 @@ function initialize_block!(sl::Slider)
sl
end


function current_sliderfraction(sl, event, endpoints, sliderrange)
fraction = clamp(if sl.horizontal[]
(event.px[1] - endpoints[][1][1]) / (endpoints[][2][1] - endpoints[][1][1])
else
(event.px[2] - endpoints[][1][2]) / (endpoints[][2][2] - endpoints[][1][2])
end, 0, 1
)

newindex = closest_fractionindex(sliderrange[], fraction)
if sl.snap[]
fraction = (newindex - 1) / (length(sliderrange[]) - 1)
end

return fraction
end

function valueindex(sliderrange, value)
for (i, val) in enumerate(sliderrange)
if val == value
Expand Down Expand Up @@ -201,4 +222,5 @@ function set_close_to!(slider::Slider, value)
closest = closest_index(slider.range[], value)
slider.selected_index = closest
slider.range[][closest]
slider.value_dragstop = slider.range[][closest]
end
2 changes: 2 additions & 0 deletions src/makielayout/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,8 @@ end
startvalue = 0
"The current value of the slider. Don't set this manually, use the function `set_close_to!`."
value = 0
"Value of slider when mouse is released after dragging."
value_dragstop = 0
"The width of the slider line"
linewidth::Float32 = 15
"The color of the slider when the mouse hovers over it."
Expand Down
Loading