slider.lua 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. local g = love.graphics
  2. require 'lib/component'
  3. Slider = extend(Component)
  4. function Slider:activate()
  5. self.value = self.value or 0
  6. self.min = self.min or 0
  7. self.max = self.max or 100
  8. self.round = self.round or 10
  9. self.scale = 1
  10. self.prevScale = self.scale
  11. self.factor = self.value
  12. self.prevFactor = self.factor
  13. self.hoverFactor = 0
  14. self.prevHoverFactor = self.hoverFactor
  15. self.hoverDirty = false
  16. end
  17. function Slider:update()
  18. local mx, my = love.mouse.getPosition()
  19. local ox, oy = self:getOffset()
  20. mx, my = mx + ox, my + oy
  21. if self.gooey.hot == self then
  22. local x, y, w, r = self:getSliderGeometry()
  23. local percent = math.clamp((mx - x) / w, 0, 1)
  24. self:setValue(self.min + (self.max - self.min) * percent)
  25. end
  26. self.prevFactor = self.factor
  27. self.factor = math.lerp(self.factor, (self.value - self.min) / (self.max - self.min), math.min(16 * ls.tickrate, 1))
  28. self.prevScale = self.scale
  29. self.scale = math.lerp(self.scale, self.gooey.hot == self and 1.15 or 1, math.min(16 * ls.tickrate, 1))
  30. self.prevHoverFactor = self.hoverFactor
  31. local hover = (not self.gooey.hot and self:containsBar(mx, my)) or self.gooey.hot == self
  32. self.hoverFactor = math.lerp(self.prevHoverFactor, hover and 1 or 0, math.min(16 * ls.tickrate, 1))
  33. if hover then
  34. if not self.hoverDirty then
  35. ctx.sound:play('juju1', function(sound) sound:setPitch(.75) end)
  36. self.hoverDirty = true
  37. end
  38. else
  39. self.hoverDirty = false
  40. end
  41. end
  42. function Slider:render()
  43. local u, v = ctx.u, ctx.v
  44. local x, y, w, r = unpack(self.geometry())
  45. local factor = math.lerp(self.prevFactor, self.factor, ls.accum / ls.tickrate)
  46. local hoverFactor = math.lerp(self.prevHoverFactor, self.hoverFactor, ls.accum / ls.tickrate)
  47. local scale = math.lerp(self.prevScale, self.scale, ls.accum / ls.tickrate)
  48. local radius = scale * r
  49. g.setFont('mesmerize', r * 1.4)
  50. g.setColor(255, 255, 255, 180 + 75 * hoverFactor)
  51. g.print(self.label, x - r, y - g.getFont():getHeight() / 2)
  52. x = x + math.max(u * .08, g.getFont():getWidth(self.label))
  53. g.setColor(255, 255, 255, 40 + 80 * hoverFactor)
  54. g.setLineWidth(2)
  55. g.line(math.round(x) + .5, math.round(y) + .5, x + w, y)
  56. g.setLineWidth(1)
  57. g.setColor(30, 30, 30)
  58. g.circle('fill', x + w * factor, y, radius, 20)
  59. g.setColor(100, 200, 50, 180 + (75 * hoverFactor))
  60. g.setLineWidth(2)
  61. g.circle('line', x + w * factor, y, radius, 20)
  62. g.setLineWidth(1)
  63. end
  64. function Slider:mousepressed(mx, my, b)
  65. local ox, oy = self:getOffset()
  66. mx, my = mx + ox, my + oy
  67. if b == 'l' and self:containsBar(mx, my) then
  68. self.gooey.hot = self
  69. end
  70. end
  71. function Slider:mousereleased(mx, my, b)
  72. --
  73. end
  74. function Slider:contains(mx, my)
  75. local x, y, w, r = self:getSliderGeometry()
  76. local factor = (self.value - self.min) / (self.max - self.min)
  77. return math.insideCircle(mx, my, x + w * factor, y, r)
  78. end
  79. function Slider:containsBar(mx, my)
  80. local x, y, w, r = self:getSliderGeometry()
  81. r = r * 1.5
  82. return math.inside(mx, my, x - r, y - r, w + 2 * r, 2 * r)
  83. end
  84. function Slider:setValue(value)
  85. local old = self.value
  86. self.value = math.round(value / self.round) * self.round
  87. if self.value ~= old then self:emit('change', {component = self}) end
  88. end
  89. function Slider:getSliderGeometry()
  90. local u, v = ctx.u, ctx.v
  91. local x, y, w, r = unpack(self.geometry())
  92. local font = g.setFont('mesmerize', r * 1.4)
  93. g.print(self.label, x, y - font:getHeight() / 2)
  94. x = x + math.max(u * .08, font:getWidth(self.label))
  95. return x, y, w, r
  96. end