Created classes package
This commit is contained in:
102
classes/volume/arc_widget.lua
Executable file
102
classes/volume/arc_widget.lua
Executable file
@ -0,0 +1,102 @@
|
||||
local P = {}
|
||||
|
||||
function P:set_value(value)
|
||||
-- Set widget value. (0 - 100)
|
||||
self.arc.value = value
|
||||
|
||||
if value > 70 then
|
||||
self.icon.image = beautiful.icons.volume.high
|
||||
elseif value > 40 then
|
||||
self.icon.image = beautiful.icons.volume.medium
|
||||
elseif value > 0 then
|
||||
self.icon.image = beautiful.icons.volume.low
|
||||
elseif value == 0 then
|
||||
self.icon.image = beautiful.icons.volume.off
|
||||
end
|
||||
end
|
||||
|
||||
function P:set_state(state)
|
||||
-- Set widget value. (0 - 100)
|
||||
if (state == "error") then
|
||||
self.icon.image = beautiful.icons.volume.error
|
||||
elseif (state == "muted") then
|
||||
self.icon.image = beautiful.icons.volume.mute
|
||||
elseif (state == "unmuted") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function P:set_tooltip(text)
|
||||
-- Set widget value. (0 - 100)
|
||||
self.tooltip.text = text
|
||||
end
|
||||
|
||||
function P:new()
|
||||
widget = {}
|
||||
setmetatable(widget, self)
|
||||
self.__index = self
|
||||
|
||||
widget.icon = wibox.widget {
|
||||
resize = true,
|
||||
image = beautiful.icons.volume.mute,
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
|
||||
widget.arc = wibox.widget {
|
||||
{
|
||||
widget.icon,
|
||||
top = beautiful.dpi(1),
|
||||
bottom = beautiful.dpi(1),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
max_value = 100,
|
||||
thickness = beautiful.dpi(4),
|
||||
start_angle = 4.71238898, -- 2pi*3/4
|
||||
--forced_height = beautiful.dpi(16),
|
||||
--forced_width = beautiful.dpi(16),
|
||||
colors = {"#27D4CC", "#00446B"},
|
||||
bg = "#FFFFFF30",
|
||||
paddings = beautiful.dpi(2),
|
||||
widget = wibox.container.arcchart
|
||||
}
|
||||
|
||||
widget.widget = wibox.widget {
|
||||
{
|
||||
{ -- Right space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
{
|
||||
widget.arc,
|
||||
top = beautiful.dpi(2),
|
||||
bottom = beautiful.dpi(2),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
{ -- Left space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
layout = wibox.container.background,
|
||||
}
|
||||
|
||||
widget.tooltip = awful.tooltip {
|
||||
objects = { widget.widget },
|
||||
text = ""
|
||||
}
|
||||
|
||||
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
|
86
classes/volume/bar_widget.lua
Normal file
86
classes/volume/bar_widget.lua
Normal file
@ -0,0 +1,86 @@
|
||||
local P = {}
|
||||
|
||||
function P:set_value(value)
|
||||
-- Set widget value. (0 - 100)
|
||||
self.bar.value = value
|
||||
end
|
||||
|
||||
function P:set_state(state)
|
||||
-- Set widget value. (0 - 100)
|
||||
if (state == "error") then
|
||||
return
|
||||
elseif (state == "muted") then
|
||||
return
|
||||
elseif (state == "unmuted") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function P:set_tooltip(text)
|
||||
-- Set widget value. (0 - 100)
|
||||
self.tooltip.text = text
|
||||
end
|
||||
|
||||
function P:new()
|
||||
widget = {}
|
||||
setmetatable(widget, self)
|
||||
self.__index = self
|
||||
|
||||
widget.bar = wibox.widget {
|
||||
max_value = 100,
|
||||
value = 0,
|
||||
--forced_height = 20,
|
||||
forced_width = beautiful.dpi(50),
|
||||
paddings = 0,
|
||||
border_width = 0,
|
||||
color = {
|
||||
type = "linear",
|
||||
from = {0, 0}, to = {beautiful.dpi(50), 0},
|
||||
stops = { { 0, "#27D4CC" }, { 1, "#00446B" }}
|
||||
},
|
||||
background_color = "#FFFFFF30",
|
||||
widget = wibox.widget.progressbar,
|
||||
shape = gears.shape.rounded_bar,
|
||||
}
|
||||
|
||||
|
||||
widget.widget = wibox.widget {
|
||||
{
|
||||
{ -- Right space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
{
|
||||
widget.bar,
|
||||
top = beautiful.dpi(2),
|
||||
bottom = beautiful.dpi(2),
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
{ -- Left space
|
||||
widget = wibox.widget.separator,
|
||||
color = beautiful.color.transparent,
|
||||
forced_width = beautiful.dpi(3)
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
layout = wibox.container.background,
|
||||
}
|
||||
|
||||
widget.tooltip = awful.tooltip {
|
||||
objects = { widget.widget },
|
||||
text = ""
|
||||
}
|
||||
|
||||
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
|
7
classes/volume/init.lua
Normal file
7
classes/volume/init.lua
Normal file
@ -0,0 +1,7 @@
|
||||
local P = require("classes/volume/volume")
|
||||
|
||||
local F = function(args)
|
||||
return P:new(args)
|
||||
end
|
||||
|
||||
return F
|
214
classes/volume/volume.lua
Executable file
214
classes/volume/volume.lua
Executable file
@ -0,0 +1,214 @@
|
||||
local widget_types = {
|
||||
bar = require("classes/volume/bar_widget"),
|
||||
arc = require("classes/volume/arc_widget")
|
||||
}
|
||||
|
||||
local P = {}
|
||||
|
||||
---
|
||||
-- Internal methods
|
||||
---
|
||||
function P:_full_args()
|
||||
-- Build complete pamixer arguments, combining sink and options.
|
||||
-- Must have a leading space.
|
||||
if (self.pa_sink == "") then
|
||||
return " " .. self.pa_options
|
||||
else
|
||||
return " --sink" .. self.pa_sink .. " " .. self.pa_options
|
||||
end
|
||||
end
|
||||
|
||||
function P:_get_status()
|
||||
-- Update mute status and volume.
|
||||
-- Values in this table are updated.
|
||||
awful.spawn.easy_async(
|
||||
"pamixer --get-mute --get-volume" .. self:_full_args(),
|
||||
function(stdout, stderr, exitreason, exitcode)
|
||||
|
||||
-- Get mute state
|
||||
local muted = string.match(stdout, "(%w%w%w%w%w?) ")
|
||||
self.muted = (muted == "true")
|
||||
|
||||
local value = string.match(stdout, "(%d?%d?%d)") -- (\d?\d?\d)\%)
|
||||
|
||||
if (value == nil) then
|
||||
self.volume = nil
|
||||
self._ready = false
|
||||
else
|
||||
self.volume = tonumber(string.format("% 3d", value))
|
||||
self._ready = true
|
||||
end
|
||||
|
||||
self:_update_widget()
|
||||
end
|
||||
)
|
||||
|
||||
-- This is used inside a timer, so return true to keep it running.
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function P:_update_widget()
|
||||
if (not self._ready) then
|
||||
self.widget:set_state("error")
|
||||
self.widget:set_value(self.max_value);
|
||||
self.widget:set_tooltip("Volume error");
|
||||
return
|
||||
end
|
||||
|
||||
self.widget:set_value(self.volume);
|
||||
self.widget:set_tooltip("Volume " .. self.volume .. "%");
|
||||
|
||||
if (self.muted) then
|
||||
self.widget:set_state("muted")
|
||||
else
|
||||
self.widget:set_state("unmuted")
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Simple actions
|
||||
---
|
||||
function P:volume_up()
|
||||
if (not self._ready) or (self.volume >= self.max_value) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --increase 5" .. self:_full_args(), false)
|
||||
wrapper.sound.play("volume_up")
|
||||
self.volume = self.volume + 5
|
||||
if self.volume > self.max_value then
|
||||
self.volume = self.max_value
|
||||
end
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:volume_down()
|
||||
if (not self._ready) or (self.volume <= 0) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --decrease 5" .. self:_full_args(), false)
|
||||
wrapper.sound.play("volume_down")
|
||||
self.volume = self.volume - 5
|
||||
if self.volume < 0 then
|
||||
self.volume = 0
|
||||
end
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:volume_set(value)
|
||||
if (not self._ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
end
|
||||
|
||||
if (value < 0) then
|
||||
value = 0
|
||||
end
|
||||
|
||||
if (value > self.max_value) then
|
||||
value = self.max_value
|
||||
end
|
||||
|
||||
awful.spawn("pamixer --set_volume " .. tostring(value) .. self:_full_args(), false)
|
||||
self.volume = value
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:mute()
|
||||
if (not self._ready) then
|
||||
return
|
||||
end
|
||||
|
||||
self.muted = true
|
||||
awful.spawn("pamixer --mute" .. self:_full_args(), false)
|
||||
v:_update_widget()
|
||||
end
|
||||
|
||||
function P:unmute()
|
||||
if (not self._ready) then
|
||||
return
|
||||
end
|
||||
|
||||
self.muted = false
|
||||
awful.spawn("pamixer --unmute" .. self:_full_args(), false)
|
||||
self:_update_widget()
|
||||
end
|
||||
|
||||
function P:toggle_mute()
|
||||
if (not self._ready) then
|
||||
return
|
||||
end
|
||||
|
||||
if self.muted then
|
||||
self:unmute()
|
||||
else
|
||||
self:mute()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Create new volume_interface
|
||||
---
|
||||
function P:new(args)
|
||||
-- Arguments
|
||||
v = {
|
||||
pa_options = args.cli_options or "",
|
||||
pa_sink = args.pa_sink or "",
|
||||
update_interval = args.update_interal or 5,
|
||||
max_value = args.max_value or 100,
|
||||
widget_type = args.widget_type or "arc",
|
||||
|
||||
|
||||
_ready = false, -- is all the information in this class up-to-date?
|
||||
-- if this is false, ui will show an error and most methods will
|
||||
-- do nothing. Updated in _get_status()
|
||||
}
|
||||
|
||||
-- Create widget for this volume interface
|
||||
v.widget = widget_types[v.widget_type]:new()
|
||||
|
||||
-- Attach button press signals
|
||||
v.widget.widget:connect_signal("button::press",
|
||||
function(_, _, _, button, mods)
|
||||
if (button == 3) then -- Right-click
|
||||
v:toggle_mute()
|
||||
elseif (button == 4) then -- Scroll up
|
||||
v:volume_up()
|
||||
elseif (button == 5) then -- Scroll down
|
||||
v:volume_down()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
setmetatable(v, self)
|
||||
self.__index = self
|
||||
|
||||
-- This timer keeps mute and volume status up-to-date.
|
||||
v.timer = gears.timer {
|
||||
timeout = v.update_interval,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
v:_get_status()
|
||||
end
|
||||
}
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
return P
|
Reference in New Issue
Block a user