Rewrote MPD interface

This commit is contained in:
2022-04-24 12:22:44 -07:00
parent 36041d8011
commit 717d7f3db3
8 changed files with 308 additions and 209 deletions

7
classes/mpc/init.lua Normal file
View File

@ -0,0 +1,7 @@
local P = require("classes/mpc/mpc")
local F = function(args)
return P:new(args)
end
return F

170
classes/mpc/mpc.lua Normal file
View File

@ -0,0 +1,170 @@
local widget_types = {
basic = require("classes/mpc/widget"),
}
local P = {
name = "mpc"
}
---
-- Internal methods
---
function P:_cmd(command)
-- Build complete pamixer arguments, combining sink and options.
-- Must have a leading space.
return "mpc --host " .. self.mpd_host .. " " .. command
end
function P:_get_status()
-- Update mute status and volume.
-- Values in this table are updated.
awful.spawn.easy_async(
self:_cmd("current --format \"title=%title% artist=%artist%\""),
function(stdout, stderr, exitreason, exitcode)
if (stdout == "") then
return
end
self.current_title = string.match(stdout, "title=(.*)artist=")
self.current_artist = string.match(stdout, "artist=(.*)")
self:_update_widget()
end
)
awful.spawn.easy_async(
self:_cmd("status"),
function(stdout, stderr, exitreason, exitcode)
self.is_playing = string.match(stdout, "(%[playing)") or false
self.is_paused = string.match(stdout, "(%[paused)") or false
self.is_stopped = not (self.is_playing or self.is_paused)
self.volume = string.match(stdout, "volume: ?(%d?%d?%d)%%")
self:_update_widget()
end
)
-- This is used inside a timer, so return true to keep it running.
return true
end
function P:_update_widget()
self.widget:update{
title = self.current_title,
artist = self.current_artist,
play = self.is_playing,
pause = self.is_paused,
stop = self.is_stopped,
volume = self.volume or 0
}
end
---
-- Simple actions
---
function P:volume_up()
awful.spawn(self:_cmd("volume +5"), false)
self:_get_status()
end
function P:volume_down()
awful.spawn(self:_cmd("volume -5"), false)
self:_get_status()
end
function P:toggle()
awful.spawn(self:_cmd("toggle"), false)
self:_get_status()
end
function P:next()
awful.spawn(self:_cmd("next"), false)
self:_get_status()
end
function P:prev()
awful.spawn(self:_cmd("prev"), false)
self:_get_status()
end
---
-- Create new volume_interface
---
function P:new(args)
-- Arguments
local m = {
update_interval = args.update_interal or 1,
widget_type = args.widget_type or "basic",
mpd_host = args.mpd_host or "localhost",
}
setmetatable(m, self)
self.__index = self
-- Create widget for this volume interface
m.widget = widget_types[m.widget_type]:new()
m.widget.widget:connect_signal("button::press",
function(_, _, _, button, mods)
if (button == 3) or (button == 1)then
m:toggle()
end
end
)
m.widget.right:connect_signal("button::press",
function(_, _, _, button, mods)
if (button == 4) then -- Scroll up
m:prev()
elseif (button == 5) then -- Scroll down
m:next()
end
end
)
m.widget.left:connect_signal("button::press",
function(_, _, _, button, mods)
if (button == 4) then -- Scroll up
m:volume_up()
elseif (button == 5) then -- Scroll down
m:volume_down()
end
end
)
-- Polling timer
m.timer_poll = gears.timer {
timeout = m.update_interval,
call_now = true,
autostart = true,
callback = function()
m:_get_status()
end
}
--[[
-- Timer waiting for changes
-- DO NOT USE, WILL DOS MPD
m.timer_wait = gears.timer {
timeout = 0.1,
call_now = true,
autostart = true,
callback = function()
awful.spawn.easy_async(
m:_cmd("current --wait"),
function(stdout, stderr, exitreason, exitcode)
m:_get_status()
end
)
end
}
--]]
return m
end
return P

128
classes/mpc/widget.lua Normal file
View File

@ -0,0 +1,128 @@
local P = {}
function P:update(args)
if (args.error ~= nil) then
self.title.markup = "MPD is not"
self.artist.markup = "connected"
self.volume.markup = "??"
else
self.title.markup = args.title or "No track"
self.artist.markup = args.artist or "loaded"
if (args.play) then
self.icon.image = beautiful.icons.music.blue.playing
elseif (args.pause) then
self.icon.image = beautiful.icons.music.blue.paused
elseif (args.stop) then
self.icon.image = beautiful.icons.music.blue.stopped
end
if (args.volume) then
self.volume.markup = args.volume .. "%"
else
self.volume.markup = ""
end
end
end
function P:new()
local widget = {}
setmetatable(widget, self)
self.__index = self
widget.title = wibox.widget.textbox("MPD is not")
widget.title.valign = "center"
widget.title.align = "left"
widget.title.font = "Hack NF 12"
widget.title.ellipsize = "end"
widget.title.forced_width = beautiful.dpi(conf.mpc_width)
widget.artist = wibox.widget.textbox("connected")
widget.artist.valign = "center"
widget.artist.align = "left"
widget.artist.font = "Hack NF 12"
widget.artist.ellipsize = "end"
widget.artist.forced_width = beautiful.dpi(conf.mpc_width)
widget.volume = wibox.widget.textbox("??")
widget.volume.valign = "center"
widget.volume.align = "left"
widget.volume.font = "Hack NF 10"
widget.volume.ellipsize = "end"
widget.volume.forced_width = beautiful.dpi(10)
widget.icon = wibox.widget {
resize = true,
image = beautiful.icons.music.blue.playing,
widget = wibox.widget.imagebox
}
widget.left = wibox.widget {
wibox.widget {
{
widget.icon,
top = beautiful.dpi(2),
bottom = beautiful.dpi(2),
left = 0, right = 0,
layout = wibox.container.margin,
},
widget.volume,
forced_num_cols = 1,
forced_num_rows = 2,
homogeneous = true,
expand = true,
layout = wibox.layout.grid
},
layout = wibox.container.background
}
widget.right = wibox.widget {
wibox.widget {
widget.title,
widget.artist,
forced_num_cols = 1,
forced_num_rows = 2,
homogeneous = true,
expand = true,
layout = wibox.layout.grid
},
layout = wibox.container.background,
}
widget.widget = wibox.widget {
{
{ -- Right spacer
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
widget.left,
widget.right,
{ -- Left spacer
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
layout = wibox.layout.align.horizontal,
},
layout = wibox.container.background,
}
widget.widget:connect_signal("mouse::enter", function(result)
widget.widget.bg = beautiful.color.bar.hover_bg
end)
widget.widget:connect_signal("mouse::leave", function(result)
widget.widget.bg = beautiful.color.transparent
end)
return widget
end
return P