diff --git a/lua/widgets/bar/init.lua b/lua/widgets/bar/init.lua index 121f25d..baf6311 100644 --- a/lua/widgets/bar/init.lua +++ b/lua/widgets/bar/init.lua @@ -2,7 +2,8 @@ local workspaces = require(... .. '.workspaces') local clock = require(... .. '.clock') local battery = require(... .. '.battery') local volume = require(... .. '.volume') -local brightness = require(... .. '.brightness') +local mpris = require(... .. '.mpris') +-- local brightness = require(... .. '.brightness') return Astal.Window({ namespace = "bar", @@ -14,6 +15,7 @@ return Astal.Window({ class_name = 'left', children = { workspaces, + mpris, } }), center_widget = Widget.Box({}), diff --git a/lua/widgets/bar/mpris.lua b/lua/widgets/bar/mpris.lua new file mode 100644 index 0000000..8e11102 --- /dev/null +++ b/lua/widgets/bar/mpris.lua @@ -0,0 +1,108 @@ +local Mpris = 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 +}) diff --git a/style/widgets/bar.scss b/style/widgets/bar.scss index 7ba7c2f..110ff17 100644 --- a/style/widgets/bar.scss +++ b/style/widgets/bar.scss @@ -26,6 +26,37 @@ centerbox { background-color: $hl; } } + + } + + stack > box.player { + min-width: 250px; + min-height: 60px; + background-position: 50% 50%; + background-size: cover; + border: 4px solid #161616; + + > box { + > button { + margin: 3px 10px; + } + } + + > .music-progress { + min-width: 242px; + min-height: 2px; + background: transparent; + + trough { + min-height: 2px; + background: $bg-alt-1; + } + + highlight { + min-height: 2px; + background: $mpd-progress-primary; + } + } } }