theme.lua 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. return function(BOXUI)
  2. local utils = BOXUI.utils
  3. local int = utils.int
  4. local clamp = utils.clamp
  5. local colorWhite = {1, 1, 1}
  6. local theme = {
  7. name = "theme",
  8. -- list
  9. itemHeight = 24, itemPadVert = 2, itemPadHori = 4,
  10. itemBack = {0.2, 0.7, 0.9},
  11. itemFore = {0.1, 0.1, 0.1}, itemForeActive = {1, 0, 0, 0.2},
  12. -- container
  13. sliderThickness = 12, sliderLengthMin = 10,
  14. sliderBack = {0.0, 0.2, 0.3},
  15. sliderFore = {0.9, 0.2, 0.4}, sliderForeActive = {0.7, 0.9, 1.0},
  16. borderThickness = 2,
  17. borderBack = {0.1, 0.1, 0.1},
  18. borderFore = {0.0, 0.4, 0.6},
  19. handleHeight = 20, handleButtonWidth = 16, handleButtonHeight = 16,
  20. handlePadVert = 4,
  21. handleBack = {0.5, 0.7, 0.8},
  22. handleFore = {0.2,0.2,0.2},
  23. -- panel
  24. panelBack = {0.1, 0.15, 0.2},
  25. -- slider
  26. sliderButtonWidth = 20, sliderButtonHeight = 20,
  27. sliderNobThickness = 4, sliderNobLength = 12,
  28. }
  29. theme.draw = {}
  30. -- CONTAINER
  31. -- active elements
  32. theme.draw.containerActive = function(self, x, y)
  33. local theme = self.theme
  34. -- draw active components
  35. local boxes = self.boxes
  36. local box = boxes.panel
  37. if box and not box.hidden and self.content.draw then
  38. local sx, sy, sw, sh = love.graphics.getScissor()
  39. love.graphics.intersectScissor(x + box.x, y + box.y, box.width, box.height)
  40. self.content:draw(x + box.x, y + box.y)
  41. if self.drawOverlay then self:drawOverlay(x, y) end
  42. love.graphics.setScissor(sx, sy, sw, sh)
  43. end
  44. box = boxes.sliderVert
  45. if box and not box.hidden then
  46. local color = self.activeArea == box and theme.sliderForeActive or theme.sliderFore
  47. love.graphics.setColor(color)
  48. love.graphics.rectangle('fill', x + box.x, y + box.y + box.pos, box.width, box.length)
  49. end
  50. box = boxes.sliderHori
  51. if box and not box.hidden then
  52. local color = self.activeArea == box and theme.sliderForeActive or theme.sliderFore
  53. love.graphics.setColor(color)
  54. love.graphics.rectangle('fill', x + box.x + box.pos, y + box.y, box.length, box.height)
  55. end
  56. end
  57. -- passive elements
  58. theme.draw.containerPassive = function(self, x, y)
  59. local oldcolor = {love.graphics.getColor()}
  60. local oldlinew = love.graphics.getLineWidth()
  61. local theme = self.theme
  62. local bt = theme.borderThickness
  63. local w, h = self.width, self.height
  64. love.graphics.setColor(theme.borderBack)
  65. love.graphics.rectangle('fill', x, y, w, h)
  66. love.graphics.setColor(theme.borderFore)
  67. love.graphics.setLineWidth(bt)
  68. love.graphics.rectangle('line', x + bt / 2, y + bt / 2, w - bt, h - bt)
  69. local boxes = self.boxes
  70. local box
  71. local fontheight = love.graphics.getFont():getHeight()
  72. love.graphics.setLineWidth(1)
  73. local bx, by, bty
  74. box = boxes.handle
  75. if box then
  76. bx, by = x + box.x, y + box.y
  77. bty = by + int((box.height - fontheight) / 2)
  78. love.graphics.setColor(theme.handleBack)
  79. love.graphics.rectangle('fill', bx, by, box.width, box.height)
  80. love.graphics.setColor(theme.handleFore)
  81. love.graphics.printf(self.title, bx, bty, box.width, "center")
  82. box = boxes.close
  83. if box then
  84. bx, by = x + box.x, y + box.y
  85. bty = by + int((box.height - fontheight) / 2)
  86. love.graphics.rectangle('line', bx + .5, by + .5, box.width - 1, box.height - 1)
  87. love.graphics.printf("X", bx, bty, box.width, "center")
  88. end
  89. box = boxes.shade
  90. if box and not box.hidden then
  91. bx, by = x + box.x, y + box.y
  92. bty = by + int((box.height - fontheight) / 2)
  93. love.graphics.rectangle('line', bx + .5, by + .5, box.width - 1, box.height - 1)
  94. love.graphics.printf("S", bx, bty, box.width, "center")
  95. end
  96. box = boxes.expand
  97. if box and not box.hidden then
  98. bx, by = x + box.x, y + box.y
  99. bty = by + int((box.height - fontheight) / 2)
  100. love.graphics.rectangle('line', bx + .5, by + .5, box.width - 1, box.height - 1)
  101. love.graphics.printf("E", bx, bty, box.width, "center")
  102. end
  103. end
  104. box = boxes.sliderVert
  105. if box and not box.hidden then
  106. love.graphics.setColor(theme.sliderBack)
  107. love.graphics.rectangle('fill', x + box.x, y + box.y, box.width, box.height)
  108. end
  109. box = boxes.sliderHori
  110. if box and not box.hidden then
  111. love.graphics.setColor(theme.sliderBack)
  112. love.graphics.rectangle('fill', x + box.x, y + box.y, box.width, box.height)
  113. end
  114. love.graphics.setColor(oldcolor)
  115. love.graphics.setLineWidth(oldlinew)
  116. end
  117. -- BUTTON
  118. theme.draw.button = function(self, x, y)
  119. x, y = x + self.x, y + self.y
  120. local fh = self.font:getHeight()
  121. local theme = self.theme
  122. local bt = theme.borderThickness
  123. love.graphics.setColor(theme.borderFore)
  124. love.graphics.rectangle('fill', x, y, self.width, self.height)
  125. love.graphics.setColor(theme.itemBack)
  126. love.graphics.rectangle('fill', x + bt, y + bt, self.width - 2 * bt, self.height - 2 * bt)
  127. love.graphics.setColor(theme.itemFore)
  128. local label = self.checked and "[X] button" or "[ ] button"
  129. love.graphics.printf(label, x, y + utils.int((self.height - fh) / 2), self.width, "center")
  130. end
  131. -- LIST
  132. theme.draw.listOverlay = function(self, x, y)
  133. local vieww, viewh, viewy = self.viewW, self.viewH, self.viewY
  134. local list = self.list
  135. local active, selected = list.itemActive, list.itemSelected
  136. if active then
  137. local panel = self.boxes.panel
  138. local x, y = x + panel.x, y + panel.y
  139. local vieww, viewh, viewy = self.viewW, self.viewH, self.viewY
  140. local listtheme = list.theme
  141. local height = listtheme.itemHeight
  142. local advance = height + listtheme.itemPadVert
  143. local mode, alphamode = love.graphics.getBlendMode()
  144. local oldcolor = {love.graphics.getColor()}
  145. love.graphics.setBlendMode("multiply", "premultiplied")
  146. --local shader = love.graphics.getShader()
  147. love.graphics.setColor(active == selected and {.7,0,0} or {0,.7,0})
  148. --love.graphics.setShader(theme.colorizeShader)
  149. love.graphics.rectangle("fill", x, y + (active - 1) * advance - viewy, vieww, height)
  150. --love.graphics.setShader()
  151. love.graphics.setColor(oldcolor)
  152. love.graphics.setBlendMode(mode, alphamode)
  153. end
  154. end
  155. -- LIST CONTENT
  156. -- y = l1: start line, y = l2: end line
  157. theme.draw.listContentPassive = function(self, x, y, l1, l2)
  158. local items = self.items
  159. if not items or #items == 0 then return end
  160. local theme = self.theme
  161. local itemh = theme.itemHeight
  162. local itempv = theme.itemPadVert
  163. local itemph = theme.itemPadHori
  164. local oldfont = love.graphics.getFont()
  165. local oldcolor = {love.graphics.getColor()}
  166. local advance = itemh + itempv
  167. local font = self.font
  168. local fonth = font:getHeight()
  169. local itemfore, itemback = theme.itemFore, theme.itemBack
  170. local width = self.width
  171. local text, icon, posx, posy
  172. love.graphics.setFont(font)
  173. local items, item = self.items, nil
  174. local start, finish = 1, #items
  175. if l1 and l2 then
  176. start = clamp(math.floor(l1 / advance) + 1, start, finish)
  177. finish = clamp(math.ceil(l2 / advance), start, finish)
  178. end
  179. for i = start, finish do
  180. item = items[i]
  181. posx, posy = x, y + (i - 1) * advance
  182. love.graphics.setColor(item.back or itemback)
  183. love.graphics.rectangle('fill', posx, posy, width, itemh)
  184. text = item.text
  185. icon = item.icon
  186. posx = posx + itemph
  187. if icon then
  188. love.graphics.setColor(item.fore or colorWhite)
  189. local iconw, iconh = icon:getDimensions()
  190. love.graphics.draw(icon, posx, posy + int((itemh - iconh) / 2))
  191. posx = posx + iconw + itemph
  192. end
  193. love.graphics.setColor(item.fore or (type(text) == "string" and itemfore or colorWhite))
  194. love.graphics.print(text, posx, posy + int((itemh - fonth) / 2))
  195. end
  196. love.graphics.setFont(oldfont)
  197. love.graphics.setColor(oldcolor)
  198. end
  199. -- SLIDER
  200. theme.draw.slider = function(self, x, y)
  201. local theme = self.theme
  202. x, y = x + self.x, y + self.y
  203. local fh = self.font:getHeight()
  204. love.graphics.setColor(theme.borderBack)
  205. love.graphics.rectangle('fill', x, y, self.width, self.height)
  206. love.graphics.setColor(theme.borderFore)
  207. love.graphics.rectangle('fill', x, int(y + self.height/2), self.width, 1)
  208. love.graphics.rectangle('fill', int(x + self.width/2), y, 1, self.height)
  209. love.graphics.setColor(1,0,0)
  210. love.graphics.printf(self.value, x, y + int((self.height - fh) / 2), self.width, "center")
  211. local boxes = self.boxes
  212. local box
  213. box = boxes.dec
  214. love.graphics.setColor(theme.itemBack)
  215. love.graphics.rectangle('fill', x + box.x, y + box.y, box.width, box.height)
  216. love.graphics.setColor(theme.itemFore)
  217. love.graphics.print("[<]", x + box.x, y + box.y + (box.height - fh) / 2)
  218. box = boxes.inc
  219. love.graphics.setColor(theme.itemBack)
  220. love.graphics.rectangle('fill', x + box.x, y + box.y, box.width, box.height)
  221. love.graphics.setColor(theme.itemFore)
  222. love.graphics.print("[>]", x + box.x, y + box.y + (box.height - fh) / 2)
  223. box = boxes.nob
  224. love.graphics.setColor(theme.borderFore)
  225. love.graphics.rectangle('fill', x + box.x, y + box.y, box.width, box.height)
  226. end
  227. BOXUI.add(theme)
  228. end