Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tArgs = {...}
- local bridge
- if type(tArgs[1]) == "string" and peripheral.getType(tArgs[1]) == "openperipheral_bridge" then
- bridge = peripheral.wrap(tArgs[1])
- bridge.clear()
- else
- error("could not find bridge on side: "..tostring(tArgs[1]))
- end
- local colourToRGB = {
- [colours.white] = 0xf0f0f0,
- [colours.orange] = 0xf2b233,
- [colours.magenta] = 0xe57fd8,
- [colours.lightBlue] = 0x99b2f2,
- [colours.yellow] = 0xdede6c,
- [colours.lime] = 0x7fcc19,
- [colours.pink] = 0xf2b2cc,
- [colours.grey] = 0x4c4c4c,
- [colours.lightGrey] = 0x999999,
- [colours.cyan] = 0x4c99b2,
- [colours.purple] = 0xb266e5,
- [colours.blue] = 0x3366cc,
- [colours.brown] = 0x7f664c,
- [colours.green] = 0x57a64e,
- [colours.red] = 0xcc4c4c,
- [colours.black] = 0x000000,
- }
- local rgbToColour = {}
- for ccColour, glassesHex in pairs(colourToRGB) do
- rgbToColour[glassesHex] = ccColour
- end
- local hexValues = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}
- local hexToColour = {}
- for i = 1, 16 do
- hexToColour[hexValues[i]] = colourToRGB[2^(i-1)]
- end
- local charOffset = {
- ["!"] = 2, ["'"] = 2, ["("] = 1, [")"] = 1, ["*"] = 1, [","] = 2, ["."] = 2, [":"] = 2,
- [";"] = 2, ["<"] = 1, [">"] = 1, ["I"] = 1, ["["] = 1, ["["] = 1, ["`"] = 2, ["f"] = 1,
- ["i"] = 2, ["k"] = 1, ["l"] = 2, ["t"] = 1, ["{"] = 1, ["|"] = 2, ["}"] = 1,
- }
- local function newGlassesRedirect(surface, width, height, xOffset, yOffset, zOffset, opacity)
- local surface = surface
- local width, height = width or 51, height or 19
- local xOffset, yOffset, zOffset = xOffset or -(math.floor(width*6/2)), yOffset or -(math.floor(height*9/2)), zOffset or 1
- local map = {}
- local clickCatcherID = false
- local clickCatcherObject = false
- local cursorX, cursorY = 1, 1
- local cursorBlink = false
- local cursorObject = false
- local currentTextColour = colourToRGB[colours.white]
- local currentBackgroundColour = colourToRGB[colours.black]
- local isDrawn = false
- local isVisible = false
- local opacity = opacity or 1
- local hasChanged = false
- local horizontalAlign, verticalAlign = "MIDDLE", "MIDDLE"
- local bezelDrawn = false
- local topBezel, bottomBezel, leftBezel, rightBezel = false, false, false, false
- local function drawBezel()
- topBezel = surface.addBox(xOffset - 6, yOffset - 9, (width + 2)*6, 9, 0xdcd56c, opacity)
- topBezel.setScreenAnchor(horizontalAlign, verticalAlign)
- topBezel.setVisible(isVisible)
- topBezel.setZ(zOffset)
- bottomBezel = surface.addBox(xOffset - 6, yOffset + height*9, (width + 2)*6, 9, 0xdcd56c, opacity)
- bottomBezel.setScreenAnchor(horizontalAlign, verticalAlign)
- bottomBezel.setVisible(isVisible)
- bottomBezel.setZ(zOffset)
- leftBezel = surface.addBox(xOffset - 6, yOffset, 6, height*9, 0xdcd56c, opacity)
- leftBezel.setScreenAnchor(horizontalAlign, verticalAlign)
- leftBezel.setVisible(isVisible)
- leftBezel.setZ(zOffset)
- rightBezel = surface.addBox(xOffset + (width*6), yOffset, 6, height*9, 0xdcd56c, opacity)
- rightBezel.setScreenAnchor(horizontalAlign, verticalAlign)
- rightBezel.setVisible(isVisible)
- rightBezel.setZ(zOffset)
- end
- local function eraseBezel()
- if topBezel then
- topBezel.delete()
- topBezel = false
- end
- if bottomBezel then
- bottomBezel.delete()
- bottomBezel = false
- end
- if leftBezel then
- leftBezel.delete()
- leftBezel = false
- end
- if rightBezel then
- rightBezel.delete()
- rightBezel = false
- end
- end
- local function drawClickCatcher()
- clickCatcherObject = surface.addBox(xOffset, yOffset, width*6, height*9, 0x000000, 0)
- clickCatcherObject.setScreenAnchor(horizontalAlign, verticalAlign)
- clickCatcherObject.setVisible(isVisible)
- clickCatcherObject.setZ(zOffset + 3)
- clickCatcherID = clickCatcherObject.getId()
- end
- local function eraseClickCatcher()
- if clickCatcherObject then
- clickCatcherObject.delete()
- clickCatcherObject = false
- end
- clickCatcherID = false
- end
- local function drawText(xPos, yPos, text, textColour)
- local textObject = surface.addText((xPos-1)*6 + xOffset + (charOffset[text] or 0), (yPos-1)*9 + yOffset, text, textColour)
- textObject.setScreenAnchor(horizontalAlign, verticalAlign)
- textObject.setVisible(isVisible)
- textObject.setZ(zOffset + 1)
- return textObject
- end
- local function drawBackground(xPos, yPos, backgroundColour)
- local backgroundObject = surface.addBox((xPos-1)*6 + xOffset, (yPos-1)*9 + yOffset, 6, 9, backgroundColour, opacity)
- backgroundObject.setScreenAnchor(horizontalAlign, verticalAlign)
- backgroundObject.setVisible(isVisible)
- backgroundObject.setZ(zOffset)
- return backgroundObject
- end
- local function drawCursor()
- cursorObject = surface.addText((cursorX-1)*6 + xOffset, (cursorY-1)*9 + yOffset, "_", currentTextColour)
- cursorObject.setScreenAnchor(horizontalAlign, verticalAlign)
- cursorObject.setVisible((isVisible and cursorBlink and (map[cursorY] and map[cursorY][cursorX]) and true) or false)
- cursorObject.setZ(zOffset + 2)
- end
- local function createCoord(xPos, yPos, text, textColour, backgroundColour)
- local coord = {
- text = text,
- textCol = textColour,
- backCol = backgroundColour,
- textObj = false,
- backObj = false,
- }
- if isDrawn then
- coord.textObj = drawText(xPos, yPos, text, textColour)
- coord.backObj = drawBackground(xPos, yPos, backgroundColour)
- end
- return coord
- end
- local updateTextObj
- local function updateCoord(xPos, yPos, text, textColour, backgroundColour)
- local coord = map[yPos] and map[yPos][xPos]
- if coord then
- if coord.text ~= text or coord.textCol ~= textColour or coord.backCol ~= backgroundColour then
- coord.text = text
- coord.textCol = textColour
- coord.backCol = backgroundColour
- if isDrawn then
- updateTextObj = coord.textObj
- updateTextObj.setText(text)
- updateTextObj.setColor(textColour)
- updateTextObj.setX((xPos-1)*6 + xOffset + (charOffset[text] or 0))
- coord.backObj.setColor(backgroundColour)
- end
- hasChanged = true
- end
- end
- end
- local function updateCursor()
- if isDrawn and cursorObject then
- cursorObject.setX((cursorX-1)*6 + xOffset)
- cursorObject.setY((cursorY-1)*9 + yOffset)
- cursorObject.setZ(zOffset + 2)
- cursorObject.setVisible((isVisible and cursorBlink and (map[cursorY] and map[cursorY][cursorX]) and true) or false)
- cursorObject.setColor(currentTextColour)
- end
- end
- local redirect = {}
- redirect.getDrawn = function()
- return isDrawn
- end
- redirect.setDrawn = function(setDrawn)
- if type(setDrawn) == "boolean" and isDrawn ~= setDrawn then
- if setDrawn == true then
- local coord
- for yPos = 1, height do
- for xPos = 1,width do
- coord = map[yPos][xPos]
- coord.textObj = drawText(xPos, yPos, coord.text, coord.textCol)
- coord.backObj = drawBackground(xPos, yPos, coord.backCol)
- end
- end
- if bezelDrawn then
- drawBezel()
- end
- drawClickCatcher()
- drawCursor()
- else
- local coord
- for yPos = 1, height do
- for xPos = 1,width do
- coord = map[yPos][xPos]
- coord.textObj.delete()
- coord.backObj.delete()
- coord.textObj = false
- coord.backObj = false
- end
- end
- cursorObject.delete()
- cursorObject = false
- eraseClickCatcher()
- eraseBezel()
- end
- isDrawn = setDrawn
- hasChanged = true
- return true
- end
- return false
- end
- redirect.getAlignment = function()
- return horizontalAlign, verticalAlign
- end
- redirect.setAlignment = function(horizontal, vertical)
- --if check args then
- if isDrawn then
- local coord
- for yPos = 1, height do
- for xPos = 1,width do
- coord = map[yPos][xPos]
- coord.textObj.setScreenAnchor(horizontal, vertical)
- coord.backObj.setScreenAnchor(horizontal, vertical)
- end
- end
- if bezelDrawn then
- topBezel.setScreenAnchor(horizontal, vertical)
- bottomBezel.setScreenAnchor(horizontal, vertical)
- leftBezel.setScreenAnchor(horizontal, vertical)
- rightBezel.setScreenAnchor(horizontal, vertical)
- end
- clickCatcherObject.setScreenAnchor(horizontal, vertical)
- cursorObject.setScreenAnchor(horizontal, vertical)
- hasChanged = true
- end
- horizontalAlign, verticalAlign = horizontal, vertical
- return true
- --end
- --return false
- end
- redirect.getVisible = function()
- return isVisible
- end
- redirect.setVisible = function(setVisible)
- if type(setVisible) == "boolean" and isVisible ~= setVisible then
- if isDrawn then
- local coord
- for yPos = 1, height do
- for xPos = 1,width do
- coord = map[yPos][xPos]
- coord.textObj.setVisible(setVisible)
- coord.backObj.setVisible(setVisible)
- end
- end
- if bezelDrawn then
- topBezel.setVisible(setVisible)
- bottomBezel.setVisible(setVisible)
- leftBezel.setVisible(setVisible)
- rightBezel.setVisible(setVisible)
- end
- clickCatcherObject.setVisible(setVisible)
- cursorObject.setVisible(setVisible and cursorBlink)
- hasChanged = true
- end
- isVisible = setVisible
- return true
- end
- return false
- end
- redirect.getOpacity = function()
- return opacity
- end
- redirect.setOpacity = function(newOpacity)
- if type(newOpacity) == "number" and newOpacity >= 0 and newOpacity <= 1 then
- if isDrawn then
- local coord
- for yPos = 1, height do
- for xPos = 1,width do
- coord = map[yPos][xPos]
- coord.backObj.setOpacity(newOpacity)
- end
- end
- if bezelDrawn then
- topBezel.setOpacity(newOpacity)
- bottomBezel.setOpacity(newOpacity)
- leftBezel.setOpacity(newOpacity)
- rightBezel.setOpacity(newOpacity)
- end
- hasChanged = true
- end
- opacity = newOpacity
- return true
- end
- return false
- end
- redirect.getSurface = function()
- return surface
- end
- redirect.setSurface = function(newSurface, redraw)
- surface = newSurface
- if redraw == true and isDrawn then
- redirect.setDrawn(false)
- redirect.setDrawn(true)
- end
- end
- redirect.getOffset = function()
- return xOffset, yOffset, zOffset
- end
- redirect.setOffset = function(xOffsetNew, yOffsetNew, zOffsetNew)
- xOffset = math.floor(tonumber(xOffsetNew) or xOffset)
- yOffset = math.floor(tonumber(yOffsetNew) or yOffset)
- zOffset = math.min(250, math.max(1, math.floor(tonumber(zOffsetNew) or zOffset)))
- if isDrawn then
- for yPos, line in ipairs(map) do
- for xPos, coord in ipairs(line) do
- coord.textObj.setX((xPos-1)*6 + xOffset + (charOffset[coord.curText] or 0))
- coord.textObj.setY((yPos-1)*9 + yOffset)
- coord.textObj.setZ(zOffset + 1)
- coord.backObj.setX((xPos-1)*6 + xOffset)
- coord.backObj.setY((yPos-1)*9 + yOffset)
- coord.backObj.setZ(zOffset)
- end
- end
- clickCatcherObject.setX(xOffset)
- clickCatcherObject.setY(yOffset)
- clickCatcherObject.setZ(zOffset + 3)
- if bezelDrawn then
- eraseBezel()
- drawBezel()
- end
- updateCursor()
- hasChanged = true
- end
- return true
- end
- redirect.getSize = function()
- return width, height
- end
- redirect.setSize = function(newWidth, newHeight)
- for yPos = 1, math.max(newHeight, height) do
- if yPos <= newHeight then
- map[yPos] = map[yPos] or {}
- for xPos = 1, math.max(newWidth, width) do
- if xPos <= newWidth then
- if not map[yPos][xPos] then
- map[yPos][xPos] = createCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
- end
- elseif map[yPos][xPos] then
- local coord = map[yPos][xPos]
- if coord.textObj then
- coord.textObj.delete()
- end
- if coord.backObj then
- coord.backObj.delete()
- end
- map[yPos][xPos] = nil
- end
- end
- elseif map[yPos] then
- for xPos = 1, math.max(newWidth, width) do
- if map[yPos][xPos] then
- local coord = map[yPos][xPos]
- if coord.textObj then
- coord.textObj.delete()
- end
- if coord.backObj then
- coord.backObj.delete()
- end
- map[yPos][xPos] = nil
- end
- end
- map[yPos] = nil
- end
- end
- width, height = newWidth, newHeight
- if isDrawn then
- clickCatcherObject.delete()
- drawClickCatcher()
- if bezelDrawn then
- eraseBezel()
- drawBezel()
- end
- end
- updateCursor()
- hasChanged = true
- end
- redirect.getClick = function(objectID, xPos, yPos)
- if objectID == clickCatcherID then
- return math.ceil((xPos+1)/6), math.ceil((yPos+1)/9)
- else
- return false, false
- end
- end
- redirect.getBezelDrawn = function()
- return bezelDrawn
- end
- redirect.setBezelDrawn = function(isBezelDrawn)
- if type(isBezelDrawn) == "boolean" and bezelDrawn ~= isBezelDrawn then
- bezelDrawn = isBezelDrawn
- if isDrawn then
- if isBezelDrawn then
- drawBezel()
- else
- eraseBezel()
- end
- hasChanged = true
- end
- return true
- end
- return false
- end
- redirect.hasChanged = function()
- return hasChanged
- end
- redirect.reset = function()
- hasChanged = false
- end
- local newTerm = {
- write = function(text)
- local textType = type(text)
- if textType == "string" or textType == "number" then
- local text = string.gsub(text, "%c", " ")
- local length = string.len(text)
- if length > 0 then
- if map[cursorY] then
- for xPos = 1, length do
- updateCoord(xPos - 1 + cursorX, cursorY, string.sub(text, xPos, xPos), currentTextColour, currentBackgroundColour)
- end
- end
- cursorX = cursorX + length
- updateCursor()
- end
- end
- end,
- blit = function(text, textColour, backgroundColour)
- if type(text) ~= "string" or type(textColour) ~= "string" or type(backgroundColour) ~= "string" then
- error("Expected string, string, string", 2)
- end
- if #text ~= #textColour or #text ~= #backgroundColour then
- error("Arguments must be the same length", 2)
- end
- local text = string.gsub(text, "%c", " ")
- local length = string.len(text)
- if length > 0 then
- if map[cursorY] then
- for xPos = 1, length do
- updateCoord(xPos - 1 + cursorX, cursorY, string.sub(text, xPos, xPos), hexToColour[string.sub(textColour, xPos, xPos)] or currentTextColour, hexToColour[string.sub(backgroundColour, xPos, xPos)] or currentBackgroundColour)
- end
- end
- cursorX = cursorX + length
- updateCursor()
- end
- end,
- clear = function()
- for yPos = 1, height do
- for xPos = 1, width do
- updateCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
- end
- end
- end,
- clearLine = function()
- if map[cursorY] then
- for xPos = 1, width do
- updateCoord(xPos, cursorY, " ", currentTextColour, currentBackgroundColour)
- end
- end
- end,
- getCursorPos = function()
- return cursorX, cursorY
- end,
- setCursorPos = function(xPos, yPos)
- cursorX = math.floor(tonumber(xPos) or cursorX)
- cursorY = math.floor(tonumber(yPos) or cursorY)
- updateCursor()
- end,
- setCursorBlink = function(blink)
- if type(blink) == "boolean" then
- cursorBlink = blink
- updateCursor()
- end
- end,
- isColour = function()
- return true
- end,
- getSize = function()
- return width, height
- end,
- scroll = function(noOfLines)
- local n = math.floor(tonumber(noOfLines) or 0)
- if n ~= 0 and height > 0 then
- for yPos = (n > 0 and 1) or height, (n < 0 and 1) or height, n/math.abs(n) do
- for xPos = 1, width do
- if map[yPos + n] then
- local coord = map[yPos + n][xPos].data
- updateCoord(xPos, yPos, coord.text, coord.textColour, coord.backgroundColour)
- else
- updateCoord(xPos, yPos, " ", currentTextColour, currentBackgroundColour)
- end
- end
- end
- end
- end,
- setTextColour = function(colour)
- local newColour = colourToRGB[tonumber(colour)]
- if newColour then
- currentTextColour = newColour
- updateCursor()
- end
- end,
- getTextColour = function()
- return rgbToColour[currentTextColour]
- end,
- setBackgroundColour = function(colour)
- local newColour = colourToRGB[tonumber(colour)]
- if newColour then
- currentBackgroundColour = newColour
- end
- end,
- getBackgroundColour = function()
- return rgbToColour[currentBackgroundColour]
- end,
- }
- newTerm.isColor = newTerm.isColour
- newTerm.setTextColor = newTerm.setTextColour
- newTerm.getTextColor = newTerm.getTextColour
- newTerm.setBackgroundColor = newTerm.setBackgroundColour
- newTerm.getBackgroundColor = newTerm.getBackgroundColour
- redirect.term = newTerm
- redirect.setSize(width, height)
- return redirect
- end
- local function setupLabel(buttonLen, minY, maxY, name)
- local labelTable = {}
- if type(name) == "table" then
- for i = 1, #name do
- labelTable[i] = name[i]
- end
- name = name.label
- elseif type(name) == "string" then
- local buttonText = string.sub(name, 1, buttonLen - 2)
- if #buttonText < #name then
- buttonText = " "..buttonText.." "
- else
- local labelLine = string.rep(" ", math.floor((buttonLen - #buttonText) / 2))..buttonText
- buttonText = labelLine..string.rep(" ", buttonLen - #labelLine)
- end
- for i = 1, maxY - minY + 1 do
- if maxY == minY or i == math.floor((maxY - minY) / 2) + 1 then
- labelTable[i] = buttonText
- else
- labelTable[i] = string.rep(" ", buttonLen)
- end
- end
- end
- return labelTable, name
- end
- local Button = {
- draw = function(self)
- local old = term.redirect(self.mon)
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.clear()
- for name, buttonData in pairs(self.buttonList) do
- if buttonData.active then
- term.setBackgroundColor(buttonData.activeColor)
- term.setTextColor(buttonData.activeText)
- else
- term.setBackgroundColor(buttonData.inactiveColor)
- term.setTextColor(buttonData.inactiveText)
- end
- for i = buttonData.yMin, buttonData.yMax do
- term.setCursorPos(buttonData.xMin, i)
- term.write(buttonData.label[i - buttonData.yMin + 1])
- end
- end
- if old then
- term.redirect(old)
- else
- term.restore()
- end
- end,
- add = function(self, name, func, xMin, yMin, xMax, yMax, inactiveColor, activeColor, inactiveText, activeText)
- local label, name = setupLabel(xMax - xMin + 1, yMin, yMax, name)
- if self.buttonList[name] then error("button already exists", 2) end
- local x, y = self.mon.getSize()
- if xMin < 1 or yMin < 1 or xMax > x or yMax > y then error("button out of bounds", 2) end
- self.buttonList[name] = {
- func = func,
- xMin = xMin,
- yMin = yMin,
- xMax = xMax,
- yMax = yMax,
- active = false,
- inactiveColor = inactiveColor or colors.red,
- activeColor = activeColor or colors.lime,
- inactiveText = inactiveText or colors.white,
- activeText = activeText or colors.white,
- label = label,
- }
- for i = xMin, xMax do
- for j = yMin, yMax do
- if self.clickMap[i][j] ~= nil then
- --undo changes
- for k = xMin, xMax do
- for l = yMin, yMax do
- if self.clickMap[k][l] == name then
- self.clickMap[k][l] = nil
- end
- end
- end
- self.buttonList[name] = nil
- error("overlapping button", 2)
- end
- self.clickMap[i][j] = name
- end
- end
- end,
- remove = function(self, name)
- if self.buttonList[name] then
- local button = self.buttonList[name]
- for i = button.xMin, button.xMax do
- for j = button.yMin, button.yMax do
- self.clickMap[i][j] = nil
- end
- end
- self.buttonList[name] = nil
- end
- end,
- run = function(self)
- while true do
- self:draw()
- local event = {self:handleEvents(os.pullEvent(self.side == "term" and "mouse_click" or "monitor_touch"))}
- if event[1] == "button_click" then
- self.buttonList[event[2]].func()
- end
- end
- end,
- handleEvents = function(self, ...)
- local event = {...}
- if #event == 0 then event = {os.pullEvent()} end
- if (self.side == "term" and event[1] == "mouse_click") or (self.side ~= "term" and event[1] == "monitor_touch" and event[2] == self.side) then
- local clicked = self.clickMap[event[3]][event[4]]
- if clicked and self.buttonList[clicked] then
- return "button_click", clicked
- end
- end
- return unpack(event)
- end,
- toggleButton = function(self, name, noDraw)
- self.buttonList[name].active = not self.buttonList[name].active
- if not noDraw then self:draw() end
- end,
- flash = function(self, name, duration)
- self:toggleButton(name)
- sleep(tonumber(duration) or 0.15)
- self:toggleButton(name)
- end,
- rename = function(self, name, newName)
- self.buttonList[name].label, newName = setupLabel(self.buttonList[name].xMax - self.buttonList[name].xMin + 1, self.buttonList[name].yMin, self.buttonList[name].yMax, newName)
- if not self.buttonList[name] then error("no such button", 2) end
- if name ~= newName then
- self.buttonList[newName] = self.buttonList[name]
- self.buttonList[name] = nil
- for i = self.buttonList[newName].xMin, self.buttonList[newName].xMax do
- for j = self.buttonList[newName].yMin, self.buttonList[newName].yMax do
- self.clickMap[i][j] = newName
- end
- end
- end
- self:draw()
- end,
- }
- local function newTouchpoint(monSide)
- local buttonInstance = {
- side = monSide or "term",
- mon = monSide and peripheral.wrap(monSide) or term.current(),
- buttonList = {},
- clickMap = {},
- }
- local x, y = buttonInstance.mon.getSize()
- for i = 1, x do
- buttonInstance.clickMap[i] = {}
- end
- setmetatable(buttonInstance, {__index = Button})
- return buttonInstance
- end
- local function resumeThread(threadInfo, eventType, ...)
- if threadInfo.running then
- if not threadInfo.filter or eventType == threadInfo.filter or eventType == "terminate" then
- threadInfo.filter = nil
- local prevTerm = term.redirect(threadInfo.term)
- local ok, passback = coroutine.resume(threadInfo.thread, eventType, ...)
- term.redirect(prevTerm)
- if not ok then
- threadInfo.running = false
- printError(passback)
- elseif coroutine.status(threadInfo.thread) == "dead" then
- threadInfo.running = false
- else
- threadInfo.filter = passback
- end
- end
- end
- end
- local function createThread(func, terminal)
- local thread = {
- running = true,
- filter = nil,
- thread = coroutine.create(func),
- term = terminal,
- }
- resumeThread(thread, nil)
- return thread
- end
- local function newSurfaceHandler(playerUUID, capture, programRedirect, toolbarRedirect, settingRedirect)
- return coroutine.create(
- function()
- local programThread
- local fnFile, err = loadfile("rom/programs/advanced/multishell")
- if fnFile then
- local tEnv = {
- shell = shell,
- }
- setmetatable( tEnv, { __index = _G } )
- setfenv( fnFile, tEnv )
- programThread = createThread(fnFile, programRedirect.term)
- else
- error(err)
- end
- local isLocked = false
- local forceSettingsDrawn = false
- local function toolbarFunc()
- local tPoint = newTouchpoint()
- local lockButtonLabel = {
- "L",
- label = "lock",
- }
- local function lockFunc()
- isLocked = not isLocked
- tPoint:toggleButton("lock")
- end
- tPoint:add(lockButtonLabel, lockFunc, 1, 1, 1, 1, colours.green, colours.red, colours.lime, colours.orange)
- local settingButtonLabel = {
- "S",
- label = "setting",
- }
- local function settingFunc()
- settingRedirect.setDrawn(not settingRedirect.getDrawn())
- tPoint:flash("setting", 0.1)
- end
- tPoint:add(settingButtonLabel, settingFunc, 2, 1, 2, 1, colours.yellow, colours.green, colours.black, colours.black)
- local terminateButtonLabel = {
- "T",
- label = "terminate",
- }
- local function terminateFunc()
- tPoint:flash("terminate", 0.1)
- resumeThread(programThread, "terminate")
- end
- tPoint:add(terminateButtonLabel, terminateFunc, 3, 1, 3, 1, colours.red, colours.yellow, colours.orange, colours.orange)
- tPoint:run()
- end
- local toolbarThread = createThread(toolbarFunc, toolbarRedirect.term)
- local function settingFunc()
- local tPoint = newTouchpoint()
- local width, height = term.getSize()
- local alignLeftButtonLabel = {}
- for i = 2, height - 1 do
- table.insert(alignLeftButtonLabel, "<")
- end
- alignLeftButtonLabel.label = "alignLeft"
- local function alignLeftFunc()
- tPoint:flash("alignLeft", 0.1)
- local horizontal, vertical = settingRedirect.getAlignment()
- settingRedirect.setAlignment("LEFT", vertical)
- local xOffset, yOffset = settingRedirect.getOffset()
- settingRedirect.setOffset(20, yOffset)
- end
- tPoint:add(alignLeftButtonLabel, alignLeftFunc, 1, 2, 1, height - 1, colours.lightGrey, colours.green, colours.black, colours.white)
- local alignRightButtonLabel = {}
- for i = 2, height - 1 do
- table.insert(alignRightButtonLabel, ">")
- end
- alignRightButtonLabel.label = "alignRight"
- local function alignRightFunc()
- tPoint:flash("alignRight", 0.1)
- local horizontal, vertical = settingRedirect.getAlignment()
- settingRedirect.setAlignment("RIGHT", vertical)
- local xOffset, yOffset = settingRedirect.getOffset()
- settingRedirect.setOffset(-(15*6 + 20), yOffset)
- end
- tPoint:add(alignRightButtonLabel, alignRightFunc, width, 2, width, height - 1, colours.lightGrey, colours.green, colours.black, colours.white)
- local alignTopButtonLabel = {
- string.rep("^", width - 2),
- label = "alignTop",
- }
- local function alignTopFunc()
- tPoint:flash("alignTop", 0.1)
- local horizontal, vertical = settingRedirect.getAlignment()
- settingRedirect.setAlignment(horizontal, "TOP")
- local xOffset, yOffset = settingRedirect.getOffset()
- settingRedirect.setOffset(xOffset, 20)
- end
- tPoint:add(alignTopButtonLabel, alignTopFunc, 2, 1, width - 1, 1, colours.lightGrey, colours.green, colours.black, colours.white)
- local alignBottomButtonLabel = {
- string.rep("v", width - 2),
- label = "alignBottom",
- }
- local function alignBottomFunc()
- tPoint:flash("alignBottom", 0.1)
- local horizontal, vertical = settingRedirect.getAlignment()
- settingRedirect.setAlignment(horizontal, "BOTTOM")
- local xOffset, yOffset = settingRedirect.getOffset()
- local width, height = settingRedirect.getSize()
- settingRedirect.setOffset(xOffset, -(height*9 + 20))
- end
- tPoint:add(alignBottomButtonLabel, alignBottomFunc, 2, height, width - 1, height, colours.lightGrey, colours.green, colours.black, colours.white)
- local opacityLabel = {
- "Opacity",
- label = "opacity",
- }
- tPoint:add(opacityLabel, nil, 5, 3, 11, 3, colours.black, colours.black, colours.white, colours.white)
- local opacityValues = {
- [0] = "0.0", [0.1] = "0.1", [0.2] = "0.2", [0.3] = "0.3", [0.4] = "0.4", [0.5] = "0.5",
- [0.6] = "0.6", [0.7] = "0.7", [0.8] = "0.8", [0.9] = "0.9", [1] = "1.0",
- }
- local opacityValueLabel = {
- "1.0",
- label = "opacityValue",
- }
- tPoint:add(opacityValueLabel, nil, 7, 4, 9, 4, colours.black, colours.black, colours.white, colours.white)
- local decreaseOpacityLabel = {
- "<<",
- label = "decreaseOpacity",
- }
- local function decreaseOpacityFunc()
- local currOpacity = programRedirect.getOpacity()
- currOpacity = math.max(0, math.floor((currOpacity - 0.1)*10)/10)
- programRedirect.setOpacity(currOpacity)
- toolbarRedirect.setOpacity(currOpacity)
- opacityValueLabel[1] = opacityValues[currOpacity]
- tPoint:rename("opacityValue", opacityValueLabel)
- tPoint:flash("decreaseOpacity", 0.1)
- end
- tPoint:add(decreaseOpacityLabel, decreaseOpacityFunc, 4, 4, 5, 4, colours.grey, colours.green, colours.white, colours.white)
- local increaseOpacityLabel = {
- ">>",
- label = "increaseOpacity",
- }
- local function increaseOpacityFunc()
- local currOpacity = programRedirect.getOpacity()
- currOpacity = math.min(1, math.ceil((currOpacity + 0.1)*10)/10)
- programRedirect.setOpacity(currOpacity)
- toolbarRedirect.setOpacity(currOpacity)
- opacityValueLabel[1] = opacityValues[currOpacity]
- tPoint:rename("opacityValue", opacityValueLabel)
- tPoint:flash("increaseOpacity", 0.1)
- end
- tPoint:add(increaseOpacityLabel, increaseOpacityFunc, 11, 4, 12, 4, colours.grey, colours.green, colours.white, colours.white)
- local resetOpacityLabel = {
- "RESET",
- label = "resetOpacity",
- }
- local function resetOpacityFunc()
- programRedirect.setOpacity(1)
- toolbarRedirect.setOpacity(1)
- opacityValueLabel[1] = "1.0"
- tPoint:rename("opacityValue", opacityValueLabel)
- tPoint:flash("resetOpacity", 0.1)
- end
- tPoint:add(resetOpacityLabel, resetOpacityFunc, 6, 5, 10, 5, colours.grey, colours.green, colours.white, colours.white)
- local widthLabel = {
- "Width",
- label = "width",
- }
- tPoint:add(widthLabel, nil, 6, 7, 10, 7, colours.black, colours.black, colours.white, colours.white)
- local widthValueLabel = {
- " 51",
- label = "widthValue",
- }
- tPoint:add(widthValueLabel, nil, 7, 8, 9, 8, colours.black, colours.black, colours.white, colours.white)
- local decreaseWidthLabel = {
- "<<",
- label = "decreaseWidth",
- }
- local function decreaseWidthFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currWidth = math.max(1, currWidth - 1)
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(-(math.floor(currWidth*6/2)))
- resumeThread(programThread, "term_resize")
- widthValueLabel[1] = string.rep(" ", 3 - string.len(currWidth))..tostring(currWidth)
- tPoint:rename("widthValue", widthValueLabel)
- tPoint:flash("decreaseWidth", 0.1)
- end
- tPoint:add(decreaseWidthLabel, decreaseWidthFunc, 4, 8, 5, 8, colours.grey, colours.green, colours.white, colours.white)
- local increaseWidthLabel = {
- ">>",
- label = "increaseWidth",
- }
- local function increaseWidthFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currWidth = math.min(999, currWidth + 1)
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(-(math.floor(currWidth*6/2)))
- resumeThread(programThread, "term_resize")
- widthValueLabel[1] = string.rep(" ", 3 - string.len(currWidth))..tostring(currWidth)
- tPoint:rename("widthValue", widthValueLabel)
- tPoint:flash("increaseWidth", 0.1)
- end
- tPoint:add(increaseWidthLabel, increaseWidthFunc, 11, 8, 12, 8, colours.grey, colours.green, colours.white, colours.white)
- local resetWidthLabel = {
- "RESET",
- label = "resetWidth",
- }
- local function resetWidthFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currWidth = 51
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(-(math.floor(currWidth*6/2)))
- resumeThread(programThread, "term_resize")
- widthValueLabel[1] = string.rep(" ", 3 - string.len(currWidth))..tostring(currWidth)
- tPoint:rename("widthValue", widthValueLabel)
- tPoint:flash("resetWidth", 0.1)
- end
- tPoint:add(resetWidthLabel, resetWidthFunc, 6, 9, 10, 9, colours.grey, colours.green, colours.white, colours.white)
- local heightLabel = {
- "Height",
- label = "height",
- }
- tPoint:add(heightLabel, nil, 6, 11, 10, 11, colours.black, colours.black, colours.white, colours.white)
- local heightValueLabel = {
- " 19",
- label = "heightValue",
- }
- tPoint:add(heightValueLabel, nil, 7, 12, 9, 12, colours.black, colours.black, colours.white, colours.white)
- local decreaseHeightLabel = {
- "<<",
- label = "decreaseHeight",
- }
- local function decreaseHeightFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currHeight = math.max(1, currHeight - 1)
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(nil, -(math.floor(currHeight*9/2)))
- toolbarRedirect.setOffset(nil, -(math.floor(currHeight*9/2)) + (currHeight+1)*9)
- resumeThread(programThread, "term_resize")
- heightValueLabel[1] = string.rep(" ", 3 - string.len(currHeight))..tostring(currHeight)
- tPoint:rename("heightValue", heightValueLabel)
- tPoint:flash("decreaseHeight", 0.1)
- end
- tPoint:add(decreaseHeightLabel, decreaseHeightFunc, 4, 12, 5, 12, colours.grey, colours.green, colours.white, colours.white)
- local increaseHeightLabel = {
- ">>",
- label = "increaseHeight",
- }
- local function increaseHeightFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currHeight = math.min(999, currHeight + 1)
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(nil, -(math.floor(currHeight*9/2)))
- toolbarRedirect.setOffset(nil, -(math.floor(currHeight*9/2)) + (currHeight+1)*9)
- resumeThread(programThread, "term_resize")
- heightValueLabel[1] = string.rep(" ", 3 - string.len(currHeight))..tostring(currHeight)
- tPoint:rename("heightValue", heightValueLabel)
- tPoint:flash("increaseHeight", 0.1)
- end
- tPoint:add(increaseHeightLabel, increaseHeightFunc, 11, 12, 12, 12, colours.grey, colours.green, colours.white, colours.white)
- local resetHeightLabel = {
- "RESET",
- label = "resetHeight",
- }
- local function resetHeightFunc()
- local currWidth, currHeight = programRedirect.getSize()
- currHeight = 19
- programRedirect.setSize(currWidth, currHeight)
- programRedirect.setOffset(nil, -(math.floor(currHeight*9/2)))
- toolbarRedirect.setOffset(nil, -(math.floor(currHeight*9/2)) + (currHeight+1)*9)
- resumeThread(programThread, "term_resize")
- heightValueLabel[1] = string.rep(" ", 3 - string.len(currHeight))..tostring(currHeight)
- tPoint:rename("heightValue", heightValueLabel)
- tPoint:flash("resetHeight", 0.1)
- end
- tPoint:add(resetHeightLabel, resetHeightFunc, 6, 13, 10, 13, colours.grey, colours.green, colours.white, colours.white)
- tPoint:run()
- end
- local settingThread = createThread(settingFunc, settingRedirect.term)
- local lastClickX, lastClickY, lastButton = false, false, false
- local guiElements = {}
- for i = 2, 13 do
- guiElements[i] = false
- end
- local eventHandlers = {
- glasses_attach = function(event)
- programRedirect.setDrawn(true)
- toolbarRedirect.setDrawn(true)
- end,
- glasses_detach = function(event)
- programRedirect.setDrawn(false)
- toolbarRedirect.setDrawn(false)
- end,
- glasses_capture = function(event)
- capture.setBackground(0xffffff, 0)
- capture.toggleGuiElements(guiElements)
- capture.setKeyRepeat(true)
- programRedirect.setVisible(true)
- toolbarRedirect.setVisible(true)
- if forceSettingsDrawn then
- settingRedirect.setDrawn(true)
- forceSettingsDrawn = false
- end
- end,
- glasses_release = function(event)
- if not isLocked then
- programRedirect.setVisible(false)
- end
- toolbarRedirect.setVisible(false)
- settingRedirect.setDrawn(false)
- end,
- glasses_chat_command = function(event)
- if event[5] == "settings" then
- forceSettingsDrawn = true
- end
- end,
- glasses_chat_message = function(event)
- end,
- glasses_key_down = function(event)
- resumeThread(programThread, "key", event[5])
- if #string.gsub(event[6], "%c", "") > 0 then
- resumeThread(programThread, "char", event[6])
- end
- end,
- glasses_key_up = function(event)
- resumeThread(programThread, "key_up", event[5])
- end,
- glasses_mouse_scroll = function(event)
- end,
- glasses_mouse_down = function(event)
- lastClickX, lastClickY, lastButton = false, false, false
- end,
- glasses_mouse_up = function(event)
- if lastClickX and lastClickY then
- resumeThread(programThread, "mouse_up", event[5] + 1, lastClickX, lastClickY)
- lastClickX, lastClickY, lastButton = false, false, false
- end
- end,
- glasses_component_mouse_wheel = function(event)
- local xPos, yPos = programRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(programThread, "mouse_scroll", -event[9]/math.abs(event[9]), xPos, yPos)
- end
- end,
- glasses_component_mouse_down = function(event)
- local xPos, yPos = programRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(programThread, "mouse_click", event[9] + 1, xPos, yPos)
- lastClickX, lastClickY, lastButton = xPos, yPos, event[9] + 1
- else
- lastClickX, lastClickY, lastButton = false, false, false
- xPos, yPos = toolbarRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(toolbarThread, "mouse_click", event[9] + 1, xPos, yPos)
- else
- xPos, yPos = settingRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(settingThread, "mouse_click", event[9] + 1, xPos, yPos)
- end
- end
- end
- end,
- glasses_component_mouse_up = function(event)
- local xPos, yPos = programRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(programThread, "mouse_up", event[9] + 1, xPos, yPos)
- elseif lastClickX and lastClickY then
- resumeThread(programThread, "mouse_up", event[9] + 1, lastClickX, lastClickY)
- end
- lastClickX, lastClickY, lastButton = false, false, false
- end,
- glasses_component_mouse_drag = function(event)
- if lastClickX and lastClickY and lastButton then
- local xPos, yPos = programRedirect.getClick(event[5], event[7], event[8])
- if xPos and yPos then
- resumeThread(programThread, "mouse_drag", lastButton, xPos, yPos)
- lastClickX, lastClickY = xPos, yPos
- end
- end
- end,
- }
- local event = {}
- local handler
- while true do
- handler = eventHandlers[ event[1] ]
- if handler then
- handler(event)
- else
- resumeThread(programThread, unpack(event))
- resumeThread(toolbarThread, unpack(event))
- resumeThread(settingThread, unpack(event))
- end
- if not programThread.running then
- capture.stopCapturing()
- programRedirect.setVisible(false)
- programRedirect.term.setBackgroundColour(colours.black)
- programRedirect.term.setTextColour(colours.white)
- programRedirect.term.clear()
- programRedirect.term.setCursorPos(1, 1)
- toolbarRedirect.setVisible(false)
- settingRedirect.setDrawn(false)
- programThread = createThread(fnFile, programRedirect.term)
- end
- event = coroutine.yield()
- end
- end
- )
- end
- local function setupPlayer(playerUUID)
- local playerSurface = bridge.getSurfaceByUUID(playerUUID)
- playerSurface.clear()
- local player = {
- capture = bridge.getCaptureControl(playerUUID),
- programRedirect = newGlassesRedirect(playerSurface, 51, 19, -153, -85, 1, 1),
- toolbarRedirect = newGlassesRedirect(playerSurface, 3, 1, -9, 95, 5, 1),
- settingRedirect = newGlassesRedirect(playerSurface, 15, 15, 20, 20, 9, 1),
- }
- player.capture.stopCapturing()
- player.programRedirect.setVisible(false)
- player.programRedirect.setBezelDrawn(true)
- player.programRedirect.setDrawn(true)
- player.toolbarRedirect.setVisible(false)
- player.toolbarRedirect.setBezelDrawn(true)
- player.toolbarRedirect.setDrawn(true)
- player.settingRedirect.setVisible(true)
- player.settingRedirect.setBezelDrawn(true)
- player.settingRedirect.setAlignment("LEFT", "TOP")
- player.thread = newSurfaceHandler(playerUUID, player.capture, player.programRedirect, player.toolbarRedirect, player.settingRedirect)
- return player
- end
- local players = {}
- local mainTerminalEvents = {
- char = true,
- key = true,
- key_up = true,
- mouse_click = true,
- mouse_drag = true,
- mouse_scroll = true,
- mouse_up = true,
- paste = true,
- term_resize = true,
- terminate = true,
- }
- local glassesEvents = {
- glasses_attach = true,
- glasses_detach = true,
- glasses_capture = true,
- glasses_release = true,
- glasses_chat_command = true,
- glasses_chat_message = true,
- glasses_key_down = true,
- glasses_key_up = true,
- glasses_mouse_scroll = true,
- glasses_mouse_down = true,
- glasses_mouse_up = true,
- glasses_component_mouse_wheel = true,
- glasses_component_mouse_down = true,
- glasses_component_mouse_up = true,
- glasses_component_mouse_drag = true,
- }
- local function main()
- local event, eventType
- local playerUUID, player
- local exit = false
- while not exit do
- event = {coroutine.yield()}
- eventType = event[1]
- if glassesEvents[eventType] then
- playerUUID = event[4]
- player = players[playerUUID]
- if not player then
- players[playerUUID] = setupPlayer(playerUUID)
- else
- if eventType == "glasses_attach" then
- local playerSurface = bridge.getSurfaceByUUID(playerUUID)
- player.programRedirect.setSurface(playerSurface)
- player.toolbarRedirect.setSurface(playerSurface)
- player.settingRedirect.setSurface(playerSurface)
- end
- local ok, passback = coroutine.resume(player.thread, event)
- if not ok then
- printError(passback)
- end
- end
- elseif not mainTerminalEvents[eventType] then
- for _, player in pairs(players) do
- local ok, passback = coroutine.resume(player.thread, event)
- if not ok then
- printError(passback)
- end
- end
- elseif eventType == "key" and event[2] == keys.backspace then
- --clean up maybe
- exit = true
- end
- end
- end
- local function render()
- local sync = false
- while true do
- for _, player in pairs(players) do
- if player.programRedirect.hasChanged() then
- sync = true
- player.programRedirect.reset()
- end
- if player.toolbarRedirect.hasChanged() then
- sync = true
- player.toolbarRedirect.reset()
- end
- if player.settingRedirect.hasChanged() then
- sync = true
- player.settingRedirect.reset()
- end
- end
- if sync then
- bridge.sync()
- sync = false
- end
- coroutine.yield()
- end
- end
- for _, playerData in ipairs(bridge.getUsers()) do
- players[playerData.uuid] = setupPlayer(playerData.uuid)
- end
- parallel.waitForAny(main, render)
- --clean up
- for playerUUID, player in pairs(players) do
- player.capture.stopCapturing()
- local playerSurface = bridge.getSurfaceByUUID(playerUUID)
- playerSurface.clear()
- end
- bridge.sync()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement