ui_spin.lua 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. local l_gfx = love.graphics
  2. local mouse = love.mouse
  3. local tostring = tostring
  4. local format = string.format
  5. -- this is a spin element
  6. -- currently it's only way of control is by mousewheel, wheelup increases the value by a step, wheeldown decreases
  7. -- it also has mutlipliers, like precise multiplier, base multiplier, coarse and turbo multipliers
  8. -- if you press left shift, or left ctrl or left alt while mouse over the spin element, you will switch its step multiplier and show its value in a box to the right
  9. -- multipliers are redefinable on runtime as well as you can deny it from use step multipliers at all
  10. -- its changeValue() method is fired on every increase or decrease
  11. Spin = {}
  12. Spin.__index = Spin
  13. Spin.ident = "ui_spin"
  14. Spin.leftCaption = false
  15. Spin.w = 48
  16. Spin.h = 16
  17. Spin.caption = "Spin"
  18. Spin.name = "Spin"
  19. Spin.caption_xpad = -4
  20. Spin.caption_ypad = 0
  21. Spin.updateable = true
  22. Spin.maxdec = 1
  23. function Spin:new(name)
  24. local self = {}
  25. setmetatable(self,Spin)
  26. self.value = 0
  27. self.step = 1
  28. self.step_mult = 1
  29. self.isHeld = false
  30. self.allowMult = false
  31. self.displMult = false
  32. self.mult_coarse = 10
  33. self.mult_base = 1
  34. self.mult_precise = 0.1
  35. self.mult_turbo = 100
  36. self.held_timer = 0
  37. self.max = nil
  38. self.min = nil
  39. if name ~= nil then self.name = name end
  40. return self
  41. end
  42. setmetatable(Spin,{__index = UIElement})
  43. function Spin:click(b)
  44. if b == 1 then
  45. self.isHeld = true
  46. local mx,my = mouse.getPosition()
  47. if self:isMouseOver() then
  48. if mx>=self.x+self.w/2 then self:increment() else self:decrement() end
  49. self:changeValue()
  50. end
  51. end
  52. end
  53. function Spin:wheelmoved(x,y)
  54. local mx,my = love.mouse.getPosition()
  55. if self:isMouseOver(mx,my) then
  56. if y > 0 then
  57. self:increment()
  58. self:changeValue()
  59. elseif y < 0 then
  60. self:decrement()
  61. self:changeValue()
  62. end
  63. end
  64. end
  65. function Spin:update(dt)
  66. if self.isHeld == true then
  67. self.held_timer = self.held_timer + dt
  68. if self.held_timer>0.5 then
  69. local mx,my = mouse.getPosition()
  70. if self:isMouseOver() then
  71. if mx>=self.x+self.w/2 then self:increment() else self:decrement() end
  72. self:changeValue()
  73. end
  74. end
  75. end
  76. end
  77. function Spin:unclick(b)
  78. if b == 1 then
  79. self.isHeld = false
  80. self.held_timer = 0
  81. end
  82. end
  83. function Spin:increment()
  84. if self.max ~= nil then
  85. if self.value<=self.max-self.step*self.step_mult then self.value = self.value + self.step*self.step_mult end
  86. else
  87. self.value = self.value + self.step*self.step_mult
  88. end
  89. end
  90. function Spin:decrement()
  91. if self.min ~= nil then
  92. if self.value>=self.min+self.step*self.step_mult then self.value = self.value - self.step*self.step_mult end
  93. else
  94. self.value = self.value - self.step*self.step_mult
  95. end
  96. end
  97. function Spin:keypressed(key)
  98. if self.allowMult == true then
  99. if key == "lshift" then
  100. self.step_mult = self.mult_coarse
  101. self.displMult = true
  102. elseif key == "lctrl" then
  103. self.step_mult = self.mult_precise
  104. self.displMult = true
  105. elseif key == "lalt" then
  106. self.step_mult = self.mult_turbo
  107. self.displMult = true
  108. end
  109. end
  110. end
  111. function Spin:keyreleased(key)
  112. if key == "lshift" or key == "lctrl" or key == "lalt" then
  113. self.step_mult = self.mult_base
  114. self.displMult = false
  115. end
  116. end
  117. function Spin:draw()
  118. local cr,cg,cb,ca = love.graphics.getColor()
  119. local dynwidth = self.w
  120. local deccnt = self.maxdec
  121. local v = format("%."..deccnt.."f",self.value)
  122. if self:isMouseOver() == true then
  123. if dynwidth<l_gfx.getFont():getWidth(tostring(v)) then
  124. dynwidth = l_gfx.getFont():getWidth(tostring(v)) + 2
  125. end
  126. end
  127. if self.active == true then
  128. l_gfx.setColor(self.colorFill)
  129. else
  130. l_gfx.setColor(self.colorDisabledFill)
  131. end
  132. l_gfx.rectangle("fill",self.x,self.y,dynwidth,self.h)
  133. if self:isMouseOver() == true then
  134. local mx,my = mouse:getPosition()
  135. l_gfx.setColor(self.colorHighlight)
  136. if mx>=self.x+dynwidth/2 then
  137. l_gfx.rectangle("fill",self.x+dynwidth/2,self.y,dynwidth/2,self.h)
  138. else
  139. l_gfx.rectangle("fill",self.x,self.y,dynwidth/2,self.h)
  140. end
  141. if self.displMult == true then
  142. local str = "x"..self.step_mult*self.step
  143. l_gfx.setColor(self.colorFill)
  144. l_gfx.rectangle("fill",self.x+dynwidth,self.y+(self.h/2-7),l_gfx.getFont():getWidth(str)+2,14)
  145. l_gfx.setColor(self.colorHighlight)
  146. l_gfx.rectangle("line",self.x+dynwidth,self.y+(self.h/2-7),l_gfx.getFont():getWidth(str),14)
  147. l_gfx.setColor(self.colorFont)
  148. l_gfx.print(str,self.x+dynwidth,self.y+(self.h/2-7))
  149. end
  150. l_gfx.setColor(self.colorFill)
  151. else
  152. end
  153. l_gfx.setColor(self.colorFont)
  154. while l_gfx.getFont():getWidth(tostring(v))>=dynwidth do
  155. deccnt = deccnt - 1
  156. if deccnt<0 then v = "..." break end
  157. v = format("%."..deccnt.."f",self.value)
  158. end
  159. local sh = self.h/2-7
  160. l_gfx.printf(v,self.x,self.y+sh,dynwidth,"center")
  161. if self.leftCaption == true then
  162. l_gfx.print(self.caption,self.x-l_gfx:getFont():getWidth(self.caption)+self.caption_xpad,self.y+(self.h/2-7)+self.caption_ypad)
  163. else
  164. l_gfx.print(self.caption,self.x+self.caption_xpad,self.y-14+self.caption_ypad)
  165. end
  166. l_gfx.setColor(cr,cg,cb,ca)
  167. end
  168. function Spin:changeValue() end
  169. function Spin:setValue(value) self.value = value end
  170. -- Editable spin, once hovered over, receives text input
  171. SpinEdit = {}
  172. SpinEdit.__index = SpinEdit
  173. SpinEdit.ident = "ui_spinedit"
  174. SpinEdit.name = "SpinEdit"
  175. -- Yes, it does look crude, but i cannot use dot or comma as assoc.array key like arr = {. = '.'}
  176. local ac = {}
  177. ac['1'] = '1'
  178. ac['2'] = '2'
  179. ac['3'] = '3'
  180. ac['4'] = '4'
  181. ac['5'] = '5'
  182. ac['6'] = '6'
  183. ac['7'] = '7'
  184. ac['8'] = '8'
  185. ac['9'] = '9'
  186. ac['0'] = '0'
  187. ac['.'] = '.'
  188. ac[','] = '.'
  189. ac['kp1'] = '1'
  190. ac['kp2'] = '2'
  191. ac['kp2'] = '3'
  192. ac['kp3'] = '3'
  193. ac['kp4'] = '4'
  194. ac['kp5'] = '5'
  195. ac['kp6'] = '6'
  196. ac['kp7'] = '7'
  197. ac['kp8'] = '8'
  198. ac['kp9'] = '9'
  199. ac['kp0'] = '0'
  200. SpinEdit.allowedChars = ac
  201. function SpinEdit:new(name)
  202. local self = setmetatable({},SpinEdit)
  203. self.name = name or self.name
  204. self.value = 0
  205. self.step = 1
  206. self.step_mult = 1
  207. self.isHeld = false
  208. self.allowMult = false
  209. self.displMult = false
  210. self.mult_coarse = 10
  211. self.mult_base = 1
  212. self.mult_precise = 0.1
  213. self.mult_turbo = 100
  214. self.held_timer = 0
  215. self.max = nil
  216. self.min = nil
  217. return self
  218. end
  219. setmetatable(SpinEdit,{__index = Spin})
  220. function SpinEdit:keypressed(key)
  221. if self.allowMult == true then
  222. if key == "lshift" then
  223. self.step_mult = self.mult_coarse
  224. self.displMult = true
  225. elseif key == "lctrl" then
  226. self.step_mult = self.mult_precise
  227. self.displMult = true
  228. elseif key == "lalt" then
  229. self.step_mult = self.mult_turbo
  230. self.displMult = true
  231. end
  232. end
  233. if self:isMouseOver() == true then
  234. local rk = self.allowedChars[key]
  235. if rk ~= nil then
  236. end
  237. end
  238. end
  239. function SpinEdit:keyreleased(key)
  240. if key == "lshift" or key == "lctrl" or key == "lalt" then
  241. self.step_mult = self.mult_base
  242. self.displMult = false
  243. end
  244. end