Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local version = "Graffiti v1.5"
- -- fields for users
- userFunctions = {}
- userLists = {}
- selectedItems = {}
- userInputs = {}
- --monitor
- local monitorSide = ""
- local monitor = nil
- -- texts
- local refreshText = "Refresh"
- local backText = "Back"
- local doneString = "Done"
- -- colors
- local buttonDefaultColor = colors.red
- local buttonPressedColor = colors.lime
- local sliderLowValueColor = colors.red
- local sliderMediumValueColor = colors.yellow
- local sliderHighValueColor = colors.lime
- local inputDefaultColor = colors.white
- local inputDefaultTextColor = colors.black
- local inputPressedColor = colors.yellow
- local listDefaultColor = colors.lightBlue
- local listSelectedColor = colors.orange
- local editorMoveColor = colors.magenta
- local editorScaleColor = colors.pink
- local editorMarkerColor = colors.gray
- local editorAlignmentTrueColor = colors.lime
- local editorAlignmentFalseColor = colors.red
- -- sizes
- local buttonDefaultWidth = 10
- local buttonDefaultHeight = 3
- local sliderDefaultLength = 10
- -- save file
- saveFileName = "Graffiti.sav"
- -- API
- initDone = false
- isAPI = false -- Determines whether the program has been loaded as an API
- variableValues = {}
- sliderValues = {}
- -- editor options
- local editMode = false
- local showEditorOptions = false
- local editActions = { "Design", "Attributes", "Delete" }
- local lastScreen = "mainScreen"
- local editorFunctions = {}
- local objectTypes = { "Button", "Text", "Variable", "Slider", "Input", "List" }
- local rightClickActions = {"Attributes", "Delete" }
- -- AddOn options
- local addOns = {}
- local addOnExtension = ".add"
- -- other
- local args = { ... }
- local quit = false
- local maxX, maxY = 51, 19
- local out = term -- Output: either "term" or the monitor
- local outIsTerm = false
- local autoLoadObjects = true
- local changeButtonColor = true
- local screens = {}
- screens.mainScreen = {}
- currentScreen = "mainScreen"
- local sides = { "left", "top", "right", "bottom", "front", "back" }
- -- Displays a star in the upper left corner for a
- -- short amount of time. Used when you want to see
- -- when something certain happens.
- -- Should only be used when you are desperately
- -- looking for a bug.
- function extremeDebug()
- out.setCursorPos(1, 1)
- out.write("*")
- os.sleep(0.5)
- out.setCursorPos(1, 1)
- out.write(" ")
- os.sleep(0.5)
- end
- -- user variables
- local randomValue= 50
- -- user functions
- function userFunctions.setRandomValue()
- randomValue = math.random(100)
- end
- -- user lists
- userLists.testList = {
- "Testitem 1",
- "Testitem 2",
- "Testitem 3"
- }
- -- Define the value of a variable-object.
- function getVariableValue(variableID)
- if (variableID == nil) then
- return ""
- end
- if (variableID == "testVariable") then
- return "Variable";
- elseif (variableID == "Time") then
- return textutils.formatTime(os.time(), true)
- else
- return variableValues[variableID]
- end
- end
- -- Definie the value of a slider-object
- -- 0: empty; 100: full
- function getSliderValue(sliderID)
- if (sliderID == nil or sliderID == "") then
- return 0
- end
- if (sliderID == "testSlider") then
- return 87;
- elseif (sliderID == "randomSlider") then
- return randomValue
- else
- return sliderValues(sliderID)
- end
- end
- -- WARNING! Everything below this comment
- -- shouldn't be edited! If you do so and the program
- -- doesn't work any more then it's your fault!
- -- API function: Sets the value of all variables
- -- with the given ID.
- function setVariableValue(variableID, newVar)
- variableValues[variableID] = newVar
- end
- -- API function: Sets the value of all sliders
- -- with the given ID.
- function setSliderValue(sliderID, newVar)
- sliderValues[sliderID] = newVar
- end
- -- Returns where the user clicked and which button
- -- he pressed (always 1 if it's a monitor).
- function getCursorInput()
- local finished = false
- while not finished do
- event, param, x, y = os.pullEvent()
- if (event == "monitor_touch" and not outIsTerm) then
- mouseButton = 1
- finished = true
- elseif (event == "mouse_click" and outIsTerm) then
- mouseButton = param
- finished = true
- end
- end
- return x, y, mouseButton
- end
- function readUserInput(message, isPassword)
- if not outIsTerm then
- print(message)
- end
- if isPassword then
- ret = read("*")
- else
- ret = read()
- end
- return ret
- end
- -- Redirects the input to the computer and lets
- -- the user enter something. The result will be
- -- in the userInputs array with the inputID as the
- -- key.
- function getUserInput(inputObject)
- if (inputObject == nil or inputObject.objType ~= "Input") then
- return
- end
- local x = inputObject.x
- local y = inputObject.y
- local inputID = inputObject.inputID
- local message = inputObject.message
- local isPassword = (inputObject.isPassword == nil) and false or inputObject.isPassword
- local maxLength = inputObject.maxLength
- local existingInput = userInputs[inputID]
- out.setBackgroundColor(colors.black)
- out.setCursorPos(x, y)
- if (existingInput ~= nil) then -- Clear the text on the input object.
- for i = -1, string.len(existingInput) do
- out.write(" ")
- end
- else
- out.write(" ")
- end
- userInputs[inputID] = nil
- out.setCursorPos(x, y)
- if not outIsTerm then
- -- make the input-object yellow
- out.setBackgroundColor(colors.yellow)
- out.write(" ")
- out.setBackgroundColor(colors.black)
- end
- if outIsTerm then
- out.setCursorPos(x + 1, y)
- end
- local userInput = readUserInput(message, isPassword)
- if (userInput ~= nil) then
- userInputs[inputID] = userInput
- end
- out.setCursorPos(x, y)
- out.setBackgroundColor(colors.white)
- out.setTextColor(colors.black)
- out.write(" ")
- if (userInput ~= nil and userInput ~= "") then
- if isPassword then
- for i = 1, string.len(userInput) do
- out.write("*")
- end
- else
- out.write(userInput)
- end
- end
- out.write(" ")
- out.setBackgroundColor(colors.black)
- out.setTextColor(colors.white)
- return ret
- end
- -- Checks if dir is a valid direction-string
- function isValidDirection(dir)
- if (dir ~= nil and
- (dir == "left" or
- dir == "up" or
- dir == "right" or
- dir == "down")) then
- return true
- end
- return false
- end
- -- display objects region start --
- -- Has to be used instead of paintutils.drawpixel
- function drawPixel(x, y, color)
- out.setCursorPos(x, y)
- out.setBackgroundColor(color)
- out.write(" ")
- end
- -- Displays a line at the given coordinates.
- -- Didn't know that paintutils has a function that
- -- does that for me...
- function showLine(x, y, direction, length, color)
- out.setBackgroundColor(color)
- direction = (isValidDirection(direction)) and direction or "right"
- local addX, addY = 1, 0
- local currentX, currentY = x, y
- if (direction == "left") then
- addX, addY = -1, 0
- elseif (direction == "up") then
- addX, addY = 0, -1
- elseif (direction == "right") then
- addX, addY = 1, 0
- elseif (direction == "down") then
- addX, addY = 0, 1
- end
- for i = 1, length do
- drawPixel(currentX, currentY, color)
- currentX = currentX + addX
- currentY = currentY + addY
- end
- end
- -- Displays a rectangle at the given coordinates.
- function showBox(x, y, width, height, color)
- for row = x, x + width - 1 do
- for col = y, y + height - 1 do
- drawPixel(row, col, color)
- end
- end
- out.setBackgroundColor(colors.black)
- end
- -- Displays the text on the screen.
- function showText(textObject)
- if (textObject.objType ~= "Text") then
- return
- end
- x = textObject.x
- y = textObject.y
- text = textObject.text
- assert(x, "Text: X-coordinate has to be set!")
- assert(y, "Text: Y-coordinate has to be set!")
- out.setCursorPos(x, y)
- out.write(text)
- end
- -- Displays the slider on the screen.
- function showSlider(slider, fillPercentage)
- if (slider == nil or slider.objType ~= "Slider") then
- return
- end
- x = slider.x
- y = slider.y
- length = slider.length
- direction = (isValidDirection(slider.direction)) and slider.direction or "right"
- startSymbol, endSymbol = "<", ">"
- addX, addY = 1, 0 -- Sets the direction of the slider, therefore it could even be diagonal.
- if (direction == "left") then
- addX, addY = -1, 0
- startSymbol, endSymbol = ">", "<"
- out.setCursorPos(x - length, y)
- out.write(endSymbol)
- elseif (direction == "up") then
- addX, addY = 0, -1
- startSymbol, endSymbol = "V", "^"
- out.setCursorPos(x, y - length)
- out.write(endSymbol)
- elseif (direction == "right") then
- addX, addY = 1, 0
- startSymbol, endSymbol = "<", ">"
- out.setCursorPos(x + length, y)
- out.write(endSymbol)
- elseif (direction == "down") then
- addX, addY = 0, 1
- startSymbol, endSymbol = "^", "V"
- out.setCursorPos(x, y + length)
- out.write(endSymbol)
- else -- return if it's not a valid direction, even if I checked it before
- return
- end
- out.setCursorPos(x, y)
- out.write(startSymbol)
- if (fillPercentage ~= nil) then
- if (fillPercentage < 33) then
- sliderColor = sliderLowValueColor
- elseif (fillPercentage > 66) then
- sliderColor = sliderHighValueColor
- else
- sliderColor = sliderMediumValueColor
- end
- filled = math.floor((length / 100) * fillPercentage)
- showLine(x + addX, y + addY, direction, filled, sliderColor)
- end
- out.setBackgroundColor(colors.black)
- end
- -- Displays the given button on the screen.
- function showButton(button, color)
- if (button == nil or button.objType ~= "Button") then
- return
- end
- x = button.x
- y = button.y
- width = button.width
- height = button.height
- text = button.text
- showBox(x, y, width, height, color)
- -- Tries to center the text in the button.
- textCol = x + math.floor((width - string.len(text)) / 2)
- textRow = y + math.ceil(height / 2) - 1
- out.setCursorPos(textCol, textRow)
- out.setBackgroundColor(color)
- out.write(text)
- out.setBackgroundColor(colors.black)
- end
- -- Displays the input-object (two white spaces)
- function showInput(inputObject)
- if (inputObject == nil or inputObject.objType ~= "Input") then
- return
- end
- local inputID = inputObject.inputID
- local x = inputObject.x
- local y = inputObject.y
- out.setCursorPos(x, y)
- out.setBackgroundColor(inputDefaultColor)
- out.setTextColor(inputDefaultTextColor)
- out.write(" ")
- out.write(userInputs[inputID])
- out.write(" ")
- out.setTextColor(colors.white)
- out.setBackgroundColor(colors.black)
- end
- -- Used by "showList" and "showSelector" to
- -- determine how wide the list should be.
- function getLongestString(stringArray)
- if (stringArray == nil or #stringArray == 0) then
- return 0
- end
- ret = 0
- for key, value in pairs(stringArray) do
- length = string.len(value)
- if (length > ret) then
- ret = length
- end
- end
- return ret
- end
- -- Displays a list on the monitor.
- function showList(listObject)
- if (listObject == nil or listObject.objType ~= "List") then
- return
- end
- if (type(listObject.elements) == "string") then
- listObject.elements = { listObject.elements }
- end
- if (#listObject.elements == 1 and userLists[listObject.elements[1]] ~= nil) then
- listObject.elements = userLists[listObject.elements[1]]
- end
- x = listObject.x
- y = listObject.y
- elements = (listObject.elements ~= nil) and listObject.elements or { "empty" }
- width = getLongestString(elements) + 2
- listObject.width = width
- height = #elements
- listObject.height = height
- elements = listObject.elements
- listID = listObject.listID
- isMultiselect = (listObject.isMultiselect ~= nil) and listObject.isMultiselect or false
- showBox(x, y, width, height, listDefaultColor)
- if (selectedItems[listID] == nil and isMultiselect) then
- selectedItems[listID] = { }
- for index, elementKey in ipairs(elements) do
- selectedItems[listID][elementKey] = false
- end
- end
- posY = 0
- for key,element in pairs(elements) do
- out.setCursorPos(x, y + posY)
- if (isMultiselect) then
- if (selectedItems[listID][key] == true) then
- out.setBackgroundColor(listSelectedColor)
- else
- out.setBackgroundColor(listDefaultColor)
- end
- else
- if (selectedItems[listID] == key) then
- out.setBackgroundColor(listSelectedColor)
- else
- out.setBackgroundColor(listDefaultColor)
- end
- end
- out.write(" " .. element .. " ")
- posY = posY + 1
- end
- out.setBackgroundColor(colors.black)
- end
- -- Displays a list and returns the field that the
- -- user touched.
- function showSelector(x, y, elements)
- width = getLongestString(elements) + 2
- height = #elements + 2 -- Elements + up and down
- elementCount = #elements
- displayCount = elementCount
- enoughXSpace = true
- -- determine where the selector should actually be displayed
- if (width > maxX) then -- Not enough monitors horizontally?
- x = 1
- enoughXSpace = false
- elseif (maxX - x < width) then -- Not enough space to the right.
- if (x >= width) then -- Let's see if there is space to the left.
- x = x - width
- else -- No space? Check where you've got more space.
- if (maxX / 2) > x then -- More space to the left.
- x = maxX - width + 1
- enoughXSpace = false
- else -- More space to the right
- x = 1
- enoughXSpace = false
- end
- end
- else -- Enough space to the right.
- x = x + 1
- end
- if (height > maxY - y) then -- Not enough space from y to bottom.
- if ((maxY / 2) > y) then -- More space below y.
- if enoughXSpace then
- if (maxY < height) then -- Too big for the whole screen.
- y = 1
- displayCount = maxY - 2
- else -- Enough space next to x and not too high.
- y = maxY - height
- end
- else -- Can't display it next to the selected point.
- y = y + 1
- displayCount = maxY - y - 1
- end
- else -- More space above y.
- if enoughXSpace then
- if (y < height) then -- Not enough space from top to y.
- if (maxY < height) then -- Too big for the whole screen.
- y = 1
- displayCount = maxY - 2
- else -- Enough space next to x and not too high.
- y = 1
- end
- else -- Enough space from top to y.
- y = y - height + 1
- end
- else
- if (y < height) then -- Not enough space from top to y.
- if (maxY < height) then -- Too big for the whole screen.
- y = 1
- displayCount = maxY - 2
- else -- Not enough space next to x but not too high.
- y = 1
- displayCount = y - 4
- end
- else -- Enough space from top to y.
- y = y - height
- end
- end
- end
- end
- out.setBackgroundColor(colors.black)
- -- Read the user input.
- scroll = 1
- right = x + width - 1
- bottom = y + displayCount + 1
- finished = false
- while not finished do
- -- Display the actual selector.
- showBox(x, y, width, height, listDefaultColor)
- out.setBackgroundColor(listDefaultColor)
- middle = math.floor(width / 2)
- out.setCursorPos(x + middle, y)
- out.write("^")
- out.setCursorPos(x + middle, bottom)
- out.write("V")
- for i = 1, displayCount do
- out.setCursorPos(x, y + i)
- out.write(" " .. elements[i + scroll - 1] .. " ")
- end
- out.setBackgroundColor(colors.black)
- touchX, touchY, mouseButton = getCursorInput()
- if (touchX < x or touchX > right or touchY < y or touchY > bottom) then
- selectedItem = nil
- result = false
- finished = true
- else -- User touched the selector.
- if (touchY == y) then -- up
- if (scroll > 1) then -- Check if it makes sense to scroll up.
- scroll = scroll - 1
- end
- elseif (touchY == bottom) then -- down
- if (displayCount < elementCount) then
- if (scroll <= elementCount - displayCount) then
- scroll = scroll + 1
- end
- end
- else
- selectedItem = elements[touchY - y + scroll - 1]
- result = true
- finished = true
- end
- end
- end
- showScreen(currentScreen)
- return result
- end
- -- Displays the text with red background colour.
- function showSimpleButton(x, y, text)
- out.setCursorPos(x, y)
- out.setBackgroundColor(colors.red)
- out.write(text)
- out.setBackgroundColor(colors.black)
- end
- -- Displays the "Back"- and "Refresh"-Buttons
- function showDefaultButtons()
- x = maxX - string.len(refreshText) + 1
- showSimpleButton(x, maxY, refreshText)
- showSimpleButton(1, maxY, backText)
- end
- -- display objects region end
- -- Returns a table with most informations that an AddOn would need.
- function getSystemInfo()
- systemInfo = {}
- systemInfo.maxX = maxX
- systemInfo.maxY = maxY
- systemInfo.selectedItems = selectedItems
- systemInfo.userInputs = userInputs
- return systemInfo
- end
- -- Loads the values of all variables and sliders
- -- of the current screen.
- function loadObjects()
- for objectID, object in pairs(screens[currentScreen]) do
- local objectType = object.objType
- local x = object.x
- local y = object.y
- if (objectType == "Variable") then
- local value = getVariableValue(object.varID)
- out.setCursorPos(x, y)
- out.write(value)
- elseif (objectType == "Slider") then
- local length = object.length
- local value = getSliderValue(object.sliderID)
- showSlider(object, value)
- end
- end
- end
- -- Displays all objects of the selected screen.
- function showScreen(screenID)
- out.clear()
- assert(screenID, "Can't show screen! Parameter screenID is invalid!")
- currentScreen = screenID
- if not editMode then
- if (currentScreen == "mainScreen") then
- backText = "Quit"
- else
- backText = "Back"
- end
- else
- backText = "Quit"
- refreshText = "Options"
- end
- local screenObject
- local objectType
- if showEditorOptions then
- screenObject = editorScreens[screenID]
- else
- screenObject = screens[screenID]
- end
- for sObjectID, sObject in pairs(screenObject) do
- objectType = sObject.objType
- if (objectType == "Button") then
- showButton(sObject, buttonDefaultColor)
- elseif (objectType == "Text") then
- showText(sObject)
- elseif (objectType == "Slider") then
- showSlider(sObject, 0)
- elseif (objectType == "Input") then
- showInput(sObject)
- elseif (objectType == "List") then
- showList(sObject)
- elseif (objectType == "Custom") then
- callAddOn(sObject, "Show")
- end
- end
- if autoLoadObjects then
- loadObjects()
- end
- showDefaultButtons()
- out.setCursorPos(1, maxY)
- end
- -- Waits until the user touches the monitor and
- -- if he touched a button, the function stored in
- -- it will be called.
- function getInput()
- local finished = false
- x, y, mouseButton = getCursorInput()
- if (y == maxY) then -- Checking the default buttons
- if (x <= string.len(backText)) then -- "Back"-Button pressed
- if (currentScreen == "mainScreen" or editMode) then
- quit = true
- else
- if (screens[currentScreen].parentScreen ~= nil) then
- showScreen(screens[currentScreen].parentScreen)
- finished = true
- else
- showScreen("mainScreen")
- finished = true
- end
- end
- elseif (x >= maxX - string.len(refreshText) and not editMode) then -- "Refresh"-Button pressed
- showScreen(currentScreen)
- finished = true
- end
- end
- if finished then
- return nil, currentScreen
- elseif quit then
- return "quit", currentScreen -- Used for the API
- end
- local param, screen = nil, currentScreen
- local sObjectID, sObject = findObject(x, y)
- if (sObjectID ~= nil and sObject ~= nil) then
- objectType = sObject.objType
- if (objectType == "Button") then
- if (sObject.isAddon) then
- callAddOn(sObject, "Click")
- elseif (sObject.funcType ~= nil and sObject.param ~= nil) then
- param, screen = callAction(sObject)
- end
- elseif (objectType == "Input") then
- getUserInput(sObject)
- elseif (objectType == "List") then
- top = sObject.y
- listID = sObject.listID
- isMultiselect = sObject.isMultiselect
- if (isMultiselect) then
- if (selectedItems[listID][y - top + 1]) then
- selectedItems[listID][y - top + 1] = false
- else
- selectedItems[listID][y - top + 1] = true
- end
- else
- selectedItems[listID] = y - top + 1
- end
- showList(sObject)
- elseif (objectType == "Custom" and sObject.canClick) then -- AddOn Object
- callAddOn(sObject, "Click")
- end
- end
- return param, screen
- end
- function callAction(button)
- actionType = button.funcType
- param = button.param
- if (actionType == "switch") then
- showScreen(param)
- return nil, param
- elseif (actionType == "function") then
- if changeButtonColor then
- showButton(button, buttonPressedColor)
- end
- if userFunctions[param] ~= nil then
- userFunctions[param]()
- elseif editorFunctions[param] ~= nil then
- editorFunctions[param]()
- end
- if changeButtonColor then
- showButton(button, buttonDefaultColor)
- else
- changeButtonColor = true
- end
- return param, currentScreen
- end
- end
- function callAddOn(object, callType)
- addOnName = object.addOnName
- objectID = object.objID
- x = object.x
- y = object.y
- width = object.width
- height = object.height
- addOnPath = fs.combine(shell.dir(), addOnName .. addOnExtension)
- systemInfo = getSystemInfo()
- systemInfo.x = x
- systemInfo.y = y
- systemInfo.width = width
- systemInfo.height = height
- if changeButtonColor then
- showButton(object, buttonPressedColor)
- end
- shell.run(addOnPath, callType, objectID, textutils.serialize(systemInfo))
- if changeButtonColor then
- showButton(button, buttonDefaultColor)
- else
- changeButtonColor = true
- end
- end
- -- Checks if the monitor on monitorSide exists and wraps it into "monitor".
- function getOutput()
- if (monitor == nil and outIsTerm == false) then
- local monitorFound = false
- for _, side in pairs(sides) do
- if (peripheral.getType(side) == "monitor") then
- monitor = peripheral.wrap(side)
- monitorFound = true
- out = monitor
- outIsTerm = false
- end
- end
- if not monitorFound then
- out = term
- outIsTerm = true
- end
- elseif outIsTerm then
- out = term
- else
- out = monitor
- end
- end
- -- Shows the message on the computer for debugging. Probably my most-used function.
- function debugMessage(message)
- if outIsTerm then
- error("Can't display a debug message on a computer!")
- end
- print(message)
- end
- -- Calls the "getInput" function until the user presses the quit-button.
- function main()
- showScreen("mainScreen")
- while not quit do
- getInput()
- end
- end
- -- Saves the content of the screens-table into the save file
- function saveScreens()
- saveString = textutils.serialize(screens)
- file = fs.open(saveFileName, "w")
- file.write(saveString)
- file.close()
- end
- -- Loads the save file and puts the content into the screens-table
- function loadScreens()
- if not fs.exists(saveFileName) then
- return
- end
- file = fs.open(saveFileName, "r")
- loadString = file.readAll()
- if (loadString ~= nil and loadString ~= "") then
- screens = textutils.unserialize(loadString)
- end
- file.close()
- end
- function splitAt(toSplit, delimiter)
- delimiterPos = string.find(toSplit, delimiter)
- left = string.sub(toSplit, 1, delimiterPos - 1)
- right = string.sub(toSplit, delimiterPos + #delimiter)
- return left, right
- end
- -- screen editor region start --
- function generateScreenList()
- ret = { "mainScreen" }
- for key, value in pairs(screens) do
- if (key ~= "mainScreen" and key ~= "defaultX" and key ~= "defaultY") then
- table.insert(ret, key)
- end
- end
- return ret
- end
- editorScreens = {
- mainScreen = {
- { objType="Text", x=2, y=1, text="Mode:" };
- { objType="List", x=2, y=2, elements=editActions, listID="editActionList", isMultiselect=false };
- { objType="Button", x=2, y=6, width=14, height=1, text="last screen", funcType="function", param="editLastScreen" };
- { objType="Button", x=2, y=8, width=14, height=1, text="edit screens", funcType="function", param="loadScreenList" };
- };
- screenListScreen = {
- { objType="List", x=2, y=2, elements=screenList, listID="screenList", isMultiselect=false };
- { objType="Button", x=2, y=maxY-6, width=12, height=1, text="Set parent", funcType="function", param="setParent" };
- { objType="Button", x=2, y=maxY-4, width=8, height=1, text="New", funcType="function", param="newScreen" };
- { objType="Button", x=2, y=maxY-3, width=8, height=1, text="Edit", funcType="function", param="editScreen" };
- { objType="Button", x=2, y=maxY-2, width=8, height=1, text="Delete", funcType="function", param="deleteScreen" };
- };
- }
- -- Used to give a List-object an array of all screens
- function editorFunctions.loadScreenList()
- screenList = generateScreenList()
- editorScreens["screenListScreen"][1].elements = screenList
- changeButtonColor = false
- showScreen("screenListScreen")
- end
- function editorFunctions.editLastScreen()
- if (lastScreen == nil) then
- lastScreen = "mainScreen"
- end
- showEditorOptions = false
- showScreen(lastScreen)
- changeButtonColor = false
- end
- -- Let's the user define the parentScreen-attribute of the current screen.
- function editorFunctions.setParent()
- if (selectedItems.screenList == nil) then
- return
- end
- list = editorScreens.screenListScreen[1]
- height = list.height
- for i = 1, height do
- if (selectedItems.screenList ~= i) then
- drawPixel(1, i + 1, colors.lime)
- end
- end
- x, y, mouseButton = getCursorInput()
- if (y > 1 and y <= height + 1) then -- Clicked inside the list.
- if (y - 1 ~= selectedItems.screenList) then -- Selected parentScreen is not selected screen.
- screens[list.elements[selectedItems.screenList]].parentScreen = list.elements[y - 1]
- end
- end
- for i = 1, height do
- drawPixel(1, i + 1, colors.black)
- end
- end
- -- Creates a new screen. The user has to enter the screen name in the computer.
- function editorFunctions.newScreen()
- out.clear()
- if not outIsTerm then
- out.setCursorPos(2, 2)
- out.write("Enter a screen-name.")
- end
- out.setCursorPos(1, 1)
- message = "Pleas enter the name of the new screen."
- userInput = readUserInput(message, false)
- while (userInput ~= nil and screens[userInput] ~= nil) do
- message = "There is already a screen with that name!"
- userInput = readUserInput(message, false)
- end
- if (userInput ~= nil) then
- screens[userInput] = { parentScreen="mainScreen" }
- showEditorOptions = false
- showScreen(userInput)
- lastScreen = userInput
- changeButtonColor = false
- end
- end
- -- Edits the screen that has been selected in the "screenList"-list.
- function editorFunctions.editScreen()
- if (selectedItems.screenList ~= nil) then
- showEditorOptions = false
- lastScreen = screenList[selectedItems.screenList]
- showScreen(screenList[selectedItems.screenList])
- changeButtonColor = false
- end
- end
- -- Deletes the screen that has been selected in the "screenList"-list.
- function editorFunctions.deleteScreen()
- if (selectedItems.screenList ~= nil and screenList[selectedItems.screenList] ~= "mainScreen") then
- screens[screenList[selectedItems.screenList]] = nil
- showEditorOptions = true
- editorFunctions.loadScreenList()
- end
- end
- -- Displays an object with default attributes and adds it to the current screen.
- function showDefaultObject(objectType, xCoord, yCoord)
- object = { }
- object.objType = objectType
- object.x = xCoord
- object.y = yCoord
- object.xPercent = maxX / xCoord
- object.yPercent = maxX / yCoord
- maxWidth = maxX - xCoord
- maxHeight = maxY - yCoord
- if (string.find(objectType, " - ") ~= nil) then -- object is an AddOn
- addOnName, objectName = splitAt(objectType, " - ")
- objectValues = addOns[addOnName][objectName]
- objectID = objectValues.objectID
- objectType = objectValues.objectType
- defaultWidth = tonumber(objectValues.defaultWidth)
- defaultHeight = tonumber(objectValues.defaultHeight)
- canScale = objectValues.canScale
- canClick = objectValues.canClick
- object.objID = objectID
- object.objType = objectType
- object.canScale = canScale
- object.canClick = canClick
- object.isAddOn = true
- object.addOnName = addOnName
- if (objectType == "Button") then
- object.width = (defaultWidth <= maxWidth) and defaultWidth or maxWidth
- object.height = (defaultHeight <= maxHeight) and defaultHeight or maxHeight
- object.widthPercent = maxX / object.width
- object.heightPercent = maxY / object.height
- object.text = objectValues.text
- object.horizontalAlignment = "left"
- object.verticalAlignment = "top"
- showButton(object, buttonDefaultColor)
- elseif (objectType == "Custom") then
- if canScale then
- object.width = (defaultWidth <= maxWidth) and defaultWidth or maxWidth
- object.height = (defaultHeight <= maxHeight) and defaultHeight or maxHeight
- else
- object.width = defaultWidth
- object.height = defaultHeight
- end
- elseif (objectType == "Variable") then
- object.varID = objectID
- elseif (objectType == "Input") then
- object.inputID = objectID
- object.message = objectValues.message
- object.isPassword = objectValues.isPassword or false
- showInput(object)
- elseif (objectType == "List") then
- object.listID = objectID
- object.elements = objectValues.elements
- showList(object)
- end
- elseif (objectType == "Button") then -- Object is not an AddOn.
- object.width = (maxWidth < buttonDefaultWidth) and maxWidth or buttonDefaultWidth
- object.height = (maxHeight < buttonDefaultHeight) and maxHeight or buttonDefaultHeight
- object.widthPercent = maxX / object.width
- object.heightPercent = maxY / object.height
- object.text = "Button"
- object.funcType = ""
- object.param = ""
- object.horizontalAlignment = "left"
- object.verticalAlignment = "top"
- showButton(object, buttonDefaultColor)
- elseif (objectType == "Text") then
- object.text = "Text"
- showText(object)
- elseif (objectType == "Variable") then
- object.varID = "testVariable"
- elseif (objectType == "Slider") then
- object.length = (maxWidth < sliderDefaultLength) and maxWidth or sliderDefaultLength
- object.lengthPercent = maxX / object.length
- object.direction = "right"
- object.sliderID = "testSlider"
- showSlider(object)
- elseif (objectType == "Input") then
- object.inputID = "testInput"
- object.message = "Enter something."
- object.isPassword = false
- showInput(object)
- elseif (objectType == "List") then
- object.elements = userLists.testList
- object.listID = "testList"
- object.isMultiselect = false
- showList(object)
- else
- return
- end
- table.insert(screens[currentScreen], object)
- end
- -- Shows lines marking the top left part of an
- -- object as well as well as pixels displaying
- -- the alignment of an object.
- function showAlignmentLines(object, left, top, right, bottom, color)
- -- Draw the lines.
- showLine(left - 1, top, "left", left - 2, color) -- left
- showLine(left, top -1, "up", top - 2, color) -- up
- showLine(right + 1, top, "right", maxX - (right + 1), color) -- right
- showLine(left, bottom + 1, "down", maxY - (bottom + 1), color) -- down
- -- Display the alignment-pixels.
- horizontalAlignment = object.horizontalAlignment
- verticalAlignment = object.verticalAlignment
- if (horizontalAlignment == "left" or horizontalAlignment == "stretch") then -- left
- drawPixel(1, top, editorAlignmentTrueColor)
- else
- drawPixel(1, top, editorAlignmentFalseColor)
- end
- if (horizontalAlignment == "right" or horizontalAlignment == "stretch") then -- right
- drawPixel(maxX, top, editorAlignmentTrueColor)
- else
- drawPixel(maxX, top, editorAlignmentFalseColor)
- end
- if (verticalAlignment == "top" or verticalAlignment == "stretch") then -- top
- drawPixel(left, 1, editorAlignmentTrueColor)
- else
- drawPixel(left, 1, editorAlignmentFalseColor)
- end
- if (verticalAlignment == "bottom" or verticalAlignment == "stretch") then -- bottom
- drawPixel(left, maxY, editorAlignmentTrueColor)
- else
- drawPixel(left, maxY, editorAlignmentFalseColor)
- end
- out.setBackgroundColor(colors.black)
- end
- -- Returns the values of horizontalAlignment and
- -- verticalAlignment depending which sides are set
- -- to true.
- function getAlignment(left, top, right, bottom)
- local retHorizontal, retVertical = "left", "top"
- if right then
- if left then
- retHorizontal = "stretch"
- else
- retHorizontal = "right"
- end
- else
- retHorizontal = "left"
- end
- if bottom then
- if top then
- retVertical = "stretch"
- else
- retVertical = "bottom"
- end
- else
- retVertical = "top"
- end
- return retHorizontal, retVertical
- end
- -- Returns the right- and bottom-coordinates of the object.
- function getObjectDimensions(object)
- if (type(object) ~= "table") then
- return -1, -1, -1, -1
- end
- objectType = object.objType
- left = object.x
- top = object.y
- if (objectType == "Button" or objectType == "List") then
- right = left + object.width - 1
- bottom = top + object.height - 1
- elseif (objectType == "Text") then
- right = left + string.len(object.text) - 1
- bottom = top
- elseif (objectType == "Variable" or objectType == "Input") then
- right = left + 1
- bottom = top
- elseif (objectType == "Slider") then
- direction = object.direction
- length = object.length
- if (direction == "left") then
- left = object.x - length
- top = object.y
- right = object.x
- bottom = top
- elseif (direction == "up") then
- left = object.x
- top = object.y - length
- right = object.x
- bottom = object.y
- elseif (direction == "down") then
- left = object.x
- top = object.y
- right = object.x
- bottom = top + length
- else -- right
- left = object.x
- top = object.y
- right = object.x + length
- bottom = top
- end
- elseif (objectType == "Custom") then -- AddOn
- if (object.canScale or object.canClick) then
- right = left + object.width
- bottom = top + object.height
- else
- right = left
- bottom = top
- end
- else
- right = -1
- bottom = -1
- end
- return left, top, right, bottom
- end
- function findObject(x, y)
- if showEditorOptions then
- screenObject = editorScreens[currentScreen]
- else
- screenObject = screens[currentScreen]
- end
- for sObjectID, sObject in pairs(screenObject) do
- left, top, right, bottom = getObjectDimensions(sObject)
- if (x >= left and x <= right and y >= top and y <= bottom) then
- return sObjectID, sObject
- end
- end
- return nil, nil
- end
- -- Let's the user delete an object or change its attributes depending on the current edit-mode.
- function editObject(objectKey)
- sObject = screens[currentScreen][objectKey]
- objType = sObject.objType
- left, top, right, bottom = getObjectDimensions(sObject)
- if (editActions[selectedItems.editActionList] == "Delete") then
- screens[currentScreen][objectKey] = nil
- elseif (editActions[selectedItems.editActionList] == "Attributes" and not screens[currentScreen][objectKey].isAddOn) then
- objAttr = { }
- index = 1
- for key, value in pairs(sObject) do
- if (key ~= "objType"
- and key ~= "x"
- and key ~= "y"
- and key ~= "width"
- and key ~= "height"
- and key ~= "length"
- and key ~= "direction"
- and key ~= "xPercent"
- and key ~= "yPercent"
- and key ~= "widthPercent"
- and key ~= "heightPercent"
- and key ~= "horizontalAlignment"
- and key ~= "verticalAlignment") then
- table.insert(objAttr, index, key)
- index = index + 1
- end
- end
- out.clear()
- yPos = 2
- top = yPos
- for attrKey, attrValue in ipairs(objAttr) do
- out.setCursorPos(2, yPos)
- out.write(attrValue .. ": ")
- out.write(sObject[attrValue])
- yPos = yPos + 1
- end
- out.setCursorPos(2, yPos + 1)
- out.setBackgroundColor(colors.red)
- out.write(doneString)
- out.setBackgroundColor(colors.black)
- bottom = yPos - 1
- finished = false
- while not finished do
- x, y, mouseButton = getCursorInput()
- if y >= top and y <= bottom then
- selectedAttr = objAttr[y - 1]
- if not outIsTerm then
- drawPixel(1, y, colors.yellow)
- end
- if (selectedAttr == "text" or
- selectedAttr == "param" or
- selectedAttr == "varID" or
- selectedAttr == "sliderID" or
- selectedAttr == "inputID" or
- selectedAttr == "listID" or
- selectedAttr == "message" or
- selectedAttr == "elements" or
- selectedAttr == "message") then
- if outIsTerm then
- out.setCursorPos(1, y)
- out.clearLine(y)
- out.setCursorPos(2, y)
- out.write(selectedAttr .. ": ")
- --out.setCursorPos(4 + string.len(selectedAttr), y)
- end
- userInput = readUserInput("Please enter a value for the " .. selectedAttr .. ".", false)
- if (userInput ~= nil) then
- screens[currentScreen][objectKey][selectedAttr] = userInput
- end
- elseif (selectedAttr == "funcType") then -- Button attribute
- if (sObject.funcType == "switch") then
- screens[currentScreen][objectKey][selectedAttr] = "function"
- else
- screens[currentScreen][objectKey][selectedAttr] = "switch"
- end
- elseif (selectedAttr == "isPassword" or selectedAttr == "isMultiselect") then
- if (sObject[selectedAttr]) then
- screens[currentScreen][objectKey][selectedAttr] = false
- else
- screens[currentScreen][objectKey][selectedAttr] = true
- end
- end
- drawPixel(1, y, colors.black)
- if (not finished and selectedAttr ~= nil) then
- out.setCursorPos(2, y) -- I don't know if that's neccessary...
- for i = 2, maxX do
- out.write(" ")
- end
- out.setCursorPos(2, y)
- out.write(selectedAttr .. ": ")
- out.write(sObject[selectedAttr])
- end
- elseif (y == yPos + 1 and x >= 2 and x <= 1 + string.len(doneString)) then
- finished = true
- end
- end
- else -- Design mode
- canScale = false
- moveX = left
- moveY = top
- if (objType == "Button") then
- drawPixel(right, bottom, editorScaleColor) -- Draw scale-pixel.
- scaleX = right
- scaleY = bottom
- canScale = true
- elseif (objType == "Slider") then
- direction = sObject.direction
- assert(direction)
- canScale = true
- if (direction == "left") then
- moveX = right
- moveY = top
- scaleX = left
- scaleY = bottom
- elseif (direction == "up") then
- moveX = left
- moveY = bottom
- scaleX = right
- scaleY = top
- else -- right or down
- moveX = left
- moveY = top
- scaleX = right
- scaleY = bottom
- end
- drawPixel(scaleX, scaleY, editorScaleColor) -- Draw scale-pixel.
- elseif (objType == "Custom" and sObject.canScale) then -- AddOn
- canScale = true
- scaleX = right
- scaleY = bottom
- drawPixel(scaleX, scaleY, editorScaleColor)
- end
- drawPixel(moveX, moveY, editorMoveColor)
- showAlignmentLines(sObject, left, top, right, bottom, editorMarkerColor)
- horizontalAlignment = screens[currentScreen][objectKey].horizontalAlignment
- verticalAlignment = screens[currentScreen][objectKey].verticalAlignment
- leftAlignment = (horizontalAlignment == "left" or horizontalAlignment == "stretch")
- rightAlignment = (horizontalAlignment == "right" or horizontalAlignment == "stretch")
- topAlignment = (verticalAlignment == "top" or verticalAlignment == "stretch")
- bottomAlignment = (verticalAlignment == "bottom" or verticalAlignment == "stretch")
- out.setBackgroundColor(colors.black)
- x, y, mouseButton = getCursorInput()
- if (x >= left and x <= right and y >= top and y <= bottom) then -- clicked inside the object
- if (x == moveX and y == moveY) then -- move object
- drawPixel(moveX, moveY, colors.white)
- x, y, mouseButton = getCursorInput()
- screens[currentScreen][objectKey].x = x
- screens[currentScreen][objectKey].y = y
- screens[currentScreen][objectKey].xPercent = x / maxX
- screens[currentScreen][objectKey].yPercent = y / maxY
- elseif (canScale and x == scaleX and y == scaleY) then -- scale object
- drawPixel(scaleX, scaleY, colors.white)
- out.setBackgroundColor(colors.black)
- x, y, mouseButton = getCursorInput()
- if (objType == "Button" or objType == "Custom") then
- if (x > moveX + 2 and y >= moveY) then
- width = x - left + 1
- height = y - top + 1
- screens[currentScreen][objectKey].width = width
- screens[currentScreen][objectKey].height = height
- screens[currentScreen][objectKey].widthPercent = width / maxX
- screens[currentScreen][objectKey].heightPercent = height / maxY
- end
- elseif (objType == "Slider") then
- if (x < moveX and y == moveY) then -- Clicked left of the slider.
- length = moveX - x
- screens[currentScreen][objectKey].direction = "left"
- screens[currentScreen][objectKey].length = length
- screens[currentScreen][objectKey].lengthPercent = length / maxX
- elseif (x == moveX and y < moveY) then -- Clicked above the slider.
- length = moveY - y
- screens[currentScreen][objectKey].direction = "up"
- screens[currentScreen][objectKey].length = length
- screens[currentScreen][objectKey].lengthPercent = length / maxY
- elseif (x > moveX and y == moveY) then -- Clicked right of the slider.
- length = x - moveX
- screens[currentScreen][objectKey].direction = "right"
- screens[currentScreen][objectKey].length = length
- screens[currentScreen][objectKey].lengthPercent = length / maxX
- elseif (x == moveX and y > moveY) then -- Clicked below the slider.
- length = y - moveY
- screens[currentScreen][objectKey].direction = "down"
- screens[currentScreen][objectKey].length = length
- screens[currentScreen][objectKey].lengthPercent = length / maxY
- end
- end
- else -- clicked something else inside the object (no idea what I could use this for)
- end
- else -- User might have clicked an alignment-pixel.
- finished = false
- while not finished do
- if (x == 1 and y == top) then -- left alignment-pixel
- --leftAlignment = not leftAlignment
- elseif (x == left and y == 1) then -- top alignment-pixel
- --topAlignment = not topAlignment
- elseif (x == maxX and y == top) then -- right alignment-pixel
- rightAlignment = not rightAlignment
- elseif (x == left and y == maxY) then -- bottom alignment-pixel
- bottomAlignment = not bottomAlignment
- else
- finished = true
- end
- horizontalAlignment, verticalAlignment = getAlignment(leftAlignment, topAlignment, rightAlignment, bottomAlignment)
- screens[currentScreen][objectKey].horizontalAlignment = horizontalAlignment
- screens[currentScreen][objectKey].verticalAlignment = verticalAlignment
- if not finished then
- showAlignmentLines(sObject, left, top, right, bottom, editorMarkerColor)
- x, y, mouseButton = getCursorInput()
- end
- end
- end
- end
- out.setBackgroundColor(colors.black)
- showScreen(currentScreen)
- end
- function markVariables()
- for sObjectID, sObject in pairs(screens[currentScreen]) do
- if (sObject.objType == "Variable") then
- drawPixel(sObject.x, sObject.y, colors.lime)
- out.setBackgroundColor(colors.black)
- end
- end
- end
- function getEditorInput()
- if not showEditorOptions then
- markVariables()
- xCoord, yCoord, mouseButton = getCursorInput()
- end
- if (showEditorOptions or yCoord == maxY and xCoord > maxX - string.len(refreshText)) then -- "Refresh" pressed => Options screen
- showEditorOptions = true
- showScreen("mainScreen")
- while showEditorOptions and not quit do
- getInput()
- end
- elseif (yCoord == maxY and xCoord >= 1 and xCoord <= string.len(backText)) then -- "Back" pressed => Quit
- quit = true
- else
- key, value = findObject(xCoord, yCoord) -- Find the object that the user touched.
- if (key == nil) then -- No object touched. Show selector for new object.
- drawPixel(xCoord, yCoord, colors.white)
- if (showSelector(xCoord, yCoord, objectTypes)) then -- something has been selected
- showDefaultObject(selectedItem, xCoord, yCoord)
- end
- else
- if (mouseButton == 1) then
- editObject(key)
- else
- if (showSelector(xCoord, yCoord, rightClickActions)) then
- if (selectedItem == "Attributes") then
- lastItem = selectedItems.editActionList
- selectedItems.editActionList = 2
- editObject(key)
- selectedItems.editActionList = lastItem
- elseif (selectedItem == "Delete") then
- lastItem = selectedItems.editActionList
- selectedItems.editActionList = 3
- editObject(key)
- selectedItems.editActionList = lastItem
- end
- end
- end
- end
- end
- end
- function screenEditor()
- editMode = true
- autoLoadObjects = false
- showEditorOptions = true
- showScreen("mainScreen")
- while not quit do
- getEditorInput()
- end
- end
- -- screen editor region end --
- -- AddOn manager region start --
- -- Removes all whitespaces to the left and right of the string.
- function trim(s)
- return s:gsub("^%s*(.-)%s*$", "%1")
- end
- -- Prints the message at the screen and exits the program.
- function throwException(message, fileName, lineNumber)
- error("AddOn loader error when reading file " .. fileName .. " at line " .. lineNumber .. ":\n" .. message)
- end
- -- Sets the optional attributes to their default-values if they haven't been set.
- function setDefaultAttributes(object)
- if (object.objectType == "Button") then
- object.defaultWidth = (object.defaultWidth ~= nil) and object.defaultWidth or buttonDefaultWidth
- object.defaultHeight = (object.defaultHeight ~= nil) and object.defaultHeight or buttonDefaultHeight
- elseif (object.objectType == "List") then
- object.elements = string.gmatch(object.elements, "[^;]+")
- end
- object.canScale = (object.canScale ~= nil) and object.canScale or false
- object.canClick = (object.canClick ~= nil) and object.canClick or false
- return object
- end
- -- Returns whether the object is valid or not. Returns a message if it isn't.
- function validateAddOnObject(object)
- if (object == nil or type(object) ~= "table") then
- return false, "Object is not a table!"
- end
- if (object.objectID == nil or object.objectID == "") then
- return false, "Object has no objecID!"
- end
- objType = object.objectType
- if (objType ~= "Button" and
- objType ~= "Variable" and
- objType ~= "Input" and
- objType ~= "List" and
- objType ~= "Custom") then
- return false, "Object has an invalid type!"
- end
- if (objType == "Button") then
- if (object.defaultWidth == nil or
- object.defaultHeight == nil) then
- return false, "Button-type objects need to have defaultWidth and defaultHeight attributes!"
- elseif (object.text == nil) then
- return false, "Button-type objects need to have a text attribute!"
- end
- elseif (objType == "List") then
- if (object.elements == nil) then
- return false, "List-type objects need to have an elements-attribute!"
- end
- elseif (objType == "Custom") then
- if (object.canScale or object.canClick) then
- if (object.defaultWidth == nil or
- object.defaultHeight == nil) then
- return false, "Default objects need to have defaultWidth and defaultHeight attributes when canScale or canClick is set to true!"
- end
- end
- end
- return true, nil
- end
- -- Reads the information between the file's <object> tags and adds the objects to the addOns-table.
- function readAddOn(filePath)
- file = fs.open(filePath, "r")
- fileName = string.sub(fs.getName(filePath), 1, -5)
- addOns[fileName] = {}
- started = false
- finished = false
- lineNumber = 0
- newObject = nil
- createNewObject = false
- newObjectLine = -1
- while not finished do
- line = file.readLine()
- line = trim(line)
- lineNumber = lineNumber + 1
- if (line == nil) then -- Reached end of line.
- throwException("Objects not found!", fileName, lineNumber)
- elseif (line == "" and started) then
- throwException("No </objects> tag found in the file! Make sure that you don't have any empty lines between the <objects> tags!", fileName, lineNumber)
- elseif (line == "<objects>") then
- if started then
- throwException("Root tag <objects> can only be used once!", fileName, lineNumber)
- else
- started = true
- end
- elseif (line == "</objects>") then
- if createNewObject then -- Code ends without finishing the last object.
- throwException("No </object> tag found to close <object> at line " .. newObjectLine, fileName, lineNumber)
- else
- finished = true
- end
- elseif (line == "<object>") then
- if createNewObject then -- no "</object>" before the next "<object>" tag.
- throwException("No </object> tag found to close <object> at line " .. newObjectLine, fileName, lineNumber)
- else
- createNewObject = true
- newObject = {}
- newObjectLine = lineNumber
- end
- elseif (line == "</object>") then -- Create object and add it to the addOns-table.
- if not createNewObject then
- throwException("No <object> tag found that needs to be closed.", fileName, lineNumber)
- else
- newObject = setDefaultAttributes(newObject)
- isValid, errMsg = validateAddOnObject(newObject)
- if not isValid then
- throwException("Object declared between line " .. newObjectLine .. " and " .. lineNumber .. " is invalid: " .. errMsg, fileName, lineNumber)
- else
- addOns[fileName][newObject.objectID] = newObject
- newObject = nil
- createNewObject = false
- newObjectLine = -1
- end
- end
- elseif (string.find(line, "=") and started) then -- Line defines an attribute.
- if not createNewObject then
- throwException("Declared an attribute without having an <object> tag!", fileName, lineNumber)
- else
- attribute, value = splitAt(line, "=")
- newObject[attribute] = value
- end
- elseif started then -- Throw an error if the line is inside the <objects> tags and if it's invalid. Otherwise keep looking for the <objects> tag.
- throwException("Line is neither a tag nor an attribute!", fileName, lineNumber)
- end
- end
- file.close()
- end
- -- Looks for AddOn files and adds them to the addOns-table.
- function loadAddOns()
- local currentDir = shell.dir()
- local files = fs.list(currentDir)
- for key, file in pairs(files) do
- if not fs.isDir(file) then -- if "file" is an actual file
- if string.sub(file, -4) == addOnExtension then -- if the file is a valid AddOn-file
- readAddOn(file)
- end
- end
- end
- for tableKey, tableValue in pairs(addOns) do
- for key, value in pairs(tableValue) do
- table.insert(objectTypes, tableKey .. " - " .. key)
- end
- end
- end
- -- AddOn manager region end --
- -- Screen size adaptation region start --
- function round(number)
- assert(number)
- comma = number % 1
- if comma < 0.5 then
- ret = math.floor(number)
- else
- ret = math.ceil(number)
- end
- return ret
- end
- -- Checks the default-size of the screens
- -- table and adapts all objects to the new size if
- -- the screen-size has changed.
- function checkDefaultSize()
- defaultX = screens["defaultX"]
- defaultY = screens["defaultY"]
- if (screens["defaultX"] == nil or screens["defaultY"] == nil) then -- Program has been started for the first time.
- screens["defaultX"] = maxX
- screens["defaultY"] = maxY
- saveScreens()
- elseif (screens["defaultX"] ~= maxX or screens["defaultY"] ~= maxY) then -- Screen-size is different since last program start.
- xDiff = maxX - defaultX
- yDiff = maxY - defaultY
- for screenID, screen in pairs(screens) do
- if (type(screen) == "table") then
- for objectID, object in pairs(screen) do
- if (type(object) == "table") then
- objType = object.objType
- x = object.x
- y = object.y
- xPercent = object.xPercent
- yPercent = object.yPercent
- widthPercent = object.widthPercent
- heightPercent = object.heightPercent
- horizontalAlignment = object.horizontalAlignment
- verticalAlignment = object.verticalAlignment
- if (horizontalAlignment == nil or verticalAlignment == nil) then
- horizontalAlignment = "left"
- verticalAlignment = "top"
- screens[screenID][objectID].horizontalAlignment = horizontalAlignment
- screens[screenID][objectID].verticalAlignment = verticalAlignment
- end
- if (horizontalAlignment == "stretch") then -- Stretch object horizontally.
- screens[screenID][objectID].x = round(maxX * xPercent)
- if (objType == "Button") then
- screens[screenID][objectID].width = round(maxX * widthPercent)
- elseif (objType == "Slider" and (direction == "left" or direction == "right")) then
- screens[screenID][objectID].length = round(maxX * object.lengthPercent)
- end
- end
- if (verticalAlignment == "stretch") then
- screens[screenID][objectID].y = round(maxY * yPercent)
- if (objType == "Button") then
- screens[screenID][objectID].height = round(maxY * heightPercent)
- elseif (objType == "Slider" and (direction == "up" or direction == "down")) then
- screens[screenID][objectID].length = round(maxX * object.lengthPercent)
- end
- end
- end
- end
- end
- end
- screens.defaultX = maxX
- screens.defaultY = maxy
- saveScreens()
- end
- end
- -- Screen size adaptation region end --
- function printInfo()
- print()
- print(version)
- print("Author: Encreedem")
- print()
- print("Param(s):")
- print("info - Shows some info about the program... but I guess you know that already.")
- print("edit - Starts the program in edit-mode.")
- print()
- print("Visit the CC-forums or my YouTube channel (LPF1337) for news and help.")
- end
- -- initialization
- function init()
- getOutput()
- maxX, maxY = out.getSize()
- if (maxX < 16 or maxY < 10) then -- smaller than 2x2
- print("Screen too small! You need at least 2x2 monitors!")
- return false
- end
- isAPI = (shell == nil)
- initDone = true
- return true
- end
- function checkArgs()
- doCall = main
- if (args[1] ~= nil) then
- if (args[1] == "edit") then
- doCall = screenEditor
- elseif (args[1] == "info") then
- printInfo()
- return
- elseif (args[1] == "term") then
- outIsTerm = true
- end
- end
- doCall()
- end
- if init() then
- if isAPI then
- loadScreens()
- --checkDefaultSize()
- else
- loadAddOns()
- loadScreens()
- --checkDefaultSize()
- checkArgs()
- if editMode then
- saveScreens()
- end
- out.clear()
- out.setCursorPos(1, 1)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement