Advertisement
AquaJD

Budj

Sep 13th, 2017
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.54 KB | None | 0 0
  1. --[[
  2.  
  3.     Budj
  4.     By Dave-ee Jones
  5.  
  6.     GUI API
  7.     - Boards (things you stick GUI objects on)
  8.     - Buttons (things you click)
  9.     - Checkboxes (things you toggle)
  10.    
  11. --]]
  12.  
  13. -- Metatables
  14. BOARD = {}
  15. BUTTON = {}
  16. CHECKBOX = {}
  17. BOARD.__index = BOARD
  18. BUTTON.__index = BUTTON
  19. CHECKBOX.__index = CHECKBOX
  20.  
  21. -- Storage tables
  22. local t_BOARDS = {}
  23. local t_BUTTONS = {}
  24. local t_CHECKBOXES = {}
  25.  
  26. --[[ BUDJ FUNCTIONS ]]--
  27.  
  28. local oldError = error
  29.  
  30. function error(_STRING)
  31.     printError("Uh Oh! Budj errored out!")
  32.     printError("Error: ".._STRING)
  33.     oldError("",0)
  34. end
  35.  
  36. -- Lets Budj handle events
  37. local heldObject = nil
  38. function handleEvent(...)
  39.     local _EVENT = { ... }
  40.     if _EVENT[1] == "mouse_click" then
  41.         if #t_BOARDS > 0 then
  42.             for i=1,#t_BOARDS do -- Go through all the boards
  43.                 for v=1,#t_BOARDS[i].OBJECTS do -- Go through all objects in a Board
  44.                     if t_BOARDS[i].OBJECTS[v].ACTIVE and t_BOARDS[i].OBJECTS[v].DRAWN then
  45.                         if _EVENT[2] == 1 then -- Mouse button 1
  46.                             if _EVENT[3] >= t_BOARDS[i].OBJECTS[v].X and _EVENT[3] <= (t_BOARDS[i].OBJECTS[v].X + t_BOARDS[i].OBJECTS[v].W - 1) then
  47.                                 -- If mouse X is in range of object's X bounds
  48.                                 if _EVENT[4] >= t_BOARDS[i].OBJECTS[v].Y and _EVENT[4] <= (t_BOARDS[i].OBJECTS[v].Y + t_BOARDS[i].OBJECTS[v].H - 1) then
  49.                                     -- If mouse Y is in range of object's Y bounds
  50.                                     heldObject = t_BOARDS[i].OBJECTS[v]
  51.                                     heldObject.INTERACT_STATE = "held"
  52.                                     heldObject:draw()
  53.                                     return "wait",heldObject
  54.                                 end
  55.                             end
  56.                         end
  57.                     end
  58.                 end
  59.             end
  60.         else
  61.             error("No boards to handle.")
  62.         end
  63.     elseif _EVENT[1] == "mouse_up" then
  64.         if heldObject ~= nil then
  65.             if heldObject.ACTIVE and heldObject.DRAWN then
  66.                 if #t_BOARDS > 0 then
  67.                     -- If there is at least 1 board
  68.                     if _EVENT[2] == 1 then -- Mouse button 1
  69.                         if _EVENT[3] >= heldObject.X and _EVENT[3] <= (heldObject.X + heldObject.W - 1) then
  70.                             -- If mouse X is in range of object's X bounds
  71.                             if _EVENT[4] >= heldObject.Y and _EVENT[4] <= (heldObject.Y + heldObject.H - 1) then
  72.                                 -- If mouse Y is in range of object's Y bounds
  73.                                 heldObject.INTERACT_STATE = "idle"
  74.                                 local _obj = heldObject
  75.                                 heldObject = nil
  76.                                 _obj:draw()
  77.                                 if _obj.FUNCTION then
  78.                                     -- If object has a function
  79.                                     local _arg1,_arg2 = _obj:run()
  80.                                     return true,_obj,{_arg1,_arg2} -- Do it!
  81.                                 end
  82.                             end
  83.                         end
  84.                     end
  85.                 end
  86.             end
  87.         else
  88.             heldObject = nil
  89.         end
  90.     end
  91.     return false
  92. end
  93.  
  94. --[[ BOARD FUNCTIONS ]]--
  95.  
  96. -- Creates a board
  97. function BOARD:new(_LABEL)
  98.     local self = {
  99.         DRAWN = false,
  100.         ACTIVE = true,
  101.         OBJECTS = {}
  102.     }
  103.     if _LABEL then
  104.         self.LABEL = _LABEL
  105.     else
  106.         error("Invalid or no label for BOARD.")
  107.     end
  108.     table.insert(t_BOARDS,self)
  109.     setmetatable(self,BOARD)
  110.     return self
  111. end
  112.  
  113. -- Toggles an existing board on or off
  114. function BOARD:toggleActive(_B)
  115.     self.ACTIVE = _B or not self.ACTIVE -- Optional argument to manually change
  116. end
  117.  
  118. -- Draws an existing board
  119. function BOARD:draw()
  120.     if self.ACTIVE then
  121.         self:undraw()
  122.         for i=1,#self.OBJECTS do
  123.             self.OBJECTS[i]:draw()
  124.         end
  125.         self.DRAWN = true
  126.     end
  127. end
  128.  
  129. -- Undraws an existing board
  130. function BOARD:undraw()
  131.     if self.ACTIVE and self.DRAWN then
  132.         for i=1,#self.OBJECTS do
  133.             self.OBJECTS[i]:undraw()
  134.         end
  135.         self.DRAWN = false
  136.     end
  137. end
  138.  
  139. --[[ BUTTON FUNCTIONS ]]--
  140.  
  141. -- Creates a button
  142. function BUTTON:new(_BOARD,_LABEL,_X,_Y,_W,_H,_TCOLOUR,_BCOLOUR,_BCOLOUR_HELD,_FILL)
  143.     local self = {
  144.         DRAWN = false,
  145.         ACTIVE = true,
  146.         INTERACT_STATE = "idle", -- States: idle, held
  147.         X = _X, -- _X being an integer
  148.         Y = _Y, -- _Y being an integer
  149.         W = _W, -- _W being an integer
  150.         H = _H, -- _H being an integer
  151.         TCOLOUR = _TCOLOUR, -- _TCOLOUR being a colour (integer)
  152.         BCOLOUR = _BCOLOUR, -- _BCOLOUR being a colour (integer)
  153.         BCOLOUR_HELD = _BCOLOUR_HELD,
  154.         INACTIVE_BCOLOUR = colors.gray,
  155.         FUNCTION = function() return "clicked" end -- Assigned later
  156.     }
  157.     if _FILL then
  158.         self.FILL = _FILL -- _FILL being a boolean
  159.     else
  160.         error("Invalid or no fill type for BUTTON.")
  161.     end
  162.     if _LABEL then
  163.         self.LABEL = tostring(_LABEL)
  164.     else
  165.         error("Invalid or no label for BUTTON.")
  166.     end
  167.     setmetatable(self,BUTTON)
  168.     self:alignLabel("left","top") -- Default alignment
  169.     self.ALIGNMENT_TYPE_X = "left"
  170.     self.ALIGNMENT_TYPE_Y = "top"
  171.     if _BOARD.OBJECTS then
  172.         self:assignBoard(_BOARD)
  173.     else
  174.         error("Invalid or no board for BUTTON.")
  175.     end
  176.     table.insert(t_BUTTONS,self)
  177.     return self
  178. end
  179.  
  180. -- Assigns an existing button to an existing board
  181. function BUTTON:assignBoard(_BOARD)
  182.     if _BOARD then
  183.         table.insert(_BOARD.OBJECTS,self)
  184.         self.BOARD = _BOARD
  185.     else
  186.         error("Invalid or no board for BUTTON.")
  187.     end
  188.     self.BOARD:draw()
  189. end
  190.  
  191. -- Assigns a function an existing button
  192. function BUTTON:assignFunction(_FUNCTION)
  193.     if _FUNCTION then
  194.         self.FUNCTION = _FUNCTION
  195.     else
  196.         error("Invalid or no function for BUTTON.")
  197.     end
  198. end
  199.  
  200. -- Assigns a new label to an existing button
  201. function BUTTON:assignLabel(_LABEL)
  202.     if _LABEL then
  203.         self.LABEL = tostring(_LABEL)
  204.     else
  205.         error("Invalid or no label for BUTTON.")
  206.     end
  207.     self:alignLabel(self.ALIGNMENT_TYPE_X,self.ALIGNMENT_TYPE_Y)
  208.     self.BOARD:draw()
  209. end
  210.  
  211. -- Aligns the label on the button
  212. -- Valid alignments for X: left, centred, right
  213. -- Valid alignments for Y: top, centred, bottom
  214. function BUTTON:alignLabel(_ALIGNMENT_X,_ALIGNMENT_Y)
  215.     local _SKIP = false
  216.     if _ALIGNMENT_X == "left" then
  217.         self.XLABEL = self.X
  218.         self.ALIGNMENT_TYPE_X = "left"
  219.     elseif _ALIGNMENT_X == "centered" then
  220.         self.XLABEL = self.X + (math.max(math.floor((self.W/2) - (#self.LABEL/2)),self.Y))
  221.         self.ALIGNMENT_TYPE_X = "centered"
  222.         if not _ALIGNMENT_Y then
  223.             if (self.H % 2 == 0) then
  224.                 self.YLABEL = self.Y + (self.H / 2) - 1
  225.             else
  226.                 self.YLABEL = self.Y + (self.H / 2)
  227.             end
  228.             _SKIP = true
  229.             self.ALIGNMENT_TYPE_Y = "centered"
  230.         end
  231.     elseif _ALIGNMENT_X == "right" then
  232.         self.XLABEL = ((self.X + self.W) - #self.LABEL)
  233.         self.ALIGNMENT_TYPE_X = "right"
  234.     else
  235.         error("Invalid or no 'X' alignment for BUTTON.")
  236.     end
  237.     if _ALIGNMENT_Y == "top" then
  238.         self.YLABEL = self.Y
  239.         self.ALIGNMENT_TYPE_Y = "top"
  240.     elseif _ALIGNMENT_Y == "bottom" then
  241.         self.YLABEL = (self.Y + self.H - 1)
  242.         self.ALIGNMENT_TYPE_Y = "bottom"
  243.     elseif _ALIGNMENT_Y == "centered" then
  244.         if (self.H % 2 == 0) then
  245.             self.YLABEL = self.Y + (self.H / 2) - 1
  246.         else
  247.             self.YLABEL = self.Y + (self.H / 2)
  248.         end
  249.         self.ALIGNMENT_TYPE_Y = "centered"
  250.     else
  251.         if not _SKIP then
  252.             error("Invalid or no 'Y' alignment for BUTTON.")
  253.         end
  254.     end
  255. end
  256.  
  257. -- Draws an existing button
  258. function BUTTON:draw()
  259.     self:undraw()
  260.     local _oldBC = term.getBackgroundColor()
  261.     local _oldTC = term.getTextColor()
  262.     local _BCOLOUR
  263.     local _TCOLOUR
  264.     if self.ACTIVE then
  265.         if self.INTERACT_STATE == "held" then
  266.             _BCOLOUR = self.BCOLOUR_HELD
  267.         else
  268.             _BCOLOUR = self.BCOLOUR
  269.         end
  270.     else
  271.         _BCOLOUR = self.INACTIVE_BCOLOUR
  272.     end
  273.     _TCOLOUR = self.TCOLOUR
  274.     if self.FILL then
  275.         paintutils.drawFilledBox(self.X,self.Y,(self.X+self.W-1),(self.Y+self.H-1),_BCOLOUR)
  276.     else
  277.         paintutils.drawBox(self.X,self.Y,(self.X+self.W-1),(self.Y+self.H-1),_BCOLOUR)
  278.     end
  279.     term.setCursorPos(self.XLABEL,self.YLABEL)
  280.     term.setTextColor(_TCOLOUR)
  281.     term.setBackgroundColor(_BCOLOUR)
  282.     write(self.LABEL)
  283.     term.setBackgroundColor(_oldBC)
  284.     term.setTextColor(_oldTC)
  285.     self.DRAWN = true
  286. end
  287.  
  288. -- Undraws an existing button
  289. function BUTTON:undraw()
  290.     self.DRAWN = false
  291.     paintutils.drawFilledBox(self.X,self.Y,(self.X+self.W-1),(self.Y+self.H-1),term.getBackgroundColor())
  292. end
  293.  
  294. -- Toggle if an existing button is active or not
  295. function BUTTON:toggleActive(_B)
  296.     self.ACTIVE = _B or not self.ACTIVE -- Optional argument to manually change
  297.     self.BOARD:draw()
  298. end
  299.  
  300. -- Runs a function linked to an existing button
  301. function BUTTON:run()
  302.     return self.FUNCTION()
  303. end
  304.  
  305. --[[ CHECKBOX FUNCTIONS ]]--
  306.  
  307. -- Create a new checkbox
  308. function CHECKBOX:new(_BOARD,_LABEL,_X,_Y,_TCOLOUR,_TBCOLOUR,_FCOLOUR,_BCOLOUR,_BCOLOUR_HELD)
  309.     local self = {
  310.         DRAWN = false,
  311.         ACTIVE = true,
  312.         STATE = false,
  313.         X = _X,
  314.         Y = _Y,
  315.         W = 1,
  316.         H = 1,
  317.         TCOLOUR = _TCOLOUR,
  318.         TBCOLOUR = _TBCOLOUR,
  319.         FCOLOUR = _FCOLOUR,
  320.         BCOLOUR = _BCOLOUR,
  321.         BCOLOUR_HELD = _BCOLOUR_HELD,
  322.         INACTIVE_BCOLOUR = colors.gray,
  323.         FUNCTION = function() return nil end
  324.     }
  325.     if _LABEL then
  326.         self.LABEL = tostring(_LABEL)
  327.     else
  328.         error("Invalid or no label for CHECKBOX.")
  329.     end
  330.     setmetatable(self,CHECKBOX)
  331.     self:alignLabel("right") -- Default alignment
  332.     self.ALIGNMENT_TYPE_X = "right"
  333.     self.FUNCTION = function() return self:getState() end
  334.     if _BOARD.OBJECTS then
  335.         self:assignBoard(_BOARD)
  336.     else
  337.         error("Invalid or no board for CHECKBOX.")
  338.     end
  339.     table.insert(t_CHECKBOXES,self)
  340.     return self
  341. end
  342.  
  343. -- Assigns an existing checkbox to an existing board
  344. function CHECKBOX:assignBoard(_BOARD)
  345.     if _BOARD then
  346.         table.insert(_BOARD.OBJECTS,self)
  347.         self.BOARD = _BOARD
  348.     else
  349.         error("Invalid or no board for CHECKBOX.")
  350.     end
  351.     self.BOARD:draw()
  352. end
  353.  
  354. -- Assigns a function an existing checkbox
  355. function CHECKBOX:assignFunction(_FUNCTION)
  356.     if _FUNCTION then
  357.         self.FUNCTION = _FUNCTION
  358.     else
  359.         error("Invalid or no function for CHECKBOX.")
  360.     end
  361. end
  362.  
  363. -- Assigns a new label to an existing checkbox
  364. function CHECKBOX:assignLabel(_LABEL)
  365.     if _LABEL then
  366.         self.LABEL = tostring(_LABEL)
  367.     else
  368.         error("Invalid or no label for CHECKBOX.")
  369.     end
  370.     self:alignLabel(self.ALIGNMENT_TYPE_X)
  371.     self.BOARD:draw()
  372. end
  373.  
  374. -- Align the label of an existing checkbox
  375. -- Valid arguments for X: left, right (either side of checkbox)
  376. function CHECKBOX:alignLabel(_ALIGNMENT_X)
  377.     if _ALIGNMENT_X == "left" then
  378.         self.XLABEL = (self.X - #self.LABEL - 1)
  379.     elseif _ALIGNMENT_X == "right" then
  380.         self.XLABEL = self.X + 2
  381.     else
  382.         error("Invalid or no 'X' alignment for CHECKBOX.")
  383.     end
  384. end
  385.  
  386. -- Toggle if an existing checkbox is active or not
  387. function CHECKBOX:toggleActive(_B)
  388.     self.ACTIVE = _B or not self.ACTIVE -- Optional argument to manually change
  389.     self.BOARD:draw()
  390. end
  391.  
  392. -- Toggle the status of a checkbox
  393. function CHECKBOX:toggleState()
  394.     self.STATE = not self.STATE
  395.     self.BOARD:draw()
  396.     return self.STATE
  397. end
  398.  
  399. -- Get the status of a checkbox
  400. function CHECKBOX:getState()
  401.     return self.STATE
  402. end
  403.  
  404. -- Runs a function linked to an existing checkbox
  405. function CHECKBOX:run()
  406.     return self.FUNCTION(),self:toggleState()
  407. end
  408.  
  409. -- Clears the drawn version of an existing checkbox
  410. function CHECKBOX:undraw()
  411.     self.DRAWN = false
  412.     local _oldBC = term.getBackgroundColor()
  413.     local _oldTC = term.getTextColor()
  414.     term.setCursorPos(self.X,self.Y)
  415.     term.setBackgroundColor(self.TBCOLOUR)
  416.     write(" ")
  417.     term.setCursorPos(self.XLABEL,self.Y)
  418.     for i=1,#self.LABEL do
  419.         write(" ")
  420.     end
  421.     term.setBackgroundColor(_oldBC)
  422.     term.setTextColor(_oldTC)
  423. end
  424.  
  425. -- Draws an existing checkbox
  426. function CHECKBOX:draw()
  427.     self.DRAWN = true
  428.     local _oldBC = term.getBackgroundColor()
  429.     local _oldTC = term.getTextColor()
  430.     local _BCOLOUR
  431.     local _TCOLOUR
  432.     if self.ACTIVE then
  433.         if self.INTERACT_STATE == "held" then
  434.             _BCOLOUR = self.BCOLOUR_HELD
  435.         else
  436.             _BCOLOUR = self.BCOLOUR
  437.         end
  438.         _TCOLOUR = self.TCOLOUR
  439.     else
  440.         _BCOLOUR = self.INACTIVE_BCOLOUR
  441.         _TCOLOUR = self.INACTIVE_TCOLOUR
  442.     end
  443.     term.setCursorPos(self.X,self.Y)
  444.     term.setTextColor(self.FCOLOUR)
  445.     term.setBackgroundColor(_BCOLOUR)
  446.     if self.STATE then
  447.         write("\4")
  448.     else
  449.         write(" ")
  450.     end
  451.     term.setTextColor(_TCOLOUR)
  452.     term.setBackgroundColor(self.TBCOLOUR)
  453.     term.setCursorPos(self.XLABEL,self.Y)
  454.     write(self.LABEL)
  455.     term.setBackgroundColor(_oldBC)
  456.     term.setTextColor(_oldTC)
  457. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement