Advertisement
oGoOgO

gui g

Jun 29th, 2024 (edited)
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.86 KB | None | 0 0
  1. local event = require("event")
  2. local gpu = require("component").gpu
  3. local math = require("math")
  4. local keyboardEvent = require("keyboardEvent")
  5. local CountDownLatch = require("countDownLatch")
  6. local logger = require("logger")
  7.  
  8. local log = logger.getLogger("gui")
  9.  
  10. local ALIGN = {
  11. left = "left",
  12. right = "right",
  13. center = "center"
  14. }
  15.  
  16. local COLORS = {
  17. blue = 0x4286F4,
  18. purple = 0xB673d6,
  19. red = 0xC14141,
  20. lightGreen = 0x7ED321,
  21. green = 0xDA841,
  22. pink = 0xF4A7B9,
  23. yellow = 0xfff950,
  24. black = 0x000000,
  25. white = 0xFFFFFF,
  26. grey = 0x47494C,
  27. lightGrey = 0xBBBBBB
  28. }
  29.  
  30. local disabled = false
  31. function debug(...)
  32. if disabled then return end
  33. local bg = gpu.getBackground()
  34. local fg = gpu.getForeground()
  35. gpu.setBackground(COLORS.black)
  36. gpu.setForeground(COLORS.white)
  37. print(...)
  38. gpu.setBackground(bg)
  39. gpu.setForeground(fg)
  40. end
  41.  
  42. local function truncateString(str, width, padding)
  43. if string.len(str) > (width - padding) then
  44. local maxLen = width - padding - 2
  45. local halfLen = math.floor(maxLen / 2)
  46. local rmHalfLen = math.ceil((string.len(str) - maxLen) / 2)
  47. local truncatedStr = string.sub(str, 1, halfLen - rmHalfLen) .. ".." .. string.sub(str, -halfLen + rmHalfLen)
  48. return truncatedStr
  49. end
  50. return str
  51. end
  52.  
  53. local function addFillersOnString(str, align, filler, number_filler)
  54. local fillerCount = math.floor(number_filler / 2)
  55. local leftFiller = string.rep(filler, fillerCount)
  56. local rightFiller = string.rep(filler, number_filler - fillerCount)
  57.  
  58. if align == "left" then
  59. return str .. rightFiller
  60. elseif align == "right" then
  61. return leftFiller .. str
  62. elseif align == "center" then
  63. return leftFiller .. str .. rightFiller
  64. else
  65. return str
  66. end
  67. end
  68.  
  69. local function addPaddingOnString(str, padding, filler)
  70. if padding < 0 then
  71. return str
  72. end
  73. return string.rep(filler, padding) .. str .. string.rep(filler, padding)
  74. end
  75.  
  76. local Component = {}
  77.  
  78. function Component:new(name, x, y, width, height)
  79. local obj = {
  80. name = name,
  81. x = x,
  82. y = y,
  83. xMin = x,
  84. yMin = y,
  85. xMax = x + width - 1,
  86. yMax = y + height - 1,
  87. width = width,
  88. height = height,
  89. parent = nil,
  90. isHidden = false,
  91. disabled = false,
  92. onTouchCallback = nil,
  93. gpu = gpu,
  94. rerender = true,
  95. components = {},
  96. componentsPrioritized = {},
  97. defaultBackgroundColor = COLORS.black
  98. }
  99. self.__index = self
  100. return setmetatable(obj, self)
  101. end
  102.  
  103. function Component:init()
  104. table.sort(self.componentsPrioritized, function(a, b)
  105. return a.renderPriority < b.renderPriority
  106. end)
  107. end
  108.  
  109. function Component:setOnTouch(callback)
  110. self.onTouchCallback = callback
  111. end
  112.  
  113. function Component:hide()
  114. if self.isHidden then return end
  115. self.isHidden = true
  116. self.rerender = true
  117. end
  118.  
  119. function Component:show()
  120. if not self.isHidden then return end
  121. self.isHidden = false
  122. self.rerender = true
  123. end
  124.  
  125. function Component:setParent(parent)
  126. self.parent = parent
  127. end
  128.  
  129. function Component:getAbsXY()
  130. if self.parent and self.parent.getAbsXY then
  131. local absParentX, absParentY = self.parent:getAbsXY()
  132. return self.x + absParentX, self.y + absParentY
  133. end
  134. return self.x, self.y
  135. end
  136.  
  137. function Component:setPosition(x, y)
  138. if self.x ~= x or self.y ~= y then
  139. self.rerender = true
  140. end
  141. self.x = x
  142. self.y = y
  143. end
  144.  
  145. function Component:setSize(width, height)
  146. if self.width ~= width or self.height ~= height then
  147. self.rerender = true
  148. end
  149. self.width = width
  150. self.height = height
  151. self.xMax = self.x + width - 1
  152. self.yMax = self.y + height - 1
  153. end
  154.  
  155. function Component:isTouched(x, y)
  156. local absParentX, absParentY = self.parent:getAbsXY()
  157. local xMix = self.xMin + absParentX
  158. local xMax = self.xMax + absParentX
  159. local yMin = self.yMin + absParentY
  160. local yMax = self.yMax + absParentY
  161. if x >= xMix and x <= xMax and y >= yMin and y <= yMax then
  162. return true
  163. end
  164. return false
  165. end
  166.  
  167. function Component:notTouch(x, y)
  168. for _, component in pairs(self.components) do
  169. if component:isTouched(x, y) then
  170. component:onTouch(x, y)
  171. else
  172. component:notTouch(x, y)
  173. end
  174. end
  175. end
  176.  
  177. function Component:onTouch(x, y)
  178. if self.onTouchCallback then
  179. self.onTouchCallback(self, x, y)
  180. end
  181. for _, component in pairs(self.components) do
  182. if component:isTouched(x, y) then
  183. component:onTouch(x, y)
  184. else
  185. component:notTouch(x, y)
  186. end
  187. end
  188. end
  189.  
  190. function Component:addComponent(component, renderPriority)
  191. component:setParent(self)
  192. self.components[component.name] = component
  193. table.insert(self.componentsPrioritized, { renderPriority = renderPriority, component = component })
  194. end
  195.  
  196. function Component:render()
  197. for _, prioritized in pairs(self.componentsPrioritized) do
  198. prioritized.component:render()
  199. end
  200. end
  201.  
  202. local Screen = {}
  203. setmetatable(Screen, { __index = Component })
  204.  
  205. function Screen:new(width, height, backgroundColor)
  206. local obj = Component.new(self, "Screen", 1, 1, width, height)
  207. obj.backgroundColor = backgroundColor
  208. gpu.setResolution(width, height)
  209. gpu.setBackground(backgroundColor)
  210. gpu.fill(obj.x, obj.y, width, height, " ")
  211. return obj
  212. end
  213.  
  214. function Screen:init()
  215. table.sort(self.componentsPrioritized, function(a, b)
  216. return a.renderPriority < b.renderPriority
  217. end)
  218.  
  219. for _, component in pairs(self.components) do
  220. component:init()
  221. end
  222.  
  223. event.listen("touch", function(_, _, x, y, _, _)
  224. for _, component in pairs(self.componentsPrioritized) do
  225. if component.component:isTouched(x, y) then
  226. component.component:onTouch(x, y)
  227. else
  228. component.component:notTouch(x, y)
  229. end
  230. end
  231. end)
  232. end
  233.  
  234. function Screen:addComponent(component, renderPriority)
  235. component:setParent(self)
  236. self.components[component.name] = component
  237. table.insert(self.componentsPrioritized, { renderPriority = renderPriority, component = component })
  238. end
  239.  
  240. function Screen:getComponent(componentName)
  241. return self.components[componentName]
  242. end
  243.  
  244. function Screen:render()
  245. for _, component in pairs(self.components) do
  246. component:render()
  247. end
  248. self.gpu.setBackground(COLORS.black)
  249. self.gpu.setForeground(COLORS.white)
  250. end
  251.  
  252. local Section = {}
  253. setmetatable(Section, { __index = Component })
  254.  
  255. function Section:new(name, x, y, width, height, title, borderColor, titleColor, titleBackground)
  256. local obj = Component.new(self, name, x, y, width, height)
  257. obj.borderColor = borderColor
  258. obj.titleColor = titleColor
  259. obj.titleBackground = titleBackground
  260. obj.title = title
  261. obj.rerender = true
  262. return obj
  263. end
  264.  
  265. function Section:setTitle(title, borderColor, titleColor, titleBackground)
  266. if title and title ~= self.title then
  267. self.title = title
  268. self.rerender = true
  269. end
  270. if borderColor and borderColor ~= self.borderColor then
  271. self.borderColor = borderColor
  272. self.rerender = true
  273. end
  274. if titleColor and titleColor ~= self.titleColor then
  275. self.titleColor = titleColor
  276. self.rerender = true
  277. end
  278. if titleBackground and titleBackground ~= self.titleBackground then
  279. self.titleBackground = titleBackground
  280. self.rerender = true
  281. end
  282. end
  283.  
  284. function Section:render()
  285. if self.rerender then
  286. local x = self.x + self.parent.x
  287. local y = self.y + self.parent.y
  288. local xMax = self.xMax + self.parent.x
  289. local yMax = self.yMax + self.parent.y
  290. self.gpu.setBackground(self.defaultBackgroundColor)
  291. self.gpu.fill(x, y, self.width, self.height, " ")
  292. self.gpu.setBackground(self.borderColor)
  293. self.gpu.fill(x, y, self.width, 1, " ")
  294. self.gpu.fill(x, y, 2, self.height, " ")
  295. self.gpu.fill(x, yMax, self.width, 1, " ")
  296. self.gpu.fill(xMax - 1, y, 2, self.height, " ")
  297. self.gpu.setBackground(self.titleBackground)
  298. self.gpu.setForeground(self.titleColor)
  299. self.gpu.fill(x + 4, y, string.len(self.title) + 2, 1, " ")
  300. self.gpu.set(x + 5, y, self.title)
  301. self.rerender = false
  302. end
  303. for _, prioritized in pairs(self.componentsPrioritized) do
  304. prioritized.component:render()
  305. end
  306. end
  307.  
  308. local Label = {}
  309. setmetatable(Label, { __index = Component })
  310.  
  311. function Label:new(name, x, y, width, padding, text, textColor, backgroundColor)
  312. local obj = Component.new(self, name, x, y, width, 1)
  313. obj.text = text
  314. obj.render_text = truncateString(text, width, padding)
  315. obj.textColor = textColor
  316. obj.backgroundColor = backgroundColor
  317. obj.padding = padding
  318. obj.align = ALIGN.left
  319. return obj
  320. end
  321.  
  322. function Label:setText(text)
  323. if text and text ~= self.text then
  324. self.text = text
  325. self.render_text = truncateString(self.text, self.width, self.padding)
  326. self.rerender = true
  327. end
  328. end
  329.  
  330. function Label:setTextColor(textColor)
  331. if textColor and textColor ~= self.textColor then
  332. self.textColor = textColor
  333. self.rerender = true
  334. end
  335. end
  336.  
  337. function Label:setBackgroundColor(backgroundColor)
  338. if backgroundColor and backgroundColor ~= self.backgroundColor then
  339. self.backgroundColor = backgroundColor
  340. self.rerender = true
  341. end
  342. end
  343.  
  344. function Label:setAlign(align)
  345. if align and align ~= self.align then
  346. self.align = align
  347. self.rerender = true
  348. end
  349. end
  350.  
  351. function Label:setPadding(padding)
  352. if padding and padding ~= self.padding then
  353. self.padding = padding
  354. self.render_text = truncateString(self.text, self.width, self.padding)
  355. self.rerender = true
  356. end
  357. end
  358.  
  359. function Label:render()
  360. if self.rerender then
  361. local absParentX, absParentY = self.parent:getAbsXY()
  362. local x = self.x + absParentX
  363. local y = self.y + absParentY
  364. self.gpu.setBackground(self.defaultBackgroundColor)
  365. self.gpu.fill(x, y, self.width, 1, " ")
  366. if not self.isHidden then
  367. self.gpu.setBackground(self.backgroundColor)
  368. self.gpu.setForeground(self.textColor)
  369. self.gpu.fill(x, y, self.width, 1, " ")
  370. local render_text = addFillersOnString(self.render_text, self.align, " ",
  371. self.width - string.len(self.render_text) - self.padding * 2)
  372. render_text = addPaddingOnString(render_text, self.padding, " ")
  373. self.gpu.set(x, y, render_text)
  374. end
  375. self.rerender = false
  376. end
  377. for _, prioritized in pairs(self.componentsPrioritized) do
  378. prioritized.component:render()
  379. end
  380. end
  381.  
  382. local Button = {}
  383. setmetatable(Button, { __index = Component })
  384.  
  385. function Button:new(name, x, y, width, height, text, textColor, backgroundColor)
  386. local obj = Component.new(self, name, x, y, width, height)
  387. obj.text = text
  388. obj.textColor = textColor
  389. obj.backgroundColor = backgroundColor
  390. return obj
  391. end
  392.  
  393. function Button:setText(text)
  394. if text and text ~= self.text then
  395. self.text = text
  396. self.rerender = true
  397. end
  398. end
  399.  
  400. function Button:setTextColor(textColor)
  401. if textColor and textColor ~= self.textColor then
  402. self.textColor = textColor
  403. self.rerender = true
  404. end
  405. end
  406.  
  407. function Button:setBackgroundColor(backgroundColor)
  408. if backgroundColor and backgroundColor ~= self.backgroundColor then
  409. self.backgroundColor = backgroundColor
  410. self.rerender = true
  411. end
  412. end
  413.  
  414. function Button:render()
  415. if self.rerender then
  416. local absParentX, absParentY = self.parent:getAbsXY()
  417. local x = self.x + absParentX
  418. local y = self.y + absParentY
  419. self.gpu.setBackground(self.backgroundColor)
  420. self.gpu.fill(x, y, self.width, self.height, " ")
  421. self.gpu.setForeground(self.textColor)
  422. local render_text = addFillersOnString(self.text, self.align, " ", self.width - string.len(self.text))
  423. local textX = x + math.floor((self.width - string.len(self.text)) / 2)
  424. local textY = y + math.floor(self.height / 2)
  425. self.gpu.set(textX, textY, render_text)
  426. self.rerender = false
  427. end
  428. for _, prioritized in pairs(self.componentsPrioritized) do
  429. prioritized.component:render()
  430. end
  431. end
  432.  
  433. local ScrollBar = {}
  434. setmetatable(ScrollBar, { __index = Component })
  435.  
  436. function ScrollBar:new(name, x, y, height, textColor, backgroundColor)
  437. local obj = Component.new(self, name, x, y, 1, height)
  438. obj.currentPos = 1
  439. obj.maxPos = 1
  440. obj.textColor = textColor
  441. obj.backgroundColor = backgroundColor
  442. return obj
  443. end
  444.  
  445. function ScrollBar:setMaxPos(maxPos)
  446. if maxPos and maxPos ~= self.maxPos then
  447. self.maxPos = maxPos
  448. self.rerender = true
  449. end
  450. end
  451.  
  452. function ScrollBar:setCurrentPos(currentPos)
  453. if currentPos and currentPos ~= self.currentPos then
  454. self.currentPos = currentPos
  455. self.rerender = true
  456. end
  457. end
  458.  
  459. function ScrollBar:scrollUp()
  460. if self.currentPos > 1 then
  461. self:setCurrentPos(self.currentPos - 1)
  462. end
  463. end
  464.  
  465. function ScrollBar:scrollDown()
  466. if self.currentPos < self.maxPos then
  467. self:setCurrentPos(self.currentPos + 1)
  468. end
  469. end
  470.  
  471. function ScrollBar:yToBarPos(y, absParentY)
  472. local relativeY = y - absParentY
  473. local maxBarHeight = self.height - 4
  474. local pos = math.ceil((relativeY - 2) / maxBarHeight * self.maxPos)
  475. return math.min(pos, self.maxPos)
  476. end
  477.  
  478. function ScrollBar:isScrollUpTouched(x, y, absParentX, absParentY)
  479. local xMin = self.xMin + absParentX
  480. local xMax = self.xMax + absParentX
  481. local yMin = self.yMin + absParentY
  482. local yMax = self.yMin + absParentY
  483. if x >= xMin and x <= xMax and y >= yMin and y <= yMax then
  484. return true
  485. end
  486. return false
  487. end
  488.  
  489. function ScrollBar:isScrollDownTouched(x, y, absParentX, absParentY)
  490. local xMin = self.xMin + absParentX
  491. local xMax = self.xMax + absParentX
  492. local yMin = self.yMax + absParentY
  493. local yMax = self.yMax + absParentY
  494. if x >= xMin and x <= xMax and y >= yMin and y <= yMax then
  495. return true
  496. end
  497. return false
  498. end
  499.  
  500. function ScrollBar:isBarTouched(x, y, absParentX, absParentY)
  501. local xMin = self.xMin + absParentX
  502. local xMax = self.xMax + absParentX
  503. local yMin = self.yMin + absParentY + 2
  504. local yMax = self.yMax + absParentY - 2
  505. if x >= xMin and x <= xMax and y >= yMin and y <= yMax then
  506. return true
  507. end
  508. return false
  509. end
  510.  
  511. function ScrollBar:render()
  512. if self.rerender then
  513. local absParentX, absParentY = self.parent:getAbsXY()
  514. local x = self.x + absParentX
  515. local y = self.y + absParentY
  516. self.gpu.setBackground(self.defaultBackgroundColor)
  517. self.gpu.fill(x, y, self.width, self.height, " ")
  518. self.gpu.setBackground(self.backgroundColor)
  519. self.gpu.setForeground(self.textColor)
  520. self.gpu.set(x, y, "^")
  521. self.gpu.set(x, y + self.height - 1, "v")
  522. local barHeight = math.ceil((self.height - 4) / self.maxPos)
  523. local barStart = y + 2 + barHeight * (self.currentPos - 1)
  524. if self.currentPos == self.maxPos then
  525. local ajustedBarHeight = barStart + barHeight - (self.yMax + absParentY - 1)
  526. self.gpu.fill(x, barStart, self.width, barHeight - ajustedBarHeight, "▒")
  527. else
  528. self.gpu.fill(x, barStart, self.width, barHeight, "▒")
  529. end
  530. self.rerender = false
  531. end
  532. end
  533.  
  534. local TextArea = {}
  535. setmetatable(TextArea, { __index = Component })
  536.  
  537. function TextArea:new(name, x, y, width, height, textColor, backgroundColor)
  538. local obj = Component.new(self, name, x, y, width, height)
  539. obj.lines = {}
  540. obj.textColor = textColor
  541. obj.backgroundColor = backgroundColor
  542. return obj
  543. end
  544.  
  545. function TextArea:setText(lines)
  546. self.lines = lines
  547. self.rerender = true
  548. end
  549.  
  550. function TextArea:setTextColor(textColor)
  551. if textColor and textColor ~= self.textColor then
  552. self.textColor = textColor
  553. self.rerender = true
  554. end
  555. end
  556.  
  557. function TextArea:setBackgroundColor(backgroundColor)
  558. if backgroundColor and backgroundColor ~= self.backgroundColor then
  559. self.backgroundColor = backgroundColor
  560. self.rerender = true
  561. end
  562. end
  563.  
  564. function TextArea:wrapText(text)
  565. local lines = {}
  566. local currentLine = ""
  567. for word in text:gmatch("%S+") do
  568. if #currentLine + #word <= self.width then
  569. currentLine = currentLine .. word .. " "
  570. else
  571. table.insert(lines, currentLine)
  572. currentLine = word .. " "
  573. end
  574. end
  575. table.insert(lines, currentLine)
  576. return lines
  577. end
  578.  
  579. function TextArea:render()
  580. if self.rerender then
  581. local absParentX, absParentY = self.parent:getAbsXY()
  582. local x = self.x + absParentX
  583. local y = self.y + absParentY
  584. self.gpu.setBackground(self.defaultBackgroundColor)
  585. self.gpu.fill(x, y, self.width, self.height, " ")
  586. self.gpu.setBackground(self.backgroundColor)
  587. self.gpu.setForeground(self.textColor)
  588. for i, line in pairs(self.lines) do
  589. self.gpu.set(x, y + i - 1, line)
  590. end
  591. self.rerender = false
  592. end
  593. end
  594.  
  595. local List = {}
  596. setmetatable(List, { __index = Component })
  597.  
  598. function List:new(name, x, y, width, height, maxItemsSize, textColor, backgroundColor)
  599. local obj = Component.new(self, name, x, y, width, height)
  600. obj.textList = {}
  601. obj.maxItemsSize = maxItemsSize
  602. obj.textColor = textColor
  603. obj.backgroundColor = backgroundColor
  604. obj.padding = 2
  605. obj.align = ALIGN.left
  606.  
  607. for i = 1, maxItemsSize do
  608. local label = Label:new(name .. "_label_" .. i, 0, 0 + (i - 1) * 2, width, obj.padding, "", textColor,
  609. backgroundColor)
  610. label.idx = i
  611. label:hide()
  612. obj:addComponent(label, i)
  613. end
  614. return obj
  615. end
  616.  
  617. function List:setTextList(textList)
  618. self.textList = textList
  619. for _, prioritizedComponent in pairs(self.componentsPrioritized) do
  620. local label = prioritizedComponent.component
  621. if textList[label.idx] then
  622. label:setText(textList[label.idx])
  623. label:show()
  624. else
  625. label:hide()
  626. label.setText("")
  627. end
  628. end
  629. end
  630.  
  631. function List:setTextColor(textColor)
  632. if textColor and textColor ~= self.textColor then
  633. for _, component in pairs(self.components) do
  634. component:setTextColor(textColor)
  635. end
  636. self.rerender = true
  637. end
  638. end
  639.  
  640. function List:setBackgroundColor(backgroundColor)
  641. if backgroundColor and backgroundColor ~= self.backgroundColor then
  642. for _, component in pairs(self.components) do
  643. component:setBackgroundColor(backgroundColor)
  644. end
  645. self.rerender = true
  646. end
  647. end
  648.  
  649. function List:setAlign(align)
  650. if align and align ~= self.align then
  651. for _, component in pairs(self.components) do
  652. component:setAlign(align)
  653. end
  654. self.rerender = true
  655. end
  656. end
  657.  
  658. function List:setPadding(padding)
  659. if padding and padding ~= self.padding then
  660. for _, component in pairs(self.components) do
  661. component:setPadding(padding)
  662. end
  663. self.rerender = true
  664. end
  665. end
  666.  
  667. function List:setOnTouch(callback)
  668. for _, component in pairs(self.components) do
  669. component:setOnTouch(callback)
  670. end
  671. end
  672.  
  673. function List:addComponent(component, renderPriority)
  674. if getmetatable(component) ~= Label then
  675. return
  676. end
  677. component:setParent(self)
  678. self.components[component.name] = component
  679. table.insert(self.componentsPrioritized, { renderPriority = renderPriority, component = component })
  680. end
  681.  
  682. function List:render()
  683. for _, component in pairs(self.components) do
  684. component:render()
  685. end
  686. end
  687.  
  688. local InputBox = {}
  689. setmetatable(InputBox, { __index = Component })
  690.  
  691. function InputBox:new(name, x, y, width, textColor, backgroundColor)
  692. local obj = Component.new(self, name, x, y, width, 1)
  693. obj.text = ""
  694. obj.focus = false
  695. obj.textColor = textColor
  696. obj.onChangeDelayTime = 0.5
  697. obj.onChangeCallback = nil
  698. obj.currCursor = "_"
  699. obj.cursorBlinkEventId = nil
  700. obj.countDownLatch = CountDownLatch:new(0)
  701. obj.backgroundColor = backgroundColor
  702. return obj
  703. end
  704.  
  705. function InputBox:setText(text)
  706. if text and text ~= self.text then
  707. self.text = text
  708. self.rerender = true
  709. end
  710. end
  711.  
  712. function InputBox:registerKeyDown()
  713. keyboardEvent.register("inputBox_" .. self.name,
  714. function(eventName, addr, char, key, player)
  715. return self.focus
  716. end,
  717. function(eventName, addr, char, key, player)
  718. if char ~= 0 and key ~= 14 and string.len(self.text) < self.width - 1 then
  719. self:setText(self.text .. string.char(char))
  720. self:onChangeDelay()
  721. elseif key == 14 and string.len(self.text) > 0 then
  722. self:setText(string.sub(self.text, 1, -2))
  723. self:onChangeDelay()
  724. end
  725. end)
  726. end
  727.  
  728. function InputBox:isTouched(x, y)
  729. local absParentX, absParentY = self.parent:getAbsXY()
  730. local xMix = self.xMin + absParentX
  731. local xMax = self.xMax + absParentX
  732. local yMin = self.yMin + absParentY
  733. local yMax = self.yMax + absParentY
  734. if x >= xMix and x <= xMax and y >= yMin and y <= yMax then
  735. self.focus = true
  736. self:cursorBlink()
  737. return true
  738. end
  739. self.focus = false
  740. self:cursorBlink()
  741. self.rerender = true
  742. return false
  743. end
  744.  
  745. function InputBox:cursorBlink()
  746. if self.focus and self.cursorBlinkEventId == nil then
  747. local absParentX, absParentY = self.parent:getAbsXY()
  748. local x = self.x + absParentX
  749. local y = self.y + absParentY
  750. self.cursorBlinkEventId = event.timer(0.5, function()
  751. local currbg = self.gpu.getBackground()
  752. if (self.currCursorChar == "_") then
  753. self.gpu.setBackground(self.textColor)
  754. self.currCursorChar = " "
  755. else
  756. self.gpu.setBackground(self.backgroundColor)
  757. self.currCursorChar = "_"
  758. end
  759. self.gpu.set(x + string.len(self.text), y, self.currCursorChar)
  760. self.gpu.setBackground(currbg)
  761. end, math.huge)
  762. elseif not self.focus and self.cursorBlinkEventId ~= nil then
  763. event.cancel(self.cursorBlinkEventId)
  764. self.cursorBlinkEventId = nil
  765. self.rerender = true
  766. end
  767. end
  768.  
  769. function InputBox:onChangeDelay()
  770. self.countDownLatch:countUp()
  771. event.timer(self.onChangeDelayTime, function(...)
  772. self.countDownLatch:countDown()
  773. if self.countDownLatch:isZero() then
  774. self:onChangeCallBack(self)
  775. end
  776. end, 1)
  777. end
  778.  
  779. function InputBox:setOnchangeDelayTime(time)
  780. self.onChangeDelayTime = time
  781. end
  782.  
  783. function InputBox:setOnChange(callback)
  784. self.onChangeCallBack = callback
  785. end
  786.  
  787. function InputBox:render()
  788. local absParentX, absParentY, x, y = nil, nil, nil, nil
  789. if self.rerender then
  790. if absParentX == nil or absParentY == nil then
  791. local absParentX, absParentY = self.parent:getAbsXY()
  792. x = self.x + absParentX
  793. y = self.y + absParentY
  794. end
  795. self.gpu.setBackground(self.defaultBackgroundColor)
  796. self.gpu.fill(x, y, self.width, 1, " ")
  797. self.gpu.setBackground(self.backgroundColor)
  798. self.gpu.setForeground(self.textColor)
  799. self.gpu.fill(x, y, self.width, 1, "_")
  800. self.gpu.set(x, y, self.text)
  801. if self.focus then
  802. local currbg = self.gpu.getBackground()
  803. self.gpu.setBackground(self.textColor)
  804. self.currCursorChar = " "
  805. self.gpu.set(x + string.len(self.text), y, " ")
  806. self.gpu.setBackground(currbg)
  807. end
  808. self.rerender = false
  809. end
  810. for _, prioritized in pairs(self.componentsPrioritized) do
  811. prioritized.component:render()
  812. end
  813. end
  814.  
  815. local Fill = {}
  816. setmetatable(Fill, { __index = Component })
  817.  
  818. function Fill:new(name, x, y, width, height, char, color)
  819. local obj = Component.new(self, name, x, y, width, height)
  820. obj.char = char
  821. obj.color = color
  822. return obj
  823. end
  824.  
  825. function Fill:setColor(color)
  826. if color and color ~= self.color then
  827. self.color = color
  828. self.rerender = true
  829. end
  830. end
  831.  
  832. function Fill:setChar(char)
  833. if char and char ~= self.char then
  834. self.char = char
  835. self.rerender = true
  836. end
  837. end
  838.  
  839. function Fill:render()
  840. if self.rerender then
  841. local absParentX, absParentY = self.parent:getAbsXY()
  842. local x = self.x + absParentX
  843. local y = self.y + absParentY
  844. self.gpu.setBackground(self.defaultBackgroundColor)
  845. self.gpu.setForeground(self.color)
  846. self.gpu.fill(x, y, self.width, self.height, self.char)
  847. self.rerender = false
  848. end
  849. for _, prioritized in pairs(self.componentsPrioritized) do
  850. prioritized.component:render()
  851. end
  852. end
  853.  
  854.  
  855. return {
  856. Screen = Screen,
  857. Section = Section,
  858. Label = Label,
  859. Button = Button,
  860. ScrollBar = ScrollBar,
  861. TextArea = TextArea,
  862. List = List,
  863. COLORS = COLORS,
  864. InputBox = InputBox,
  865. Fill = Fill,
  866. debug = debug
  867. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement