Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- CREATED BY ALAKAZARD12 (Azelk)
- This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
- ]]
- local cBack = nil
- local cText = nil
- local W, H = term.getSize()
- local touched
- local tTouched
- local function round(n)
- local raw = n - math.floor(n)
- if raw > 0.5 then
- return math.ceil(n)
- else
- return math.floor(n)
- end
- end
- local function listen(UI)
- local output
- if UI.output then
- output = UI.output
- end
- local activeT
- local lastClick
- local tabOn = 0
- local lastTabbed
- local function clearTab()
- if lastTabbed then
- lastTabbed.Tabbed = false
- UI:draw()
- tabOn = 0
- lastTabbed = nil
- end
- end
- while true do
- if UI.stopList == true then break end
- local event, p1, p2, p3, p4, p5 = os.pullEventRaw()
- if UI.output then
- output = UI.output
- end
- if output then
- output(event, p1, p2, p3, p4, p5)
- end
- if event == "mouse_drag" then
- clearTab()
- local check
- function check(par, bg, fx, fy)
- table.sort(par, function(x, y)
- return x.zIndex > y.zIndex
- end)
- for i,v in ipairs(par) do
- if (v.visible == true and v.active == true) and (v.type == "button") then
- -- if p2 >= v.position[1] and p2 <= v.position[1] + v.size[1] - 1 and p3 >= v.position[2] and p3 <= v.position[2] + v.size[2] - 1 then
- if lastClick == v then
- if p1 == 1 then
- if v.drag1Func then
- v.drag1Func(p2, p3)
- end
- elseif p1 == 2 then
- if v.drag2Func then
- v.drag2Func(p2, p3)
- end
- elseif p1 == 3 then
- if v.drag3Func then
- v.drag3Func(p2, p3)
- end
- end
- end
- if p2 >= v.position[1] and p2 <= v.position[1] + v.size[1] - 1 and p3 >= v.position[2] and p3 <= v.position[2] + v.size[2] - 1 then
- if p1 == 1 then
- if v.drag1FuncO then
- v.drag1FuncO(x, y)
- end
- elseif p1 == 2 then
- if v.drag2FuncO then
- v.drag2FuncO(x, y)
- end
- elseif p1 == 3 then
- if v.drag3FuncO then
- v.drag3FuncO(x, y)
- end
- end
- end
- end
- if v.type == "frame" and v.active == true then
- if v.showBackground then
- check(v.children, v.backgroundColor, fx + v.position[1] - 1, fy + v.position[2] - 1)
- else
- check(v.children, bg, fx + v.position[1] - 1, fy + v.position[2] - 1)
- end
- end
- end
- end
- check(UI.Children, UI.backgroundColor, 0, 0)
- elseif event == "key" then
- if p1 == 15 then
- if tabOn == UI.maxTab then
- tabOn = 0
- else
- local nKey = 0
- local cKey
- local check
- function check(par, bg, fx, fy)
- table.sort(par, function(x, y)
- return x.zIndex > y.zIndex
- end)
- for i,v in ipairs(par) do
- if (v.canTab == true and v.active == true) and (v.type == "button" or v.type == "textbox") then
- if v.tabIndex > tabOn then
- if nKey == 0 then
- nKey = v.tabIndex
- cKey = v
- end
- if nKey - tabOn > v.tabIndex - tabOn then
- nKey = v.tabIndex
- cKey = v
- end
- end
- end
- if v.type == "frame" and v.active == true then
- if v.showBackground then
- check(v.children, v.backgroundColor, fx + v.position[1] - 1, fy + v.position[2] - 1)
- else
- check(v.children, bg, fx + v.position[1] - 1, fy + v.position[2] - 1)
- end
- end
- end
- end
- check(UI.Children, UI.backgroundColor, 0, 0)
- clearTab()
- if cKey then
- cKey.Tabbed = true
- tabOn = nKey
- lastTabbed = cKey
- UI:draw()
- end
- end
- end
- if activeT then
- if p1 == 14 then
- activeT.text = string.sub(activeT.text, 1, #activeT.text - 1)
- activeT.rText = string.sub(activeT.rText, 1, #activeT.rText - 1)
- UI:draw()
- elseif p1 == 28 then
- activeT.isActive = false
- UI:draw()
- if activeT.textChangeFunc then
- activeT.textChangeFunc(activeT.rText)
- end
- activeT = nil
- end
- else
- if p1 == 28 and lastTabbed then
- if lastTabbed.type == "textbox" then
- activeT = lastTabbed
- lastTabbed.isActive = true
- UI:draw()
- else
- if lastTabbed.enterPressFunc then
- lastTabbed.enterPressFunc()
- end
- end
- clearTab()
- end
- end
- elseif event == "char" then
- if activeT then
- activeT.text = activeT.text .. (activeT.textChar or p1)
- activeT.rText = (activeT.rText or "") .. p1
- term.setTextColor(activeT.textColor)
- UI:draw()
- end
- elseif event == "mouse_click" then
- local didPress = false
- clearTab()
- lastClick = nil
- local check
- function check(par, bg, fx, fy)
- if didPress == true then return end
- table.sort(par, function(x, y)
- return x.zIndex > y.zIndex
- end)
- for i,v in ipairs(par) do
- if v.visible == true and v.active == true and (v.type == "button" or v.type == "textbox") then
- if p2 >= v.position[1] + fx and p2 <= v.position[1] + v.size[1] + fx - 1 and p3 >= v.position[2] + fy and p3 <= v.position[2] + fy + v.size[2] - 1 then
- didPress = true
- lastClick = v
- if activeT then
- activeT.isActive = false
- if activeT.textChangeFunc then
- activeT.textChangeFunc(activeT.rText)
- end
- activeT = nil
- UI:draw()
- end
- if v.type == "button" then
- if p1 == 1 and v.button1Func then
- v.button1Func(p2, p3)
- elseif p1 == 2 and v.button2Func then
- v.button2Func(p2, p3)
- elseif p1 == 3 and v.button3Func then
- v.button3Func(p2, p3)
- end
- break
- elseif v.type == "textbox" then
- activeT = v
- if v.showText == true then
- v.isActive = true
- UI:draw()
- end
- break
- end
- end
- end
- if v.type == "frame" and v.active == true then
- if v.showBackground then
- check(v.children, v.backgroundColor, fx + v.position[1] - 1, fy + v.position[2] - 1)
- else
- check(v.children, bg, fx + v.position[1] - 1, fy + v.position[2] - 1)
- end
- end
- end
- end
- check(UI.Children, UI.backgroundColor, 0, 0)
- end
- end
- end
- local function draw(UI)
- if cBack == nil then
- cBack = {}
- term.setBackgroundColor(UI.backgroundColor)
- term.clear()
- for i = 1, W do
- local pOn = {}
- for y = 1, H do
- table.insert(pOn, UI.backgroundColor)
- end
- table.insert(cBack, pOn)
- end
- end
- if cText == nil then
- cText = {}
- for i = 1, W do
- local pOn = {}
- for y = 1, H do
- table.insert(pOn, {" ", colors.white})
- end
- table.insert(cText, pOn)
- end
- end
- tTouched = {}
- touched = {}
- for i = 1, W do
- local pOn = {}
- for y = 1, H do
- table.insert(pOn, 0)
- end
- table.insert(touched, pOn)
- end
- for i = 1, W do
- local pOn = {}
- for y = 1, H do
- table.insert(pOn, 0)
- end
- table.insert(tTouched, pOn)
- end
- local cusPos
- local check
- function check(par, bg, fx, fy)
- table.sort(par, function(x, y)
- return x.zIndex < y.zIndex
- end)
- for i,v in pairs(par) do
- if v.visible == true and (v.type == "label" or v.type == "button" or v.type == "textbox" or v.type == "frame" or v.type == "image") then
- local Back = v.backgroundColor
- if v.Tabbed == true then
- Back = v.tabColor
- end
- if v.showBackground == false then
- Back = bg
- end
- term.setBackgroundColor(Back)
- if v.showBackground == true then
- for xs = 1, v.size[1] do
- for ys = 1, v.size[2] do
- local x = v.position[1] + xs - 1 + fx
- local y = v.position[2] + ys - 1 + fy
- if cBack[x] then
- if cBack[x][y] ~= Back then
- term.setBackgroundColor(Back)
- term.setCursorPos(x, y)
- term.write(" ")
- cBack[x][y] = Back
- end
- touched[x][y] = 1
- end
- end
- end
- end
- if v.type == "image" then
- if v.image then
- paintutils.drawImage(v.image, v.position[1] + fx, v.position[2] + fy)
- end
- end
- if v.type == "label" or v.type == "button" or v.type == "textbox" then
- if v.showText == true then
- term.setTextColor(v.textColor)
- local text = v.text
- if v.isActive == true then
- text = text .. " "
- end
- if #text > v.size[1] then
- text = string.sub(text, #text - v.size[1] + 1, #text)
- end
- local x = v.position[1]
- local y = v.position[2]
- if v.xAlign == "center" then
- x = round((v.size[1] - #text) / 2 + v.position[1])
- elseif v.xAlign == "right" then
- x = round(v.size[1] - #text + v.position[1])
- end
- term.setCursorPos(x + fx, y + fy)
- term.write(text)
- for i = 1, #text do
- local on = string.sub(text, i, i)
- if cBack[x + fx + i - 1][y + fy] then
- if cText[x + fx + i - 1][y + fy] ~= on or cBack[x + fx + i - 1][y + fy] ~= Back then
- term.setCursorPos(x + fx + i - 1, y + fy)
- term.write(on)
- cText[x + fx + i - 1][y + fy] = on
- cBack[x + fx + i - 1][y + fy] = Back
- end
- tTouched[x + fx + i - 1][y + fy] = 1
- end
- end
- if v.isActive == true then
- cusPos = {x + #text - 1 + fx, y + fy, v.textColor}
- end
- end
- end
- if v.type == "frame" then
- if v.showBackground then
- check(v.children, v.backgroundColor, fx + v.position[1] - 1, fy + v.position[2] - 1)
- else
- check(v.children, bg, fx + v.position[1] - 1, fy + v.position[2] - 1)
- end
- end
- end
- end
- end
- check(UI.Children, UI.backgroundColor, 0, 0)
- for i,x in pairs(touched) do
- for y,t in pairs(x) do
- term.setCursorPos(1, 1)
- if t == 0 then
- term.setCursorPos(i, y)
- term.setBackgroundColor(UI.backgroundColor)
- term.write(" ")
- cBack[i][y] = UI.backgroundColor
- end
- end
- end
- for i,x in pairs(tTouched) do
- for y,t in pairs(x) do
- term.setCursorPos(1, 1)
- if t == 0 then
- term.setCursorPos(i, y)
- term.setBackgroundColor(cBack[i][y])
- term.write(" ")
- -- cBack[i][y] = UI.backgroundColor
- end
- end
- end
- if cusPos then
- term.setCursorPos(cusPos[1], cusPos[2])
- term.setTextColor(cusPos[3])
- term.setCursorBlink(true)
- else
- term.setCursorBlink(false)
- end
- end
- local function newUI()
- -- Start creating the GUI
- local UI = {}
- UI.maxTab = 1
- UI.Children = {}
- UI.backgroundColor = colors.cyan
- function UI:checkTabs()
- local high = 0
- local check
- function check(par)
- for i,v in pairs(par) do
- if v.tabIndex then
- if v.tabIndex > high then
- high = v.tabIndex
- end
- end
- if v.type == "frame" then
- check(v.children)
- end
- end
- end
- check(UI.Children)
- UI.maxTab = high
- end
- function UI:setOutput(func)
- UI.output = func
- end
- function UI:stopListen()
- UI.stopList = true
- end
- function UI:setBackgroundColor(color)
- UI.backgroundColor = color
- end
- function UI:draw()
- draw(UI)
- end
- function UI:listen()
- UI.stopList = false
- listen(UI)
- end
- function UI:create(iType, par)
- iType = iType:lower()
- local ins
- if iType == "checkbox" then
- ins = {}
- ins.canTab = true
- ins.visible = true
- ins.showBackground = true
- ins.active = true
- ins.char = "X"
- ins.value = false
- ins.backgroundColor = colors.gray
- ins.textColor = colors.white
- ins.tabIndex = 1
- ins.tabColor = colors.blue
- function ins:setChar(char)
- ins.char = char
- end
- function ins:setValue(val)
- ins.value = val
- end
- function ins:setBackgroundColor(color)
- ins.backgroundColor = color
- end
- function ins:setTextColor(color)
- ins.textColor = color
- end
- function ins:setTabColor(color)
- ins.tabColor = color
- end
- function ins:setTabIndex(i)
- ins.tabIndex = i
- UI:checkTabs()
- end
- elseif iType == "frame" then
- ins = {}
- ins.visible = true
- ins.showBackground = true
- ins.type = iType
- ins.backgroundColor = colors.orange
- ins.size = {10, 3}
- ins.position = {1, 1}
- ins.zIndex = 1
- ins.children = {}
- ins.active = true
- function ins:setZIndex(i)
- ins.zIndex = i
- end
- function ins:setActive(b)
- ins.active = b
- end
- function ins:setVisible(b)
- ins.visible = b
- end
- function ins:setShowBackground(b)
- ins.showBackground = b
- end
- function ins:setBackgroundColor(color)
- ins.backgroundColor = color
- end
- function ins:setSize(x, y)
- ins.size = {x, y}
- end
- function ins:getSize()
- return ins.size[1], ins.size[2]
- end
- function ins:getPosition()
- return ins.position[1], ins.position[2]
- end
- function ins:setPosition(x, y)
- ins.position = {x, y}
- end
- function ins:getBackgroundColor()
- return ins.backgroundColor
- end
- elseif iType == "image" then
- ins = {}
- ins.visible = true
- ins.type = iType
- ins.image = nil
- ins.zIndex = 1
- ins.backgroundColor = colors.black
- ins.size = {8, 8}
- ins.position = {1, 1}
- ins.showBackground = true
- function ins:setShowBackground(b)
- ins.showBackground = b
- end
- function ins:setVisible(b)
- ins.visible = b
- end
- function ins:setImage(i)
- ins.image = i
- end
- function ins:setZIndex(i)
- ins.zIndex = i
- end
- function ins:setBackgroundColor(col)
- ins.backgroundColor = col
- end
- function ins:setSize(x, y)
- ins.size = {x, y}
- end
- function ins:setPosition(x, y)
- ins.position = {x, y}
- end
- function ins:getPosition()
- return unpack(ins.position)
- end
- function ins:getSize()
- return unpack(ins.size)
- end
- elseif iType == "button" or iType == "label" or iType == "textbox" then
- ins = {}
- ins.canTab = true
- ins.tabIndex = 1
- ins.tabColor = colors.blue
- ins.xAlign = "left"
- ins.visible = true
- ins.active = true
- ins.showBackground = true
- ins.showText = true
- ins.type = iType
- ins.backgroundColor = colors.gray
- ins.textColor = colors.white
- ins.text = iType
- ins.rText = iType
- ins.size = {6, 1}
- ins.position = {1, 1}
- ins.zIndex = 1
- function ins:setActive(b)
- ins.active = b
- end
- function ins:getBackgroundColor()
- return ins.backgroundColor
- end
- function ins:getTextColor()
- return ins.textColor
- end
- function ins:getXAlign()
- return ins.xAlign
- end
- function ins:setZIndex(i)
- ins.zIndex = i
- end
- function ins:setTabIndex(i)
- ins.tabIndex = i
- UI:checkTabs()
- end
- function ins:setTabColor(color)
- ins.tabColor = color
- end
- function ins:setTextColor(color)
- ins.textColor = color
- end
- function ins:setShowBackground(bool)
- ins.showBackground = bool
- end
- function ins:setShowText(bool)
- ins.showText = bool
- end
- function ins:setXAlign(t)
- ins.xAlign = t
- end
- function ins:setVisible(bool)
- ins.visible = bool
- end
- function ins:setBackgroundColor(color)
- ins.backgroundColor = color
- end
- function ins:setSize(x, y)
- ins.size = {round(x), round(y)}
- end
- function ins:setPosition(x, y)
- ins.position = {round(x), round(y)}
- end
- function ins:getPosition()
- return unpack(ins.position)
- end
- function ins:getSize()
- return unpack(ins.size)
- end
- function ins:setText(text)
- ins.text = text or "nil"
- ins.rText = text or "nil"
- end
- function ins:getText()
- return ins.rText or "nil"
- end
- if iType == "textbox" then
- function ins:setTextChar(char)
- ins.textChar = char
- end
- function ins.textChange(func)
- ins.textChangeFunc = func
- end
- end
- if iType == "button" then
- function ins.button1DragOver(func)
- ins.drag1FuncO = func
- end
- function ins.button2DragOver(func)
- ins.drag2FuncO = func
- end
- function ins.button3DragOver(func)
- ins.drag3FuncO = func
- end
- function ins.button1Drag(func)
- ins.drag1Func = func
- end
- function ins.button2Drag(func)
- ins.drag2Func = func
- end
- function ins.button3Drag(func)
- ins.drag3Func = func
- end
- function ins.button1Click(func)
- ins.button1Func = func
- end
- function ins.enterPress(func)
- ins.enterPressFunc = func
- end
- function ins.button2Click(func)
- ins.button2Func = func
- end
- function ins.button3Click(func)
- ins.button3Func = func
- end
- end
- end
- function ins:destroy()
- local li
- if par then
- li = par.children
- else
- li = UI.Children
- end
- for i,v in pairs(li) do
- if v == ins then
- table.remove(li, i)
- break
- end
- end
- end
- if par then
- table.insert(par.children, ins)
- else
- table.insert(UI.Children, ins)
- end
- return ins
- end
- return UI
- end
- function new()
- local UI = newUI()
- return UI
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement