abc123mewot

Buttons API - ComputerCraft

Dec 11th, 2017 (edited)
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.19 KB | None | 0 0
  1. --Button API (c) Jeremiah Lowe 2017
  2. --Created in ZeroBrane studio and tested on the 1.7.10 pack
  3. --Revised on 12/2023 for use on Devil's Anarchy 1.12.2 pack
  4. --Can be adapted to work with other libraries
  5. --=====================
  6. --= Library functions =
  7. --=====================
  8. --The default style for all non-toggle buttons
  9. defaultStyle = {
  10.   procedural = false,
  11.   backCol = colors.lightGray,
  12.   foreCol = colors.white,
  13.   dispTxt = "Button",
  14.   padd = 1,
  15.   size = 1
  16. }
  17. --Returns a style that is used when drawing the button to the screen
  18. --displayText: The text to display on the button
  19. --backgroundColor: The background color of the button
  20. --foregroundColor: The foreground/text color of the button
  21. --textSize: The text size
  22. --padding: The padding size of the button
  23. function createStyle(displayText, backgroundColor, foregroundColor, textSize, padding)
  24.   if displayText == nil then displayText = defaultStyle.dispTxt end
  25.   if textSize == nil then textSize = defaultStyle.size end
  26.   if padding == nil then padding = defaultStyle.padd end
  27.   if backgroundColor == nil then backgroundColor = defaultStyle.backCol end
  28.   if foregroundColor == nil then foregroundColor = defaultStyle.foreCol end
  29.   return {procedural = false, backCol = backgroundColor, foreCol = foregroundColor, dispTxt = displayText, size = textSize, padd = padding}
  30. end
  31. --Creates a style that changes when you press the button
  32. --pressedStyle: The style to use when the button is pressed
  33. --unpressedStyle: The style to use when the button is not pressed
  34. function createProceduralStyle(pressedStyle, unpressedStyle, unusableStyle)
  35.   if pressedStyle == nil then pressedStyle = defaultStyle end
  36.   if unpressedStyle == nil then unpressedStyle = defaultStyle end
  37.   if unusableStyle == nil then unusableStyle = defaultStyle end
  38.   return {procedural = true, pStyle = pressedStyle, uStyle = unpressedStyle, dStyle = unusableStyle}
  39. end
  40. --The default style for all toggle buttons
  41. defaultStyleT = createProceduralStyle(
  42.   createStyle("Enabled", colors.lightGray, colors.green, 1, 1),
  43.   createStyle("Disabled", colors.lightGray, colors.red, 1, 1),
  44.   createStyle("Unusable", colors.lightGray, colors.black, 1, 1))
  45. --Returns a button with the specified values, can be added with addButton
  46. --xPosition: X position of the button
  47. --yPosition: Y position of the button
  48. --isToggleButton (default false): Is the button a toggle button?
  49. --style (defaults to default style): Style of the button
  50. --onClickFunction: Called when the button is clicked params:[monitor, button, style]
  51. --onDrawFunction (default nil): Called when the button is drawn params:[button, style]
  52. function createButton(xPosition, yPosition, style, isToggleButton, onClickFunction, onDrawFunction)
  53.   local btn = {
  54.     x = xPosition, y = yPosition, s = style,
  55.     isToggle = isToggleButton,
  56.     onClick = onClickFunction,
  57.     onDraw = onDrawFunction,
  58.     enabled = false, drawn = false, unusable = false
  59.   }
  60.   --Gets the correct style for the button, depends on if it is enabled or not
  61.   function btn.getStyle()
  62.     if btn.s.procedural then
  63.       if btn.unusable then
  64.         return btn.s.dStyle
  65.       elseif btn.enabled then
  66.         return btn.s.pStyle
  67.       else
  68.         return btn.s.uStyle
  69.       end
  70.     else
  71.       return btn.s
  72.     end
  73.   end
  74.   return btn
  75. end
  76. --Array of curent buttons
  77. local buttons = {}
  78. --Counts the length of a table
  79. --NOTE: This is an internal method, only use it if you know what you're doing
  80. --tbl: The table
  81. function len(tbl)
  82.   local count = 0
  83.   for k, v in pairs(tbl) do count = count + 1 end
  84.   return count
  85. end
  86. --Returns a "Button ID" that used for removing the button
  87. --btn: The button to add
  88. function addButton(btn)
  89.   local l = len(buttons)
  90.   for i=0, l do
  91.     if buttons[i] == nil then
  92.       buttons[i] = btn
  93.       return i
  94.     end
  95.   end
  96.   i[l] = btn
  97.   return l
  98. end
  99. --Returns the removed button
  100. --id: The ID of the button to remove, retrieved from addButton(btn)
  101. function removeButton(id)
  102.   local btn = buttons[id]
  103.   if btn ~= nil then
  104.     buttons[id] = nil
  105.   end
  106.   return btn
  107. end
  108. --====================
  109. --=     Graphics     =
  110. --====================
  111. --Applies a style onto a monitor
  112. --NOTE: This is an internal method, only use it if you know what you're doing
  113. --mon: The monitor
  114. --btn: The button the style is from
  115. --s: The style
  116. function initMonitor(mon, btn, s)
  117.   assert(mon ~= nil)
  118.   assert(btn ~= nil)
  119.   assert(s ~= nil)
  120.   assert(not s.procedural)
  121.   if mon.isColor() then
  122.     mon.setTextColor(s.foreCol)
  123.     mon.setBackgroundColor(s.backCol)
  124.   end
  125.   mon.setTextScale(s.size)
  126.   mon.setCursorPos(btn.x, btn.y)
  127.   mon.setCursorBlink(false)
  128. end
  129. --Writes a line to the monitor, similar to println(msg) from other languages
  130. --mon: The monitor to write to
  131. --txt: The text to write
  132. function monWriteLine(mon, txt)
  133.   cx, cy = mon.getCursorPos()
  134.   mon.write(txt)
  135.   mon.setCursorPos(cx, cy + 1)
  136. end
  137. --Draws over the button's area
  138. --mon: The monitor to draw on
  139. --btn: The button to edit
  140. function monitorClearButtonArea(mon, btn)
  141.  
  142. end
  143. --Draws a button to the specified monitor
  144. --mon: The monitor to draw on
  145. --btn: The button to draw
  146. function monitorDrawButton(mon, btn)
  147.   assert(mon ~= nil)
  148.   assert(btn ~= nil)
  149.   monitorClearButtonArea(mon, btn)
  150.   local s = btn.getStyle()
  151.   if s == nil then s = defaultStyle end
  152.   initMonitor(mon, btn, s)
  153.   local dtxt = s.dispTxt
  154.   for i=1, s.padd do dtxt = " " .. dtxt .. " " end
  155.   local w, ln = string.len(dtxt), ""
  156.   for i=1, w do ln = ln .. " " end
  157.   for i=1, s.padd do monWriteLine(mon, ln) end
  158.   monWriteLine(mon, dtxt)
  159.   for i=1, s.padd do monWriteLine(mon, ln) end
  160.   btn.drawn = true
  161.   btn.x2, btn.y2 = mon.getCursorPos()
  162.   btn.x2 = btn.x2 + w
  163.   if btn.onDraw ~= nil then btn.onDraw(mon, btn, s) end
  164. end
  165. --Draws all the buttons to the monitor
  166. --mon: The monitor to draw it on
  167. function monitorDraw(mon)
  168.   assert(mon ~= nil and buttons ~= nil)
  169.   for k, b in pairs(buttons) do
  170.     if b ~= nil then
  171.       monitorDrawButton(mon, b)
  172.     end
  173.   end
  174. end
  175. --====================
  176. --= Event management =
  177. --====================
  178. --Detects if a coordinate intersects with a rectangle
  179. --x, y: The coordinate to check
  180. --x1, y1: The minimum coordinates of the rectangle
  181. --x2, y2: The maximum coordinates of the rectangle
  182. function intersects(x, y, x1, y1, x2, y2)
  183.   local xInt = x >= x1 and x <= x2
  184.   local yInt = y >= y1 and y <= y2
  185.   return xInt and yInt
  186. end
  187. --Sends a touch event to the rest of the API and redraws any updated buttons
  188. --mon: The monitor to re-draw the buttons onto
  189. --x, y: The x and y coordinates of the touch event
  190. function onTouch(mon, x, y)
  191.   for k, b in pairs(buttons) do
  192.     if b ~= nil and b.drawn then
  193.       local int = intersects(x, y, b.x, b.y, b.x2, b.y2)
  194.       if int and b.onClick ~= nil and not b.unusable then
  195.         if b.isToggle then
  196.           b.enabled = not b.enabled
  197.           b.onClick(b, b.enabled)
  198.         else
  199.           b.onClick(b, true)
  200.           b.enabled = false
  201.         end
  202.         monitorDrawButton(mon, b)
  203.       end
  204.     end
  205.   end
  206. end
  207. --An input loop that constantly checks for events, This is an INFINITE loop!
  208. function inputLoop()
  209.   while true do
  210.     local e, s, x, y = os.pullEvent("monitor_touch")
  211.     onTouch(peripheral.wrap(s), x, y)
  212.   end
  213. end
  214.  
Advertisement
Add Comment
Please, Sign In to add comment