Skip to content

Instantly share code, notes, and snippets.

@SkyyySi
Created January 26, 2023 16:50
Show Gist options
  • Save SkyyySi/9370c3f840a00e3c2c8f7365977478fb to your computer and use it in GitHub Desktop.
Save SkyyySi/9370c3f840a00e3c2c8f7365977478fb to your computer and use it in GitHub Desktop.
A wibox.container for turning any widget into a button. For awesomewm.
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
---@class wibox.container.button : wibox.container.background
---@operator call(table): wibox.container.button._instance
---@field private _private table
local button = {}
button.mt = {}
setmetatable(button, button.mt)
button.__index = button
button.mt.__index = button.mt
---@class wibox.container.button._instance : wibox.container.button
function button:set_on_click(value) self._private.on_click = value end
function button:set_bg_normal(value) self._private.bg_normal = value end
function button:set_bg_hover(value) self._private.bg_hover = value end
function button:set_bg_press(value) self._private.bg_press = value end
function button:set_bg_release(value) self._private.bg_release = value end
function button:set_callback_normal(value) self._private.callback_normal = value end
function button:set_callback_hover(value) self._private.callback_hover = value end
function button:set_callback_press(value) self._private.callback_press = value end
function button:set_callback_release(value) self._private.callback_release = value end
function button:set_use_mouse_effects(value) self._private.use_mouse_effects = value end
---@return wibox.container.button._instance
function button.new(args)
args = args or {}
---@type wibox.container.button._instance
local widget = gears.table.crush(wibox.container.background(), button, true)
--- If you just want to do something on click, use `on_click()` instead of
--- using the callbacks below. They are only intended for deeper control.
if args.on_click ~= nil then widget:set_on_click(args.on_click) else widget:set_on_click(function(self, b) end) end
if args.bg_normal ~= nil then widget:set_bg_normal(args.bg_normal) else widget:set_bg_normal( beautiful.button_normal or "#FFFFFF00") end
if args.bg_hover ~= nil then widget:set_bg_hover(args.bg_hover) else widget:set_bg_hover( beautiful.button_hover or "#FFFFFF20") end
if args.bg_press ~= nil then widget:set_bg_press(args.bg_press) else widget:set_bg_press( beautiful.button_press or "#FFFFFF40") end
if args.bg_release ~= nil then widget:set_bg_release(args.bg_release) else widget:set_bg_release(beautiful.button_release or "#FFFFFF20") end
if args.callback_normal ~= nil then widget:set_callback_normal(args.callback_normal) else widget:set_callback_normal( function(self, color) self.bg = color end) end
if args.callback_hover ~= nil then widget:set_callback_hover(args.callback_hover) else widget:set_callback_hover( function(self, color) self.bg = color end) end
if args.callback_press ~= nil then widget:set_callback_press(args.callback_press) else widget:set_callback_press( function(self, color, b) self.bg = color end) end
if args.callback_release ~= nil then widget:set_callback_release(args.callback_release) else widget:set_callback_release(function(self, color, b) self.bg = color end) end
if args.use_mouse_effects ~= nil then widget:set_use_mouse_effects(args.use_mouse_effects) else widget:set_use_mouse_effects(beautiful.button_use_mouse_effects or true) end
widget._private.is_being_pressed = false
local old_cursor, old_wibox
widget:connect_signal("mouse::enter", function(self)
self._private.callback_hover(self, self._private.bg_hover)
if self._private.use_mouse_effects then
local wb = mouse.current_wibox or {}
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
end
end)
widget:connect_signal("mouse::leave", function(self)
self._private.callback_normal(self, self._private.bg_normal)
if self._private.use_mouse_effects and old_wibox then
old_wibox.cursor = old_cursor
old_cursor, old_wibox = nil, nil
end
end)
widget:connect_signal("button::press", function(self, _, _, b)
self._private.is_being_pressed = true
self._private.callback_press(self, self._private.bg_press)
end)
widget:connect_signal("button::release", function(self, _, _, b)
if self._private.is_being_pressed then
self._private.on_click(self, b)
end
self._private.is_being_pressed = false
self._private.callback_release(self, self._private.bg_release)
end)
return gears.table.crush(widget, args, true)
end
function button.mt:__call(...)
return self.new(...)
end
return button
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment