Advertisement
theinsekt

txUI (copy)

Sep 17th, 2014
272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.54 KB | None | 0 0
  1. --pastebin get Zf2esvzE txUI
  2. --this is a copy paste
  3. --I needed to make this copy because wanted to test some changes
  4. --copied from:
  5. --[[ http://www.computercraft.info/forums2/index.php?/topic/19575-txui-elegant-gui-components-with-application-framework-capabilities/ ]]
  6.  
  7. -- --
  8. -- txUI - ComputerCraft User Interface Library
  9. -- dev
  10. -- tuogex
  11. -- --
  12.  
  13. -- --
  14. -- UIManager @static
  15. -- Holds the windows of the program and handles events
  16. -- --
  17. UIManager = {}
  18. UIManager.prototype = {
  19.     --vars
  20.     windows = {};
  21.     --functions
  22.     drawAll = function(self)
  23.                 --change term to an invisible window
  24.                 local termCopy=term.native()
  25.                 local w,h=termCopy.getSize()
  26.                 local myWindow=window.create(termCopy, 1, 1, w, h,false)
  27.                 term.redirect(myWindow)
  28.  
  29.                 --original code
  30.         for key, val in pairs(self.windows) do
  31.             if (val.visible) then
  32.                 val:draw()
  33.             end
  34.         end
  35.  
  36.                 --set window to visible and restore term
  37.                 myWindow.setVisible(true)
  38.                 myWindow.redraw()
  39.                 term.redirect(termCopy)
  40.     end;
  41.     appUpdate = function(self, eventTbl) end;
  42.     startUpdateCycle = function(self)
  43.         local handleEvent = function()
  44.             local event = {os.pullEventRaw()}
  45.             if (event[1] == "terminate") then
  46.                 self:terminate()
  47.             elseif (event[1] == "mouse_click" or event[1] == "monitor_touch") then
  48.                 for key, val in pairs(self.windows) do
  49.                     if (val.visible and val:click(event[3], event[4], event[2])) then
  50.                         break
  51.                     end
  52.                 end
  53.             elseif (event[1] == "mouse_scroll") then
  54.                 for key, val in pairs(self.windows) do
  55.                     if (val.visible and val:scroll(event[2])) then
  56.                         break
  57.                     end
  58.                 end
  59.             elseif (event[1] == "mouse_drag") then
  60.                 for key, val in pairs(self.windows) do
  61.                     if (val.visible and val:drag(event[3], event[4], event[2])) then
  62.                         break
  63.                     end
  64.                 end
  65.             elseif (event[1] == "char") then
  66.                 for key, val in pairs(self.windows) do
  67.                     if (val.visible and val:char(event[2])) then
  68.                         break
  69.                     end
  70.                 end
  71.             elseif (event[1] == "key") then
  72.                 for key, val in pairs(self.windows) do
  73.                     if (val.visible and val:key(event[2])) then
  74.                         break
  75.                     end
  76.                 end
  77.             else
  78.                 for key, val in pairs(self.windows) do
  79.                     if (val.visible and val:event(event)) then
  80.                         break
  81.                     end
  82.                 end
  83.             end
  84.             return event
  85.         end
  86.         while (true) do
  87.             if (#self.windows == 0) then
  88.                 self:exit()
  89.             end
  90.             self:drawAll()
  91.             for key, val in pairs(self.windows) do
  92.                 if (val.visible) then
  93.                     val:update()
  94.                 end
  95.             end
  96.             local eventTbl = handleEvent()
  97.             self:appUpdate(eventTbl);
  98.             --close windows marked for close
  99.             local closed = {}
  100.             for key, val in pairs(self.windows) do
  101.                 if (val.closed) then
  102.                     table.insert(closed, key)
  103.                 end
  104.             end
  105.             for key, val in pairs(closed) do
  106.                 table.remove(self.windows, val)
  107.             end
  108.         end
  109.     end;
  110.     setVisibleWindow = function(self, windowTbl)
  111.         for key, val in pairs(self.windows) do
  112.             local wasVisible = val.visible
  113.             val.visible = (val == windowTbl)
  114.             if (not wasVisible) then
  115.                 val:onView()
  116.             end
  117.             if (wasVisible and not val.visible) then
  118.                 val:onHide()
  119.             end
  120.         end
  121.     end;
  122.     addWindow = function(self, windowTbl)
  123.         windowTbl.closed = false
  124.         table.insert(self.windows, windowTbl)
  125.     end;
  126.     closeWindow = function(self, windowTbl)
  127.         for key, val in pairs(self.windows) do
  128.             if (val == windowTbl) then
  129.                 val.closed = true
  130.             end
  131.         end
  132.     end;
  133.     terminate = function(self)
  134.         self:exit()
  135.     end;
  136.     exit = function(self)
  137.         term.setBackgroundColor(colors.black)
  138.         term.clear()
  139.         term.setCursorPos(1, 1)
  140.         error()
  141.     end;
  142. }
  143. UIManager.mt = {
  144.     __index = function (table, key)
  145.         return UIManager.prototype[key]
  146.     end;
  147. }
  148. setmetatable(UIManager, UIManager.mt)
  149.  
  150. -- --
  151. -- DrawUtils @static
  152. -- Utilities to aid in drawing
  153. -- --
  154. DrawUtils = {}
  155. DrawUtils.prototype = {
  156.     drawRect = function(self, x, y, w, h, color)
  157.         term.setBackgroundColor(color)
  158.         for pY = y, h - 1 + y, 1 do
  159.             term.setCursorPos(x, pY)
  160.             for pX = x, w - 1 + x, 1 do
  161.                 term.write(" ")
  162.             end
  163.         end
  164.     end;
  165.     alignText = function(self, alignment, textLength, x, w)
  166.         if (alignment == "left") then
  167.             return x
  168.         elseif (alignment == "center") then
  169.             return x + ((w - textLength) / 2)
  170.         elseif (alignment == "right") then
  171.             return x + (w - textLength)
  172.         end
  173.     end;
  174.     limitText = function(self, text, limit, tail)
  175.         if (string.len(text) > limit) then
  176.             return string.sub(text, 0, limit - string.len(tail)) .. tail
  177.         else
  178.             return text
  179.         end
  180.     end;
  181.     wrapText = function(self, text, limit)
  182.             local index = 0
  183.             return text:gsub("(%C?)", function (w)
  184.                 index = index + 1
  185.                 return w .. (index % limit == 0 and "\n" or "")
  186.             end)
  187.     end;
  188.     splitText = function(self, str, pat)
  189.         local t = {}
  190.         local fpat = "(.-)" .. pat
  191.         local last_end = 1
  192.         local s, e, cap = str:find(fpat, 1)
  193.         while s do
  194.             if (s ~= 1 or cap ~= "") then
  195.                 table.insert(t,cap)
  196.             end
  197.             last_end = e + 1
  198.             s, e, cap = str:find(fpat, last_end)
  199.         end
  200.         if (last_end <= #str) then
  201.             cap = str:sub(last_end)
  202.             table.insert(t, cap)
  203.         end
  204.         return t
  205.     end;
  206. }
  207. DrawUtils.mt = {
  208.     __index = function(table, key)
  209.         return DrawUtils.prototype[key]
  210.     end;
  211. }
  212. setmetatable(DrawUtils, DrawUtils.mt)
  213.  
  214. -- --
  215. -- Window
  216. -- Pretty self explainatory
  217. -- --
  218. Window = {}
  219. Window.prototype = {
  220.     -- vars
  221.     bgColor = colors.lightGray;
  222.     tlColor = colors.gray;
  223.     components = {};
  224.     titleLabel = {};
  225.     z = 0;
  226.     x = 1;
  227.     y = 1;
  228.     h = 1;
  229.     w = 1;
  230.     visible = false;
  231.     closed = false;
  232.     --functions
  233.     draw = function(self)
  234.         --drawPane
  235.         DrawUtils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)
  236.         --drawTitle
  237.         term.setBackgroundColor(self.tlColor)
  238.         term.setCursorPos(self.x, self.y)
  239.         for pX = self.x, self.w + self.x, 1 do
  240.             term.write(" ")
  241.         end
  242.         if (self.titleLabel ~= nil) then
  243.             self.titleLabel:draw()
  244.         end
  245.         --draw components
  246.         self:drawComponents()
  247.     end;
  248.     drawComponents = function(self)
  249.         for key, val in pairs(self.components) do
  250.             val:draw()
  251.         end
  252.     end;
  253.     setTitleLabel = function(self, newLabel)
  254.         newLabel.parent = self
  255.         self.titleLabel = newLabel
  256.     end;
  257.     addComponent = function(self, componentTbl)
  258.         componentTbl.parent = self
  259.         componentTbl.removed = false
  260.         table.insert(self.components, componentTbl)
  261.     end;
  262.     removeComponent = function(self, componentTbl)
  263.         for key, val in pairs(self.components) do
  264.             if (val == componentTbl) then
  265.                 val.removed = true
  266.             end
  267.         end
  268.     end;
  269.     close = function(self)
  270.         UIManager:closeWindow(self)
  271.     end;
  272.     click = function(self, x, y)
  273.         for key, val in pairs(self.components) do
  274.             val:click(x, y)
  275.         end
  276.     end;
  277.     key = function(self, keyCode)
  278.         for key, val in pairs(self.components) do
  279.             val:key(keyCode)
  280.         end
  281.     end;
  282.     char = function(self, char)
  283.         for key, val in pairs(self.components) do
  284.             val:char(char)
  285.         end
  286.     end;
  287.     scroll = function(self, direction)
  288.         for key, val in pairs(self.components) do
  289.             val:scroll(direction)
  290.         end
  291.     end;
  292.     drag = function(self, x, y)
  293.         for key, val in pairs(self.components) do
  294.             val:drag(x, y)
  295.         end
  296.     end;
  297.     event = function(self, eventTbl)
  298.         for key, val in pairs(self.components) do
  299.             val:event(eventTbl)
  300.         end
  301.     end;
  302.     onView = function(self)
  303.     end;
  304.     onHide = function(self)
  305.     end;
  306.     update = function(self)
  307.         local removed = {}
  308.         for key, val in pairs(self.components) do
  309.             if (val.removed) then
  310.                 table.insert(removed, key)
  311.             else
  312.                 val:update()
  313.             end
  314.         end
  315.         for key, val in pairs(removed) do
  316.             table.remove(self.components, val)
  317.         end
  318.     end;
  319. }
  320. Window.mt = {
  321.     __index = function (table, key)
  322.         return Window.prototype[key]
  323.     end;
  324. }
  325. function Window:new(windowTbl)
  326.     setmetatable(windowTbl, Window.mt)
  327.     windowTbl.components = {}
  328.     return windowTbl
  329. end
  330.  
  331. -- --
  332. -- Component @abstract
  333. -- Abstract class used to represent components in a window
  334. -- --
  335. Component = {}
  336. Component.prototype = {
  337.     --vars
  338.     x = 1;
  339.     y = 1;
  340.     h = 1;
  341.     w = 1;
  342.     z = 0;
  343.     parent = {};
  344.     removed = false;
  345.     --functions
  346.     draw = function(self) end;
  347.     click = function(self, x, y, button) return false end;
  348.     key = function(self, keyCode) return false end;
  349.     char = function(self, char) return false end;
  350.     scroll = function(self, direction) return false end;
  351.     drag = function(self, x, y, button) return false end;
  352.     event = function(self, eventTbl) return false end;
  353.     update = function(self) return false end;
  354.     termX = function(self) return self.x + self.parent.x - 1 end;
  355.     termY = function(self) return self.y + self.parent.y - 1 end;
  356. }
  357.  
  358. -- --
  359. -- Panel
  360. -- Pretty self explainatory
  361. -- --
  362. Panel = {}
  363. Panel.prototype = {
  364.     -- vars
  365.     bgColor = colors.lightGray;
  366.     components = {};
  367.     z = 0;
  368.     x = 1;
  369.     y = 1;
  370.     h = 1;
  371.     w = 1;
  372.     --functions
  373.     draw = function(self)
  374.         --drawPane
  375.         DrawUtils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)
  376.         --draw components
  377.         self:drawComponents()
  378.     end;
  379.     drawComponents = function(self)
  380.         for key, val in pairs(self.components) do
  381.             val:draw()
  382.         end
  383.     end;
  384.     addComponent = function(self, componentTbl)
  385.         componentTbl.parent = self
  386.         componentTbl.removed = false
  387.         table.insert(self.components, componentTbl)
  388.     end;
  389.     removeComponent = function(self, componentTbl)
  390.         for key, val in pairs(self.components) do
  391.             if (val == componentTbl) then
  392.                 val.removed = true
  393.             end
  394.         end
  395.     end;
  396.     close = function(self)
  397.         UIManager:closeWindow(self)
  398.     end;
  399.     click = function(self, x, y)
  400.         for key, val in pairs(self.components) do
  401.             val:click(x, y)
  402.         end
  403.     end;
  404.     key = function(self, keyCode)
  405.         for key, val in pairs(self.components) do
  406.             val:key(keyCode)
  407.         end
  408.     end;
  409.     char = function(self, char)
  410.         for key, val in pairs(self.components) do
  411.             val:char(char)
  412.         end
  413.     end;
  414.     scroll = function(self, direction)
  415.         for key, val in pairs(self.components) do
  416.             val:scroll(direction)
  417.         end
  418.     end;
  419.     drag = function(self, x, y)
  420.         for key, val in pairs(self.components) do
  421.             val:drag(x, y)
  422.         end
  423.     end;
  424.     event = function(self, eventTbl)
  425.         for key, val in pairs(self.components) do
  426.             val:event(eventTbl)
  427.         end
  428.     end;
  429.     update = function(self)
  430.         local removed = {}
  431.         for key, val in pairs(self.components) do
  432.             if (val.removed) then
  433.                 table.insert(removed, key)
  434.             else
  435.                 val:update()
  436.             end
  437.         end
  438.         for key, val in pairs(removed) do
  439.             table.remove(self.components, val)
  440.         end
  441.     end;
  442. }
  443. Panel.mt = {
  444.     __index = function (table, key)
  445.         if (Panel.prototype[key] ~= nil) then
  446.             return Panel.prototype[key]
  447.         else
  448.             return Component.prototype[key]
  449.         end
  450.     end;
  451. }
  452. function Panel:new(panelTbl)
  453.     setmetatable(panelTbl, Panel.mt)
  454.     panelTbl.components = {}
  455.     return panelTbl
  456. end
  457.  
  458. -- --
  459. -- Button extends Component
  460. -- A component that you can click
  461. -- --
  462. Button = {}
  463. Button.prototype = {
  464.     --vars
  465.     h = 3;
  466.     w = 16;
  467.     bgColor = colors.lightBlue;
  468.     textColor = colors.white;
  469.     activeColor = colors.blue;
  470.     activeTextColor = colors.white;
  471.     active = false;
  472.     text = "txUI Button";
  473.     textAlign = "center";
  474.     vertCenter = true;
  475.     --functions
  476.     action = function(self) end;
  477.     draw = function(self)
  478.         DrawUtils:drawRect(self:termX(), self:termY(), self.w, self.h, (function(self) if (self.active) then return self.activeColor else return self.bgColor end end)(self))
  479.         term.setTextColor((function(self) if (self.active) then return self.activeTextColor else return self.textColor end end)(self))
  480.         local lines = #DrawUtils:splitText(self.text, "\n")
  481.         for k, v in ipairs(DrawUtils:splitText(self.text, "\n")) do
  482.             term.setCursorPos(DrawUtils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))
  483.             term.write(v)
  484.         end
  485.     end;
  486.     click = function (self, x, y)
  487.         if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then
  488.             self.active = true
  489.             self:action()
  490.         else
  491.             self.active = false
  492.         end
  493.     end;
  494.     update = function(self) return false end;
  495. }
  496. Button.mt = {
  497.     __index = function (table, key)
  498.         if (Button.prototype[key] ~= nil) then
  499.             return Button.prototype[key]
  500.         else
  501.             return Component.prototype[key]
  502.         end
  503.     end;
  504. }
  505. function Button:new(buttonTbl)
  506.     if (buttonTbl == nil) then
  507.         buttonTbl = self
  508.     end
  509.     setmetatable(buttonTbl, Button.mt)
  510.     return buttonTbl
  511. end
  512.  
  513. -- --
  514. -- Label extends Component
  515. -- A component that displays text
  516. -- --
  517. Label = {}
  518. Label.prototype = {
  519.     --vars
  520.     h = 1;
  521.     w = 16;
  522.     bgColor = colors.white;
  523.     textColor = colors.black;
  524.     text = "txUI Label";
  525.     textAlign = "center";
  526.     vertCenter = true;
  527.     --functions
  528.     draw = function(self)
  529.         DrawUtils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)
  530.         term.setBackgroundColor(self.bgColor)
  531.         term.setTextColor(self.textColor)
  532.         local lines = #DrawUtils:splitText(self.text, "\n")
  533.         for k, v in ipairs(DrawUtils:splitText(self.text, "\n")) do
  534.             term.setCursorPos(DrawUtils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))
  535.             term.write(v)
  536.         end
  537.     end;
  538.     update = function(self) return false end;
  539. }
  540. Label.mt = {
  541.     __index = function (table, key)
  542.         if (Label.prototype[key] ~= nil) then
  543.             return Label.prototype[key]
  544.         else
  545.             return Component.prototype[key]
  546.         end
  547.     end;
  548. }
  549. function Label:new(labelTbl)
  550.     if (labelTbl == nil) then
  551.         labelTbl = self
  552.     end
  553.     setmetatable(labelTbl, Label.mt)
  554.     return labelTbl
  555. end
  556.  
  557. -- --
  558. -- TextField extends Component
  559. -- A component that allows for text input
  560. -- --
  561. TextField = {}
  562. TextField.prototype = {
  563.     --vars
  564.     h = 1;
  565.     w = 16;
  566.     bgColor = colors.white;
  567.     textColor = colors.black;
  568.     placeholderColor = colors.lightGray;
  569.     placeholder = "txUI TextField";
  570.     text = "";
  571.     textAlign = "left";
  572.     textMask = "";
  573.     active = false;
  574.     cursorPos = 0;
  575.     displayOffset = 0;
  576.     --functions
  577.     draw = function(self)
  578.         DrawUtils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)
  579.         term.setBackgroundColor(self.bgColor)
  580.         if (self.active or string.len(self.text) ~= 0) then
  581.             local toWrite = string.sub(self.text, self.displayOffset + 1, self.displayOffset + self.w)
  582.             if (string.len(self.textMask) ~= 0) then
  583.                 toWrite = string.gsub(toWrite, "%C", self.textMask)
  584.             end
  585.             term.setCursorPos(DrawUtils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))
  586.             term.setTextColor(self.textColor)
  587.             term.write(toWrite)
  588.         else
  589.             local toWrite = string.sub(self.placeholder, self.displayOffset + 1)
  590.             term.setCursorPos(DrawUtils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))
  591.             term.setTextColor(self.placeholderColor)
  592.             term.write(toWrite)
  593.         end
  594.         term.setCursorBlink(self.active)
  595.         if (self.active) then
  596.             term.setCursorPos(self:termX() + self.cursorPos - self.displayOffset, self:termY() + (self.h / 2))
  597.         end
  598.     end;
  599.     click = function (self, x, y)
  600.         if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then
  601.             self.active = true
  602.         else
  603.             self.active = false
  604.         end
  605.     end;
  606.     action = function(self)
  607.     end;
  608.     key = function(self, keyCode)
  609.         if (self.active == false) then
  610.             return
  611.         end
  612.         if (keyCode == keys.backspace) then
  613.             if (self.cursorPos > 0) then
  614.                 self.text = string.sub(self.text, 1, self.cursorPos - 1) .. string.sub(self.text, self.cursorPos + 1)
  615.                 self.cursorPos = self.cursorPos - 1
  616.                 if (self.cursorPos - self.displayOffset < 0) then
  617.                     self.displayOffset = self.displayOffset - 1
  618.                 end
  619.                 self:draw()
  620.             end
  621.         elseif (keyCode == keys.left) then
  622.             if (self.cursorPos > 0) then
  623.                 self.cursorPos = self.cursorPos - 1
  624.                 if (self.cursorPos - self.displayOffset < 0) then
  625.                     self.displayOffset = self.displayOffset - 1
  626.                 end
  627.                 self:draw()
  628.             end
  629.         elseif (keyCode == keys.right) then
  630.             if (self.cursorPos < string.len(self.text)) then
  631.                 self.cursorPos = self.cursorPos + 1
  632.                 if (self.cursorPos - self.displayOffset > self.w - 1) then
  633.                     self.displayOffset = self.displayOffset + 1
  634.                 end
  635.                 self:draw()
  636.             end
  637.         elseif (keyCode == keys.enter) then
  638.             self:action()
  639.         end
  640.     end;
  641.     char = function(self, char)
  642.         if (self.active == false) then
  643.             return
  644.         end
  645.         self.text = string.sub(self.text, 1, self.cursorPos) .. char .. string.sub(self.text, self.cursorPos + 1)
  646.         if (self.cursorPos - self.displayOffset > self.w - 2) then
  647.             self.displayOffset = self.displayOffset + 1
  648.         end
  649.         self.cursorPos = self.cursorPos + 1
  650.     end;
  651.     update = function(self)
  652.         if (self.active) then
  653.             self:draw()
  654.         end
  655.     end;
  656. }
  657. TextField.mt = {
  658.     __index = function (table, key)
  659.         if (TextField.prototype[key] ~= nil) then
  660.             return TextField.prototype[key]
  661.         else
  662.             return Component.prototype[key]
  663.         end
  664.     end;
  665. }
  666. function TextField:new(textFieldTbl)
  667.     if (textFieldTbl == nil) then
  668.         textFieldTbl = self
  669.     end
  670.     setmetatable(textFieldTbl, TextField.mt)
  671.     return textFieldTbl
  672. end
  673.  
  674. -- --
  675. -- List extends Component
  676. -- A component that lets you hold lists of other components
  677. -- --
  678. List = {}
  679. List.prototype = {
  680.     --vars
  681.     h = 5;
  682.     w = 16;
  683.     bgColor = colors.white;
  684.     bgColorStripe = colors.lightGray;
  685.     textColor = colors.black;
  686.     textColorStripe = colors.black;
  687.     activeColor = colors.gray;
  688.     activeTextColor = colors.white;
  689.     textAlign = "left";
  690.     scrollBarColor = colors.gray;
  691.     scrollBarTextColor = colors.white;
  692.     scrollBar = true;
  693.     wrapText = false;
  694.     displayOffset = 0;
  695.     components = {};
  696.     active = false;
  697.     --functions
  698.     draw = function(self)
  699.         DrawUtils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)
  700.         term.setBackgroundColor(self.bgColor)
  701.         -- draw the components
  702.         local index = 1
  703.         for key, val in pairs(self.components) do
  704.             val.w = self.w - (self.scrollBar and 1 or 0)
  705.             val.y = self.displayOffset + index
  706.             index = index + val.h
  707.             if ((val.y > 0) and (val.y <= self.h)) then
  708.                 val:draw()
  709.             end
  710.             self.components[key] = val
  711.         end
  712.         -- draw the scroll bar
  713.         if (self.scrollBar) then
  714.             DrawUtils:drawRect(self:termX() + self.w - 1, self:termY(), 1, self.h, self.scrollBarColor)
  715.             term.setBackgroundColor(self.scrollBarColor)
  716.             term.setTextColor(self.scrollBarTextColor)
  717.             term.setCursorPos(self:termX() + self.w - 1, self:termY())
  718.             term.write("^")
  719.             term.setCursorPos(self:termX() + self.w - 1, self:termY() + self.h - 1)
  720.             term.write("v")
  721.         end
  722.     end;
  723.     click = function (self, x, y)
  724.         for key, val in pairs(self.components) do
  725.             if ((val.y > 0) and (val.y <= self.h)) then
  726.                 val:click(x, y)
  727.             end
  728.         end
  729.         if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then
  730.             self.active = true
  731.         else
  732.             self.active = false
  733.         end
  734.         if (self.scrollBar) then
  735.             if ((x == self:termX() + self.w - 1) and (y == self:termY())) then
  736.                 if (self.displayOffset < 0) then
  737.                     self.displayOffset = self.displayOffset + 1
  738.                 end
  739.             end
  740.             if ((x == self:termX() + self.w - 1) and (y == self:termY() + self.h - 1)) then
  741.                 if (self.displayOffset > -#self.components + 1) then
  742.                     self.displayOffset = self.displayOffset - 1
  743.                 end
  744.             end
  745.         end
  746.     end;
  747.     scroll = function (self, direction)
  748.         if (self.active) then
  749.             if (direction == -1) then
  750.                 if (self.displayOffset < 0) then
  751.                     self.displayOffset = self.displayOffset + 1
  752.                 end
  753.             end
  754.             if (direction == 1) then
  755.                 if (self.displayOffset > -#self.components + 1) then
  756.                     self.displayOffset = self.displayOffset - 1
  757.                 end
  758.             end
  759.         end
  760.     end;
  761.     addComponent = function(self, componentTbl)
  762.         componentTbl.h = 1
  763.         componentTbl.w = self.w - (self.scrollBar and 1 or 0)
  764.         if (not self.wrapText) then
  765.             componentTbl.text = DrawUtils:limitText(componentTbl.text, componentTbl.w, "...")
  766.         else
  767.             if (string.len(componentTbl.text) > componentTbl.w) then
  768.                 componentTbl.h = math.ceil(string.len(componentTbl.text) / componentTbl.w)
  769.                 componentTbl.text = DrawUtils:wrapText(componentTbl.text, componentTbl.w)
  770.             end
  771.         end
  772.         componentTbl.bgColor = (#self.components % 2 == 0 and self.bgColor or self.bgColorStripe)
  773.         componentTbl.textColor = (#self.components % 2 == 0 and self.textColor or self.textColorStripe)
  774.         componentTbl.textAlign = self.textAlign
  775.         componentTbl.activeColor = self.activeColor
  776.         componentTbl.activeTextColor = self.activeTextColor
  777.         componentTbl.parent = self
  778.         componentTbl.removed = false
  779.         table.insert(self.components, componentTbl)
  780.     end;
  781.     update = function(self) return false end;
  782. }
  783. List.mt = {
  784.     __index = function (table, key)
  785.         if (List.prototype[key] ~= nil) then
  786.             return List.prototype[key]
  787.         else
  788.             return Component.prototype[key]
  789.         end
  790.     end;
  791. }
  792. function List:new(listTbl)
  793.     if (listTbl == nil) then
  794.         listTbl = self
  795.     end
  796.     setmetatable(listTbl, List.mt)
  797.     listTbl.components = {}
  798.     return listTbl
  799. end
  800.  
  801. -- --
  802. -- Checkbox extends Component
  803. -- A component that lets users make a boolean choice
  804. -- --
  805. Checkbox = {}
  806. Checkbox.prototype = {
  807.     --vars
  808.     h = 1;
  809.     w = 16;
  810.     bgColor = colors.lightGray;
  811.     boxColor = colors.white;
  812.     textColor = colors.black;
  813.     checkedChar = "X";
  814.     checked = false;
  815.     text = "txUI Checkbox";
  816.     textPosition = "right";
  817.     --functions
  818.     draw = function(self)
  819.         DrawUtils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)
  820.         -- draw box and set label position
  821.         term.setBackgroundColor(self.boxColor)
  822.         term.setTextColor(self.textColor)
  823.         if (self.textPosition == "right") then
  824.             DrawUtils:drawRect(self:termX(), self:termY(), 1, 1, self.boxColor)
  825.             term.setCursorPos(self:termX(), self:termY())
  826.             term.write(self.checked and self.checkedChar or " ")
  827.             term.setCursorPos(self:termX() + 2, self:termY())
  828.         elseif (self.textPosition == "left") then
  829.             DrawUtils:drawRect(self:termX() + self.w - 1, self:termY(), 1, 1, self.boxColor)
  830.             term.setCursorPos(self:termX() + self.w - 1, self:termY())
  831.             term.write(self.checked and self.checkedChar or " ")
  832.             term.setCursorPos(self:termX() + self.w - string.len(self.text) - 2, self:termY())
  833.         end
  834.         -- draw label
  835.         term.setBackgroundColor(self.bgColor)
  836.         term.write(self.text)
  837.     end;
  838.     click = function (self, x, y)
  839.         if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then
  840.             self.checked = not self.checked
  841.         end
  842.     end;
  843.     update = function(self) return false end;
  844. }
  845. Checkbox.mt = {
  846.     __index = function (table, key)
  847.         if (Checkbox.prototype[key] ~= nil) then
  848.             return Checkbox.prototype[key]
  849.         else
  850.             return Component.prototype[key]
  851.         end
  852.     end;
  853. }
  854. function Checkbox:new(checkboxTbl)
  855.     if (checkboxTbl == nil) then
  856.         checkboxTbl = self
  857.     end
  858.     setmetatable(checkboxTbl, Checkbox.mt)
  859.     return checkboxTbl
  860. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement