From ffeb1cabd24c4cab741290e081d1af9e73979475 Mon Sep 17 00:00:00 2001 From: Noryie Date: Tue, 15 Mar 2022 20:12:31 +0100 Subject: [PATCH] Update nGUI.lua --- nGUI.lua | 500 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 451 insertions(+), 49 deletions(-) diff --git a/nGUI.lua b/nGUI.lua index b87fa04..3c3dd52 100644 --- a/nGUI.lua +++ b/nGUI.lua @@ -1,29 +1,37 @@ -- Shad's GUI free for everyone to use -local sGUI = {} - -local frame = { __type = "Frame", name = ""} -sGUI.frames = {} +frame = { __type = "Frame", name = ""} frame.__index = frame -local button = { __type = "Button", name = ""} -frame.buttons = {} +button = { __type = "Button", name = ""} button.__index = button -local textbox = { __type = "Textbox", name = ""} -frame.textboxs = {} +label = { __type = "Label", name = ""} +label.__index = label + +textbox = { __type = "Textbox", name = ""} textbox.__index = textbox -local w, h = term.getSize() +timer = { __type = "Timer", name = ""} +timer.__index = timer -frame.new = function(name) - local newElement = {name=name, fWindow = window.create(term.native(),1,1,w,h)} - if(sGUI.frames[name] == nil)then - sGUI.frames[name] = newElement +checkbox = { __type = "Checkbox", name = ""} +checkbox.__index = checkbox + +local w, h = term.getSize() +local activeFrame +local frames = {} + +frame.new = function(name, screen) + local newElement = {name=name, fWindow = window.create((screen~=nil and screen or term.native()),1,1,w,h), objects={},bgcolor = colors.black, fgcolor=colors.white} + if(frames[name] == nil)then + frames[name] = newElement newElement.fWindow.setVisible(false) - return setmetatable(newElement, frame); + local metaTab = setmetatable(newElement, frame); + metaTab.debugLabel=metaTab:addLabel("DebugLabel") + return metaTab; else - return sGUI.frames[name]; + return frames[name]; end end @@ -34,79 +42,473 @@ end function frame:show() self.draw = true + self.changed = true + self.fWindow.setBackgroundColor(self.bgcolor) + self.fWindow.setTextColor(self.fgcolor) + self.fWindow.setVisible(true) + if(activeFrame~=nil)then + activeFrame:hide() + end + activeFrame = self end + function frame:hide() + self.fWindow.setVisible(false) + self.changed = true self.draw = false end +function frame:addTimer(name) +local newElement = {frame = self, timer=5, repeats=0} + if(self.objects[name] == nil)then + self.objects[name] = newElement + return setmetatable(newElement, timer); + else + return nil, "id "..name.." already exists"; + end +end + +function timer:setTime(time, repeats) + self.timer = time + if(repeats>0)then + self.repeats = repeats + else + self.repeats = -1 + end +end + +function timer:start(time, repeats) + self.active = true + if(time~=nil)then self.timer = time end + if(repeats~=nil)then self.repeats = repeats end + self.timeObj = os.startTimer(self.timer) +end + +function timer:cancel() + self.active = false + os.cancelTimer(self.timeObj) +end + +function timer:onCall(func) + self.call = func +end + +function frame:addCheckbox(name) +local newElement = {frame = self, x=1, y=1, bgcolor=colors.lightBlue, fgcolor=colors.black,symbol="X",changed=true,checked=false,drawCalls=0} + if(self.objects[name] == nil)then + self.objects[name] = newElement + return setmetatable(newElement, checkbox); + else + return nil, "id "..name.." already exists"; + end +end + +function checkbox:show() + if not(self.draw)then + self.draw = true + self.changed = true + end +end + +function checkbox:hide() + if (self.draw)then + self.draw = false + self.changed = true + end +end + +function checkbox:setPosition(x,y) + self.x = tonumber(x) + self.y = tonumber(y) + self.changed = true +end + +function checkbox:setBackground(color) + self.bgcolor = color + self.changed = true +end + +function checkbox:setForeground(color) + self.fgcolor = color + self.changed = true +end + +function checkbox:setSymbol(symbol) + self.symbol = string.sub(symbol,1,1) + self.changed = true +end + +function checkbox:drawObject() + if(self.draw)then + self.drawCalls= self.drawCalls+1 + self.frame.fWindow.setCursorPos(self.x,self.y) + self.frame.fWindow.setBackgroundColor(self.bgcolor) + self.frame.fWindow.setTextColor(self.fgcolor) + if(self.checked)then + self.frame.fWindow.write(self.symbol) + else + self.frame.fWindow.write(" ") + end + self.changed = false + end +end + +function frame:addLabel(name) +local newElement = {frame = self, x=1, y=1, bgcolor=self.bgcolor, fgcolor=self.fgcolor,text="Label",changed=true,drawCalls=0} + if(self.objects[name] == nil)then + self.objects[name] = newElement + return setmetatable(newElement, label); + else + return nil, "id "..name.." already exists"; + end +end + +function label:show() + if not(self.draw)then + self.draw = true + self.changed = true + end +end + +function label:hide() + if (self.draw)then + self.draw = false + self.changed = true + end +end + +function label:setPosition(x,y) + self.x = tonumber(x) + self.y = tonumber(y) + self.changed = true +end + +function label:setBackground(color) + self.bgcolor = color + self.changed = true +end + +function label:setForeground(color) + self.fgcolor = color + self.changed = true +end + +function label:setText(text) + self.text = text + self.changed = true +end + +function label:drawObject() + if(self.draw)then + self.drawCalls= self.drawCalls+1 + self.frame.fWindow.setCursorPos(self.x,self.y) + self.frame.fWindow.setBackgroundColor(self.bgcolor) + self.frame.fWindow.setTextColor(self.fgcolor) + self.frame.fWindow.write(self.text) + self.changed = false + end +end + +function frame:addTextbox(name) +local newElement = {frame = self, x=1, y=1, bgcolor=colors.lightBlue, fgcolor=colors.black,w=3,h=1,text="",changed=true,drawCalls=0} + if(self.objects[name] == nil)then + self.objects[name] = newElement + return setmetatable(newElement, textbox); + else + return nil, "id "..name.." already exists"; + end +end + +function textbox:show() + if not(self.draw)then + self.draw = true + self.changed = true + end +end + +function textbox:hide() + if (self.draw)then + self.draw = false + self.changed = true + end +end + +function textbox:setPosition(x,y) + self.x = tonumber(x) + self.y = tonumber(y) + self.changed = true +end + +function textbox:setSize(w,l) + self.w = tonumber(w) + self.l = tonumber(l) + self.changed = true +end + +function textbox:setBackground(color) + self.bgcolor = color + self.changed = true +end + +function textbox:setForeground(color) + self.fgcolor = color + self.changed = true +end + +function textbox:setText(text) + self.text = tostring(text) + self.changed = true +end + +function textbox:onChange(func) + self.changeFunc = func +end + +function textbox:onClick(func) + self.clickFunc = func +end + +function textbox:drawObject() + local text = "" + if(self.draw)then + if(string.len(self.text)>=self.w)then + text = string.sub(self.text, string.len(self.text)-self.w+2, string.len(self.text)) + else + text = self.text + end + local n = self.w-string.len(text) + text = text..string.rep(" ", n) + self.drawCalls= self.drawCalls+1 + self.frame.fWindow.setCursorPos(self.x,self.y) + self.frame.fWindow.setBackgroundColor(self.bgcolor) + self.frame.fWindow.setTextColor(self.fgcolor) + self.frame.fWindow.write(text) + self.changed = false + end +end + function frame:addButton(name) -local newElement = {name=name,frame = self, x=1, y=1, bgcolor=colors.white, fgcolor=colors.black,w=3,h=1,text="Click"} - if(self.buttons[name] == nil)then - self.buttons[name] = newElement +local newElement = {frame = self, x=1, y=1, bgcolor=colors.lightBlue, fgcolor=colors.black,w=3,h=1,text="Click",align="center",changed=true,drawCalls=0} + if(self.objects[name] == nil)then + self.objects[name] = newElement return setmetatable(newElement, button); else - return self.buttons[name]; + return nil, "id "..name.." already exists"; end end function button:show() - self.draw = true - self:redraw() + if not(self.draw)then + self.draw = true + self.changed = true + end end function button:hide() - self.draw = false + if (self.draw)then + self.draw = false + self.changed = true + end end function button:setPosition(x,y) self.x = tonumber(x) self.y = tonumber(y) + self.changed = true +end + +function button:setSize(w,l) + self.w = tonumber(w) + self.l = tonumber(l) + self.changed = true +end + +function button:setAlign(align) + self.align = align + self.changed = true end function button:setBackground(color) - self.bgolor = color - if(self.draw)then - button:redraw() - end + self.bgcolor = color + self.changed = true +end + +function button:setForeground(color) + self.fgcolor = color + self.changed = true end function button:setText(text) self.text = text + self.changed = true end -function button:redraw() - print(self.name) - self.frame.fWindow.setCursorPos(self.x,self.y) - self.frame.fWindow.setBackgroundColor(self.bgcolor) - paintutils.drawFilledBox(self.x, self.y, self.x+self.w, self.y+self.h, self.bgcolor) +function button:onClick(func) + self.clickFunc = func end +function button:drawObject() + if(self.draw)then + local text = string.sub(self.text, 1, self.w) + local n = self.w-string.len(text) + if(self.align=="left")then + text = text..string.rep(" ", n) + end + if(self.align=="right")then + text = string.rep(" ", n)..text + end + if(self.align=="center")then + text = string.rep(" ", math.floor(n/2))..text..string.rep(" ", math.floor(n/2)) + text = text..(string.len(text) < self.w and " " or "") + end + --Debug("Drawcalls: "..self.drawCalls) + self.drawCalls = self.drawCalls+1 + self.frame.fWindow.setCursorPos(self.x,self.y) + self.frame.fWindow.setBackgroundColor(self.bgcolor) + self.frame.fWindow.setTextColor(self.fgcolor) + self.frame.fWindow.write(text) + self.changed = false + end +end -function sGUI.DrawObjects() - for k,v in pairs(sGUI.frames)do - if(v.draw)then - v.fWindow.setVisible(true) - v.fWindow.redraw() +local function checkMouseClick(clicktype,x,y) + activeFrame.textboxActive = false + for k,v in pairs(activeFrame.objects)do + if(v.__type=="Button")then + if(v.x<=x)and(v.x+v.w>x)and(v.y<=y)and(v.y+v.h>y)then + if(v.clickFunc~=nil)then + v.clickFunc(v,clicktype) + end + end + end + if(v.__type=="Textbox")then + if(v.x<=x)and(v.x+v.w>x)and(v.y<=y)and(v.y+v.h>y)then + v.frame.textboxActive = true + v.frame.activeTextbox = v + v.frame.fWindow.setCursorPos(v.x+(string.len(v.text) < v.w and string.len(v.text) or v.w)-1,v.y) + v.frame.cursorX = v.x+(string.len(v.text) < v.w and string.len(v.text) or v.w-1) + v.frame.cursorY = v.y + v.frame.fWindow.setCursorBlink(true) + if(v.clickFunc~=nil)then + v.clickFunc(v,clicktype) + end + end + end + if(v.__type=="Checkbox")then + if(v.x==x)and(v.y==y)then + v.checked = not v.checked + v.changed = true + if(v.clickFunc~=nil)then + v.clickFunc(v,clicktype) + end + end + end + end + if not(activeFrame.textboxActive)then + activeFrame.fWindow.setCursorBlink(false) + end +end + +local function checkTimer(timeObject) + for k,v in pairs(activeFrame.objects)do + if(v.__type=="Timer")and(v.active)then + if(v.timeObj == timeObject)then + v.call(v) + if(v.repeats~=0)then + v.timeObj = os.startTimer(v.timer) + v.repeats = v.repeats > 0 and v.repeats-1 + end + end end end end -function sGUI.StartUpdate() - while true do - local event, key = os.pullEvent() - sGUI.DrawObjects() - os.sleep(0.1) +local function drawObjects() + if(activeFrame.draw)then + activeFrame.fWindow.clear() + for k,v in pairs(activeFrame.objects)do + if(v.draw~=nil)then + v:drawObject() + end + end + if(activeFrame.textboxActive)then + activeFrame.fWindow.setCursorPos(activeFrame.cursorX, activeFrame.cursorY) + end + activeFrame.fWindow.setBackgroundColor(activeFrame.bgcolor) + activeFrame.fWindow.setTextColor(activeFrame.fgcolor) + activeFrame.fWindow.setVisible(true) + activeFrame.fWindow.redraw() end end -function sGUI.getFrame(name) +local function checkForChangedObjects() +local changed = activeFrame.changed + for k,v in pairs(activeFrame.objects)do + if(v.changed)then + changed = true + end + end + if(changed)then + drawObjects() + end +end + +local function checkKeyboardInput(event, key) + if(activeFrame.textboxActive)then + if(event=="key")then + if(key==259)then + activeFrame.activeTextbox:setText(string.sub(activeFrame.activeTextbox.text,1,string.len(activeFrame.activeTextbox.text)-1)) + end + if(key==257)then + if(activeFrame.textboxActive)then + activeFrame.textboxActive = false + activeFrame.fWindow.setCursorBlink(false) + end + end + end + if(event=="char")then + activeFrame.activeTextbox:setText(activeFrame.activeTextbox.text..key) + end + activeFrame.cursorX = activeFrame.activeTextbox.x+(string.len(activeFrame.activeTextbox.text) < activeFrame.activeTextbox.w and string.len(activeFrame.activeTextbox.text) or activeFrame.activeTextbox.w-1) + activeFrame.cursorY = activeFrame.activeTextbox.y + if(activeFrame.activeTextbox.changeFunc~=nil)then + activeFrame.activeTextbox.changeFunc(activeFrame.activeTextbox) + end + end +end + +function frame.startUpdate() + checkForChangedObjects() + while true do + local event, p1,p2,p3 = os.pullEvent() + debug(event,p1,p2,p3) + if(event=="mouse_click")then + checkMouseClick(p1,p2,p3) + end + if(event=="timer")then + checkTimer(p1) + end + if(event=="char")or(event=="key")then + checkKeyboardInput(event,p1) + end + checkForChangedObjects() + end +end + + +function debug(...) + local args = {...} + activeFrame.debugLabel:setPosition(2,h) + local str = "[Debug] " + for k,v in pairs(args)do + str = str..v..(#args~=k and ", " or "") + end + activeFrame.debugLabel:setText(str) + activeFrame.debugLabel:show() +end + +function frame.get(name) end -local myFrame = frame.new("Test") -local myButton = myFrame:addButton("Testbutton") -myButton:setPosition(1,2) -myButton:show() -myFrame:show() - -sGUI.StartUpdate() \ No newline at end of file +return frame; \ No newline at end of file