awesome/lib/wibox/layout/base.lua

96 lines
3.1 KiB
Lua
Raw Normal View History

---------------------------------------------------------------------------
-- @author Uli Schlachter
-- @copyright 2010 Uli Schlachter
-- @release @AWESOME_VERSION@
-- @classmod wibox.layout.base
---------------------------------------------------------------------------
local pairs = pairs
local xpcall = xpcall
local print = print
local min = math.min
local max = math.max
local cairo = require("lgi").cairo
local base = {}
--- Figure out the geometry in device coordinate space. This gives only tight
-- bounds if no rotations by non-multiples of 90° are used.
function base.rect_to_device_geometry(cr, x, y, width, height)
local x1, y1 = cr:user_to_device(x, y)
local x2, y2 = cr:user_to_device(x, y + height)
local x3, y3 = cr:user_to_device(x + width, y + height)
local x4, y4 = cr:user_to_device(x + width, y)
local x = min(x1, x2, x3, x4)
local y = min(y1, y2, y3, y4)
local width = max(x1, x2, x3, x4) - x
local height = max(y1, y2, y3, y4) - y
return x, y, width, height
end
--- Fit a widget for the given available width and height
-- @param context The context in which we are fit.
-- @param widget The widget to fit (this uses widget:fit(width, height)).
-- @param width The available width for the widget
-- @param height The available height for the widget
-- @return The width and height that the widget wants to use
function base.fit_widget(context, widget, width, height)
if not widget.visible then
return 0, 0
end
-- Sanitize the input. This also filters out e.g. NaN.
local width = math.max(0, width)
local height = math.max(0, height)
return widget._fit_geometry_cache:get(context, width, height)
end
--- Draw a widget via a cairo context
-- @param context The context in which we are drawn.
-- @param cr The cairo context used
-- @param widget The widget to draw (this uses widget:draw(cr, width, height)).
-- @param x The position that the widget should get
-- @param y The position that the widget should get
-- @param width The widget's width
-- @param height The widget's height
function base.draw_widget(context, cr, widget, x, y, width, height)
if not widget.visible then
return
end
-- Use save() / restore() so that our modifications aren't permanent
cr:save()
-- Move (0, 0) to the place where the widget should show up
cr:translate(x, y)
-- Make sure the widget cannot draw outside of the allowed area
cr:rectangle(0, 0, width, height)
cr:clip()
if widget.opacity ~= 1 then
cr:push_group()
end
-- Let the widget draw itself
xpcall(function()
widget:draw(context, cr, width, height)
end, function(err)
print(debug.traceback("Error while drawing widget: "..tostring(err), 2))
end)
if widget.opacity ~= 1 then
cr:pop_group_to_source()
cr.operator = cairo.Operator.OVER
cr:paint_with_alpha(widget.opacity)
end
-- Register the widget for input handling
context:widget_at(widget, base.rect_to_device_geometry(cr, 0, 0, width, height))
cr:restore()
end
return base
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80