local M = require "quarrel.ui.consts" local awful = require "awful" local gshape = require "gears.shape" local gtable = require "gears.table" local qbind = require "quarrel.bind" local qcolor = require "quarrel.color" local wibox = require "wibox" --- Clip Cairo context ---@param cr cairo_surface Cairo surface ---@param w integer Widget width ---@param h integer Widget height ---@return nil function M.shape(cr, w, h) -- gears.shape.rounded_rect(cr, w, h, dpi(4)) gshape.rounded_rect(cr, w, h, M.BORDER_RADIUS) -- gshape.rectangle(cr, w, h) end --- Returns qvars.text_font with size scaled by factor ---@param factor number? ---@return string function M.font(factor) return M.TEXT_FONT .. " " .. M.FONT_SIZE * (factor or 1) end --- Injects background widget styling into target ---@param target table ---@return table function M.styled(target) return gtable.crush({ bg = qcolor.palette.bg(), border_color = qcolor.palette.border(), border_width = M.BORDER_WIDTH, shape = M.shape, }, target) end --- Generates a styled popup ---@param target table ---@return table function M.popup(target, debug) target.widget = { widget = wibox.container.margin, margins = M.BIG_PADDING, target.widget, } return awful.popup(M.styled(target)) end --- Generates svg recolor string ---@param color string ---@return string function M.recolor(color) return "svg{fill:" .. color .. "}" end --- Generates icon widget ---@param args table ---@return table function M.icon(args) return wibox.widget(gtable.crush({ widget = wibox.widget.imagebox, image = args.icon, forced_width = (not args.unsized) and M.CHAR_HEIGHT, forced_height = (not args.unsized) and M.CHAR_HEIGHT, stylesheet = M.recolor(args.color or qcolor.palette.fg()), }, args.widget or {})) end --- Generates button widget ---@param args table ---@return table function M.button(args) args.press = args.press or function(_) end local widget = wibox.widget(gtable.crush({ widget = wibox.widget.imagebox, image = args.icon, forced_height = M.CHAR_HEIGHT, forced_width = M.CHAR_HEIGHT, stylesheet = M.recolor(qcolor.palette.fg()), press = args.press, }, args.widget or {})) widget.buttons = { qbind { triggers = qbind.btns.left, press = function() widget:press() end, hidden = true, }, } return widget end --- Generates toggle widget ---@param args table ---@return table function M.toggle(args) args.press = args.press or function(_) end local widget = M.button { widget = gtable.crush({ toggled = false, silent_press = function(self, state) if state then self.toggled = state else self.toggled = not self.toggled end if self.toggled then self.image = args.on else self.image = args.off end end, }, args.widget or {}), icon = args.off, press = function(self) if not args.manual then self:silent_press() end args.press(self) end, } return widget end ---@param widget wibox.widget.base ---@param cursor string ---@return wibox.widget.base function M.hoverable(widget, cursor) local last_wibox widget:connect_signal("mouse::enter", function() local w = mouse.current_wibox last_wibox = w if w then w.cursor = cursor end if type(widget.hover) == "function" then -- on enter bind widget.hover() elseif type(widget.hover) == "table" and widget.hover.enter then -- { enter: fun(), leave: fun() } widget.hover.enter() end end) widget:connect_signal("mouse::leave", function() local w = last_wibox or mouse.current_wibox if w then w.cursor = "left_ptr" end if type(widget.hover) == "table" and widget.hover.leave then -- { enter: fun(), leave: fun() } widget.hover.leave() end end) return widget end return M