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:

{alsa,pulse}bar: added margins/paddings args
[etc/awesome.git] / widget / alsabar.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2013, Luca CPZ
5       * (c) 2013, Rman
6
7 --]]
8
9 local helpers = require("lain.helpers")
10 local awful   = require("awful")
11 local naughty = require("naughty")
12 local wibox   = require("wibox")
13
14 local math, string, type, tonumber = math, string, type, tonumber
15
16 -- ALSA volume bar
17 -- lain.widget.alsabar
18
19 local function factory(args)
20     local alsabar = {
21         colors = {
22             background = "#000000",
23             mute       = "#EB8F8F",
24             unmute     = "#A4CE8A"
25         },
26
27         _current_level = 0,
28         _playback      = "off"
29     }
30
31     local args       = args or {}
32     local timeout    = args.timeout or 5
33     local settings   = args.settings or function() end
34     local width      = args.width or 63
35     local height     = args.height or 1
36     local margins    = args.margins or 1
37     local paddings   = args.paddings or 1
38     local ticks      = args.ticks or false
39     local ticks_size = args.ticks_size or 7
40
41     alsabar.cmd                 = args.cmd or "amixer"
42     alsabar.channel             = args.channel or "Master"
43     alsabar.togglechannel       = args.togglechannel
44     alsabar.colors              = args.colors or alsabar.colors
45     alsabar.followtag           = args.followtag or false
46     alsabar.notification_preset = args.notification_preset
47
48     if not alsabar.notification_preset then
49         alsabar.notification_preset      = {}
50         alsabar.notification_preset.font = "Monospace 10"
51     end
52
53     local format_cmd = string.format("%s get %s", alsabar.cmd, alsabar.channel)
54
55     if alsabar.togglechannel then
56         format_cmd = { awful.util.shell, "-c", string.format("%s get %s; %s get %s",
57         alsabar.cmd, alsabar.channel, alsabar.cmd, alsabar.togglechannel) }
58     end
59
60     alsabar.bar = wibox.widget {
61         color            = alsabar.colors.unmute,
62         background_color = alsabar.colors.background,
63         forced_height    = height,
64         forced_width     = width,
65         margins          = margins,
66         paddings         = margins,
67         ticks            = ticks,
68         ticks_size       = ticks_size,
69         widget           = wibox.widget.progressbar
70     }
71
72     alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
73
74     function alsabar.update(callback)
75         helpers.async(format_cmd, function(mixer)
76             local vol, playback = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
77
78             if not vol or not playback then return end
79
80             if vol ~= alsabar._current_level or playback ~= alsabar._playback then
81                 alsabar._current_level = tonumber(vol)
82                 alsabar.bar:set_value(alsabar._current_level / 100)
83                 if alsabar._current_level == 0 or playback == "off" then
84                     alsabar._playback = playback
85                     alsabar.tooltip:set_text("[Muted]")
86                     alsabar.bar.color = alsabar.colors.mute
87                 else
88                     alsabar._playback = "on"
89                     alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, vol))
90                     alsabar.bar.color = alsabar.colors.unmute
91                 end
92
93                 volume_now = {
94                     level  = alsabar._current_level,
95                     status = alsabar._playback
96                 }
97
98                 settings()
99
100                 if type(callback) == "function" then callback() end
101             end
102         end)
103     end
104
105     function alsabar.notify()
106         alsabar.update(function()
107             local preset = alsabar.notification_preset
108
109             preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
110
111             if alsabar._playback == "off" then
112                 preset.title = preset.title .. " Muted"
113             end
114
115             -- tot is the maximum number of ticks to display in the notification
116             -- fallback: default horizontal wibox height
117             local wib, tot = awful.screen.focused().mywibox, 20
118
119             -- if we can grab mywibox, tot is defined as its height if
120             -- horizontal, or width otherwise
121             if wib then
122                 if wib.position == "left" or wib.position == "right" then
123                     tot = wib.width
124                 else
125                     tot = wib.height
126                 end
127             end
128
129             int = math.modf((alsabar._current_level / 100) * tot)
130             preset.text = string.format("[%s%s]", string.rep("|", int),
131                           string.rep(" ", tot - int))
132
133             if alsabar.followtag then preset.screen = awful.screen.focused() end
134
135             if not alsabar.notification then
136                 alsabar.notification = naughty.notify {
137                     preset  = preset,
138                     destroy = function() alsabar.notification = nil end
139                 }
140             else
141                 naughty.replace_text(alsabar.notification, preset.title, preset.text)
142             end
143         end)
144     end
145
146     helpers.newtimer(string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel), timeout, alsabar.update)
147
148     return alsabar
149 end
150
151 return factory