Instantly share code, notes, and snippets.
Last active
January 30, 2021 11:31
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save MakerTim/bccdcda978dbcf227050c490afbaddcc to your computer and use it in GitHub Desktop.
ComputerCraft (MinecrafMod) Lua libary for making buttons, labels, images and charts on monitors or terminals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local monitors = { term = term } | |
local monitorsData = {} | |
local currentMonitor = "term" | |
function _findMonitors() | |
for index, peripheralName in pairs(peripheral.getNames()) do | |
if string.sub(peripheralName, 1, 7) == "monitor" then | |
monitors[peripheralName] = peripheral.wrap(peripheralName) | |
end | |
end | |
end | |
_findMonitors() | |
function _createPage() | |
return { | |
header = nil, | |
buttons = {}, | |
charts = {}, | |
labels = {}, | |
images = {} | |
} | |
end | |
function setupScreen(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
local monitor = monitors[peripheralName] | |
monitor.setTextScale(0.5) | |
monitor.setTextColor(colors.white) | |
monitor.setBackgroundColor(colors.black) | |
monitor.clear() | |
monitorsData[peripheralName] = { | |
name = peripheralName, | |
backgroundColor = colors.black, | |
textColor = colors.white, | |
page = 1, | |
pages = { | |
_createPage() | |
}, | |
} | |
return monitorsData[peripheralName] | |
end | |
-- Hard reset | |
function resetScreen(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
return setupScreen(peripheralName) | |
end | |
function _checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
if monitorsData[peripheralName] == nil then | |
error("Peripheral " .. peripheralName .. " has not been trough setup, did you start with setupScreen(peripheralName)?", 1) | |
end | |
end | |
-- buttons | |
function _drawButton(peripheralName, pageData, buttonName, buttonData) | |
local backgroundColor | |
if buttonData["active"] then | |
backgroundColor = buttonData["activeColor"] | |
else | |
backgroundColor = buttonData["color"] | |
end | |
monitors[peripheralName].setBackgroundColor(backgroundColor) | |
local yspot = math.floor((buttonData["ymin"] + buttonData["ymax"]) / 2) | |
local xspot = math.floor((buttonData["xmax"] - buttonData["xmin"] - string.len(text)) / 2) + 1 | |
for j = buttonData["ymin"], buttonData["ymax"] do | |
monitors[peripheralName].setCursorPos(buttonData["xmin"], j) | |
if j == yspot then | |
for k = 0, buttonData["xmax"] - buttonData["xmin"] - string.len(text) + 1 do | |
if k == xspot then | |
monitors[peripheralName].write(text) | |
else | |
monitors[peripheralName].write(" ") | |
end | |
end | |
else | |
for i = buttonData["xmin"], buttonData["xmax"] do | |
monitors[peripheralName].write(" ") | |
end | |
end | |
end | |
mon.setBackgroundColor(monitorsData[peripheralName].backgroundColor) | |
end | |
function _drawButtons(peripheralName, page) | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local buttons = pageData.buttons | |
for buttonName, buttonData in pairs(buttons) do | |
_drawButton(peripheralName, pageData, buttonName, buttonData) | |
end | |
end | |
-- args func = peripheralName, buttonName, buttonData, x, y | |
function addButton(peripheralName, page, name, func, x, y, width, height, color, activeColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
color = color or colors.red | |
activeColor = activeColor or colors.lime | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.buttons[buttonName] = { | |
name = buttonName, | |
func = func, | |
active = false, | |
xmin = x, | |
ymin = y, | |
xmax = x + width - 1, | |
ymax = y + height - 1, | |
color = color, | |
activeColor = activeColor | |
} | |
end | |
function updateButton(peripheralName, page, buttonName, newColor, newActiveColor, newFunction) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local buttonData = pageData.buttons[buttonName] | |
if newColor ~= nil then | |
chartData["color"] = color | |
end | |
if newActiveColor ~= nil then | |
chartData["activeColor"] = newActiveColor | |
end | |
if newFunction ~= nil then | |
chartData["func"] = newFunction | |
end | |
_drawButton(peripheralName, pageData, buttonName, buttonData) | |
end | |
function updateButtonState(peripheralName, page, buttonName, forceState) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local button = monitorsData[peripheralName].pages[page].buttons[buttonName]; | |
if forceState == nil then | |
button["active"] = not button["active"] | |
else | |
button["active"] = forceState == true | |
end | |
_drawButtons(peripheralName) | |
end | |
function removeButton(peripheralName, page, buttonName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.buttons[buttonName] = nil | |
end | |
-- charts | |
function _drawChart(peripheralName, pageData, chartName, chartData) | |
local heigth = chartData["ymax"] - chartData["ymin"] | |
local percentPerStep = math.floor(100 / heigth) | |
local barHeight = math.floor(chartData["value"] / percentPerStep) | |
local xspot = math.floor((chartData["xmax"] - chartData["xmin"]) / 2) - 1 | |
local yspot = math.floor((chartData["ymin"] + chartData["ymax"]) / 2) | |
local text = chartData["value"] .. "%" | |
if chartData["label"] ~= nil then | |
local labelX = math.floor((chartData["xmax"] - chartData["xmin"] - string.len(chartData["label"])) / 2) | |
monitors[peripheralName].setCursorPos(chartData["xmin"] + labelX, chartData["ymax"] + 1) | |
monitors[peripheralName].write(chartData["label"]) | |
end | |
local emptyColor = 0 | |
if chartData["color"] == colors.gray then | |
emptyColor = colors.lightGray | |
else | |
emptyColor = colors.gray | |
end | |
if chartData["color"] == colors.white then | |
monitors[peripheralName].setTextColor(colors.black) | |
end | |
for j = chartData["ymin"], chartData["ymax"] do | |
monitors[peripheralName].setCursorPos(chartData["xmin"], j) | |
if j == yspot then | |
for k = 0, chartData["xmax"] - chartData["xmin"] - string.len(text) + 1 do | |
if barHeight + chartData["ymax"] >= chartData["ymax"] + (chartData["ymax"] - j) then | |
monitors[peripheralName].setBackgroundColor(chartData["color"]) | |
else | |
monitors[peripheralName].setBackgroundColor(emptyColor) | |
end | |
if k == xspot then | |
monitors[peripheralName].write(text) | |
else | |
monitors[peripheralName].write(" ") | |
end | |
end | |
else | |
for i = chartData["xmin"], chartData["xmax"] do | |
if barHeight + chartData["ymax"] >= chartData["ymax"] + (chartData["ymax"] - j) then | |
monitors[peripheralName].setBackgroundColor(chartData["color"]) | |
else | |
monitors[peripheralName].setBackgroundColor(emptyColor) | |
end | |
monitors[peripheralName].write(" ") | |
end | |
end | |
end | |
monitors[peripheralName].setBackgroundColor(colors.black) | |
monitors[peripheralName].setTextColor(colors.white) | |
end | |
function _drawCharts(peripheralName, page) | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local charts = pageData.charts | |
for chartName, chartData in pairs(charts) do | |
_drawChart(peripheralName, pageData, chartName, chartData) | |
end | |
end | |
function addChart(peripheralName, page, chartName, percentage, x, y, width, height, color, label) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
color = color or colors.white | |
pageData.charts[chartName] = { | |
value = percentage, | |
xmin = x, | |
ymin = y, | |
xmax = x + width - 1, | |
ymax = y + height - 1, | |
color = color, | |
label = label | |
} | |
end | |
function updateChart(peripheralName, page, chartName, newValue, newColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local chartData = pageData.charts[chartName] | |
if newValue ~= nil then | |
chartData["value"] = newValue | |
end | |
if newColor ~= nil then | |
chartData["color"] = newColor | |
end | |
_drawChart(peripheralName, pageData, chartName, chartData) | |
end | |
function removeChart(peripheralName, page, chartName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.charts[chartName] = nil | |
end | |
-- labels | |
function _drawLabel(peripheralName, pageData, labelName, labelData) | |
monitors[peripheralName].setCursorPos(labelData["x"], labelData["y"]) | |
monitors[peripheralName].setTextColor(labelData["color"] or monitorsData[peripheralName].textColor) | |
monitors[peripheralName].setBackgroundColor(labelData["backgroundColor"] or monitorsData[peripheralName].backgroundColor) | |
monitors[peripheralName].write(labelName) | |
end | |
function _drawLables(peripheralName, page) | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local labels = pageData.labels | |
for labelName, labelData in pairs(labels) do | |
_drawLabel(peripheralName, pageData, labelName, labelData) | |
end | |
end | |
function setHeader(peripheralName, page, header, color, backgroundColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
if monitorsData[peripheralName].pages[page].header ~= nil then | |
removeLabel(peripheralName, page, monitorsData[peripheralName].header) | |
end | |
monitorsData[peripheralName].pages[page].header = header | |
local x = (w - string.len(text)) / 2 + 1 | |
local y = 1 | |
addLabel(peripheralName, page, header, x, y, color, backgroundColor) | |
end | |
function addLabel(peripheralName, page, labelName, x, y, color, backgroundColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.labels[labelName] = { | |
x = x, | |
y = y, | |
color = color, | |
backgroundColor = backgroundColor | |
} | |
end | |
function updateLabelSetTextColor(peripheralName, page, labelName, newTextColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.labels[labelName]["color"] = newTextColor | |
end | |
function updateLabelSetBackgroundColor(peripheralName, page, labelName, newBackgroundColor) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.labels[labelName]["backgroundColor"] = newBackgroundColor | |
end | |
function removeLabel(peripheralName, page, labelName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.labels[labelName] = nil | |
end | |
-- images | |
function _drawImage(peripheralName, pageData, imageName, imageData) | |
if imageData["paintutil"] then | |
paintutils.drawImage(imageData["data"], imageData["x"], imageData["y"]) | |
else | |
for line, colorData in pairs(imageData["data"]) do | |
monitors[peripheralName].setCursorPos(imageData["x"] + line - 1, imageData["y"]) | |
local spaces = colorData:gsub("%w", " ") | |
local colorText = colorData:gsub("%w", "0") | |
monitors[peripheralName].blit(spaces, colorText, colorData) | |
end | |
end | |
end | |
function _drawImages(peripheralName, page) | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
local images = pageData.images | |
for imageName, imageData in pairs(images) do | |
_drawImage(peripheralName, pageData, imageName, imageData) | |
end | |
end | |
function addImage(peripheralName, page, imageName, imageTable, usePaintUtil) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.images[imageName] = { | |
x = x, | |
y = y, | |
data = imageTable, | |
paintutil = usePaintUtil | |
} | |
end | |
function updateImagePos(peripheralName, page, imageName, x, y) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
monitors[peripheralName].clear() | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.images[imageName].x = x | |
pageData.images[imageName].y = y | |
updateMonitor(peripheralName) | |
end | |
function removeImage(peripheralName, page, imageName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
page = page or monitorsData[peripheralName].page | |
local pageData = monitorsData[peripheralName].pages[page]; | |
pageData.images[imageName] = nil | |
end | |
-- global update all | |
function updateMonitor(peripheralName) | |
peripheralName = peripheralName or currentMonitor | |
_drawButtons(peripheralName) | |
_drawCharts(peripheralName) | |
_drawLabels(peripheralName) | |
_drawImages(peripheralName) | |
end | |
function changeToPage(peripheralName, newPage) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
while newPage > table.getn(monitorsData[peripheralName].pages) do | |
table.insert(monitorsData[peripheralName].pages, _createPage()) | |
end | |
monitorsData[peripheralName].page = newPage | |
updateMonitor(peripheralName) | |
end | |
function lowerOnePage(peripheralName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
local currentPage = monitorsData[peripheralName].page | |
local newPage = currentPage - 1 | |
if currentPage == 1 then | |
newPage = table.getn(monitorsData[peripheralName].pages) | |
end | |
changeToPage(peripheralName, newPage) | |
end | |
function lowerOnePage(peripheralName) | |
_checkPeripheralSetupOrThrowsNotSetupError(peripheralName) | |
local currentPage = monitorsData[peripheralName].page | |
local newPage = currentPage + 1 | |
if currentPage == table.getn(monitorsData[peripheralName].pages) then | |
newPage = 1 | |
end | |
changeToPage(peripheralName, newPage) | |
end | |
-- check if button is pressed and trigger it | |
function checkPressedButton(peripheralName, x, y) | |
if monitorsData[peripheralName] ~= nil then | |
local page = monitorsData[peripheralName].pages[monitorsData[peripheralName].page] | |
local buttons = page.buttons | |
for buttonName, buttonData in pairs(buttons) do | |
if y >= buttonData.ymin and y <= buttonData.ymax then | |
if x >= buttonData.xmin and x <= buttonData.xmax then | |
toggleButtonState(peripheralName, buttonName) | |
buttonData["func"](monitorsData[peripheralName], buttonData, buttonData.xmin - x, y - buttonData.ymin) | |
sleep(0.15) | |
toggleButtonState(peripheralName, buttonName) | |
return true | |
end | |
end | |
end | |
end | |
return false | |
end | |
-- method to have in while true do loop | |
function onClick(listenForEvent) | |
listenForEvent = listenForEvent or "monitor_touch" | |
local event, side, x, y = os.pullEvent(listenForEvent) | |
local foundButton = false | |
if event == "monitor_touch" then | |
foundButton = checkPressedButton(side, x, y) | |
end | |
return event, side, x, y, foundButton; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment