slider.lua 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. return function(BOXUI)
  2. local utils = BOXUI.utils
  3. local int = utils.int
  4. local clamp = utils.clamp
  5. local M = utils.newclass("slider")
  6. -- AREAS
  7. local units = {}
  8. M.units = units
  9. units.SLIDER_INC = utils.newbox("inc" ) -- name = str
  10. units.SLIDER_DEC = utils.newbox("dec")
  11. units.SLIDER_NOB = utils.newbox("nob")
  12. local incdec = function(owner, dir)
  13. local value = utils.clamp(owner.value + dir * owner.step, owner.valueMin, owner.valueMax)
  14. if value == owner.value then return end
  15. owner.value = value
  16. local ratio = owner.value / (owner.valueMax - owner.valueMin)
  17. local boxes = owner.boxes
  18. local nob = boxes.nob
  19. if owner.vertical then
  20. local bh = boxes.dec.height
  21. local nobpos = boxes.dec.y - nob.height - int((owner.height - 2 * bh - nob.height) * ratio)
  22. boxes.nob.y = nobpos
  23. else
  24. local bw = boxes.dec.width
  25. local nobpos = bw + int((owner.width - 2 * bw - nob.width) * ratio)
  26. boxes.nob.x = nobpos
  27. end
  28. end
  29. units.SLIDER_INC.click = function(owner) incdec(owner, 1) end
  30. units.SLIDER_DEC.click = function(owner) incdec(owner, -1) end
  31. M.init = function(self, x, y, width, height)
  32. self.theme = BOXUI.theme
  33. self.x, self.y = x, y
  34. self.width, self.height = width, height
  35. self.value = 75
  36. self.valueMin = 0
  37. self.valueMax = 100
  38. self.step = 1
  39. self.stepTime = 0.010
  40. self.stepInit = 0.250
  41. self.dt = 0
  42. self.active = nil
  43. self.selected = nil
  44. self.onClick = nil
  45. self.font = love.graphics.getFont()
  46. self.units = utils.deepcopy(M.units)
  47. end
  48. M.adjust = incdec
  49. M.refresh = function(self)
  50. local theme = self.theme
  51. local width, height = self.width, self.height
  52. local bw, bh = theme.sliderButtonWidth, theme.sliderButtonHeight
  53. local nt, nl = theme.sliderNobThickness, theme.sliderNobLength
  54. local u = self.units
  55. local boxes = {}
  56. local ratio = self.value / (self.valueMax - self.valueMin)
  57. --self.stepTime = (self.step) / (self.valueMax - self.valueMin)
  58. self.boxes = boxes
  59. if self.vertical then
  60. local bx = int((width - bw) / 2)
  61. local nobx = int((width - nl) / 2)
  62. local nobpos = height - bh - nt - int((height - 2 * bh - nt) * ratio)
  63. boxes.inc = utils.setbox(u.SLIDER_INC, bx, 0, bw, bh)
  64. boxes.dec = utils.setbox(u.SLIDER_DEC, bx, height - bh, bw, bh)
  65. boxes.nob = utils.setbox(u.SLIDER_NOB, nobx, nobpos, nl, nt)
  66. else
  67. local by = int((height - bh) / 2)
  68. local noby = int((height - nl) / 2)
  69. local nobpos = bw + int((width - 2 * bw - nt) * ratio)
  70. boxes.dec = utils.setbox(u.SLIDER_DEC, 0, by, bw, bh)
  71. boxes.inc = utils.setbox(u.SLIDER_INC, width - bw, by, bw, bh)
  72. boxes.nob = utils.setbox(u.SLIDER_NOB, nobpos, noby, nt, nl)
  73. end
  74. self.draw = self.theme.draw.slider
  75. end
  76. M.wheelmoved = function(self, x, y, dx, dy)
  77. end
  78. M.mousemoved = function(self, x, y, button)
  79. x, y = x - self.x, y - self.y
  80. self.active = nil
  81. for k,v in pairs(self.boxes) do
  82. if utils.includesPoint(v, x, y) then self.active = v break end
  83. end
  84. end
  85. M.mousepressed = function(self, x, y, button)
  86. x, y = x - self.x, y - self.y
  87. self.dt = 0
  88. self.stepping = false
  89. self.selected = button == 1 and self.active
  90. end
  91. M.mousereleased = function(self, x, y, button)
  92. local active, selected = self.active, self.selected
  93. if active and active == selected and active.click then
  94. active.click(self)
  95. end
  96. self.selected = false
  97. end
  98. M.update = function(self, dt)
  99. local active, selected = self.active, self.selected
  100. if not selected or selected ~= active or not selected.click then return end
  101. self.dt = self.dt + dt
  102. if not self.stepping then
  103. if self.dt < self.stepInit then return end
  104. self.stepping = true; self.dt = self.dt - self.stepInit
  105. end
  106. if self.dt < self.stepTime then return end
  107. active.click(self)
  108. self.dt = self.dt - self.stepTime
  109. end
  110. --M.focus = function(self) self.active = true end
  111. --M.unfocus = function(self) self.active = false end
  112. BOXUI.add(M)
  113. end