diff options
Diffstat (limited to 'widgets/volumedropdown.lua')
-rw-r--r-- | widgets/volumedropdown.lua | 195 |
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 |