utils.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. local utils = {}
  2. local _floor = math.floor
  3. local _ceil = math.ceil
  4. local _min, _max = math.min, math.max
  5. utils.int = _floor -- works better for pixel coords
  6. utils.max = _max
  7. utils.min = _min
  8. utils.trim = function(x) return x > 0 and _floor(x) or _ceil(x) end
  9. utils.round = function(x) return x > 0 and _floor(x + 0.5) or _ceil(x - 0.5) end
  10. utils.clamp = function(x, a, b)
  11. if x < a then return a end
  12. if x > b then return b end
  13. return x
  14. end
  15. utils.newbox = function(name, x, y, width, height)
  16. x, y = (x or 0), (y or 0)
  17. width, height = (width or 0), (height or 0)
  18. return {name = name, x = x, y = y, width = width, height = height}
  19. end
  20. utils.setbox = function(box, x, y, width, height)
  21. box.x, box.y = x, y
  22. box.width, box.height = width, height
  23. return box
  24. end
  25. utils.includesPoint = function(box, x, y)
  26. local diffx, diffy = x - box.x, y - box.y
  27. return diffx >= 0 and diffx < box.width and
  28. diffy >= 0 and diffy < box.height
  29. end
  30. utils.includesBox = function(boxA, boxB)
  31. local diffx, diffy = boxB.x - boxA.x, boxB.y - boxA.y
  32. return diffx >= 0 and diffx + boxB.width < boxA.width and
  33. diffy >= 0 and diffy + boxB.height < boxA.height
  34. end
  35. utils.intersectsRect = function(boxA, x, y, width, height)
  36. local diffx, diffy = x - boxA.x, y - boxA.y
  37. return diffx + width > 0 and diffx < boxA.width and
  38. diffy + height > 0 and diffy < boxA.height
  39. end
  40. utils.intersectsBox = function(boxA, boxB)
  41. local diffx, diffy = boxB.x - boxA.x, boxB.y - boxA.y
  42. return diffx + boxB.width > 0 and diffx < boxA.width and
  43. diffy + boxB.height > 0 and diffy < boxA.height
  44. end
  45. -- this assumes h:[0, 6] & s:[0, 1], l:[0, 1]
  46. utils.hsl2rgb = function(h, s, l, a)
  47. if s <= 0 then return l, l, l, a end
  48. local c = 2 * s * ((l > 0.5) and (1 - l) or l)
  49. local m = l - c / 2
  50. local r, g, b
  51. if h < 1 then b, r, g = 0, c, c * h
  52. elseif h < 2 then b, g, r = 0, c, c * (2 - h)
  53. elseif h < 3 then r, g, b = 0, c, c * (h - 2)
  54. elseif h < 4 then r, b, g = 0, c, c * (4 - h)
  55. elseif h < 5 then g, b, r = 0, c, c * (h - 4)
  56. else g, r, b = 0, c, c * (6 - h)
  57. end
  58. return (r + m), (g + m), (b + m), a
  59. end
  60. utils.rgb2hsl = function(r, g, b, a)
  61. local max, min = _max(r, g, b), _min(r, g, b)
  62. if max == min then return 0, 0, min, a end
  63. local d, l, s, h = max - min, max + min
  64. s = d / (l > 1 and 2 - l or l)
  65. l = l / 2
  66. if max == r then
  67. h = (g - b) / d
  68. if h < 0 then h = h + 6 end
  69. elseif max == g then
  70. h = (b - r) / d + 2
  71. else
  72. h = (r - g) / d + 4
  73. end
  74. return h, s, l, a
  75. end
  76. --utils.format = string.format
  77. local _sub = string.sub
  78. local _find = string.find
  79. local _insert = table.insert
  80. utils.split = function(s, sep)
  81. local t = {}; local init = 1; local m, n
  82. sep = sep or '\n'
  83. while true do
  84. m, n = _find(s, sep, init, true)
  85. if m == nil then
  86. _insert(t, _sub(s, init))
  87. break
  88. end
  89. _insert(t, _sub(s, init, m - 1))
  90. init = n + 1
  91. end
  92. return t, #t
  93. end
  94. local deepcopy
  95. deepcopy = function(t, mem)
  96. if type(t) ~= 'table' then return t end
  97. local copy = mem[t]
  98. if copy then return copy end
  99. copy = {}
  100. mem[t] = copy
  101. local meta = getmetatable(t)
  102. for k, v in pairs(t) do
  103. k = deepcopy(k, mem)
  104. v = deepcopy(v, mem)
  105. copy[k] = v
  106. end
  107. setmetatable(copy, meta)
  108. return copy
  109. end
  110. utils.deepcopy = function(t) return deepcopy(t, {}) end
  111. local ids = {}
  112. utils.genid = function(name)
  113. local id = (ids[name] or 0) + 1
  114. ids[name] = id
  115. return ("%s_%i"):format(name, id)
  116. end
  117. local typeof
  118. typeof = function(class, typename)
  119. if not class then return false end
  120. if class.name == typename then return true end
  121. return typeof(class.parent, typename)
  122. end
  123. local default_object = {
  124. name = "boxuiObject",
  125. ["type"] = function(object) return object.class.name end,
  126. ["typeOf"] = function(object, typename) return typeof(object.class, typename) end,
  127. }
  128. default_object.__index = default_object
  129. utils.newclass = function(name, parent)
  130. parent = parent or default_object
  131. local class = utils.deepcopy(parent)
  132. class.name = name
  133. class.parent = parent
  134. class.new = function(...)
  135. local object = setmetatable({}, class)
  136. object.class = class
  137. object.name = utils.genid(class.name)
  138. class.init(object, ...)
  139. return object
  140. end -- new
  141. return class
  142. end
  143. -- add or update
  144. utils.addprops = function(t, props)
  145. for k, v in pairs(props) do
  146. t[k] = v
  147. end
  148. return t
  149. end
  150. -- update existing
  151. utils.freshenprops = function(t, props)
  152. for k, v in pairs(props) do
  153. if t[k] ~= nil then t[k] = v end
  154. end
  155. return t
  156. end
  157. return utils