]> git.madduck.net Git - etc/awesome.git/blob - widget/pulsebar.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

contrib.gpmdp: instantiate in factory
[etc/awesome.git] / widget / pulsebar.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013, Luke Bonham                     
6       * (c) 2013, Rman                            
7                                                   
8 --]]
9
10 local helpers        = require("lain.helpers")
11 local awful          = require("awful")
12 local naughty        = require("naughty")
13 local wibox          = require("wibox")
14 local math           = { modf   = math.modf }
15 local string         = { format = string.format,
16                          match  = string.match,
17                          gmatch = string.gmatch,
18                          rep    = string.rep }
19 local type, tonumber = type, tonumber
20
21 -- Pulseaudio volume bar
22 -- lain.widget.pulsebar
23
24 local function factory(args)
25     local pulsebar = {
26         colors = {
27             background = "#000000",
28             mute       = "#EB8F8F",
29             unmute     = "#A4CE8A"
30         },
31
32         _current_level = 0,
33         _muted         = false
34     }
35
36     local args       = args or {}
37     local timeout    = args.timeout or 5
38     local settings   = args.settings or function() end
39     local width      = args.width or 63
40     local height     = args.heigth or 1
41     local ticks      = args.ticks or false
42     local ticks_size = args.ticks_size or 7
43     local scallback  = args.scallback
44
45     pulsebar.cmd           = args.cmd or "pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
46     pulsebar.sink          = args.sink or 0
47     pulsebar.colors        = args.colors or pulsebar.colors
48     pulsebar.followtag     = args.followtag or false
49     pulsebar.notifications = args.notification_preset
50     pulsebar.device        = "N/A"
51
52     if not pulsebar.notification_preset then
53         pulsebar.notification_preset      = {}
54         pulsebar.notification_preset.font = "Monospace 10"
55     end
56
57     pulsebar.bar = wibox.widget {
58         forced_height    = height,
59         forced_width     = width,
60         color            = pulsebar.colors.unmute,
61         background_color = pulsebar.colors.background,
62         margins          = 1,
63         paddings         = 1,
64         ticks            = ticks,
65         ticks_size       = ticks_size,
66         widget           = wibox.widget.progressbar,
67     }
68
69     pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
70
71     function pulsebar.update(callback)
72         if scallback then pulsebar.cmd = scallback() end
73
74         helpers.async({ awful.util.shell, "-c", pulsebar.cmd }, function(s)
75             volume_now = {
76                 index = string.match(s, "index: (%S+)") or "N/A",
77                 sink  = string.match(s, "device.string = \"(%S+)\"") or "N/A",
78                 muted = string.match(s, "muted: (%S+)") or "N/A"
79             }
80
81             pulsebar.device = volume_now.index
82
83             local ch = 1
84             volume_now.channel = {}
85             for v in string.gmatch(s, ":.-(%d+)%%") do
86               volume_now.channel[ch] = v
87               ch = ch + 1
88             end
89
90             volume_now.left  = volume_now.channel[1] or "N/A"
91             volume_now.right = volume_now.channel[2] or "N/A"
92
93             local volu = volume_now.left
94             local mute = volume_now.muted
95
96             if (volu and volu ~= pulsebar._current_level) or (mute and mute ~= pulsebar._muted) then
97                 pulsebar._current_level = volu
98                 pulsebar.bar:set_value(pulsebar._current_level / 100)
99                 if (not mute and volu == 0) or mute == "yes" then
100                     pulsebar._muted = true
101                     pulsebar.tooltip:set_text ("[Muted]")
102                     pulsebar.bar.color = pulsebar.colors.mute
103                 else
104                     pulsebar._muted = false
105                     pulsebar.tooltip:set_text(string.format("%s: %s", pulsebar.sink, volu))
106                     pulsebar.bar.color = pulsebar.colors.unmute
107                 end
108
109                 settings()
110
111                 if type(callback) == "function" then callback() end
112             end
113         end)
114     end
115
116     function pulsebar.notify()
117         pulsebar.update(function()
118             local preset = pulsebar.notification_preset
119
120             if pulsebar._muted then
121                 preset.title = string.format("Sink %s - Muted", pulsebar.sink)
122             else
123                 preset.title = string.format("%s - %s%%", pulsebar.sink, pulsebar._current_level)
124             end
125
126             int = math.modf((pulsebar._current_level / 100) * awful.screen.focused().mywibox.height)
127             preset.text = string.format("[%s%s]", string.rep("|", int),
128                           string.rep(" ", awful.screen.focused().mywibox.height - int))
129
130             if pulsebar.followtag then preset.screen = awful.screen.focused() end
131
132             if not pulsebar.notification then
133                 pulsebar.notification = naughty.notify {
134                     preset  = preset,
135                     destroy = function() pulsebar.notification = nil end
136                 }
137             else
138                 naughty.replace_text(pulsebar.notification, preset.title, preset.text)
139             end
140         end)
141     end
142
143     helpers.newtimer(string.format("pulsebar-%s", pulsebar.sink), timeout, pulsebar.update)
144
145     return pulsebar
146 end
147
148 return setmetatable(pulsebar, { __call = function(_, ...) return factory(...) end })