ui_listbox.lua 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. local l_gfx = love.graphics
  2. local min = math.min
  3. -- simple list box with index and clickable string list
  4. -- usually linked to collection in its behavior
  5. ListBox = {}
  6. ListBox.__index = ListBox
  7. ListBox.ident = "ui_listbox"
  8. ListBox.name = "ListBox"
  9. ListBox.caption = "ListBox"
  10. ListBox.itemSpacing = 1 -- this will define a gap between items
  11. ListBox.itemCaptionAlign = "left"
  12. ListBox.itemCaptionPadding = 4 -- this will make text appear shifted
  13. ListBox.displayMax = 16
  14. ListBox.shift = 0
  15. ListBox.showBorder = false
  16. ListBox.showScroll = false
  17. ListBox.scrollWidth = 16
  18. function ListBox:new(name)
  19. local self = {}
  20. setmetatable(self,ListBox)
  21. self.items = {}
  22. self.index = 0
  23. self.itemHeight = 16
  24. if name ~= nil then self.name = name end
  25. return self
  26. end
  27. setmetatable(ListBox,{__index = UIElement})
  28. function ListBox:mousepressed(x,y,b)
  29. if self:isMouseOver(x,y) then
  30. if b == 1 or b == 2 then
  31. local c = #self.items
  32. if c>0 then
  33. local sx,sy,sw,ih = self.x,self.y,self.w,self.itemHeight
  34. for i=(self.shift+1),(self.shift+math.min(self.displayMax,c)) do
  35. local factor = i-1-self.shift
  36. local ix,iy = sx,factor*ih+factor*self.itemSpacing
  37. if x>=sx and x<=sx+sw and y>=sy+iy and y<=sy+iy+ih then
  38. self.index = i
  39. break
  40. end
  41. end
  42. end
  43. self:click(b)
  44. end
  45. end
  46. end
  47. function ListBox:wheelmoved(x,y)
  48. if y > 0 then
  49. self.shift = self.shift - 1
  50. if self.shift<0 then self.shift = 0 end
  51. elseif y < 0 then
  52. if self.shift<(#self.items-self.displayMax) then
  53. self.shift = self.shift+1
  54. end
  55. end
  56. end
  57. -- this will return highlighted element
  58. function ListBox:getSelected()
  59. return self.items[self.index]
  60. end
  61. function ListBox:addItem(item,name)
  62. table.insert(self.items,item)
  63. if #self.items == 1 then self.index = 1 end
  64. end
  65. function ListBox:clear()
  66. for k,v in pairs(self.items) do self.items[k] = nil end
  67. self.index = 0
  68. end
  69. function ListBox:last()
  70. self.index = #self.items
  71. end
  72. function ListBox:first()
  73. if #self.items>0 then self.index = 1 else self.index = 0 end
  74. end
  75. function ListBox:setSize(w,h)
  76. self.w = w or self.w self.h = h or self.h
  77. self.displayMax = math.floor(self.h/(self.itemHeight+self.itemSpacing))
  78. print(self.name.."|"..self.displayMax)
  79. end
  80. -- if you specify a number, it will return you an item as if you index an array, otherwise it will try to look for it by comparing strings
  81. function ListBox:getItem(item)
  82. local c = #self.items
  83. if c>0 then
  84. for i=1,c do
  85. if self.items[i]:getName() == name then
  86. return self.items[i]
  87. elseif self.items[i].items ~= nil and deep == true then
  88. self.items[i]:getItem(name,deep)
  89. end
  90. end
  91. end
  92. return nil
  93. end
  94. function ListBox:setItemValue(item,value)
  95. self.items[item] = value
  96. end
  97. function ListBox:draw()
  98. local cr,cg,cb,ca = l_gfx.getColor()
  99. if self.showBorder == true then
  100. l_gfx.setColor(self.colorLine)
  101. l_gfx.rectangle("line",self.x,self.y,self.w,self.h)
  102. end
  103. local c = #self.items
  104. local fh = l_gfx.getFont():getHeight()/2
  105. if c>0 then
  106. local sx,sy,sw,ih = self.x,self.y,self.w,self.itemHeight
  107. for i=(self.shift+1),(self.shift+math.min(self.displayMax,c)) do
  108. if self.index == i then
  109. l_gfx.setColor(self.colorHighlight)
  110. else
  111. l_gfx.setColor(self.colorFill)
  112. end
  113. local factor = i-1-self.shift
  114. local space = factor*self.itemSpacing
  115. local ix,iy,iw = self.x, self.y+factor*self.itemHeight+space,self.w
  116. if self.showScroll == true then iw = iw - self.scrollWidth end
  117. local fpad = self.itemHeight/2-fh
  118. l_gfx.rectangle("fill",ix,iy,iw,self.itemHeight)
  119. l_gfx.setColor(self.colorFont)
  120. if type(self.items[i]) == "table" then
  121. l_gfx.printf(self.items[i][1],ix+self.itemCaptionPadding,iy+fpad,iw-self.itemCaptionPadding,self.itemCaptionAlign)
  122. elseif type(self.items[i]) == "string" then
  123. l_gfx.printf(self.items[i],ix+self.itemCaptionPadding,iy+fpad,iw-self.itemCaptionPadding,self.itemCaptionAlign)
  124. end
  125. end
  126. if self.showScroll == true then
  127. l_gfx.setColor(self.colorFill)
  128. l_gfx.rectangle("line",self.w+self.x-self.scrollWidth,self.y,self.scrollWidth,self.h)
  129. local h = self.h/(math.max(#self.items/self.displayMax,1))
  130. l_gfx.rectangle("fill",self.w+self.x-self.scrollWidth,self.y+self.shift*self.displayMax,self.scrollWidth,h)
  131. end
  132. end
  133. l_gfx.setColor(cr,cg,cb,ca)
  134. end
  135. GaugeList = {}
  136. GaugeList.__index = GaugeList
  137. GaugeList.ident = "ui_gaugelist"
  138. GaugeList.name = "GaugeList"
  139. GaugeList.colorProgress = {0,160,160,128}
  140. function GaugeList:new(name)
  141. local self = {}
  142. setmetatable(self,GaugeList)
  143. self.items = {}
  144. self.index = 0
  145. self.itemHeight = 16
  146. if name ~= nil then self.name = name end
  147. return self
  148. end
  149. setmetatable(GaugeList,{__index = ListBox})
  150. function GaugeList:addItem(item,val)
  151. table.insert(self.items,{item,val or 0})
  152. if #self.items == 1 then self.index = 1 end
  153. end
  154. function GaugeList:setItemValue(item,value,value2)
  155. self.items[item][1] = value or self.items[item][1]
  156. self.items[item][2] = value2 or 0
  157. end
  158. function GaugeList:draw()
  159. if self.showBorder == true then
  160. l_gfx.setColor(self.colorLine)
  161. l_gfx.rectangle("line",self.x,self.y,self.w,self.h)
  162. end
  163. local c = #self.items
  164. local fh = l_gfx.getFont():getHeight()/2
  165. if c>0 then
  166. local sx,sy,sw,ih = self.x,self.y,self.w,self.itemHeight
  167. for i=(self.shift+1),(self.shift+math.min(self.displayMax,c)) do
  168. if self.index == i then
  169. l_gfx.setColor(self.colorHighlight)
  170. else
  171. l_gfx.setColor(self.colorFill)
  172. end
  173. local factor = i-1-self.shift
  174. local space = factor*self.itemSpacing
  175. local ix,iy,iw = self.x, self.y+factor*self.itemHeight+space,self.w
  176. if self.showScroll == true then iw = iw - self.scrollWidth end
  177. local fpad = self.itemHeight/2-fh
  178. l_gfx.rectangle("fill",ix,iy,iw,self.itemHeight)
  179. l_gfx.setColor(self.colorProgress)
  180. local prg = min(self.items[i][2]/100,1)
  181. l_gfx.rectangle("fill",ix,iy,prg*iw,self.itemHeight)
  182. l_gfx.setColor(self.colorFont)
  183. if type(self.items[i][1]) == "table" then
  184. l_gfx.printf(self.items[i][1][1],ix+self.itemCaptionPadding,iy+fpad,iw-self.itemCaptionPadding,self.itemCaptionAlign)
  185. elseif type(self.items[i][1]) == "string" then
  186. l_gfx.printf(self.items[i][1],ix+self.itemCaptionPadding,iy+fpad,iw-self.itemCaptionPadding,self.itemCaptionAlign)
  187. end
  188. end
  189. if self.showScroll == true then
  190. l_gfx.setColor(self.colorFill)
  191. l_gfx.rectangle("line",self.w+self.x-self.scrollWidth,self.y,self.scrollWidth,self.h)
  192. local h = self.h/(math.max(#self.items/self.displayMax,1))
  193. l_gfx.rectangle("fill",self.w+self.x-self.scrollWidth,self.y+self.shift*self.displayMax,self.scrollWidth,h)
  194. end
  195. end
  196. end
  197. function GaugeList:clear()
  198. for k,v in pairs(self.items) do
  199. self.items[k][1],self.items[k][2] = nil,nil
  200. self.items[k] = nil
  201. end
  202. self.index = 0
  203. end