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:

widgets: no global tables, but one instance per call; closes #336; closes #337
[etc/awesome.git] / widget / alsabar.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                          rep    = string.rep }
18 local type, tonumber = type, tonumber
19
20 -- ALSA volume bar
21 -- lain.widget.alsabar
22
23 local function factory(args)
24     local alsabar = {
25         colors = {
26             background = "#000000",
27             mute       = "#EB8F8F",
28             unmute     = "#A4CE8A"
29         },
30
31         _current_level = 0,
32         _muted         = false
33     }
34
35     local args       = args or {}
36     local timeout    = args.timeout or 5
37     local settings   = args.settings or function() end
38     local width      = args.width or 63
39     local height     = args.height or 1
40     local ticks      = args.ticks or false
41     local ticks_size = args.ticks_size or 7
42
43     alsabar.cmd                 = args.cmd or "amixer"
44     alsabar.channel             = args.channel or "Master"
45     alsabar.togglechannel       = args.togglechannel
46     alsabar.colors              = args.colors or alsabar.colors
47     alsabar.followtag           = args.followtag or false
48     alsabar.notification_preset = args.notification_preset
49
50     if not alsabar.notification_preset then
51         alsabar.notification_preset      = {}
52         alsabar.notification_preset.font = "Monospace 10"
53     end
54
55     local format_cmd = string.format("%s get %s", alsabar.cmd, alsabar.channel)
56
57     if alsabar.togglechannel then
58         format_cmd = { awful.util.shell, "-c", string.format("%s get %s; %s get %s",
59         alsabar.cmd, alsabar.channel, alsabar.cmd, alsabar.togglechannel) }
60     end
61
62     alsabar.bar = wibox.widget {
63         forced_height    = height,
64         forced_width     = width,
65         color            = alsabar.colors.unmute,
66         background_color = alsabar.colors.background,
67         margins          = 1,
68         paddings         = 1,
69         ticks            = ticks,
70         ticks_size       = ticks_size,
71         widget           = wibox.widget.progressbar
72     }
73
74     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
75
76     function alsabar.update(callback)
77         helpers.async(format_cmd, function(mixer)
78             local volu,mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
79             if (volu and tonumber(volu) ~= alsabar._current_level) or (mute and string.match(mute, "on") ~= alsabar._muted) then
80                 alsabar._current_level = tonumber(volu) or alsabar._current_level
81                 alsabar.bar:set_value(alsabar._current_level / 100)
82                 if (not mute and tonumber(volu) == 0) or mute == "off" then
83                     alsabar._muted = true
84                     alsabar.tooltip:set_text ("[Muted]")
85                     alsabar.bar.color = alsabar.colors.mute
86                 else
87                     alsabar._muted = false
88                     alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, volu))
89                     alsabar.bar.color = alsabar.colors.unmute
90                 end
91
92                 volume_now = {}
93                 volume_now.level = tonumber(volu)
94                 volume_now.status = mute
95
96                 settings()
97
98                 if type(callback) == "function" then callback() end
99             end
100         end)
101     end
102
103     function alsabar.notify()
104         alsabar.update(function()
105             local preset = alsabar.notification_preset
106
107             if alsabar._muted then
108                 preset.title = string.format("%s - Muted", alsabar.channel)
109             else
110                 preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
111             end
112
113             int = math.modf((alsabar._current_level / 100) * awful.screen.focused().mywibox.height)
114             preset.text = string.format("[%s%s]", string.rep("|", int),
115                           string.rep(" ", awful.screen.focused().mywibox.height - int))
116
117             if alsabar.followtag then preset.screen = awful.screen.focused() end
118
119             if not alsabar.notification then
120                 alsabar.notification = naughty.notify {
121                     preset  = preset,
122                     destroy = function() alsabar.notification = nil end
123                 }
124             else
125                 naughty.replace_text(alsabar.notification, preset.title, preset.text)
126             end
127         end)
128     end
129
130     helpers.newtimer(string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel), timeout, alsabar.update)
131
132     return alsabar
133 end
134
135 return factory