Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local menu = getfenv()
- local printTitle
- local exitCondition = false
- local function writeCentered(text)
- termWidth = term.getSize()
- term.clearLine()
- local x, y = term.getCursorPos()
- term.setCursorPos(1, y)
- local spaces = termWidth - text:len()
- if spaces < 0 then
- spaces = 0
- text = text:sub(1, termwidth)
- end
- spaces = math.floor(spaces/2)
- for n = 1, spaces do
- write(" ")
- end
- write(text)
- end
- local function menuPrint(title, names, selectionLineNumber, selectionNumber)
- term.clear()
- term.setCursorPos(1, 1)
- printTitle(title)
- for n = 1, #names do
- term.setCursorPos(1, selectionLineNumber[n])
- term.clearLine()
- if n == selectionNumber then writeCentered("[ " .. names[n] .. " ]")
- else
- writeCentered(names[n])
- end
- end
- end
- local function updateMenu(names, selectionNumber, selectionLineNumber, offset)
- term.setCursorPos(1, selectionLineNumber[selectionNumber + offset])
- writeCentered(names[selectionNumber])
- term.setCursorPos(1, selectionLineNumber[selectionNumber])
- writeCentered("[ " .. names[selectionNumber] .. " ]")
- end
- local function menuPrintScroll(title, names)
- printTitle(title)
- local _,height = term.getSize()
- local mid = math.ceil((height-4)/2)+4
- for i=1, #names do
- local line = mid + 2*(i-1)
- term.setCursorPos(1, line)
- if line + 2 > height then
- writeCentered(". . .")
- break
- elseif i == 1 then
- writeCentered("[ "..names[i].." ]")
- else
- writeCentered(names[i])
- end
- end
- end
- local function updateMenuScroll(names, selectionNumber, title, spacing)
- term.clear()
- term.setCursorPos(1, 1)
- printTitle(title)
- local _,height = term.getSize()
- local mid = math.ceil((height-4)/2)+4
- term.setCursorPos(1, mid)
- writeCentered("[ "..names[selectionNumber].." ]")
- local count = 1
- for line=mid-spacing,5+((mid-5)%spacing)+spacing,-spacing do
- if names[selectionNumber-count] then term.setCursorPos(1, line) writeCentered(names[selectionNumber-count]) else break end
- count = count + 1
- end
- if names[selectionNumber-count] then
- term.setCursorPos(1, 5+((mid-5)%spacing))
- if names[selectionNumber-(count+1)] then
- writeCentered(". . .")
- else
- writeCentered(names[selectionNumber-count])
- end
- end
- count = 1
- for line=mid+spacing,(height-(height%spacing))-spacing,spacing do
- if names[selectionNumber+count] then term.setCursorPos(1, line) writeCentered(names[selectionNumber+count]) else break end
- count = count + 1
- end
- if names[selectionNumber+count] then
- term.setCursorPos(1, height-(height%spacing))
- if names[selectionNumber+count+1] then
- writeCentered(". . .")
- else
- writeCentered(names[selectionNumber+count])
- end
- end
- end
- function printTitle(title)
- term.setCursorPos(1, 1)
- writeCentered(string.rep("=", title:len() + 4))
- term.setCursorPos(1, 2)
- writeCentered("| " .. title .. " |")
- term.setCursorPos(1, 3)
- writeCentered(string.rep("=", title:len() + 4))
- term.setCursorPos(1, 5)
- end
- function menu.create(title)
- assert(type(title) == "string", "menu.create: title argument must be string")
- menuTable = {title, {}, {}}
- setmetatable(menuTable, {__index = menu})
- return menuTable
- end
- function menu.addOption(menuTable, name, func)
- assert(type(menuTable) == "table", "menu.addOption: menu argument must be table")
- assert(type(name) == "string", "menu.addOption: name argument must be string")
- assert(type(func) == "function", "menu.addOption: function argument must be function")
- assert(#menuTable == 3, "menu.addOption: menu argument must be of form {string, table, table}")
- assert(type(menuTable[1]) == "string", "menu.addOption: menu argument must be of form {string, table, table}")
- assert(type(menuTable[2]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
- assert(type(menuTable[3]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
- menuTable[2][#menuTable[2] + 1] = name
- menuTable[3][#menuTable[3] + 1] = func
- return menuTable
- end
- function menu.display(menuTable, scroll, once, spacing)
- term.clear()
- term.setCursorPos(1, 1)
- assert(type(menuTable) == "table", "menu.display: menu argument must be table")
- assert(#menuTable == 3, "menu.display: menu argument must be of form {string, table, table}")
- assert(type(menuTable[1]) == "string", "menu.display: menu argument must be of form {string, table, table}")
- assert(type(menuTable[2]) == "table", "menu.display: menu argument must be of form {string, table, table}")
- assert(type(menuTable[3]) == "table", "menu.display: menu argument must be of form {string, table, table}")
- assert(#menuTable[2] == #menuTable[3], "menu.display: must be equal number of names and functions")
- assert(#menuTable[2] >= 1, "menu.display: menu must have at least one option")
- local title = menuTable[1]
- local names = menuTable[2]
- local functions = menuTable[3]
- local options = #names
- local selectionNumber = 1
- local selectionLineNumber = {}
- local termX, termY = term.getSize()
- local menuHeight = termY - 4
- term.setCursorBlink(false)
- for index, name in ipairs(names) do
- assert(type(name) == "string", "menu.display: all names must be of type string")
- if name:len() > (termX - 4) then
- name = name:sub(1, termX - 4)
- end
- end
- for index, func in ipairs(functions) do
- assert(type(func) == "function", "menu.display: all functions must be of type function")
- end
- if not scroll then
- if not spacing then
- for n = 1, 4 do
- if (5 - n) * options <= menuHeight then
- spacing = 5 - n
- break
- end
- end
- if spacing <= 0 then return nil, "notEnoughSpace" end
- --[[if title:len() > (termX - 4) then title = title:sub(1, termX - 4) end
- writeCentered(string.rep("=", title:len() + 4))
- writeCentered("| " .. title .. " |")
- writeCentered(string.rep("=", title:len() + 4))
- term.setCursorPos(1, 5)]]
- end
- local lineNum = 5
- for n = 1, options do
- selectionLineNumber[n] = lineNum
- lineNum = lineNum + spacing
- end
- end
- spacing = spacing or 2
- if spacing <= 0 then return nil, "invalidSpacing" end
- if not scroll then menuPrint(title, names, selectionLineNumber, selectionNumber) else updateMenuScroll(names, selectionNumber, title, spacing) end
- while true do
- event, keyID = os.pullEvent("key")
- if keyID == 200 then
- if selectionNumber > 1 then
- selectionNumber = selectionNumber - 1
- if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
- end
- elseif keyID == 208 then
- if selectionNumber < options then
- selectionNumber = selectionNumber + 1
- if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
- end
- elseif keyID == 28 then
- term.clear()
- term.setCursorPos(1, 1)
- functions[selectionNumber]()
- if exitCondition or once then
- exitCondition = false
- term.clear()
- term.setCursorPos(1, 1)
- return true
- end
- if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
- end
- end
- end
- function menu.exit()
- exitCondition = true
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement