Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --
- -- Methods browser
- --
- -- by: Sharidan - www.sharidan.dk
- --
- local function wrapTerm(obj)
- -- Wraps the specified terminal/monitor object with additional methods
- obj.width, obj.height = obj.getSize()
- function obj._fixMono(c)
- if (c == colors.black or c == colors.blue or c == colors.green or c == colors.cyan or c == colors.red or c == colors.purple or c == colors.brown or c == colors.gray) then
- return colors.black
- else
- return colors.white
- end
- end
- function obj.color(fore, back)
- local f, b = fore, back
- if (not obj.isColor()) then
- f = obj._fixMono(fore)
- if (back) then
- b = obj._fixMono(back)
- end
- end
- obj.setTextColor(f)
- if (b) then
- obj.setBackgroundColor(b)
- end
- end
- function obj.cls(fore, back)
- if (fore) then
- obj.color(fore, back)
- end
- obj.clear()
- obj.setCursorPos(1, 1)
- end
- function obj.clearln(y, fore, back)
- if (fore) then
- obj.color(fore, back)
- end
- obj.setCursorPos(1, y)
- obj.clearLine()
- end
- function obj.gotoXY(x, y)
- obj.setCursorPos(x, y)
- end
- function obj.writeXY(x, y, text)
- local txt = ""..text..""
- obj.setCursorPos(x, y)
- obj.write(txt)
- end
- function obj.rightXY(x, y, text)
- local txt = ""..text..""
- obj.setCursorPos((x - #txt) + 1, y)
- obj.write(txt)
- end
- function obj.centerY(y, text)
- local txt = ""..text..""
- obj.setCursorPos(math.floor((obj.width - #txt) / 2) + 1, y)
- obj.write(txt)
- end
- function obj.progressBar(x, y, w, v, m)
- local tw, th = term.getSize()
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.setCursorPos(x, y)
- term.write(string.rep(" ", w))
- term.clearLine()
- local b = math.ceil((tw / 100) * (v / (m / 100)))
- if (b > tw) then
- b = tw
- end
- term.setCursorPos(x, y)
- local l = tw - b
- if (b > 0) then
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.white)
- term.write(string.rep("#", b))
- end
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- term.write(string.rep("#", l))
- end
- end
- wrapTerm(term)
- local function wrapText(text, width)
- local function split(str, pat)
- local r = {}
- if (string.find(str, pat)) then
- for s in str:gmatch("[^"..pat.."]+") do
- table.insert(r, s)
- end
- else
- table.insert(r, str)
- end
- return r
- end
- local txt = split(text, "\n")
- local l = {}
- for t = 1, #txt do
- local cl = ""
- local msg = ""..txt[t]..""
- for w in msg:gmatch("%S+%s*") do
- if (#cl + #w >= width) then
- table.insert(l, cl)
- cl = w
- else
- cl = cl..w
- end
- end -- for
- if (cl ~= "") then
- table.insert(l, cl)
- end
- end
- return l
- end
- local function newList()
- -- Self contained list object
- local self = {}
- self._e = {}
- self._s = 0
- self._x = 1
- self._y = 1
- self._w = 0
- self._h = 0
- self._mw = 0
- self._mh = 0
- function self._calcSize()
- self._mw = 0
- for i = 1, #self._e do
- if (#self._e[i] > self._mw) then
- self._mw = tonumber(#self._e[i])
- end
- end
- self._mh = tonumber(#self._e)
- end
- function self.clear()
- self._e = {}
- self._s = 0
- self._o = 0
- self._x = 1
- self._y = 1
- self._w = 0
- self._h = 0
- self._a = 1 -- 0: left, 1: center, 2: right
- self._mw = 0
- self._mh = 0
- end
- function self.add(caption)
- table.insert(self._e, caption)
- self._s = 1
- self._o = 0
- self._calcSize()
- end
- function self.getWidth()
- if (self._w == 0) then
- return self._mw + 2
- else
- return self._w
- end
- end
- function self.setHeight(h)
- self._h = tonumber(h)
- end
- function self.getHeight()
- if (self._h == 0) then
- return self._mh
- else
- return self._h
- end
- end
- function self.setPos(x, y)
- self._x = tonumber(x)
- self._y = tonumber(y)
- end
- function self.setAlign(a)
- if (a == "left") then
- self._a = 0
- elseif (a == "center") then
- self._a = 1
- elseif (a == "right") then
- self._a = 2
- end
- end
- function self.setList(lst)
- self._e = {}
- for i = 1, #lst do
- self.add(lst[i])
- end
- if (self._h > term.height) then
- self._h = term.height
- end
- end
- function self.render()
- local py = 1
- local w = 0
- if (self._w > 0) then
- w = self._w
- else
- w = self._mw + 2
- end
- for i = 1, self._h do
- local idx = i + self._o
- if (idx <= #self._e) then
- local prefix, caption, suffix = "", self._e[idx], ""
- if (self._a == 0) then
- -- Left align
- prefix = " "
- suffix = string.rep(" ", (w - 1) - #caption)
- elseif (self._a == 1) then
- -- Centered
- local half = math.floor((w - #caption) / 2)
- prefix = string.rep(" ", half)
- if (half * 2 < (w - #caption)) then
- half = half + 1
- end
- suffix = string.rep(" ", half)
- elseif (self._a == 2) then
- -- Right align
- prefix = string.rep(" ", (w - 1) - #caption)
- suffix = " "
- end
- if (self._s == idx) then
- term.setTextColor(colors.black)
- term.setBackgroundColor(colors.white)
- else
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- end
- term.setCursorPos(self._x, (self._y + py) - 1)
- term.write(prefix..caption..suffix)
- py = py + 1
- end
- end
- end
- function self.checkEvent(event, p1, p2, p3, p4)
- local r = nil
- if (event == "key") then
- if (p1 == keys.home) then -- home
- self._s = 1
- self._o = 0
- self.render()
- elseif (p1 == keys.up) then -- up
- if (self._s > 1) then
- self._s = self._s - 1
- if (self._s < self._o + 1) then
- self._o = self._o - 1
- end
- self.render()
- end
- elseif (p1 == keys.down) then -- down
- if (self._s + 1 <= #self._e) then
- self._s = self._s + 1
- if (self._s - self._o > self._h) then
- self._o = self._o + 1
- end
- self.render()
- end
- elseif (p1 == keys["end"]) then -- end
- self._s = #self._e
- self._o = #self._e - self._h
- if (self._o < 0) then
- self._o = 0
- end
- self.render()
- elseif (p1 == keys.enter) then -- enter
- r = tostring(self._e[self._s])
- end
- end
- return r
- end
- self.clear()
- return self
- end
- local devs = {}
- local function getDevices()
- local r = {}
- r.t = {}
- local lst = peripheral.getNames()
- for i = 1, #lst do
- local typ = peripheral.getType(lst[i])
- if (typ) then
- local fnd = nil
- for t = 1, #r.t do
- if (r.t[t] == typ) then
- fnd = true
- break
- end
- end
- if (not fnd) then
- table.insert(r.t, typ)
- table.sort(r.t)
- r[typ] = {}
- end
- table.insert(r[typ], lst[i])
- table.sort(r[typ])
- end
- end
- return r
- end
- local noDesc = "No description available."
- local function splitValue(value)
- local vName, vType, vDesc, vOpt = "", "", noDesc, false
- if (type(value) == "string") then
- vType = tostring(value)
- if (vType == "BOOLEAN") then
- vDesc = "true if success."
- elseif (vType == "VOID") then
- vName = nil
- end
- elseif (type(value) == "table") then
- vName = tostring(value.name)
- vType = tostring(value.type)
- vDesc = tostring(value.description)
- if (value.optional == true) then
- vOpt = true
- end
- else
- vType = tostring(value)
- end
- if (vName) then
- return { vName, vType, vDesc, vOpt }
- end
- end
- local function getVarInfo(var)
- local r = ""
- if (var[4] == true) then
- r = "<"..var[1]..">"
- else
- r = var[1]
- end
- if (var[1] ~= "") then
- r = r.." :: "
- end
- r = r..var[2]
- if (var[4] == true) then
- r = r.." (optional)"
- end
- r = r.."\n"
- r = r..var[3]
- return r
- end
- local function usageMenu(dev, meth)
- term.cls(colors.white, colors.black)
- local p = peripheral.wrap(dev)
- local m = p.getAdvancedMethodsData()
- local name, desc, args, ret = nil, nil, {}, {}
- for a, b in pairs(m) do
- if (a == meth) then
- for property, value in pairs(b) do
- if (property == "name") then
- if (value) then
- name = value
- end
- elseif (property == "returnType") then
- if (type(value) == "table") then
- for i = 1, #value do
- local v = splitValue(value[i])
- if (v) then
- table.insert(ret, v)
- end
- end
- elseif (type(value) == "string") then
- if (string.lower(value) ~= "void" and string.lower(value) ~= "nil") then
- local v = splitValue(value[i])
- if (v) then
- table.insert(ret, v)
- end
- end
- end
- elseif (property == "returnTypes") then
- if (type(value) == "table") then
- for i = 1, #value do
- local v = splitValue(value[i])
- if (v) then
- table.insert(ret, v)
- end
- end
- elseif (type(value) == "string") then
- if (string.lower(value) ~= "void" and string.lower(value) ~= "nil") then
- local v = splitValue(value[i])
- if (v) then
- table.insert(ret, v)
- end
- end
- end
- elseif (property == "description") then
- if (value) then
- desc = value
- end
- elseif (property == "args") then
- if (type(value) == "table") then
- for i = 1, #value do
- local v = splitValue(value[i])
- if (v) then
- table.insert(args, v)
- end
- end
- elseif (type(value) == "string") then
- local v = splitValue(value[i])
- if (v) then
- table.insert(args, v)
- end
- end
- end
- end
- break
- end
- end
- if (name == nil) then
- name = meth
- end
- if (desc == nil) then
- desc = noDesc
- end
- local g, s = "method", 1
- local done = nil
- local drawUI = true
- while not done do
- if (drawUI) then
- term.cls(colors.white, colors.black)
- term.clearln(1, colors.black, colors.white)
- term.writeXY(2, 1, "Hardware Method Browser")
- if (#ret == 0 and #args == 0) then
- term.color(colors.white, colors.black)
- term.writeXY(2, 4, name.."()")
- else
- if (#ret > 0) then
- term.color(colors.white, colors.black)
- local sr = s
- if (g ~= "return") then
- sr = 0
- end
- local x = 4
- for i = 1, #ret do
- if (i == sr) then
- term.color(colors.black, colors.white)
- else
- term.color(colors.white, colors.black)
- end
- local txt = " "..ret[i][2]..""
- term.writeXY(x, 3, txt)
- x = x + (#txt) + 1
- if (i < #ret) then
- term.color(colors.white, colors.black)
- term.writeXY(x, 3, ",")
- x = x + 1
- end
- end
- end
- term.color(colors.white, colors.black)
- local x = 4
- if (#ret > 0) then
- term.writeXY(4, 4, "=")
- x = x + 2
- end
- if (g == "method") then
- term.color(colors.black, colors.white)
- end
- term.writeXY(x, 4, " "..name.." ")
- term.color(colors.white, colors.black)
- x = x + #name + 3
- if (#args == 0) then
- term.writeXY(x, 4, "()")
- else
- term.writeXY(x, 4, "(")
- end
- if (#args > 0) then
- term.color(colors.white, colors.black)
- local sa = s
- if (g ~= "args") then
- sa = 0
- end
- local x = 4
- for i = 1, #args do
- if (i == sa) then
- term.color(colors.black, colors.white)
- else
- term.color(colors.white, colors.black)
- end
- local txt = " "..args[i][1]..""
- term.writeXY(x, 5, txt)
- x = x + (#txt) + 1
- if (i < #args) then
- term.color(colors.white, colors.black)
- term.writeXY(x, 5, ",")
- x = x + 1
- end
- end
- term.color(colors.white, colors.black)
- term.writeXY(4, 6, ")")
- end
- end
- local txt = {}
- if (g == "return") then
- txt = wrapText(getVarInfo(ret[s]), term.width - 2)
- elseif (g == "method") then
- txt = wrapText(desc, term.width - 2)
- elseif (g == "args") then
- txt = wrapText(getVarInfo(args[s]), term.width - 2)
- end
- term.color(colors.white, colors.black)
- if (#txt > 0) then
- for i = 1, #txt do
- if (i + 7 < term.height - 1) then
- term.writeXY(2, i + 7, txt[i])
- end
- end
- else
- term.writeXY(2, 7, "No description available.")
- end
- term.clearln(term.height, colors.black, colors.white)
- term.writeXY(2, term.height, "[Q]: Quit, [BckSpace]: Back")
- drawUI = nil
- end
- local event, p1 = os.pullEvent()
- if (event == "char" and string.lower(p1) == "q") then
- return "quit"
- elseif (event == "key") then
- if (p1 == keys.backspace) then -- backspace
- done = true
- elseif (p1 == keys.up) then -- arrow up
- if (g == "method") then
- if (#ret > 0) then
- g = "return"
- s = 1
- drawUI = true
- end
- elseif (g == "args") then
- g = "method"
- s = 1
- drawUI = true
- end
- elseif (p1 == keys.down) then -- arrow down
- if (g == "return") then
- g = "method"
- s = 1
- drawUI = true
- elseif (g == "method") then
- if (#args > 0) then
- g = "args"
- s = 1
- drawUI = true
- end
- end
- elseif (p1 == keys.left) then -- arrow left
- if (g == "return" or g == "args") then
- if (s > 1) then
- s = s - 1
- drawUI = true
- end
- end
- elseif (p1 == keys.right) then -- arrow right
- if (g == "return") then
- if (s < #ret) then
- s = s + 1
- drawUI = true
- end
- elseif (g == "args") then
- if (s < #args) then
- s = s + 1
- drawUI = true
- end
- end
- end
- end
- end
- end
- local function methodMenu(dev)
- local lst = peripheral.getMethods(dev)
- local mlst = {}
- local op = nil
- for i = 1, #lst do
- if (lst[i] == "getAdvancedMethodsData") then
- op = true
- elseif (lst[i] == "listMethods") then
- -- Standard listing methods
- else
- table.insert(mlst, lst[i])
- end
- end
- table.sort(mlst)
- list = newList()
- list.setList(mlst)
- list.setPos(1, 5)
- list.setHeight(term.height - 6)
- list.setAlign("left")
- local done = false
- local drawUI = true
- while not done do
- if (drawUI) then
- term.cls(colors.white, colors.black)
- term.clearln(1, colors.black, colors.white)
- term.writeXY(2, 1, "Hardware Method Browser")
- term.color(colors.white, colors.black)
- term.writeXY(1, 3, "Methods for "..dev..":")
- term.clearln(term.height, colors.black, colors.white)
- if (op) then
- term.writeXY(2, term.height, "[Q]: Quit, [BckSpace]: Back, [Enter]: View")
- else
- term.writeXY(2, term.height, "[Q]: Quit, [BckSpace]: Back")
- end
- drawUI = nil
- end
- list.render()
- local event, p1, p2, p3, p4 = os.pullEvent()
- local r = list.checkEvent(event, p1, p2, p3, p4)
- if (r and op) then
- if (usageMenu(dev, r) == "quit") then
- return "quit"
- else
- drawUI = true
- end
- else
- if (event == "char" and string.lower(p1) == "q") then
- return "quit"
- elseif (event == "key" and p1 == keys.backspace) then
- done = true
- end
- end
- end
- end
- local function deviceMenu(typ)
- local list = newList()
- list.setList(devs[typ])
- list.setPos(1, 3)
- list.setHeight(term.height - 4)
- list.setAlign("left")
- local done = false
- local drawUI = true
- while not done do
- if (drawUI) then
- term.cls(colors.white, colors.black)
- term.clearln(1, colors.black, colors.white)
- term.writeXY(2, 1, "Hardware Method Browser")
- term.clearln(term.height, colors.black, colors.white)
- term.writeXY(2, term.height, "[Q]: Quit, [BckSpace]: Back, [Enter]: View")
- drawUI = nil
- end
- list.render()
- local event, p1, p2, p3, p4 = os.pullEvent()
- local r = list.checkEvent(event, p1, p2, p3, p4)
- if (r) then
- if (methodMenu(r) == "quit") then
- return "quit"
- else
- drawUI = true
- end
- elseif (event == "char" and string.lower(p1) == "q") then
- return "quit"
- elseif (event == "key" and p1 == keys.backspace) then
- done = true
- end
- end
- end
- local function mainLoop()
- devs = getDevices()
- local list = newList()
- list.setList(devs.t)
- list.setPos(1, 3)
- list.setHeight(term.height - 4)
- list.setAlign("left")
- local done = false
- local drawUI = true
- while not done do
- if (drawUI) then
- term.cls(colors.white, colors.black)
- term.clearln(1, colors.black, colors.white)
- term.writeXY(2, 1, "Hardware Method Browser")
- term.clearln(term.height, colors.black, colors.white)
- term.writeXY(2, term.height, "[Q]: Quit, [R]: Refresh, [Enter]: View")
- drawUI = nil
- end
- list.render()
- local event, p1, p2, p3, p4 = os.pullEvent()
- local r = list.checkEvent(event, p1, p2, p3, p4)
- if (r) then
- if (deviceMenu(r) == "quit") then
- done = true
- else
- drawUI = true
- end
- elseif (event == "char") then
- if (string.lower(p1) == "q") then
- done = true
- elseif (string.lower(p1) == "r") then
- devs = getDevices()
- list.setList(devs.t)
- drawUI = true
- end
- elseif (event == "key" and p1 == keys["end"]) then
- done = true
- end
- end
- term.cls(colors.white, colors.black)
- end
- mainLoop()
Add Comment
Please, Sign In to add comment