Advertisement
faubiguy

Menu

Oct 22nd, 2012
330
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.15 KB | None | 0 0
  1. local menu = getfenv()
  2.  
  3. local printTitle
  4.  
  5. local exitCondition = false
  6.  
  7. local function writeCentered(text)
  8.  termWidth = term.getSize()
  9.  term.clearLine()
  10.  local x, y = term.getCursorPos()
  11.  term.setCursorPos(1, y)
  12.  local spaces = termWidth - text:len()
  13.  if spaces < 0 then
  14.   spaces = 0
  15.   text = text:sub(1,  termwidth)
  16.  end
  17.  spaces = math.floor(spaces/2)
  18.  for n = 1, spaces do
  19.   write(" ")
  20.  end
  21.  write(text)
  22. end
  23.  
  24. local function menuPrint(title, names, selectionLineNumber, selectionNumber)
  25.  term.clear()
  26.  term.setCursorPos(1, 1)
  27.  printTitle(title)
  28.  for n = 1, #names do
  29.   term.setCursorPos(1, selectionLineNumber[n])
  30.   term.clearLine()
  31.   if n == selectionNumber then writeCentered("[ " .. names[n] .. " ]")
  32.   else
  33.    writeCentered(names[n])
  34.   end
  35.  end
  36. end
  37.  
  38. local function updateMenu(names, selectionNumber, selectionLineNumber, offset)
  39.  term.setCursorPos(1, selectionLineNumber[selectionNumber + offset])
  40.  writeCentered(names[selectionNumber])
  41.  term.setCursorPos(1, selectionLineNumber[selectionNumber])
  42.  writeCentered("[ " .. names[selectionNumber] .. " ]")
  43. end
  44.  
  45. local function menuPrintScroll(title, names)
  46.  printTitle(title)
  47.  local _,height = term.getSize()
  48.  local mid = math.ceil((height-4)/2)+4
  49.  for i=1, #names do
  50.   local line = mid + 2*(i-1)
  51.   term.setCursorPos(1, line)
  52.   if line + 2 > height then
  53.    writeCentered(". . .")
  54.    break
  55.   elseif i == 1 then
  56.    writeCentered("[ "..names[i].." ]")
  57.   else
  58.    writeCentered(names[i])
  59.   end
  60.  end
  61.    
  62. end
  63.  
  64. local function updateMenuScroll(names, selectionNumber, title, spacing)
  65.  term.clear()
  66.  term.setCursorPos(1, 1)
  67.  printTitle(title)
  68.  local _,height = term.getSize()
  69.  local mid = math.ceil((height-4)/2)+4
  70.  term.setCursorPos(1, mid)
  71.  writeCentered("[ "..names[selectionNumber].." ]")
  72.  local count = 1
  73.  for line=mid-spacing,5+((mid-5)%spacing)+spacing,-spacing do
  74.   if names[selectionNumber-count] then term.setCursorPos(1, line) writeCentered(names[selectionNumber-count]) else break end
  75.   count = count + 1
  76.  end
  77.  if names[selectionNumber-count] then
  78.   term.setCursorPos(1, 5+((mid-5)%spacing))
  79.   if names[selectionNumber-(count+1)] then
  80.    writeCentered(". . .")
  81.   else
  82.    writeCentered(names[selectionNumber-count])
  83.   end
  84.  end
  85.  count = 1
  86.  for line=mid+spacing,(height-(height%spacing))-spacing,spacing do
  87.   if names[selectionNumber+count] then term.setCursorPos(1, line) writeCentered(names[selectionNumber+count]) else break end
  88.   count = count + 1
  89.  end
  90.  if names[selectionNumber+count] then
  91.   term.setCursorPos(1, height-(height%spacing))
  92.   if names[selectionNumber+count+1] then
  93.    writeCentered(". . .")
  94.   else
  95.    writeCentered(names[selectionNumber+count])
  96.   end
  97.  end
  98. end
  99.  
  100. function printTitle(title)
  101.  term.setCursorPos(1, 1)
  102.  writeCentered(string.rep("=", title:len() + 4))
  103.  term.setCursorPos(1, 2)
  104.  writeCentered("| " .. title .. " |")
  105.  term.setCursorPos(1, 3)
  106.  writeCentered(string.rep("=", title:len() + 4))
  107.  term.setCursorPos(1, 5)
  108. end
  109.  
  110. function menu.create(title)
  111.  assert(type(title) == "string", "menu.create: title argument must be string")
  112.  menuTable = {title, {}, {}}
  113.  setmetatable(menuTable, {__index = menu})
  114.  return menuTable
  115. end
  116.  
  117. function menu.addOption(menuTable, name, func)
  118.  assert(type(menuTable) == "table", "menu.addOption: menu argument must be table")
  119.  assert(type(name) == "string", "menu.addOption: name argument must be string")
  120.  assert(type(func) == "function", "menu.addOption: function argument must be function")
  121.  assert(#menuTable == 3, "menu.addOption: menu argument must be of form {string, table, table}")
  122.  assert(type(menuTable[1]) == "string", "menu.addOption: menu argument must be of form {string, table, table}")
  123.  assert(type(menuTable[2]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  124.  assert(type(menuTable[3]) == "table", "menu.addOption: menu argument must be of form {string, table, table}")
  125.  menuTable[2][#menuTable[2] + 1] = name
  126.  menuTable[3][#menuTable[3] + 1] = func
  127.  return menuTable
  128. end
  129.  
  130. function menu.display(menuTable, scroll, once, spacing)
  131.  term.clear()
  132.  term.setCursorPos(1, 1)
  133.  assert(type(menuTable) == "table", "menu.display: menu argument must be table")
  134.  assert(#menuTable == 3, "menu.display: menu argument must be of form {string, table, table}")
  135.  assert(type(menuTable[1]) == "string", "menu.display: menu argument must be of form {string, table, table}")
  136.  assert(type(menuTable[2]) == "table", "menu.display: menu argument must be of form {string, table, table}")
  137.  assert(type(menuTable[3]) == "table", "menu.display: menu argument must be of form {string, table, table}")
  138.  assert(#menuTable[2] == #menuTable[3], "menu.display: must be equal number of names and functions")
  139.  assert(#menuTable[2] >= 1, "menu.display: menu must have at least one option")
  140.  local title = menuTable[1]
  141.  local names = menuTable[2]
  142.  local functions =  menuTable[3]
  143.  local options = #names
  144.  local selectionNumber = 1
  145.  local selectionLineNumber = {}
  146.  local termX, termY = term.getSize()
  147.  local menuHeight = termY - 4
  148.  term.setCursorBlink(false)
  149.  for index, name in ipairs(names) do
  150.   assert(type(name) == "string", "menu.display: all names must be of type string")
  151.   if name:len() > (termX - 4) then
  152.    name = name:sub(1, termX - 4)
  153.   end
  154.  end
  155.  for index, func in ipairs(functions) do
  156.   assert(type(func) == "function", "menu.display: all functions must be of type function")
  157.  end
  158.  if not scroll then
  159.   if not spacing then
  160.    for n = 1, 4 do
  161.     if (5 - n) * options <= menuHeight then
  162.      spacing = 5 - n
  163.      break
  164.     end
  165.    end
  166.    if spacing <= 0 then return nil, "notEnoughSpace" end
  167.    --[[if title:len() > (termX - 4) then title = title:sub(1, termX - 4) end
  168.    writeCentered(string.rep("=", title:len() + 4))
  169.    writeCentered("| " .. title .. " |")
  170.    writeCentered(string.rep("=", title:len() + 4))
  171.    term.setCursorPos(1, 5)]]
  172.   end
  173.   local lineNum = 5
  174.   for n = 1, options do
  175.    selectionLineNumber[n] = lineNum
  176.    lineNum = lineNum + spacing
  177.   end
  178.  end
  179.  spacing = spacing or 2
  180.  if spacing <= 0 then return nil, "invalidSpacing" end
  181.  if not scroll then menuPrint(title, names, selectionLineNumber, selectionNumber) else updateMenuScroll(names, selectionNumber, title, spacing) end
  182.  while true do
  183.   event, keyID = os.pullEvent("key")
  184.   if keyID == 200 then
  185.    if selectionNumber > 1 then
  186.     selectionNumber = selectionNumber - 1
  187.     if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
  188.    end
  189.   elseif keyID == 208 then
  190.    if selectionNumber < options then
  191.     selectionNumber = selectionNumber + 1
  192.     if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
  193.    end
  194.   elseif keyID == 28 then
  195.    term.clear()
  196.    term.setCursorPos(1, 1)
  197.    functions[selectionNumber]()
  198.    if exitCondition or once then
  199.     exitCondition = false
  200.     term.clear()
  201.     term.setCursorPos(1, 1)
  202.     return true
  203.    end
  204.    if scroll then updateMenuScroll(names, selectionNumber, title, spacing) else menuPrint(title, names, selectionLineNumber, selectionNumber) end
  205.   end
  206.  end
  207. end
  208.  
  209. function menu.exit()
  210.  exitCondition = true
  211. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement