gezepi

termMenu

Dec 19th, 2013
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.77 KB | None | 0 0
  1. local bolDebug = true
  2.  
  3. --[[    termMenu
  4.     API used for displaying menus on the terminal (or monitor)
  5.     Uses the same menu structure as gbMenu
  6.     Also has some other useful term functions
  7.    
  8.     --gezepi
  9. ]]
  10.  
  11. print("termMenu")
  12.  
  13. local width, height     --Size of text object
  14. local _width, _height   --SIze of montior
  15. local inputTimeout = 10
  16. local xO = 1    --X offset for printedt text
  17. local yO = 1    --Y offset for printed text
  18. local textOnScreen = {}
  19. local files
  20. local mon = nil
  21. local bug
  22.  
  23. function init(nFiles)
  24.     files = nFiles
  25.     os.loadAPI(files.tools)
  26.     tools.init(files)
  27.     bug = tools.bug(bolDebug)
  28.     tools.unload()
  29. end
  30. --[[    Initializes the API.  If given 'term' for newmon it will display on main screen of turtle or computer   ]]
  31. function new(newX, newY, newW, newH, newmon)
  32.     xO = newX
  33.     yO = newY
  34.     mon = newmon
  35.     _width, _height = mon.getSize()
  36.     width = newW
  37.     height = newH
  38. end
  39. --[[    Returns what x coord to start printing the given string so it ends up centered  ]]
  40. function centerX(s)
  41.     if tonumber(s)==nil then s = string.len(s) end
  42.     return ((width+1) / 2) - (s / 2)
  43. end
  44. --[[    Returns the center of the area  ]]
  45. function centerY(s)
  46.     if not tonumber(s) then s = string.len(s) end
  47.     return math.ceil((height+1) / 2) - s/2
  48. end
  49. --[[    Like term.write but at the given coords ]]
  50. function addText(x,y,s)
  51.     --print("x:",x,"y:",y,"s:",s)
  52.     x=xO+x-1 ; y=yO+y-1
  53.     mon.setCursorPos(x,y)
  54.     mon.write(s)
  55. end
  56. --[[    Like addText but blanks the rest of the line    ]]
  57. function addLine(y,s)
  58.     y = yO+y
  59.     mon.setCursorPos(xO,y)
  60.     mon.write(string.rep(" ", width))
  61.     addText(xO,y,s)
  62. end
  63. --[[    Clears the entire area  ]]
  64. function clearText()
  65.     for i=0,height do
  66.         addLine(i,"")
  67.     end
  68. end
  69. --[[    Clears a box area   ]]
  70. function clearBox(x, y, w, h)
  71.     for i=0, h do
  72.         addText(x, y+i, string.rep(" ", w))
  73.     end
  74. end
  75. --[[    Prints the str centered on the row  ]]
  76. function printCenterX(row, str)
  77.     row = row or 1
  78.     str = str or "Nil string"
  79.     addText(centerX(str), row, str)
  80. end
  81. --[[    Prints str centered vertically beginning at col ]]
  82. function printCenterY(col, str)
  83.     addText(col, centerY(), str)
  84. end
  85. --[[    Prints str centered on screen   ]]
  86. function printCenter(str)
  87.     addText(center(str), centerY(), str)
  88. end
  89. --[[    Draws a box.  Blanks everything inside of it    ]]
  90. function drawBox(x, y, w, h)
  91.     --x=xO+x ; y=yO+y
  92.     if w<=1 then w = width * w end
  93.     if h<=1 then h = height * h end
  94.     addText(x,y,"+"..string.rep("-", w-2).."+")
  95.     for i=1,h-1 do
  96.         addText(x,y+i,"|"..string.rep(" ", w-2).."|")
  97.     end
  98.     addText(x,y+h,"+"..string.rep("-", w-2).."+")
  99. end
  100. --[[    Draws a UI and prompts user for a number    ]]
  101. --[[function getNumber(maximum)
  102.     drawBox(centerX(12), centerY()-2, 12, 4)
  103.     addText(centerX("How many?"), centerY()-1,"How many?")
  104.     local s = "(1-"..maximum..")"
  105.     addText(centerX(s),centerY(),s)
  106.     addText(centerX(1)-1, centerY()+1,"")
  107.     num = io.read()
  108.     if num=="" then return nil end
  109.     num =tonumber(num)
  110.     if num==nil or num>maximum then
  111.         return getNumber(maximum)
  112.     end
  113.     return num
  114. end--]]
  115. --[[    Prints a named box  ]]
  116. function printDialog(s, w, h)
  117.     s = s or "Dialog"
  118.     w = w or string.len(s) + 4
  119.     h = h or 5
  120.     drawBox(centerX(w), centerY(h), w, h)
  121.     addText(centerX(string.len(s)+2), centerY(h), "+"..s.."+")
  122.     return centerX(w), centerY(h), w, h
  123. end
  124. --[[    Shrinks a table so it only contains entries with filString in them  ]]
  125. local function filterMenu(menu, filString)
  126.     retM = {}
  127.     retM.name = menu.name
  128.     retM.selections = {}
  129.     local i = 1
  130.     for k,v in pairs(menu.selections) do
  131.         if filString~="" and string.lower(v.name)==string.lower(filString) then
  132.             retM.selections = {}
  133.             retM.selections[1] = v
  134.             return retM
  135.         end
  136.         if string.find(string.lower(v.name), string.lower(filString))~=nil then
  137.             retM.selections[i] = v
  138.             i = i + 1
  139.         end
  140.     end
  141.     return retM
  142. end
  143. --[[    Prompts user for a boolean  ]]
  144. function getInputBoolean(name, hVal, lVal)
  145.     lVal = lVal or "false"
  146.     hVal = hVal or "true"
  147.     local w
  148.     if string.len("*"..hVal.."  "..lVal) > string.len(name) then w = string.len("*"..hVal.."  "..lVal)+2 end
  149.     local dx, dy, dw, dh = printDialog(name or "Boolean", w, 2)
  150.     addText(dx+1, dy+1, "*"..hVal.."  "..lVal)
  151.     local choice = true
  152.     while true do
  153.         local e, p1, p2, p3 = os.pullEvent("key")
  154.         p1 = keys.getName(p1)
  155.         if p1=="left" and not choice then
  156.             addText(dx+1, dy+1, "*"..hVal.."  "..lVal)
  157.             choice = true
  158.         elseif p1=="right" and choice then
  159.             addText(dx+1, dy+1, " "..hVal.." *"..lVal)
  160.             choice = false
  161.         elseif p1=="enter" then
  162.             clearBox(dx, dy, dw, dh)
  163.             return choice
  164.         end
  165.     end
  166. end
  167. --[[    Sets the cursor position within the alloted space   ]]
  168. function setCursor(nX, nY)
  169.     mon.setCursorPos(xO+nX-1, yO+nY-1)
  170. end
  171. --[[    Prompts user for a number   ]]
  172. function getInputNum(name,minimum,maximum, err)
  173.     local range = "From "
  174.     if minimum then range = range..minimum else range = range.."-inf" end
  175.     if maximum then range = range.." to "..maximum else range = range.." to inf" end
  176.     local w
  177.     if string.len(range)>string.len(name) then w = string.len(range)+2 end
  178.     local dx, dy, dw, dh = printDialog((name or "Number")..(err or ""), w, 3)
  179.     if range then termMenu.printCenterX(dy+1, range) end
  180.     addText(dx+1, dy+2, ">   ")
  181.     setCursor(dx+2, dy+2)
  182.     local num = io.read()
  183.     num = tonumber(num)
  184.     if num~=nil then
  185.         if maximum and minimum and num <= maximum and num >= minimum then
  186.             clearBox(dx, dy, dw, dh)
  187.             return num
  188.         end
  189.         if maximum and not minimum and num <= maximum then clearText() ; return num end
  190.         if minimum and not maximum and num >= minimum then clearText() ; return num end
  191.         if not minimum and not maximum then clearText() ; return num end
  192.         return getInputNum(name,minimum, maximum, "*")
  193.     end
  194.     clearBox(dx, dy, dw, dh)
  195.     return nil
  196. end
  197. --[[    Prompts the user for a string   ]]
  198. function getInputString(name)
  199.     local dx, dy, dw, dh = printDialog(name or "String", nil, 2)
  200.     addText(dx+1, dy+1, ">   ")
  201.     setCursor(dx+2, dy+1)
  202.     local s = io.read()
  203.     clearBox(dx,dy,dw,dh)
  204.     return s
  205. end
  206. --[[    Displays a menu to the user ]]
  207. function dispMenu(x,y,thing,sSearch)
  208.     clearText()
  209.     drawBox(1,1,width,height)
  210.     if thing == nil then error("Passed a nil menu") end
  211.     if sSearch == nil then sSearch = "" end
  212.     wholeMenu = thing
  213.     thing = filterMenu(thing, sSearch)
  214.     --bug("Menu:"..thing.name)
  215.     local n = "+"..thing.name.."+"
  216.     addText(centerX(n),y,n)
  217.     for k,v in pairs(thing.selections) do
  218.         addText(x,y+k," "..v.name)
  219.         if k > height-2 then
  220.             break
  221.         end
  222.     end
  223.  
  224.     local choice
  225.     if #thing.selections == -1 then
  226.         --choice = thing.selections[1]
  227.     else
  228.         local function dispInput(s)
  229.             mon.setCursorPos(xO+1,yO+height)
  230.             mon.write(">"..s)
  231.         end
  232.         local cursorPos = 1
  233.         dispInput(sSearch)
  234.         local function cursorMove(dY)
  235.             mon.setCursorPos(xO+x-1,yO+cursorPos)
  236.             mon.write(" ")
  237.             cursorPos = cursorPos + dY
  238.             if cursorPos > height-1 then cursorPos = height-1 end
  239.             if cursorPos > #thing.selections then cursorPos = #thing.selections end
  240.             if cursorPos < 1 then cursorPos = 1 end
  241.             mon.setCursorPos(xO+x-1,yO+cursorPos)
  242.             mon.write("-")
  243.         end
  244.         cursorMove(0)
  245.         while 1 do
  246.             local e,p1,p2 = os.pullEvent()
  247.             if e=="char" then           --Alphabet input
  248.                 sSearch = sSearch..p1
  249.                 return dispMenu(x, y,wholeMenu, sSearch)
  250.             elseif e=="key" then        --Arrows/Enter input
  251.                 if p1==28 then          --Enter
  252.                     if cursorPos > #thing.selections then
  253.                         choice = nil
  254.                     else
  255.                         choice = thing.selections[cursorPos]
  256.                     end
  257.                     break   --User chose something, exit
  258.                 elseif p1==208 then --Down
  259.                     cursorMove(1)
  260.                 elseif p1==200 then --Up
  261.                     cursorMove(-1)
  262.                 elseif p1==203 then --Left
  263.                     choice = nil
  264.                     break
  265.                 elseif p1==14 then  --Backspace
  266.                     sSearch = string.sub(sSearch, 0,string.len(sSearch)-1)
  267.                     return dispMenu(x, y,wholeMenu, sSearch)
  268.                 end--keys
  269.             end--char / key
  270.         end--input while
  271.     end
  272.    
  273.     if choice ~= nil then
  274.         clearText()
  275.         if choice.data==nil then return {name=choice.name, data=choice.name} end
  276.         if type(choice.data)=="function" then
  277.             choice.data()
  278.         end
  279.         return choice
  280.     else
  281.         clearText()
  282.         return nil
  283.     end
  284. end
  285. --[[    Test function for boxes, etc    ]]
  286. function test()
  287.     --mon.clear()
  288.     mon.setCursorPos(xO,yO)
  289.     mon.write("+")
  290.     mon.setCursorPos(xO,yO)
  291.     for i=10,1,-1 do
  292.         clearText()
  293.         drawBox(1,1,i/10,i/10)
  294.         sleep(.1)
  295.     end
  296.     for i=1,10 do
  297.         clearText()
  298.         drawBox(1,1,i/10,i/10)
  299.         sleep(.1)
  300.     end
  301.     --addLine(4, "hello world")
  302.     local s = "hello world"
  303.     addText(centerX(s), centerY(),s)
  304.     mon.setCursorPos(1,_height)
  305. end
  306. --[[    Test menu   ]]
  307. function testMenu()
  308.     test = {
  309.         name="Test",
  310.         selections={
  311.             {name="First thing", data = {0,0}},
  312.             {name="Second thing", data={-1,0}},
  313.             {name="Third thing", data={-1,0}},
  314.             {name="Fourth thing"},
  315.             {name="Fifth thing"},
  316.             {name="Sixth thing"},
  317.             {name="Seventh thing"},
  318.         }
  319.     }
  320.     c = dispMenu(2,1,test)
  321.     if c==nil then c = "nothing" else c = c.name end
  322.     print("Chose: "..c)
  323.     mon.setCursorPos(1,_height)
  324. end
Advertisement
Add Comment
Please, Sign In to add comment