Advertisement
Encreedem

GraffitiAPI v1.0

Jul 23rd, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.29 KB | None | 0 0
  1. local version = "GraffitiAPI v1.0"
  2.  
  3. -- fields for users
  4. userFunctions = {}
  5. userLists = {}
  6. selectedItems = {}
  7. userInputs = {}
  8.  
  9. --monitor
  10. monitorSide = "right"
  11. monitor = nil
  12.  
  13. -- texts
  14. local refreshText = "Refresh"
  15. local backText = "Back"
  16. local doneString = "Done"
  17.  
  18. -- colors
  19. local buttonDefaultColor = colors.red
  20. local buttonPressedColor = colors.lime
  21. local sliderLowValueColor = colors.red
  22. local sliderMediumValueColor = colors.yellow
  23. local sliderHighValueColor = colors.lime
  24. local inputDefaultColor = colors.white
  25. local inputPressedColor = colors.yellow
  26. local listDefaultColor = colors.lightBlue
  27. local listSelectedColor = colors.orange
  28. local editorMoveColor = colors.magenta
  29. local editorScaleColor = colors.pink
  30.  
  31. -- Save file
  32. saveFileName = "Graffiti.sav"
  33.  
  34. -- API
  35. variableValues = {}
  36. sliderValues = {}
  37.  
  38. -- other
  39. args = { ... }
  40. quit = false
  41. local maxX, maxY = 51, 19
  42. local autoLoadObjects = true
  43. local changeButtonColor = true
  44. local screens = {}
  45. screens.mainScreen = {}
  46. currentScreen = "mainScreen"
  47.  
  48. function readUserInput(message, isPassword)
  49.   term.restore()
  50.   print(message)
  51.  
  52.   if isPassword  then
  53.     ret = read("*")
  54.   else
  55.     ret = read()
  56.   end
  57.  
  58.   term.redirect(monitor)
  59.   return ret
  60. end
  61.  
  62. -- Redirects the input to the computer and lets
  63. -- the user enter something. The result will be
  64. -- in the userInputs array with the inputID as the
  65. -- key.
  66. function getUserInput(inputObject)
  67.   if (inputObject == nil or inputObject.objType ~= "Input") then
  68.     return
  69.   end
  70.  
  71.   x = inputObject.x
  72.   y = inputObject.y
  73.   inputID = inputObject.inputID
  74.   message = inputObject.message
  75.   isPassword = (inputObject.isPassword == nil) and false or inputObject.isPassword
  76.   maxLength = inputObject.maxLength
  77.  
  78.   existingInput = userInputs[inputID]
  79.   if (existingInput ~= nil) then -- Clear the text on the input object.
  80.     term.setCursorPos(x, y)
  81.     for i = -1, string.len(existingInput) do
  82.       term.write(" ")
  83.     end
  84.    
  85.     userInputs[inputID] = nil
  86.   end
  87.  
  88.   -- make the input-object yellow
  89.   term.setCursorPos(x, y)
  90.   term.setBackgroundColor(colors.yellow)
  91.   term.write("  ")
  92.   term.setBackgroundColor(colors.black)
  93.  
  94.   userInput = readUserInput(message, isPassword)
  95.   if (userInput ~= nil) then
  96.     userInputs[inputID] = userInput
  97.   end
  98.  
  99.   term.setCursorPos(x, y)
  100.   term.setBackgroundColor(colors.white)
  101.   term.setTextColor(colors.black)
  102.  
  103.   term.write(" ")
  104.   if (userInput ~= nil and userInput ~= "") then
  105.     if isPassword then
  106.       for i = 1, string.len(userInput) do
  107.         term.write("*")
  108.       end
  109.     else
  110.       term.write(userInput)
  111.     end
  112.   end
  113.  
  114.   term.write(" ")
  115.   term.setBackgroundColor(colors.black)
  116.   term.setTextColor(colors.white)
  117.  
  118.   return ret
  119. end
  120.  
  121. -- Checks if dir is a valid direction-string
  122. function isValidDirection(dir)
  123.   if (dir == "left" or
  124.       dir == "up" or
  125.       dir == "right" or
  126.       dir == "down") then
  127.     return true
  128.   end
  129.  
  130.   return false
  131. end
  132.  
  133. -- display objects region start --
  134.  
  135. function showBox(x, y, width, height, color)
  136.   for row = x, x + width - 1 do
  137.     for col = y, y + height - 1 do
  138.       paintutils.drawPixel(row, col, color)
  139.     end
  140.   end
  141.  
  142.   term.setBackgroundColor(colors.black)
  143. end
  144.  
  145. -- Displays the text on the screen.
  146. function showText(textObject)
  147.   if (textObject.objType ~= "Text") then
  148.     return
  149.   end
  150.  
  151.   x = textObject.x
  152.   y = textObject.y
  153.   text = textObject.text
  154.   assert(x, "Text: X-coordinate has to be set!")
  155.   assert(y, "Text: Y-coordinate has to be set!")
  156.  
  157.   term.setCursorPos(x, y)
  158.   term.write(text)
  159. end
  160.  
  161. -- Displays the slider on the screen.
  162. function showSlider(slider, fillPercentage)
  163.   if (slider == nil or slider.objType ~= "Slider") then
  164.     return
  165.   end
  166.  
  167.   x = slider.x
  168.   y = slider.y
  169.   length = slider.length
  170.   direction = (isValidDirection(slider.direction)) and slider.direction or "right"
  171.  
  172.   startSymbol, endSymbol = "<", ">"
  173.   addX, addY = 1, 0 -- Sets the direction of the slider, therefore it could even be diagonal.
  174.  
  175.   if (direction == "left") then
  176.     addX, addY = -1, 0
  177.     startSymbol, endSymbol = ">", "<"
  178.     term.setCursorPos(x - length, y)
  179.     term.write(endSymbol)
  180.   elseif (direction == "up") then
  181.     addX, addY = 0, -1
  182.     startSymbol, endSymbol = "V", "^"
  183.     term.setCursorPos(x, y - length)
  184.     term.write(endSymbol)
  185.   elseif (direction == "right") then
  186.     addX, addY = 1, 0
  187.     startSymbol, endSymbol = "<", ">"
  188.     term.setCursorPos(x + length, y)
  189.     term.write(endSymbol)
  190.   elseif (direction == "down") then
  191.     addX, addY = 0, 1
  192.     startSymbol, endSymbol = "^", "V"
  193.     term.setCursorPos(x, y + length)
  194.     term.write(endSymbol)
  195.   else -- return if it's not a valid direction, even if I checked it before
  196.     return
  197.   end
  198.  
  199.   term.setCursorPos(x, y)
  200.   term.write(startSymbol)
  201.  
  202.   if (fillPercentage ~= nil) then
  203.     if (fillPercentage < 33) then
  204.       sliderColor = sliderLowValueColor
  205.     elseif (fillPercentage > 66) then
  206.       sliderColor = sliderHighValueColor
  207.     else
  208.       sliderColor = sliderMediumValueColor
  209.     end
  210.    
  211.     filled = math.floor((length / 100) * fillPercentage)
  212.     currentX = x + addX
  213.     currentY = y + addY
  214.    
  215.     for i = 1, filled - 1 do
  216.       paintutils.drawPixel(currentX, currentY, sliderColor)
  217.       currentX = currentX + addX
  218.       currentY = currentY + addY
  219.     end
  220.   end
  221.  
  222.   term.setBackgroundColor(colors.black)
  223. end
  224.  
  225. -- Displays the given button on the screen.
  226. function showButton(button, color)
  227.   if (button == nil or button.objType ~= "Button") then
  228.     return
  229.   end
  230.  
  231.   x = button.x
  232.   y = button.y
  233.   width = button.width
  234.   height = button.height
  235.   text = button.text
  236.  
  237.   showBox(x, y, width, height, color)
  238.  
  239.   -- Tries to center the text in the button.
  240.   textCol = x + math.floor((width - string.len(text)) / 2)
  241.   textRow = y + math.ceil(height / 2) - 1
  242.   term.setCursorPos(textCol, textRow)
  243.   term.setBackgroundColor(color)
  244.   term.write(text)
  245.  
  246.   term.setBackgroundColor(colors.black)
  247. end
  248.  
  249. -- Displays the input-object (two white spaces)
  250. function showInput(inputObject)
  251.   if (inputObject == nil or inputObject.objType ~= "Input") then
  252.     return
  253.   end
  254.  
  255.   inputId = inputObject.inputID
  256.   x = inputObject.x
  257.   y = inputObject.y
  258.  
  259.   term.setCursorPos(x, y)
  260.   term.setBackgroundColor(inputDefaultColor)
  261.   term.setTextColor(colors.black)
  262.   term.write(" ")
  263.   if (userInputs[inputID] ~= nil) then
  264.     term.write(userInputs[inputID])
  265.   end
  266.   term.write(" ")
  267.  
  268.   term.setBackgroundColor(colors.black)
  269.   term.setTextColor(colors.white)
  270. end
  271.  
  272. -- Used by "showList" and "showSelector" to
  273. -- determine how wide the list should be.
  274. function getLongestString(stringArray)
  275.   if (stringArray == nil or #stringArray == 0) then
  276.     return 0
  277.   end
  278.  
  279.   ret = 0
  280.  
  281.   for key, value in pairs(stringArray) do
  282.     length = string.len(value)
  283.     if (length > ret) then
  284.       ret = length
  285.     end
  286.   end
  287.  
  288.   return ret
  289. end
  290.  
  291. -- Displays a list on the monitor.
  292. function showList(listObject)
  293.   if (listObject == nil or listObject.objType ~= "List") then
  294.     return
  295.   end
  296.  
  297.   if (type(listObject.elements) == "string") then
  298.     listObject.elements = { listObject.elements }
  299.   end
  300.  
  301.   if (#listObject.elements == 1 and userLists[listObject.elements[1]] ~= nil) then
  302.     listObject.elements = userLists[listObject.elements[1]]
  303.   end
  304.  
  305.   x = listObject.x
  306.   y = listObject.y
  307.   elements = (listObject.elements ~= nil) and listObject.elements or { "empty" }
  308.   width = getLongestString(elements) + 2
  309.   listObject.width = width
  310.   height = #elements
  311.   listObject.height = height
  312.   elements = listObject.elements
  313.   listID = listObject.listID
  314.   isMultiselect = (listObject.isMultiselect ~= nil) and listObject.isMultiselect or false
  315.  
  316.   showBox(x, y, width, height, listDefaultColor)
  317.  
  318.   if (selectedItems[listID] == nil and isMultiselect) then
  319.     selectedItems[listID] = {  }
  320.     for index, elementKey in ipairs(elements) do
  321.       selectedItems[listID][elementKey] = false
  322.     end
  323.   end
  324.  
  325.   posY = 0
  326.   for key,element in pairs(elements) do
  327.     term.setCursorPos(x, y + posY)
  328.    
  329.     if (isMultiselect) then
  330.       if (selectedItems[listID][key] == true) then
  331.         term.setBackgroundColor(listSelectedColor)
  332.       else
  333.         term.setBackgroundColor(listDefaultColor)
  334.       end
  335.     else
  336.       if (selectedItems[listID] == key) then
  337.         term.setBackgroundColor(listSelectedColor)
  338.       else
  339.         term.setBackgroundColor(listDefaultColor)
  340.       end
  341.     end
  342.    
  343.     term.write(" " .. element .. " ")
  344.     posY = posY + 1
  345.   end
  346.  
  347.   term.setBackgroundColor(colors.black)
  348. end
  349.  
  350. -- Displays the text with red background colour.
  351. function showSimpleButton(x, y, text)
  352.   term.setCursorPos(x, y)
  353.   term.setBackgroundColor(colors.red)
  354.   term.write(text)
  355.   term.setBackgroundColor(colors.black)
  356. end
  357.  
  358. -- Displays the "Back"- and "Refresh"-Buttons
  359. function showDefaultButtons()
  360.   x = maxX - string.len(refreshText) + 1
  361.   showSimpleButton(x, maxY, refreshText)
  362.  
  363.   showSimpleButton(1, maxY, backText)
  364. end
  365.  
  366. -- display objects region end
  367.  
  368. function setVariableValue(varID, value)
  369.   variableValues[varID] = value
  370. end
  371.  
  372. function setSliderValue(sliderID, value)
  373.   sliderValues[sliderID] = value
  374. end
  375.  
  376. -- Loads the values of all variables and sliders
  377. -- of the current screen.
  378. function loadObjects()
  379.   for objectID, object in pairs(screens[currentScreen]) do
  380.     objectType = object.objType
  381.     x = object.x
  382.     y = object.y
  383.    
  384.     if (objectType == "Variable") then
  385.       if (variableValues[object.varID] ~= nil) then
  386.         term.setCursorPos(x, y)
  387.         term.write(variableValues[object.varID])
  388.       end
  389.     elseif (objectType == "Slider") then
  390.       if (sliderValues[object.sliderID] ~= nil) then
  391.         showSlider(object, sliderValues[object.sliderID])
  392.       end
  393.     end
  394.   end
  395. end
  396.  
  397. -- Displays all objects of the selected screen.
  398. function showScreen(screenID)
  399.   term.clear()
  400.   currentScreen = screenID
  401.  
  402.   if (currentScreen == "mainScreen") then
  403.     backText = "Quit"
  404.   else
  405.     backText = "Back"
  406.   end
  407.  
  408.   local objectType
  409.  
  410.   for sObjectID, sObject in pairs(screens[screenID]) do
  411.     objectType = sObject.objType
  412.    
  413.     if (objectType == "Button") then
  414.       showButton(sObject, buttonDefaultColor)
  415.     elseif (objectType == "Text") then
  416.       showText(sObject)
  417.     elseif (objectType == "Slider") then
  418.       showSlider(sObject, 0)
  419.     elseif (objectType == "Input") then
  420.       showInput(sObject)
  421.     elseif (objectType == "List") then
  422.       showList(sObject)
  423.     end
  424.   end
  425.  
  426.   if autoLoadObjects then
  427.     loadObjects()
  428.   end
  429.  
  430.   showDefaultButtons()
  431.  
  432.   term.setCursorPos(1, maxY)
  433. end
  434.  
  435. -- Waits until the user touches the monitor and
  436. -- if he touched a button, the function stored in
  437. -- it will be called.
  438. function getInput(monSide)
  439.   monitorSide = monSide
  440.   loadScreens()
  441.   getMonitor()
  442.   maxX, maxY = monitor.getSize()
  443.   showScreen(currentScreen)
  444.  
  445.   while (not quit) do
  446.     finished = false
  447.     key, side, x, y = os.pullEvent("monitor_touch")
  448.    
  449.     if (y == maxY) then -- Checking the default buttons
  450.       if (x <= string.len(backText)) then -- "Back"-Button pressed
  451.         if (currentScreen == "mainScreen") then
  452.           term.clear()
  453.           term.setCursorPos(1, 1)
  454.           term.restore()
  455.           return "quit"
  456.         else
  457.           if (screens[currentScreen].parentScreen ~= nil) then
  458.             showScreen(screens[currentScreen].parentScreen)
  459.             finished = true
  460.           else
  461.             showScreen("mainScreen")
  462.             finished = true
  463.           end
  464.         end
  465.       elseif (x >= maxX - string.len(refreshText)) then -- "Refresh"-Button pressed
  466.         showScreen(currentScreen)
  467.         finished = true
  468.       end
  469.     end
  470.    
  471.     for sObjectID, sObject in pairs(screens[currentScreen]) do
  472.       if (finished == false and quit == false) then
  473.         objectType = sObject.objType
  474.        
  475.         if (objectType == "Button") then
  476.           left = sObject.x
  477.           top = sObject.y
  478.           width = sObject.width
  479.           height = sObject.height
  480.           right = left + width
  481.           bottom = top + height
  482.          
  483.           if (x >= left and x < right and y >= top and y < bottom) then
  484.             if (sObject.funcType == "switch") then
  485.               showScreen(sObject.param)
  486.             else -- funcType "function"
  487.               term.restore()
  488.               return sObject.param
  489.             end
  490.           end
  491.         elseif (objectType == "Input") then
  492.           left = sObject.x
  493.           top = sObject.y
  494.           inputID = sObject.inputID
  495.           message = sObject.message
  496.           isPassword = sObject.isPassword
  497.          
  498.           if ((x == left or x == left + 1) and y == top) then
  499.             getUserInput(sObject)
  500.           end
  501.         elseif (objectType == "List") then
  502.           left = sObject.x
  503.           top = sObject.y
  504.           width = sObject.width
  505.           height = #sObject.elements
  506.           right = left + width
  507.           bottom = top + height
  508.          
  509.           listID = sObject.listID
  510.           isMultiselect = sObject.isMultiselect
  511.          
  512.           if (x >= left and x < right and y >= top and y < bottom) then
  513.             if (isMultiselect) then
  514.               if (selectedItems[listID][y - top + 1]) then
  515.                 selectedItems[listID][y - top + 1] = false
  516.               else
  517.                 selectedItems[listID][y - top + 1] = true
  518.               end
  519.             else
  520.               selectedItems[listID] = y - top + 1
  521.             end
  522.            
  523.             showList(sObject)
  524.           end
  525.         end
  526.       end
  527.     end
  528.   end
  529. end
  530.  
  531. function getMonitor()
  532.   if (peripheral.getType(monitorSide) == "monitor") then
  533.     monitor = peripheral.wrap(monitorSide)
  534.     term.redirect(monitor)
  535.   else
  536.     error("No monitor at " .. monitorSide .. " side!");
  537.   end
  538. end
  539.  
  540. -- Shows the message on the computer for debugging. Probably my most-used function.
  541. function debugMessage(message)
  542.   term.restore()
  543.   print(message)
  544.   term.redirect(monitor)
  545. end
  546.  
  547. function loadScreens()
  548.   if not fs.exists(saveFileName) then
  549.     error(saveFileName .. " not found!")
  550.   end
  551.  
  552.   file = fs.open(saveFileName, "r")
  553.   loadString = file.readAll()
  554.   if (loadString ~= nil and loadString ~= "") then
  555.     screens = textutils.unserialize(loadString)
  556.   end
  557.   file.close()
  558. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement