ui/lua/widgets/bar/mpris.lua
2024-11-20 02:19:18 -08:00

109 lines
3.6 KiB
Lua

local Mpris <const> = lgi.require("AstalMpris")
local mpris = Mpris.get_default()
local map = require('lua.lib').map
return Widget.Stack({
transition_type = 'SLIDE_UP_DOWN',
transition_duration = 125,
children = {},
setup = function(self)
self:add_events(Gdk.EventMask.SCROLL_MASK);
self:add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK);
local function add_player(player)
self:add_named(
Widget.Box({
class_name = 'player',
vertical = true,
hexpand = false,
setup = function(self) self['name'] = player:get_bus_name() end,
css = bind(player, 'cover-art'):as(
function(coverart)
if coverart then
return
'background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(22, 22, 22, 0.9)), url("' .. coverart .. '");'
.. 'background-position: 50% 50%; background-size: cover'
else
return ''
end
end),
children = {
Widget.Box({
vertical = true,
hexpand = true,
valign = 'CENTER',
halign = 'END',
children = {
Widget.Button({
on_click = function() player:previous() end,
child = Widget.Icon({ icon = 'media-skip-backward-symbolic' })
}),
Widget.Button({
on_click = function() player:play_pause() end,
child = Widget.Icon({
icon = bind(player, 'playback-status'):as(function(status)
return (player:get_playback_status() == 'PLAYING' and 'media-playback-pause-symbolic' or 'media-playback-start-symbolic')
end)
})
}),
Widget.Button({
on_click = function() player:next() end,
child = Widget.Icon({ icon = 'media-skip-forward-symbolic' })
})
}
}),
Widget.Slider({
hexpand = true,
class_name = 'music-progress',
valign = 'END',
halign = 'START',
-- for some reason, this is broken
on_change_value = function(self) player:set_position(self:get_value() * player:get_length()) end,
setup = function(self)
Variable():poll(500, function()
if player == nil then return end
self:set_value(player:get_position() / player:get_length())
end)
end,
})
}
}),
player:get_bus_name()
)
end
map(mpris:get_players(), add_player)
self:hook(mpris, 'player-added', function(self, player)
add_player(player)
end)
self:hook(mpris, 'player-closed', function(self, player)
print('remove player', player:get_bus_name())
self:get_named(player:get_bus_name()):destroy()
end)
local accumulated_delta_y = 0
self:hook(self, 'scroll-event', function(_, event)
local children = self:get_children()
local current_child = self:get_visible_child()
local _, delta_y = event:get_scroll_deltas()
local index
accumulated_delta_y = accumulated_delta_y + delta_y
for i, child in ipairs(children) do
if child == current_child then
index = i
end
end
if math.abs(accumulated_delta_y) > 10 then
self:set_visible_child(children[(index + math.floor(accumulated_delta_y / 10)) % #children + 1])
accumulated_delta_y = 0
end
end)
end
})