Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Button API (c) Jeremiah Lowe 2017
- --Created in ZeroBrane studio and tested on the 1.7.10 pack
- --Revised on 12/2023 for use on Devil's Anarchy 1.12.2 pack
- --Can be adapted to work with other libraries
- --=====================
- --= Library functions =
- --=====================
- --The default style for all non-toggle buttons
- defaultStyle = {
- procedural = false,
- backCol = colors.lightGray,
- foreCol = colors.white,
- dispTxt = "Button",
- padd = 1,
- size = 1
- }
- --Returns a style that is used when drawing the button to the screen
- --displayText: The text to display on the button
- --backgroundColor: The background color of the button
- --foregroundColor: The foreground/text color of the button
- --textSize: The text size
- --padding: The padding size of the button
- function createStyle(displayText, backgroundColor, foregroundColor, textSize, padding)
- if displayText == nil then displayText = defaultStyle.dispTxt end
- if textSize == nil then textSize = defaultStyle.size end
- if padding == nil then padding = defaultStyle.padd end
- if backgroundColor == nil then backgroundColor = defaultStyle.backCol end
- if foregroundColor == nil then foregroundColor = defaultStyle.foreCol end
- return {procedural = false, backCol = backgroundColor, foreCol = foregroundColor, dispTxt = displayText, size = textSize, padd = padding}
- end
- --Creates a style that changes when you press the button
- --pressedStyle: The style to use when the button is pressed
- --unpressedStyle: The style to use when the button is not pressed
- function createProceduralStyle(pressedStyle, unpressedStyle, unusableStyle)
- if pressedStyle == nil then pressedStyle = defaultStyle end
- if unpressedStyle == nil then unpressedStyle = defaultStyle end
- if unusableStyle == nil then unusableStyle = defaultStyle end
- return {procedural = true, pStyle = pressedStyle, uStyle = unpressedStyle, dStyle = unusableStyle}
- end
- --The default style for all toggle buttons
- defaultStyleT = createProceduralStyle(
- createStyle("Enabled", colors.lightGray, colors.green, 1, 1),
- createStyle("Disabled", colors.lightGray, colors.red, 1, 1),
- createStyle("Unusable", colors.lightGray, colors.black, 1, 1))
- --Returns a button with the specified values, can be added with addButton
- --xPosition: X position of the button
- --yPosition: Y position of the button
- --isToggleButton (default false): Is the button a toggle button?
- --style (defaults to default style): Style of the button
- --onClickFunction: Called when the button is clicked params:[monitor, button, style]
- --onDrawFunction (default nil): Called when the button is drawn params:[button, style]
- function createButton(xPosition, yPosition, style, isToggleButton, onClickFunction, onDrawFunction)
- local btn = {
- x = xPosition, y = yPosition, s = style,
- isToggle = isToggleButton,
- onClick = onClickFunction,
- onDraw = onDrawFunction,
- enabled = false, drawn = false, unusable = false
- }
- --Gets the correct style for the button, depends on if it is enabled or not
- function btn.getStyle()
- if btn.s.procedural then
- if btn.unusable then
- return btn.s.dStyle
- elseif btn.enabled then
- return btn.s.pStyle
- else
- return btn.s.uStyle
- end
- else
- return btn.s
- end
- end
- return btn
- end
- --Array of curent buttons
- local buttons = {}
- --Counts the length of a table
- --NOTE: This is an internal method, only use it if you know what you're doing
- --tbl: The table
- function len(tbl)
- local count = 0
- for k, v in pairs(tbl) do count = count + 1 end
- return count
- end
- --Returns a "Button ID" that used for removing the button
- --btn: The button to add
- function addButton(btn)
- local l = len(buttons)
- for i=0, l do
- if buttons[i] == nil then
- buttons[i] = btn
- return i
- end
- end
- i[l] = btn
- return l
- end
- --Returns the removed button
- --id: The ID of the button to remove, retrieved from addButton(btn)
- function removeButton(id)
- local btn = buttons[id]
- if btn ~= nil then
- buttons[id] = nil
- end
- return btn
- end
- --====================
- --= Graphics =
- --====================
- --Applies a style onto a monitor
- --NOTE: This is an internal method, only use it if you know what you're doing
- --mon: The monitor
- --btn: The button the style is from
- --s: The style
- function initMonitor(mon, btn, s)
- assert(mon ~= nil)
- assert(btn ~= nil)
- assert(s ~= nil)
- assert(not s.procedural)
- if mon.isColor() then
- mon.setTextColor(s.foreCol)
- mon.setBackgroundColor(s.backCol)
- end
- mon.setTextScale(s.size)
- mon.setCursorPos(btn.x, btn.y)
- mon.setCursorBlink(false)
- end
- --Writes a line to the monitor, similar to println(msg) from other languages
- --mon: The monitor to write to
- --txt: The text to write
- function monWriteLine(mon, txt)
- cx, cy = mon.getCursorPos()
- mon.write(txt)
- mon.setCursorPos(cx, cy + 1)
- end
- --Draws over the button's area
- --mon: The monitor to draw on
- --btn: The button to edit
- function monitorClearButtonArea(mon, btn)
- end
- --Draws a button to the specified monitor
- --mon: The monitor to draw on
- --btn: The button to draw
- function monitorDrawButton(mon, btn)
- assert(mon ~= nil)
- assert(btn ~= nil)
- monitorClearButtonArea(mon, btn)
- local s = btn.getStyle()
- if s == nil then s = defaultStyle end
- initMonitor(mon, btn, s)
- local dtxt = s.dispTxt
- for i=1, s.padd do dtxt = " " .. dtxt .. " " end
- local w, ln = string.len(dtxt), ""
- for i=1, w do ln = ln .. " " end
- for i=1, s.padd do monWriteLine(mon, ln) end
- monWriteLine(mon, dtxt)
- for i=1, s.padd do monWriteLine(mon, ln) end
- btn.drawn = true
- btn.x2, btn.y2 = mon.getCursorPos()
- btn.x2 = btn.x2 + w
- if btn.onDraw ~= nil then btn.onDraw(mon, btn, s) end
- end
- --Draws all the buttons to the monitor
- --mon: The monitor to draw it on
- function monitorDraw(mon)
- assert(mon ~= nil and buttons ~= nil)
- for k, b in pairs(buttons) do
- if b ~= nil then
- monitorDrawButton(mon, b)
- end
- end
- end
- --====================
- --= Event management =
- --====================
- --Detects if a coordinate intersects with a rectangle
- --x, y: The coordinate to check
- --x1, y1: The minimum coordinates of the rectangle
- --x2, y2: The maximum coordinates of the rectangle
- function intersects(x, y, x1, y1, x2, y2)
- local xInt = x >= x1 and x <= x2
- local yInt = y >= y1 and y <= y2
- return xInt and yInt
- end
- --Sends a touch event to the rest of the API and redraws any updated buttons
- --mon: The monitor to re-draw the buttons onto
- --x, y: The x and y coordinates of the touch event
- function onTouch(mon, x, y)
- for k, b in pairs(buttons) do
- if b ~= nil and b.drawn then
- local int = intersects(x, y, b.x, b.y, b.x2, b.y2)
- if int and b.onClick ~= nil and not b.unusable then
- if b.isToggle then
- b.enabled = not b.enabled
- b.onClick(b, b.enabled)
- else
- b.onClick(b, true)
- b.enabled = false
- end
- monitorDrawButton(mon, b)
- end
- end
- end
- end
- --An input loop that constantly checks for events, This is an INFINITE loop!
- function inputLoop()
- while true do
- local e, s, x, y = os.pullEvent("monitor_touch")
- onTouch(peripheral.wrap(s), x, y)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment