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
50 changes: 50 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_cloe_to!(slider, value)` or one a mouse
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_cloe_to

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this section should go before the example I think, with an appropriate subheading

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,50 @@ fig
\end{examplefigure}


This slightly more complicated example compares the behavior of the `value`
and `value_dragstop` slide attributes.

\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.
40 changes: 32 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(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,18 @@ 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)
# dif is never used?
# dif = event.px - event.prev_px
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these comments can be removed then


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 +117,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 +131,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 +157,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 @@ -197,4 +220,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 @@ -678,6 +678,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