summaryrefslogtreecommitdiff
path: root/widgets/volumedropdown.lua
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/volumedropdown.lua')
-rw-r--r--widgets/volumedropdown.lua195
1 files changed, 195 insertions, 0 deletions
diff --git a/widgets/volumedropdown.lua b/widgets/volumedropdown.lua
new file mode 100644
index 0000000..dad20eb
--- /dev/null
+++ b/widgets/volumedropdown.lua
@@ -0,0 +1,195 @@
+local awful = require("awful")
+local wibox = require("wibox")
+local beautiful = require("beautiful")
+local apply_dpi = beautiful.xresources.apply_dpi
+local pavolctld = require("lib.pavolctld")
+
+-- return table
+local widget = {}
+
+widget.dbmeter = wibox.widget.textbox("-999.99 dB") -- max width text
+local dbmeter_maxwidth, _ = widget.dbmeter:get_preferred_size_at_dpi(beautiful.xresources.get_dpi()) -- max width, TODO per screen dpi
+dbmeter_maxwidth = dbmeter_maxwidth * 1.5 -- ???
+
+local slider = wibox.widget {
+ bar_height = 0,
+ widget = wibox.widget.slider,
+ maximum = pavolctld.max_volume,
+}
+local progressbar = wibox.widget {
+ max_value = pavolctld.max_volume,
+ shape = beautiful.slider_bar_shape,
+ bg = beautiful.slider_handle_color,
+ widget = wibox.widget.progressbar,
+}
+widget.vslider = wibox.widget {
+ {
+ {
+ progressbar,
+ height = apply_dpi(3),
+ widget = wibox.container.constraint
+ },
+ halign = "center",
+ widget = wibox.container.place,
+ },
+ slider,
+ layout = wibox.layout.stack,
+}
+
+-- scrollbox for default sink select
+widget.defsink = wibox.widget.textbox()
+local default_sink_scrollbox = wibox.widget {
+ widget.defsink,
+ step_function = wibox.container.scroll.step_functions.linear_increase,
+ speed = apply_dpi(15),
+ extra_space = apply_dpi(25), -- space between repetition
+ pause = true, -- start paused
+ widget = wibox.container.scroll.horizontal,
+}
+
+local muted = wibox.widget {
+ color = "#222222",
+ check_color = beautiful.border_focus,
+ forced_width = apply_dpi(20),
+ widget = wibox.widget.checkbox,
+}
+
+-- widget dropdown
+local volume_dropdown = wibox.widget {
+ {
+ {
+ {
+ default_sink_scrollbox,
+ margins = beautiful.margin_topbottom,
+ widget = wibox.container.margin,
+ },
+ bg = "#333333",
+ widget = wibox.container.background,
+ },
+ margins = beautiful.border_width,
+ color = "#222222",
+ widget = wibox.container.margin,
+ },
+ {
+ {
+ {
+ {
+ {
+ text = "Mute:",
+ widget = wibox.widget.textbox,
+ },
+ left = apply_dpi(5),
+ right = apply_dpi(5),
+ widget = wibox.container.margin,
+ },
+ fill_vertical = true,
+ widget = wibox.container.place,
+ },
+ {
+ muted,
+ fill_vertical = true,
+ widget = wibox.container.place,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ fill_vertical = true,
+ widget = wibox.container.place,
+ },
+ widget.vslider,
+ {
+ widget.dbmeter,
+ halign = "right",
+ forced_width = dbmeter_maxwidth,
+ widget = wibox.container.place,
+ },
+ forced_num_cols = 2,
+ forced_num_rows = 2,
+ homogeneous = false,
+ expand = true,
+ forced_width = apply_dpi(300),
+ forced_height = apply_dpi(60),
+ layout = wibox.layout.grid,
+}
+widget.dropdown = awful.popup {
+ widget = {
+ volume_dropdown,
+ left = beautiful.margin_leftright,
+ right = beautiful.margin_leftright,
+ top = beautiful.margin_topbottom,
+ bottom = beautiful.margin_topbottom,
+ widget = wibox.container.margin,
+ },
+ border_color = beautiful.border_normal,
+ border_width = beautiful.border_width,
+ ontop = true,
+ hide_on_right_click = true,
+ preferred_positions = "bottom",
+ preferred_anchors = "back",
+ visible = false,
+}
+
+function widget.set_volume(vol, mute)
+ progressbar:set_value(vol)
+ muted.checked = mute
+ if vol == slider.value then return end
+ slider.value = vol
+ if widget.dropdown.visible then
+ slider:emit_signal("widget::redraw_needed")
+ end
+end
+
+-- slider
+slider:buttons(volume_buttons)
+slider:connect_signal("property::value", function()
+ if pavolctld.sinks.default.vol == slider.value then return end
+ widget.dropdown.visible = true -- make sure widget isn't hidden
+ pavolctld.volume_set(slider.value)
+end)
+
+-- scroll when hovering
+default_sink_scrollbox:connect_signal("mouse::enter", function()
+ default_sink_scrollbox:continue()
+end)
+
+default_sink_scrollbox:connect_signal("mouse::leave", function()
+ default_sink_scrollbox:pause()
+ default_sink_scrollbox:reset_scrolling()
+end)
+
+-- change sink
+default_sink_scrollbox:connect_signal("button::press", function()
+ widget.dropdown.visible = true -- make sure widget isn't hidden
+
+ local g = mouse.current_widget_geometry -- relative to widget.dropdown
+ local menugeo = {
+ x = widget.dropdown.x + g.x - beautiful.margin_topbottom,
+ y = widget.dropdown.y + g.y + g.height + beautiful.margin_topbottom + (beautiful.border_width * 2),
+ width = g.width + beautiful.margin_topbottom * 2,
+ }
+ local menuopts = { items = {}, theme = menugeo }
+ for i, s in pairs(pavolctld.sinks.sinks) do
+ table.insert(menuopts.items, {
+ s.desc,
+ function() pavolctld.default_sink_set(i) end
+ })
+ end
+
+ if widget.menu then widget.menu:hide() end
+ widget.menu = awful.menu(menuopts) -- old menu dereferenced, should be cleaned up by gc
+ widget.menu:show({ coords = menugeo })
+end)
+
+widget.dropdown:connect_signal("property::visible", function()
+ if widget.menu then
+ widget.menu:hide()
+ widget.menu = nil
+ end
+end)
+
+-- mute button
+muted:connect_signal("button::press", function()
+ widget.dropdown.visible = true -- make sure widget isn't hidden
+ pavolctld.mute_toggle()
+end)
+
+return widget