Run Code
|
API
|
Code Wall
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Patreon
CC: LDInterface
--V1.0 --HI THIS IS AN EDIT! --[[LDInterface API: Page based modular interface. Pages: - Creating pages (Page:new) adds them to the API internal page list. Page:new() also returns the newly created page so you can add stuff to it. (Page:addObj(<drawable>)) - only the active page and the global page are drawn to the monitor. - the current active page can be selected with setActivePage(<ID>). - Page IDs start at 1 (globalPage) and can be accessed with Page.id after creation for each individual page - Mouse Clicks or Monitor Touches are handed to the clicked drawable - globalPage: always drawn after the current active page so drawables placed here are visible regardless of the selected page. Drawables: - Drawn to the screen if added to a Page with Page:addObj - Standard drawables include: - Buttons (Button) - Labels (Label) - Scroll Bars (ScrollBar) - Drop down boxes (DropDownMenu) - You can add your own drawables if they include the following: MUST HAVES: - xT, yT (number, number) Coordinates of the top left corner - xB, yB (number, number) Coordinates of the bottom left corner - draw(self) (function) Function used to draw your drawable Optional: - onClick(self, x, y) (function) Called by the page and passed the clicked location (in screen coordinates) if the click happened inside your drawable. Themes: - Used to change colors quickly. ]] os.loadAPI("displayUtils") du = displayUtils local running = true pageList = {} groupList = {} local activePage = 1 local nextDrawableID = 0 autoAddNewDrawables = false autoAddPageID = 1 local theme = { btText = colors.white, btInactive = colors.red, btActive = colors.green, lblText = colors.white, lblBack = colors.black, scrbBack = colors.gray, scrbSlider = colors.red, ddmMainText = colors.white, ddmDropText = colors.lightGray, ddmMainBack = colors.lightGray, ddmDropBack = colors.gray, pbFilled = colors.pink, pbEmpty = colors.gray, pbText = colors.white } local contains = function(obj, x, y) return x <= obj.xB and x >= obj.xT and y <= obj.yB and y >= obj.yT end function setTheme(thm) local mustHave = { "btText", "btInactive", "btActive", "lblText", "lblBack", "scrbBack", "scrbSlider", "ddmMainText", "ddmMainBack", "ddmDropText", "ddmDropBack", "pbFilled", "pbEmpty", "pbText" } local valid = true for k,v in pairs(mustHave) do valid = valid and (thm[v] ~= nil) end if valid then theme = thm else error("LDInterface.setTheme: Passed theme does not include colors for all of the basic drawables!", 2) end end function getTheme() return theme end --Standard drawables --[[Drawable: ]] Drawable = { new = function(self, x1, y1, x2, y2) local temp = { ID = nextDrawableID, xT = x1, yT = y1, xB = x2, yB = y2 } nextDrawableID = nextDrawableID + 1 setmetatable(temp, {__index = self}) if autoAddNewDrawables and pageList[autoAddPageID] then pageList[autoAddPageID]:addObj(temp) end return temp end, draw = function(self) du.standardPrint(self.xT, self.yT, "+") du.standardPrint(self.xT, self.yB, "+") du.standardPrint(self.xB, self.yT, "+") du.standardPrint(self.xB, self.yB, "#") end } --[[Group: ]] Group = { new = function(self) local grp = { itemList = {}, grpID = #groupList+1 } table.insert(groupList, grp) setmetatable(grp, {__index = self}) return grp end, add = function(self, obj) table.insert(self.itemList, obj) obj.group = self.grpID return #self.itemList end, runCallback = function(self, exclude) for _, item in pairs(self.itemList) do if item.ID ~= exclude and item.groupCallback and type(item.groupCallback)=="function" then item:groupCallback(exclude) end end end, isPart = function(self, id) for _, item in pairs(self.itemList) do if item.ID==id then return true end end return false end, } --[[Label: Simple textbox to display a string. Text can be changed at runtime with Label:setText(<text>) ]] Label = { new = function(self, setText, xPos, yPos) if type(setText) ~= "string" then error("blah!",2) end local lbl = Drawable:new(xPos, yPos, xPos+#setText, yPos) lbl.text = setText setmetatable(lbl, {__index = self}) return lbl end, draw = function(self) du.standardCustomPrint(self.xT, self.yT, self.text, theme.lblText, theme.lblBack) end, setText = function(self, text) du.standardCustomPrint(self.xT, self.yT, string.rep(" ", #self.text), theme.lblText, colors.black) self.text = text self.xB = self.xT + #text self:draw() end } --[[Button: Square button which displays its name in its center. You define the button area with two pairs of monitor coordinates. The passed function is run when you click the button. Alternatively you can override the onClick field after creating a button. Button:toggle() is used to change its state, Button:flash() flashes the button (briefly changing its state for about 1 tick) to give feedback to the user. State can be read thorugh Button.state ]] Button = { new = function(self, setName, x1Pos, y1Pos, x2Pos, y2Pos, runnable) local bt = Drawable:new(x1Pos, y1Pos, x2Pos, y2Pos) bt.name = setName bt.func = runnable bt.col = theme.btInactive bt.state = false setmetatable(bt, {__index = self}) return bt end, draw = function(self) local width = self.xB - self.xT +1 local height = self.yB - self.yT +1 local nameStr = string.rep(" ", (width - self.name:len())/2)..self.name nameStr = nameStr..string.rep(" ", width - nameStr:len()) for i=0, height-1 do if(i == math.floor(height/2)) then du.standardCustomPrint(self.xT, self.yT+i, nameStr, theme.btText, self.col) else du.standardCustomPrint(self.xT, self.yT+i, string.rep(" ", width), theme.btText, self.col) end end end, update = function(self) if(self.state) then self.col = theme.btActive else self.col = theme.btInactive end self:draw() end, toggle = function(self) self.state = not self.state self:update() end, flash = function(self) self:toggle() sleep(0.1) self:toggle() end, setState = function(self, s) if type(s)=="boolean" then self.state = s self:update() end end, onClick = function(self, x, y) self.func(self, x ,y) end } --[[DropDownMenu: Drop down selection box which saves the last selected entry. Entries can be added with DropDownMenu:addItem(<string>) The selected entry can be read from DropDownMenu.text If the onChange field is overridden with a function it is called whenever the text field changes. The function gets passed the new text as its second parameter. Warning: the Drop down box redraws the whole page when it is toggeled! ]] DropDownMenu = { new = function(self, xPos, yPos, length) local ddm = Drawable:new(xPos, yPos, xPos+length, yPos) ddm.len = length ddm.itemList = {} ddm.text = "" ddm.open = false ddm.openedWidth = length+1 ddm.btDrop = Button:new("V", xPos+length, yPos, xPos+length, yPos, function(bt) bt:flash() ddm:toggle() end) setmetatable(ddm, {__index = self}) return ddm end, draw = function(self) local ch = "" for i=1, self.len do ch = self.text:sub(i,i) if ch == "" then ch = " " end du.standardCustomPrint(self.xT+i-1, self.yT, ch, theme.ddmMainText, theme.ddmMainBack) end self.btDrop:draw() if self.open then for i=1, #self.itemList do du.standardCustomPrint(self.xT, self.yT+i, self.itemList[i]..string.rep(" ", self.openedWidth-#self.itemList[i]), theme.ddmDropText, theme.ddmDropBack) end end end, onClick = function(self, x, y) local oldText = self.text if contains(self.btDrop, x, y) then self.btDrop:onClick(x, y) elseif self.open then x = x-self.xT y = y-self.yT if y>0 then self.text = self.itemList[y] end self:toggle() end if self.onChange and type(self.onChange) == "function" and self.text ~= oldText then self:onChange(self.text) end end, toggle = function(self) self.open = not self.open if self.open then self.btDrop.name = "^" self.xB = self.xT+self.openedWidth-1 self.yB = self.yT+#self.itemList else self.btDrop.name = "V" self.xB = self.xT+self.len self.yB = self.yT end self.btDrop.xB = self.xB redraw() end, addItem = function(self, item) strItem = tostring(item) if (#strItem > self.openedWidth) then self.openedWidth = #strItem end table.insert(self.itemList, strItem) end } ScrollBar = { new = function(self, x1Pos, y1Pos, x2Pos, y2Pos, vertical, buttonScale, maxVal) local sb = Drawable:new(x1Pos, y1Pos, x2Pos, y2Pos) sb.vert = vertical sb.btscale = buttonScale sb.value = 0 sb.max = maxVal or 100 sb.step = 1 sb.sldHeight = y2Pos-y1Pos+1 sb.sldWidth = x2Pos-x1Pos+1 if vertical then sb.btMinus = Button:new("^", x1Pos, y1Pos, x2Pos, y1Pos+buttonScale-1, function(bt) bt:flash() sb:dec(sb.step) end) sb.btPlus = Button:new("V", x1Pos, y2Pos-buttonScale+1, x2Pos, y2Pos, function(bt) bt:flash() sb:inc(sb.step) end) sb.sldHeight = math.floor((sb.sldHeight-2*buttonScale+1)/maxVal)+1 sb.sldMoveSpace = y2Pos-y1Pos-2*buttonScale-sb.sldHeight+1 else sb.btMinus = Button:new("<", x1Pos, y1Pos, x1Pos+buttonScale-1, y2Pos, function(bt) bt:flash() sb:dec(sb.step) end) sb.btPlus = Button:new(">", x2Pos-buttonScale+1, y1Pos, x2Pos, y2Pos, function(bt) bt:flash() sb:inc(sb.step) end) sb.sldWidth = math.floor((sb.sldWidth-2*buttonScale+1)/maxVal)+1 sb.sldMoveSpace = x2Pos-x1Pos-2*buttonScale-sb.sldWidth+1 end setmetatable(sb, {__index = self}) return sb end, draw = function(self) local width = self.xB-self.xT+1 local height = self.yB-self.yT+1 for i=self.yT, self.yB do du.standardCustomPrint(self.xT, i, string.rep(" ", width), colors.black, theme.scrbBack) end self.btMinus:draw() self.btPlus:draw() local xOffset = 0 local yOffset = 0 if self.vert then yOffset = self.btscale+math.floor((self.sldMoveSpace*self.value)/self.max) else xOffset = self.btscale+math.floor((self.sldMoveSpace*self.value)/self.max) end for i=0,self.sldHeight-1 do du.standardCustomPrint(self.xT+xOffset, self.yT+yOffset+i, string.rep(" ", self.sldWidth), colors.black, theme.scrbSlider) end end, onClick = function(self, x, y) local oldVal = self.value if contains(self.btMinus, x, y) then self.btMinus:onClick(x, y) elseif contains(self.btPlus, x, y) then self.btPlus:onClick(x, y) else x = x-self.xT y = y-self.yT local setValue = self.value local len = self.max if self.vert then setValue = y-self.btscale len = self.yB-self.yT-2*self.btscale else setValue = x-self.btscale len = self.xB-self.xT-2*self.btscale end self.value = math.floor((setValue/len)*self.max) end if self.onChange and type(self.onChange)=="function" and self.value ~= oldVal then self:onChange(self.value) end self:draw() end, inc = function(self, val) val = val or 1 self.value = self.value+val if self.value > self.max then self.value = self.max end end, dec = function(self, val) val = val or 1 self.value = self.value-val if self.value < 0 then self.value = 0 end end } ConsoleOutput = { new = function(self, x1Pos, y1Pos, x2Pos, y2Pos) local co = Drawable:new(x1Pos, y1Pos, x2Pos, y2Pos) co.maxLineCount = y2Pos - y1Pos + 1 co.width = x2Pos - x1Pos co.lines = {} setmetatable(co, {__index = self}) return co end, draw = function(self) local numLines = #self.lines for index, str in pairs(self.lines) do du.standardPrint(self.xT, self.yB - numLines + index, string.rep(" ", self.width)) du.standardPrint(self.xT, self.yB - numLines + index, str) end end, print = function(self, str) while(#str > self.width) do table.insert(self.lines, str:sub(1, self.xB)) str = str:sub(self.xB+1) end table.insert(self.lines, str) while(#self.lines > self.maxLineCount) do table.remove(self.lines, 1) end self:draw() end, clear = function(self) for i=0,self.maxLineCount-1 do du.standardPrint(self.xT, self.yT+i, string.rep(" ", self.width)) end end } ProgressBar = { new = function(self, x1Pos, y1Pos, x2Pos, y2Pos, maxVal) local pb = Drawable:new(x1Pos, y1Pos, x2Pos, y2Pos) pb.width = x2Pos - x1Pos + 1 pb.height = y2Pos - y1Pos + 1 pb.vert = (pb.width < pb.height) pb.max = maxVal pb.curr = 0 pb.text = "" pb.post = "" pb.txCol = theme.pbText pb.cA = theme.pbFilled pb.cB = theme.pbEmpty setmetatable(pb, {__index = self}) return pb end, draw = function(self) if self.vert then du.standardVerticalProgressBar(self.xT, self.yT, self.width, self.height, self.max, self.curr, self.cA, self.cB, self.txCol, self.text, self.post, true) else du.standardHorizontalProgressBar(self.xT, self.yT, self.width, self.height, self.max, self.curr, self.cA, self.cB, self.txCol, self.text, self.post, true) end end, setVertical = function(self, vert) if type(vert) == "boolean" then self.vert = vert end end, setText = function(self, text, post) self.text = tostring(text) if post then self.post = tostring(post) end end, setColors = function(self, bgColA, bgColB, txCol) self.cA = bgColA self.cB = bgColB self.txCol = txCol end, inc = function(self, val) local oldCurr = self.curr val = val or 1 self.curr = self.curr+val if self.curr > self.max then self.curr = self.max end if self.onChange and type(self.onChange) == "function" and self.curr ~= oldCurr then self:onChange(oldCurr) end self:draw() end, dec = function(self, val) local oldCurr = self.curr val = val or 1 self.curr = self.curr-val if self.curr < 0 then self.curr = 0 end if self.onChange and type(self.onChange) == "function" and self.curr ~= oldCurr then self:onChange(oldCurr) end self:draw() end, setVal = function(self, val) local oldCurr = self.curr self.curr = val if self.curr < 0 then self.curr = 0 elseif self.curr > self.max then self.curr = self.max end if self.onChange and type(self.onChange) == "function" and self.curr ~= oldCurr then self:onChange(oldCurr) end self:draw() end } Page = { new = function(self) local p = { objList = {}, id = #pageList+1 } setmetatable(p, {__index = self}) table.insert(pageList, p) return p end, addObj = function(self, obj) if(type(obj.draw) == "function") then table.insert(self.objList, obj) end end, handleEvent = function(self, event) if(event[1] == "mouse_click" or event[1] == "monitor_touch") then for index, obj in pairs(self.objList) do if(contains(obj, event[3], event[4]) and type(obj.onClick) == "function") then if obj.group then groupList[obj.group]:runCallback(obj.ID) end obj:onClick(event[3], event[4]) end end elseif(event[1] == "stopEvent") then running = false end end, draw = function(self, clear) if clear then term.clear() end for index, obj in pairs(self.objList) do obj:draw() end end } globalPage = Page:new() function handleEvents(...) event = {...} if(event[1] == "stopEvent") then running = false else if(activePage ~= 1) then pageList[activePage]:handleEvent(event) end globalPage:handleEvent(event) end end function setAutoAdd(bool, id) if type(bool) == "boolean" and type(id) == "number" then autoAddNewDrawables = bool autoAddPageID = id end end function redraw() if(activePage ~= 1) then pageList[activePage]:draw(true) end globalPage:draw(activePage == 1) --du.standardCustomPrint(1, 1, tostring(activePage), colors.white, colors.black) end function run() while running do handleEvents(os.pullEvent()) end end function setActivePage(id) if(pageList[id]) then activePage = id redraw() end end function nextPage() if pageList[activePage+1] then activePage = activePage + 1 end end function prevPage() if pageList[activePage-1] then activePage = activePage - 1 end end function hasPage(id) return pageList[id] ~= nil end function stop() running = false end du.setStandardMon(term)
run
|
edit
|
history
|
help
0
Enums in Lua (library)
Volume of sphere
Brainfuck Interpreter (Lua) [reposted]
Error PCALL
Roots without the math library in Lua
ok
gdgdf
kraft1c
Basic class example
Basic Lehmer RNG implementation using closures