grid.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. -- @author cedlemo
  2. --
  3. --
  4. local base = require("wibox.layout.base")
  5. local widget_base = require("wibox.widget.base")
  6. local table = table
  7. local pairs = pairs
  8. local floor = math.floor
  9. local wibox = require('wibox')
  10. local helpers = require('blingbling.helpers')
  11. local grid = { mt = {} }
  12. local data = setmetatable({}, { __mode = "k" })
  13. local function round(x)
  14. return floor(x + 0.5)
  15. end
  16. function grid:draw(wibox, cr, width, height)
  17. local median_width = floor(width / data[self].num_columns)
  18. local median_height = floor(height / data[self].num_lines)
  19. local pos = 0
  20. for _, d in pairs(data[self].widgets) do
  21. local x, y, w, h
  22. x = round(median_width * (d.left - 1))
  23. y = round(median_height * (d.top - 1))
  24. w = floor(median_width * d.cols)
  25. h = floor(median_height * d.lines)
  26. -- Keep for widget debug
  27. -- str = "x " .. tostring(x) .. " y ".. tostring(y) .. " w " .. tostring(w) .. " h " .. tostring(h)
  28. -- print("width " .. tostring(width) .. "height " .. tostring(height))
  29. -- print("columns ".. tostring(data[self].num_columns) .. "median_width ".. tostring(median_width))
  30. -- print("lines ".. tostring(data[self].num_lines) .. "median_height ".. tostring(median_height))
  31. -- print(str)
  32. base.draw_widget(wibox, cr, d.widget, x, y, w, h)
  33. end
  34. end
  35. local function matrix_add(matrix, object, x, y, w, h)
  36. for i = 1, (y - 1) do
  37. if matrix[i] == nil then matrix[i] = {} end
  38. end
  39. for i=0, (h - 1) do
  40. if matrix[y + i] == nil then matrix[y + i] = {} end
  41. local line = matrix[y + i]
  42. if #line < x - 1 then
  43. for j = #line + 1, (x - 1) do
  44. table.insert(line, j, "-")
  45. end
  46. end
  47. for j=0,(w -1) do
  48. table.insert(line, x + j, object)
  49. end
  50. end
  51. end
  52. function grid:add_child(child, left, top, n_cols, n_lines)
  53. widget_base.check_widget(child)
  54. matrix_add(data[self].matrix, child, left, top, n_cols, n_lines)
  55. local widget_data = {}
  56. widget_data.widget = child
  57. widget_data.left = left
  58. widget_data.top = top
  59. widget_data.cols = n_cols
  60. widget_data.lines = n_lines
  61. table.insert(data[self].widgets, widget_data)
  62. if data[self].num_lines < n_lines + (top - 1) then
  63. data[self].num_lines = n_lines + (top - 1)
  64. end
  65. if data[self].num_columns < n_cols + (left - 1) then
  66. data[self].num_columns = n_cols + (left - 1)
  67. end
  68. child:connect_signal("widget::updated", self._emit_updated)
  69. self._emit_updated()
  70. end
  71. function grid:get_child(left, top)
  72. return data[self].matrix[left][top]
  73. end
  74. function grid:set_padding(padding)
  75. end
  76. function grid.new()
  77. local _grid = widget_base.make_widget()
  78. data[_grid] = {}
  79. data[_grid].matrix = {} -- Used a map for access through get_child
  80. data[_grid].widgets = {}
  81. data[_grid].num_lines = 0
  82. data[_grid].num_columns = 0
  83. _grid._emit_updated = function()
  84. _grid:emit_signal("widget::updated")
  85. end
  86. _grid.add_child = grid.add_child
  87. _grid.get_child = grid.get_child
  88. _grid.set_padding = grid.set_padding
  89. _grid.draw = grid.draw
  90. return _grid
  91. end
  92. function grid.mt:__call(...)
  93. return grid.new(...)
  94. end
  95. return setmetatable(grid, grid.mt)