Merge branch 'add_gears_matrix'
This commit is contained in:
commit
564fae8934
|
@ -16,6 +16,7 @@ return
|
||||||
wallpaper = require("gears.wallpaper");
|
wallpaper = require("gears.wallpaper");
|
||||||
timer = require("gears.timer");
|
timer = require("gears.timer");
|
||||||
cache = require("gears.cache");
|
cache = require("gears.cache");
|
||||||
|
matrix = require("gears.matrix");
|
||||||
}
|
}
|
||||||
|
|
||||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- @author Uli Schlachter
|
||||||
|
-- @copyright 2015 Uli Schlachter
|
||||||
|
-- @release @AWESOME_VERSION@
|
||||||
|
-- @module gears.matrix
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local cairo = require("lgi").cairo
|
||||||
|
local debug = require("gears.debug")
|
||||||
|
local matrix = {}
|
||||||
|
|
||||||
|
--- Copy a cairo matrix
|
||||||
|
-- @param matrix The matrix to copy.
|
||||||
|
-- @return A copy of the given cairo matrix.
|
||||||
|
function matrix.copy(matrix)
|
||||||
|
debug.assert(cairo.Matrix:is_type_of(matrix), "Argument should be a cairo matrix")
|
||||||
|
local ret = cairo.Matrix()
|
||||||
|
ret:init(matrix.xx, matrix.yx, matrix.xy, matrix.yy, matrix.x0, matrix.y0)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if two cairo matrices are equal
|
||||||
|
-- @param m1 The first matrix to compare with.
|
||||||
|
-- @param m2 The second matrix to compare with.
|
||||||
|
-- @return True if they are equal.
|
||||||
|
function matrix.equals(m1, m2)
|
||||||
|
for _, k in pairs{ "xx", "xy", "yx", "yy", "x0", "y0" } do
|
||||||
|
if m1[k] ~= m2[k] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Calculate a bounding rectangle for transforming a rectangle by a matrix.
|
||||||
|
-- @param matrix The cairo matrix that describes the transformation.
|
||||||
|
-- @param x The x coordinate of the rectangle.
|
||||||
|
-- @param y The y coordinate of the rectangle.
|
||||||
|
-- @param width The width of the rectangle.
|
||||||
|
-- @param height The height of the rectangle.
|
||||||
|
-- @return The x, y, width and height of the bounding rectangle.
|
||||||
|
function matrix.transform_rectangle(matrix, x, y, width, height)
|
||||||
|
-- Transform all four corners of the rectangle
|
||||||
|
local x1, y1 = matrix:transform_point(x, y)
|
||||||
|
local x2, y2 = matrix:transform_point(x, y + height)
|
||||||
|
local x3, y3 = matrix:transform_point(x + width, y + height)
|
||||||
|
local x4, y4 = matrix:transform_point(x + width, y)
|
||||||
|
-- Find the extremal points of the result
|
||||||
|
local x = math.min(x1, x2, x3, x4)
|
||||||
|
local y = math.min(y1, y2, y3, y4)
|
||||||
|
local width = math.max(x1, x2, x3, x4) - x
|
||||||
|
local height = math.max(y1, y2, y3, y4) - y
|
||||||
|
|
||||||
|
return x, y, width, height
|
||||||
|
end
|
||||||
|
|
||||||
|
return matrix
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -5,30 +5,13 @@
|
||||||
-- @classmod wibox.layout.base
|
-- @classmod wibox.layout.base
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
local pairs = pairs
|
|
||||||
local xpcall = xpcall
|
local xpcall = xpcall
|
||||||
local print = print
|
local print = print
|
||||||
local min = math.min
|
|
||||||
local max = math.max
|
|
||||||
local cairo = require("lgi").cairo
|
local cairo = require("lgi").cairo
|
||||||
|
local wbase = require("wibox.widget.base")
|
||||||
|
|
||||||
local base = {}
|
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
|
--- Fit a widget for the given available width and height
|
||||||
-- @param context The context in which we are fit.
|
-- @param context The context in which we are fit.
|
||||||
-- @param widget The widget to fit (this uses widget:fit(width, height)).
|
-- @param widget The widget to fit (this uses widget:fit(width, height)).
|
||||||
|
@ -85,7 +68,7 @@ function base.draw_widget(context, cr, widget, x, y, width, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register the widget for input handling
|
-- Register the widget for input handling
|
||||||
context:widget_at(widget, base.rect_to_device_geometry(cr, 0, 0, width, height))
|
context:widget_at(widget, wbase.rect_to_device_geometry(cr, 0, 0, width, height))
|
||||||
|
|
||||||
cr:restore()
|
cr:restore()
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
local debug = require("gears.debug")
|
local debug = require("gears.debug")
|
||||||
local object = require("gears.object")
|
local object = require("gears.object")
|
||||||
local cache = require("gears.cache")
|
local cache = require("gears.cache")
|
||||||
|
local matrix = require("gears.matrix")
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local type = type
|
local type = type
|
||||||
|
@ -15,6 +16,12 @@ local table = table
|
||||||
|
|
||||||
local base = {}
|
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)
|
||||||
|
return matrix.transform_rectangle(cr.matrix, x, y, width, height)
|
||||||
|
end
|
||||||
|
|
||||||
--- Set/get a widget's buttons
|
--- Set/get a widget's buttons
|
||||||
function base:buttons(_buttons)
|
function base:buttons(_buttons)
|
||||||
if _buttons then
|
if _buttons then
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
local wbase = require("wibox.widget.base")
|
local wbase = require("wibox.widget.base")
|
||||||
local lbase = require("wibox.layout.base")
|
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
local capi = { awesome = awesome }
|
local capi = { awesome = awesome }
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
|
@ -20,7 +19,7 @@ local base_size = nil
|
||||||
local reverse = false
|
local reverse = false
|
||||||
|
|
||||||
function systray:draw(context, cr, width, height)
|
function systray:draw(context, cr, width, height)
|
||||||
local x, y, _, _ = lbase.rect_to_device_geometry(cr, 0, 0, width, height)
|
local x, y, _, _ = wbase.rect_to_device_geometry(cr, 0, 0, width, height)
|
||||||
local num_entries = capi.awesome.systray()
|
local num_entries = capi.awesome.systray()
|
||||||
local bg = beautiful.bg_systray or beautiful.bg_normal or "#000000"
|
local bg = beautiful.bg_systray or beautiful.bg_normal or "#000000"
|
||||||
local spacing = beautiful.systray_icon_spacing or 0
|
local spacing = beautiful.systray_icon_spacing or 0
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- @author Uli Schlachter
|
||||||
|
-- @copyright 2015 Uli Schlachter
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local matrix = require("gears.matrix")
|
||||||
|
local cairo = require("lgi").cairo
|
||||||
|
|
||||||
|
describe("gears.matrix", function()
|
||||||
|
describe("copy", function()
|
||||||
|
it("Test copy", function()
|
||||||
|
local m1 = cairo.Matrix()
|
||||||
|
m1:init(1, 2, 3, 4, 5, 6)
|
||||||
|
local m2 = matrix.copy(m1)
|
||||||
|
assert.is.equal(m1.xx, m2.xx)
|
||||||
|
assert.is.equal(m1.xy, m2.xy)
|
||||||
|
assert.is.equal(m1.yx, m2.yx)
|
||||||
|
assert.is.equal(m1.yy, m2.yy)
|
||||||
|
assert.is.equal(m1.x0, m2.x0)
|
||||||
|
assert.is.equal(m1.y0, m2.y0)
|
||||||
|
|
||||||
|
m1.x0 = 42
|
||||||
|
assert.is_not.equal(m1.x0, m2.x0)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("equals", function()
|
||||||
|
it("Same matrix", function()
|
||||||
|
local m = cairo.Matrix.create_rotate(1)
|
||||||
|
assert.is_true(matrix.equals(m, m))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Different matrix equals", function()
|
||||||
|
local m1 = cairo.Matrix.create_rotate(1)
|
||||||
|
local m2 = cairo.Matrix.create_rotate(1)
|
||||||
|
assert.is_true(matrix.equals(m1, m2))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Different matrix unequal", function()
|
||||||
|
local m1 = cairo.Matrix()
|
||||||
|
local m2 = cairo.Matrix()
|
||||||
|
m1:init(1, 2, 3, 4, 5, 6)
|
||||||
|
m2:init(1, 2, 3, 4, 5, 0)
|
||||||
|
assert.is_false(matrix.equals(m1, m2))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("transform_rectangle", function()
|
||||||
|
local function round(n)
|
||||||
|
return math.floor(n + 0.5)
|
||||||
|
end
|
||||||
|
local function test(m, x, y, width, height,
|
||||||
|
expected_x, expected_y, expected_width, expected_height)
|
||||||
|
local actual_x, actual_y, actual_width, actual_height =
|
||||||
|
matrix.transform_rectangle(m, x, y, width, height)
|
||||||
|
assert.is.equal(round(actual_x), expected_x)
|
||||||
|
assert.is.equal(round(actual_y), expected_y)
|
||||||
|
assert.is.equal(round(actual_width), expected_width)
|
||||||
|
assert.is.equal(round(actual_height), expected_height)
|
||||||
|
-- Stupid rounding issues...
|
||||||
|
assert.is_true(math.abs(round(actual_x) - actual_x) < 0.00000001)
|
||||||
|
assert.is_true(math.abs(round(actual_y) - actual_y) < 0.00000001)
|
||||||
|
assert.is_true(math.abs(round(actual_width) - actual_width) < 0.00000001)
|
||||||
|
assert.is_true(math.abs(round(actual_height) - actual_height) < 0.00000001)
|
||||||
|
end
|
||||||
|
it("Identity matrix", function()
|
||||||
|
test(cairo.Matrix.create_identity(), 1, 2, 3, 4, 1, 2, 3, 4)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Rotate 180", function()
|
||||||
|
test(cairo.Matrix.create_rotate(math.pi),
|
||||||
|
1, 2, 3, 4, -4, -6, 3, 4)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Rotate 90", function()
|
||||||
|
test(cairo.Matrix.create_rotate(math.pi / 2),
|
||||||
|
1, 2, 3, 4, -6, 1, 4, 3)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
Loading…
Reference in New Issue