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

Slider dragging signals #3884

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions lib/wibox/widget/slider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,28 @@
-- @beautiful beautiful.slider_bar_active_color
-- @param color

--- Emitted when the user starts dragging the handle.
--
-- @signal drag_start
-- @tparam number value The current value

--- Emitted for every mouse move while the handle is being dragged.
--
-- This signal is only emitted by the user dragging the handle. It is therefore
-- preferrable over `property::value`, as it cannot create a loop when trying to
-- hook up the slider as representation of an external value (e.g. system
-- volume).
--
-- @signal drag
-- @tparam number value The current value

--- Emitted when the user stops dragging the handle.
--
-- This signal is emitted when the user releases the mouse button after dragging
-- the handle.
--
-- @signal drag_end
-- @tparam number value The current value

local properties = {
-- Handle
Expand Down Expand Up @@ -334,6 +356,15 @@
end
end

--- Returns `true` while the user is dragging the handle.
--
-- @property is_dragging
-- @propertydefault Depends on the current dragging state.
-- @treturn boolean
function slider:get_is_dragging()
return self._private.is_dragging

Check warning on line 365 in lib/wibox/widget/slider.lua

View check run for this annotation

Codecov / codecov/patch

lib/wibox/widget/slider.lua#L365

Added line #L365 was not covered by tests
end

local function get_extremums(self)
local min = self._private.minimum or properties.minimum
local max = self._private.maximum or properties.maximum
Expand Down Expand Up @@ -535,6 +566,9 @@

move_handle(self, width, x, y)

self._private.is_dragging = true
self:emit_signal("drag_start", self.value)

-- Calculate a matrix transforming from screen coordinates into widget coordinates
local wgeo = geo.drawable.drawable:geometry()
local matrix = matrix_from_device:translate(-wgeo.x, -wgeo.y)
Expand All @@ -545,11 +579,14 @@

capi.mousegrabber.run(function(mouse)
if not mouse.buttons[1] then
self._private.is_dragging = false
self:emit_signal("drag_end", self.value)
return false
end

-- Calculate the point relative to the widget
move_handle(self, width, matrix:transform_point(mouse.x, mouse.y))
self:emit_signal("drag", self.value)

return true
end,handle_cursor)
Expand Down
111 changes: 111 additions & 0 deletions tests/test-wibox-widget-slider.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
local runner = require("_runner")
local wibox = require("wibox")
local gears = {
shape = require("gears.shape")
}

local steps = {}

-- The test runner doesn't support it (yet), but it would be nice to have named
-- steps.
local function step(_, func)
table.insert(steps, func)
end

-- Apparently in CI the wibox won't always be at the coordinates we specify.
-- So we'll have to click around blindly until we find our widget,
-- then use those coordinates as offset for the actual test.
local offset_x = nil
local offset_y = nil

local w
local slider

local on_mouse_press = nil
local on_drag_start = nil
local on_drag = nil
local on_drag_end = nil
local on_property_value = nil

step("create slider widget", function()
slider = wibox.widget.slider {
minimum = 0,
maximum = 100,
bar_shape = gears.shape.rounded_rect,
bar_height = 3,
bar_color = "#ffffff",
handle_color = "#0000ff",
handle_shape = gears.shape.circle,
handle_border_color = "#ffffff",
handle_border_width = 1,
}

slider:connect_signal("button::press", function()
on_mouse_press = true

if offset_x ~= nil then
return
end

local coords = mouse.coords()
offset_x = coords.x
offset_y = coords.y
print(coords.x, coords.y)
end)
slider:connect_signal("drag_start", function() on_drag_start = true end)
slider:connect_signal("drag", function() on_drag = true end)
slider:connect_signal("drag_end", function() on_drag_end = true end)
slider:connect_signal("property::value", function() on_property_value = true end)

w = wibox {
ontop = true,
x = 0,
y = 0,
width = 250,
height = 50,
visible = true,
widget = slider,
}

-- Mute luacheck warning
assert(w.ontop)

return true
end)

for x = 0, 2000, 5 do
for y = 0, 2000, 5 do
step("find widget", function()
if offset_x ~= nil then
return true
end

mouse.coords({ x = x, y = y })
root.fake_input("button_press", 1)
root.fake_input("button_release", 1)

return true
end)
end
end

step("test dragging", function()
mouse.coords({ x = offset_x, y = offset_y })
root.fake_input("button_press", 1)
mouse.coords({ x = offset_x + 100, offset_y })
root.fake_input("button_release", 1)
return true
end)

step("check signals", function()
assert(on_mouse_press, "Signal `button::press` was not called")
assert(on_drag_start, "Signal `drag_start` was not called")
assert(on_property_value, "Signal `property::value` was not called")
assert(on_drag, "Signal `drag` was not called")
assert(on_drag_end, "Signal `drag_end` was not called")
return true
end)

runner.run_steps(steps)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
Loading