serafim7

liteECSapi [OpenComputers]

Jul 26th, 2016
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 29.71 KB | None | 0 0
  1. --урезанная api.lib для codedoor ECS
  2.  
  3. local component = require("component")
  4. local term = require("term")
  5. local unicode = require("unicode")
  6. local event = require("event")
  7.  
  8. local ecs = {}
  9.  
  10. ecs.windowColors = {
  11.     background = 0xeeeeee,
  12.     usualText = 0x444444,
  13. }
  14.  
  15. ecs.colors = {
  16.     green = 0x57A64E,
  17.     red = 0xCC4C4C
  18. }
  19.  
  20. --Цветной текст
  21. function ecs.colorText(x,y,textColor,text)
  22.   component.gpu.setForeground(textColor)
  23.   component.gpu.set(x,y,text)
  24. end
  25.  
  26. --Цветной текст с жопкой!
  27. function ecs.colorTextWithBack(x,y,textColor,backColor,text)
  28.   component.gpu.setForeground(textColor)
  29.   component.gpu.setBackground(backColor)
  30.   component.gpu.set(x,y,text)
  31. end
  32.  
  33. --Юникодовский разделитель
  34. function ecs.separator(x, y, width, back, fore)
  35.     ecs.colorTextWithBack(x, y, fore, back, string.rep("-", width))
  36. end
  37.  
  38. --Юникодовская рамка
  39. function ecs.border(x, y, width, height, back, fore)
  40.     local stringUp = "┌"..string.rep("─", width - 2).."┐"
  41.     local stringDown = "└"..string.rep("─", width - 2).."┘"
  42.     component.gpu.setForeground(fore)
  43.     component.gpu.setBackground(back)
  44.     component.gpu.set(x, y, stringUp)
  45.     component.gpu.set(x, y + height - 1, stringDown)
  46.  
  47.     local yPos = 1
  48.     for i = 1, (height - 2) do
  49.         component.gpu.set(x, y + yPos, "│")
  50.         component.gpu.set(x + width - 1, y + yPos, "│")
  51.         yPos = yPos + 1
  52.     end
  53. end
  54.  
  55. --Кнопка в виде текста в рамке
  56. function ecs.drawFramedButton(x, y, width, height, text, color)
  57.     ecs.border(x, y, width, height, component.gpu.getBackground(), color)
  58.     component.gpu.fill(x + 1, y + 1, width - 2, height - 2, " ")
  59.     x = x + math.floor(width / 2 - unicode.len(text) / 2)
  60.     y = y + math.floor(width / 2 - 1)
  61.     component.gpu.set(x, y, text)
  62. end
  63.  
  64. --Заливка всего экрана указанным цветом
  65. function ecs.clearScreen(color)
  66.   if color then component.gpu.setBackground(color) end
  67.   term.clear()
  68. end
  69.  
  70. --Очистить экран, установить комфортные цвета и поставить курсок на 1, 1
  71. function ecs.prepareToExit(color1, color2)
  72.     term.setCursor(1, 1)
  73.     ecs.clearScreen(color1 or 0x333333)
  74.     component.gpu.setForeground(color2 or 0xffffff)
  75.     component.gpu.set(1, 1, "")
  76. end
  77.  
  78. --Корректировка стартовых координат. Core-функция для всех моих программ
  79. function ecs.correctStartCoords(xStart,yStart,xWindowSize,yWindowSize)
  80.     local xSize,ySize = component.gpu.getResolution()
  81.     if xStart == "auto" then
  82.         xStart = math.floor(xSize/2 - xWindowSize/2)
  83.     end
  84.     if yStart == "auto" then
  85.         yStart = math.ceil(ySize/2 - yWindowSize/2)
  86.     end
  87.     return xStart,yStart
  88. end
  89.  
  90. --Обычный квадрат указанного цвета
  91. function ecs.square(x,y,width,height,color)
  92.   component.gpu.setBackground(color)
  93.   component.gpu.fill(x,y,width,height," ")
  94. end
  95.  
  96. --Вертикальный скроллбар. Маст-хев!
  97. function ecs.srollBar(x, y, width, height, countOfAllElements, currentElement, backColor, frontColor)
  98.     local sizeOfScrollBar = math.ceil(1 / countOfAllElements * height)
  99.     local displayBarFrom = math.floor(y + height * ((currentElement - 1) / countOfAllElements))
  100.  
  101.     ecs.square(x, y, width, height, backColor)
  102.     ecs.square(x, displayBarFrom, width, sizeOfScrollBar, frontColor)
  103.  
  104.     sizeOfScrollBar, displayBarFrom = nil, nil
  105. end
  106.  
  107. --Отрисовка поля с текстом. Сюда пихать массив вида {"строка1", "строка2", "строка3", ...}
  108. function ecs.textField(x, y, width, height, lines, displayFrom, background, foreground, scrollbarBackground, scrollbarForeground)
  109.     x, y = ecs.correctStartCoords(x, y, width, height)
  110.  
  111.     background = background or 0xffffff
  112.     foreground = foreground or ecs.windowColors.usualText
  113.  
  114.     local sLines = #lines
  115.     local lineLimit = width - 3
  116.  
  117.     --Парсим строки
  118.     local line = 1
  119.     while lines[line] do
  120.         local sLine = unicode.len(lines[line])
  121.         if sLine > lineLimit then
  122.             local part1, part2 = unicode.sub(lines[line], 1, lineLimit), unicode.sub(lines[line], lineLimit + 1, -1)
  123.             lines[line] = part1
  124.             table.insert(lines, line + 1, part2)
  125.             part1, part2 = nil, nil
  126.         end
  127.         line = line + 1
  128.         sLine = nil
  129.     end
  130.     line = nil
  131.  
  132.     ecs.square(x, y, width - 1, height, background)
  133.     ecs.srollBar(x + width - 1, y, 1, height, sLines, displayFrom, scrollbarBackground, scrollbarForeground)
  134.  
  135.     component.gpu.setBackground(background)
  136.     component.gpu.setForeground(foreground)
  137.     local yPos = y
  138.     for i = displayFrom, (displayFrom + height - 1) do
  139.         if lines[i] then
  140.             component.gpu.set(x + 1, yPos, lines[i])
  141.             yPos = yPos + 1
  142.         else
  143.             break
  144.         end
  145.     end
  146.  
  147.     return sLines
  148. end
  149.  
  150. --Функция отрисовки кнопки указанной ширины
  151. function ecs.drawButton(x,y,width,height,text,backColor,textColor)
  152.     x,y = ecs.correctStartCoords(x,y,width,height)
  153.  
  154.     local textPosX = math.floor(x + width / 2 - unicode.len(text) / 2)
  155.     local textPosY = math.floor(y + height / 2)
  156.     ecs.square(x,y,width,height,backColor)
  157.     ecs.colorText(textPosX,textPosY,textColor,text)
  158.  
  159.     return x, y, (x + width - 1), (y + height - 1)
  160. end
  161.  
  162. --Ограничение длины строки. Маст-хев функция.
  163. function ecs.stringLimit(mode, text, size, noDots)
  164.     if unicode.len(text) <= size then return text end
  165.     local length = unicode.len(text)
  166.     if mode == "start" then
  167.         if noDots then
  168.             return unicode.sub(text, length - size + 1, -1)
  169.         else
  170.             return "…" .. unicode.sub(text, length - size + 2, -1)
  171.         end
  172.     else
  173.         if noDots then
  174.             return unicode.sub(text, 1, size)
  175.         else
  176.             return unicode.sub(text, 1, size - 1) .. "…"
  177.         end
  178.     end
  179. end
  180.  
  181. --Конвертация из юникода в символ. Вроде норм, а вроде и не норм. Но полезно.
  182. function ecs.convertCodeToSymbol(code)
  183.     local symbol
  184.     if code ~= 0 and code ~= 13 and code ~= 8 and code ~= 9 and code ~= 200 and code ~= 208 and code ~= 203 and code ~= 205 and not keyboard.isControlDown() then
  185.         symbol = unicode.char(code)
  186.         if keyboard.isShiftPressed then symbol = unicode.upper(symbol) end
  187.     end
  188.     return symbol
  189. end
  190.  
  191. --Функция для ввода текста в мини-поле.
  192. function ecs.inputText(x, y, limit, cheBiloVvedeno, background, foreground, justDrawNotEvent, maskTextWith)
  193.     limit = limit or 10
  194.     cheBiloVvedeno = cheBiloVvedeno or ""
  195.     background = background or 0xffffff
  196.     foreground = foreground or 0x000000
  197.  
  198.     component.gpu.setBackground(background)
  199.     component.gpu.setForeground(foreground)
  200.     component.gpu.fill(x, y, limit, 1, " ")
  201.  
  202.     local text = cheBiloVvedeno
  203.  
  204.     local function draw()
  205.         term.setCursorBlink(false)
  206.  
  207.         local dlina = unicode.len(text)
  208.         local xCursor = x + dlina
  209.         if xCursor > (x + limit - 1) then xCursor = (x + limit - 1) end
  210.  
  211.         if maskTextWith then
  212.             component.gpu.set(x, y, ecs.stringLimit("start", string.rep("?", dlina), limit))
  213.         else
  214.             component.gpu.set(x, y, ecs.stringLimit("start", text, limit))
  215.         end
  216.  
  217.         term.setCursor(xCursor, y)
  218.  
  219.         term.setCursorBlink(true)
  220.     end
  221.  
  222.     draw()
  223.  
  224.     if justDrawNotEvent then term.setCursorBlink(false); return cheBiloVvedeno end
  225.  
  226.     while true do
  227.         local e = {event.pull()}
  228.         if e[1] == "key_down" then
  229.             if e[4] == 14 then
  230.                 term.setCursorBlink(false)
  231.                 text = unicode.sub(text, 1, -2)
  232.                 if unicode.len(text) < limit then component.gpu.set(x + unicode.len(text), y, " ") end
  233.                 draw()
  234.             elseif e[4] == 28 then
  235.                 term.setCursorBlink(false)
  236.                 return text
  237.             else
  238.                 local symbol = ecs.convertCodeToSymbol(e[3])
  239.                 if symbol then
  240.                     text = text..symbol
  241.                     draw()
  242.                 end
  243.             end
  244.         elseif e[1] == "touch" then
  245.             term.setCursorBlink(false)
  246.             return text
  247.         elseif e[1] == "clipboard" then
  248.             if e[3] then
  249.                 text = text..e[3]
  250.                 draw()
  251.             end
  252.         end
  253.     end
  254. end
  255.  
  256. --Запомнить область пикселей и возвратить ее в виде массива
  257. function ecs.rememberOldPixels(x, y, x2, y2)
  258.     local newPNGMassiv = { ["backgrounds"] = {} }
  259.     local xSize, ySize = component.gpu.getResolution()
  260.     newPNGMassiv.x, newPNGMassiv.y = x, y
  261.  
  262.     --Перебираем весь массив стандартного PNG-вида по высоте
  263.     local xCounter, yCounter = 1, 1
  264.     for j = y, y2 do
  265.         xCounter = 1
  266.         for i = x, x2 do
  267.  
  268.             if (i > xSize or i < 0) or (j > ySize or j < 0) then
  269.                 error("Can't remember pixel, because it's located behind the screen: x("..i.."), y("..j..") out of xSize("..xSize.."), ySize("..ySize..")\n")
  270.             end
  271.  
  272.             local symbol, fore, back = component.gpu.get(i, j)
  273.  
  274.             newPNGMassiv["backgrounds"][back] = newPNGMassiv["backgrounds"][back] or {}
  275.             newPNGMassiv["backgrounds"][back][fore] = newPNGMassiv["backgrounds"][back][fore] or {}
  276.  
  277.             table.insert(newPNGMassiv["backgrounds"][back][fore], {xCounter, yCounter, symbol} )
  278.  
  279.             xCounter = xCounter + 1
  280.             back, fore, symbol = nil, nil, nil
  281.         end
  282.  
  283.         yCounter = yCounter + 1
  284.     end
  285.  
  286.     xSize, ySize = nil, nil
  287.     return newPNGMassiv
  288. end
  289.  
  290. --Нарисовать запомненные ранее пиксели из массива
  291. function ecs.drawOldPixels(massivSudaPihay)
  292.     --Перебираем массив с фонами
  293.     for back, backValue in pairs(massivSudaPihay["backgrounds"]) do
  294.         component.gpu.setBackground(back)
  295.         for fore, foreValue in pairs(massivSudaPihay["backgrounds"][back]) do
  296.             component.gpu.setForeground(fore)
  297.             for pixel = 1, #massivSudaPihay["backgrounds"][back][fore] do
  298.                 if massivSudaPihay["backgrounds"][back][fore][pixel][3] ~= transparentSymbol then
  299.                     component.gpu.set(massivSudaPihay.x + massivSudaPihay["backgrounds"][back][fore][pixel][1] - 1, massivSudaPihay.y + massivSudaPihay["backgrounds"][back][fore][pixel][2] - 1, massivSudaPihay["backgrounds"][back][fore][pixel][3])
  300.                 end
  301.             end
  302.         end
  303.     end
  304. end
  305.  
  306. --КЛИКНУЛИ ЛИ В ЗОНУ
  307. function ecs.clickedAtArea(x,y,sx,sy,ex,ey)
  308.   if (x >= sx) and (x <= ex) and (y >= sy) and (y <= ey) then return true end    
  309.   return false
  310. end
  311.  
  312. --Моя любимая функция ошибки C:
  313. function ecs.error(...)
  314.     local args = {...}
  315.     local text = ""
  316.     if #args > 1 then
  317.         for i = 1, #args do
  318.             --text = text .. "[" .. i .. "] = " .. tostring(args[i])
  319.             if type(args[i]) == "string" then args[i] = "\"" .. args[i] .. "\"" end
  320.             text = text .. tostring(args[i])
  321.             if i ~= #args then text = text .. ", " end
  322.         end
  323.     else
  324.         text = tostring(args[1])
  325.     end
  326.     ecs.universalWindow("auto", "auto", math.ceil(component.gpu.getResolution() * 0.45), ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x880000, "Ошибка!"}, {"EmptyLine"}, {"WrappedText", 0x262626, text}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "OK!"}})
  327. end
  328.  
  329. --Окошки
  330. function ecs.universalWindow(x, y, width, background, closeWindowAfter, ...)
  331.     local objects = {...}
  332.     local countOfObjects = #objects
  333.  
  334.     local pressedButton
  335.     local pressedMultiButton
  336.  
  337.     --Задаем высотные константы для объектов
  338.     local objectsHeights = {
  339.         ["button"] = 3,
  340.         ["centertext"] = 1,
  341.         ["emptyline"] = 1,
  342.         ["input"] = 3,
  343.         ["slider"] = 3,
  344.         ["select"] = 3,
  345.         ["selector"] = 3,
  346.         ["separator"] = 1,
  347.         ["switch"] = 1,
  348.         ["color"] = 3,
  349.     }
  350.  
  351.     --Скорректировать ширину, если нужно
  352.     local function correctWidth(newWidthForAnalyse)
  353.         width = math.max(width, newWidthForAnalyse)
  354.     end
  355.  
  356.     --Корректируем ширину
  357.     for i = 1, countOfObjects do
  358.         local objectType = string.lower(objects[i][1])
  359.        
  360.         if objectType == "centertext" then
  361.             correctWidth(unicode.len(objects[i][3]) + 2)
  362.         elseif objectType == "slider" then --!!!!!!!!!!!!!!!!!! ВОТ ТУТ НЕ ЗАБУДЬ ФИКСАНУТЬ
  363.             correctWidth(unicode.len(objects[i][7]..tostring(objects[i][5].." ")) + 2)
  364.         elseif objectType == "select" then
  365.             for j = 4, #objects[i] do
  366.                 correctWidth(unicode.len(objects[i][j]) + 2)
  367.             end
  368.         --elseif objectType == "selector" then
  369.            
  370.         --elseif objectType == "separator" then
  371.            
  372.         elseif objectType == "textfield" then
  373.             correctWidth(5)
  374.         elseif objectType == "wrappedtext" then
  375.             correctWidth(6)
  376.         elseif objectType == "button" then
  377.             --Корректируем ширину
  378.             local widthOfButtons = 0
  379.             local maxButton = 0
  380.             for j = 2, #objects[i] do
  381.                 maxButton = math.max(maxButton, unicode.len(objects[i][j][3]) + 2)
  382.             end
  383.             widthOfButtons = maxButton * #objects[i]
  384.             correctWidth(widthOfButtons)
  385.         elseif objectType == "switch" then
  386.             local dlina = unicode.len(objects[i][5]) + 2 + 10 + 4
  387.             correctWidth(dlina)
  388.         elseif objectType == "color" then
  389.             correctWidth(unicode.len(objects[i][2]) + 6)
  390.         end
  391.     end
  392.  
  393.     --Считаем высоту этой хуйни
  394.     local height = 0
  395.     for i = 1, countOfObjects do
  396.         local objectType = string.lower(objects[i][1])
  397.         if objectType == "select" then
  398.             height = height + (objectsHeights[objectType] * (#objects[i] - 3))
  399.         elseif objectType == "textfield" then
  400.             height = height + objects[i][2]
  401.         elseif objectType == "wrappedtext" then
  402.             --Заранее парсим текст перенесенный
  403.             objects[i].wrapped = string.wrap({objects[i][3]}, width - 4)
  404.             objects[i].height = #objects[i].wrapped
  405.             height = height + objects[i].height
  406.         else
  407.             height = height + objectsHeights[objectType]
  408.         end
  409.     end
  410.  
  411.     --Коорректируем стартовые координаты
  412.     x, y = ecs.correctStartCoords(x, y, width, height)
  413.     --Запоминаем инфу о том, что было нарисовано, если это необходимо
  414.     local oldPixels, oldBackground, oldForeground
  415.     if closeWindowAfter then
  416.         oldBackground = component.gpu.getBackground()
  417.         oldForeground = component.gpu.getForeground()
  418.         oldPixels = ecs.rememberOldPixels(x, y, x + width - 1, y + height - 1)
  419.     end
  420.     --Считаем все координаты объектов
  421.     objects[1].y = y
  422.     if countOfObjects > 1 then
  423.         for i = 2, countOfObjects do
  424.             local objectType = string.lower(objects[i - 1][1])
  425.             if objectType == "select" then
  426.                 objects[i].y = objects[i - 1].y + (objectsHeights[objectType] * (#objects[i - 1] - 3))
  427.             elseif objectType == "textfield" then
  428.                 objects[i].y = objects[i - 1].y + objects[i - 1][2]
  429.             elseif objectType == "wrappedtext" then
  430.                 objects[i].y = objects[i - 1].y + objects[i - 1].height
  431.             else
  432.                 objects[i].y = objects[i - 1].y + objectsHeights[objectType]
  433.             end
  434.         end
  435.     end
  436.  
  437.     --Объекты для тача
  438.     local obj = {}
  439.     local function newObj(class, name, ...)
  440.         obj[class] = obj[class] or {}
  441.         obj[class][name] = {...}
  442.     end
  443.  
  444.     --Отображение объекта по номеру
  445.     local function displayObject(number, active)
  446.         local objectType = string.lower(objects[number][1])
  447.                
  448.         if objectType == "centertext" then
  449.             local xPos = x + math.floor(width / 2 - unicode.len(objects[number][3]) / 2)
  450.             component.gpu.setForeground(objects[number][2])
  451.             component.gpu.setBackground(background)
  452.             component.gpu.set(xPos, objects[number].y, objects[number][3])
  453.        
  454.         elseif objectType == "input" then
  455.  
  456.             if active then
  457.                 --Рамочка
  458.                 ecs.border(x + 1, objects[number].y, width - 2, objectsHeights.input, background, objects[number][3])
  459.                 --Тестик
  460.                 objects[number][4] = ecs.inputText(x + 3, objects[number].y + 1, width - 6, "", background, objects[number][3], false, objects[number][5])
  461.             else
  462.                 --Рамочка
  463.                 ecs.border(x + 1, objects[number].y, width - 2, objectsHeights.input, background, objects[number][2])
  464.                 --Текстик
  465.                 component.gpu.set(x + 3, objects[number].y + 1, ecs.stringLimit("start", objects[number][4], width - 6))
  466.                 ecs.inputText(x + 3, objects[number].y + 1, width - 6, objects[number][4], background, objects[number][2], true, objects[number][5])
  467.             end
  468.  
  469.             newObj("Inputs", number, x + 1, objects[number].y, x + width - 2, objects[number].y + 2)
  470.  
  471.         elseif objectType == "slider" then
  472.             local widthOfSlider = width - 2
  473.             local xOfSlider = x + 1
  474.             local yOfSlider = objects[number].y + 1
  475.             local countOfSliderThings = objects[number][5] - objects[number][4]
  476.             local showSliderValue= objects[number][7]
  477.  
  478.             local dolya = widthOfSlider / countOfSliderThings
  479.             local position = math.floor(dolya * objects[number][6])
  480.             --Костыль
  481.             if (xOfSlider + position) > (xOfSlider + widthOfSlider - 1) then position = widthOfSlider - 2 end
  482.  
  483.             --Две линии
  484.             ecs.separator(xOfSlider, yOfSlider, position, background, objects[number][3])
  485.             ecs.separator(xOfSlider + position, yOfSlider, widthOfSlider - position, background, objects[number][2])
  486.             --Слудир
  487.             ecs.square(xOfSlider + position, yOfSlider, 2, 1, objects[number][3])
  488.  
  489.             --Текстик под слудиром
  490.             if showSliderValue then
  491.                 local text = showSliderValue .. tostring(objects[number][6]) .. (objects[number][8] or "")
  492.                 local textPos = (xOfSlider + widthOfSlider / 2 - unicode.len(text) / 2)
  493.                 ecs.square(x, yOfSlider + 1, width, 1, background)
  494.                 ecs.colorText(textPos, yOfSlider + 1, objects[number][2], text)
  495.             end
  496.  
  497.             newObj("Sliders", number, xOfSlider, yOfSlider, x + widthOfSlider, yOfSlider, dolya)
  498.  
  499.         elseif objectType == "select" then
  500.             local usualColor = objects[number][2]
  501.             local selectionColor = objects[number][3]
  502.  
  503.             objects[number].selectedData = objects[number].selectedData or 1
  504.  
  505.             local symbol = "?"
  506.             local yPos = objects[number].y
  507.             for i = 4, #objects[number] do
  508.                 --Коробка для галочки
  509.                 ecs.border(x + 1, yPos, 5, 3, background, usualColor)
  510.                 --Текст
  511.                 component.gpu.set(x + 7, yPos + 1, objects[number][i])
  512.                 --Галочка
  513.                 if objects[number].selectedData == (i - 3) then
  514.                     ecs.colorText(x + 3, yPos + 1, selectionColor, symbol)
  515.                 else
  516.                     component.gpu.set(x + 3, yPos + 1, "  ")
  517.                 end
  518.  
  519.                 obj["Selects"] = obj["Selects"] or {}
  520.                 obj["Selects"][number] = obj["Selects"][number] or {}
  521.                 obj["Selects"][number][i - 3] = { x + 1, yPos, x + width - 2, yPos + 2 }
  522.  
  523.                 yPos = yPos + objectsHeights.select
  524.             end
  525.  
  526.         elseif objectType == "selector" then
  527.             local borderColor = objects[number][2]
  528.             local arrowColor = objects[number][3]
  529.             local selectorWidth = width - 2
  530.             objects[number].selectedElement = objects[number].selectedElement or objects[number][4]
  531.  
  532.             local topLine = "-" .. string.rep("-", selectorWidth - 6) .. "T---¬"
  533.             local midLine = "¦" .. string.rep(" ", selectorWidth - 6) .. "¦   ¦"
  534.             local botLine = "L" .. string.rep("-", selectorWidth - 6) .. "+----"
  535.  
  536.             local yPos = objects[number].y
  537.  
  538.             local function bordak(borderColor)
  539.                 component.gpu.setBackground(background)
  540.                 component.gpu.setForeground(borderColor)
  541.                 component.gpu.set(x + 1, objects[number].y, topLine)
  542.                 component.gpu.set(x + 1, objects[number].y + 1, midLine)
  543.                 component.gpu.set(x + 1, objects[number].y + 2, botLine)
  544.                 component.gpu.set(x + 3, objects[number].y + 1, ecs.stringLimit("start", objects[number].selectedElement, width - 6))
  545.                 ecs.colorText(x + width - 4, objects[number].y + 1, arrowColor, "Ў")
  546.             end
  547.  
  548.             bordak(borderColor)
  549.        
  550.             --Выпадающий список, самый гемор, блядь
  551.             if active then
  552.                 local xPos, yPos = x + 1, objects[number].y + 3
  553.                 local spisokWidth = width - 2
  554.                 local countOfElements = #objects[number] - 3
  555.                 local spisokHeight = countOfElements + 1
  556.                 local oldPixels = ecs.rememberOldPixels( xPos, yPos, xPos + spisokWidth - 1, yPos + spisokHeight - 1)
  557.  
  558.                 local coords = {}
  559.  
  560.                 bordak(arrowColor)
  561.  
  562.                 --Рамку рисуем поверх фоника
  563.                 local topLine = "+"..string.rep("-", spisokWidth - 6).."+---+"
  564.                 local midLine = "¦"..string.rep(" ", spisokWidth - 2).."¦"
  565.                 local botLine = "L"..string.rep("-", selectorWidth - 2) .. "-"
  566.                 ecs.colorTextWithBack(xPos, yPos - 1, arrowColor, background, topLine)
  567.                 for i = 1, spisokHeight - 1 do
  568.                     component.gpu.set(xPos, yPos + i - 1, midLine)
  569.                 end
  570.                 component.gpu.set(xPos, yPos + spisokHeight - 1, botLine)
  571.  
  572.                 --Элементы рисуем
  573.                 xPos = xPos + 2
  574.                 for i = 1, countOfElements do
  575.                     ecs.colorText(xPos, yPos, borderColor, ecs.stringLimit("start", objects[number][i + 3], spisokWidth - 4))
  576.                     coords[i] = {xPos - 1, yPos, xPos + spisokWidth - 4, yPos}
  577.                     yPos = yPos + 1
  578.                 end
  579.  
  580.                 --Обработка
  581.                 local exit
  582.                 while true do
  583.                     if exit then break end
  584.                     local e = {event.pull()}
  585.                     if e[1] == "touch" then
  586.                         for i = 1, #coords do
  587.                             if ecs.clickedAtArea(e[3], e[4], coords[i][1], coords[i][2], coords[i][3], coords[i][4]) then
  588.                                 ecs.square(coords[i][1], coords[i][2], spisokWidth - 2, 1, ecs.colors.blue)
  589.                                 ecs.colorText(coords[i][1] + 1, coords[i][2], 0xffffff, objects[number][i + 3])
  590.                                 os.sleep(0.3)
  591.                                 objects[number].selectedElement = objects[number][i + 3]
  592.                                 exit = true
  593.                                 break
  594.                             end
  595.                         end
  596.                     end
  597.                 end
  598.  
  599.                 ecs.drawOldPixels(oldPixels)
  600.             end
  601.  
  602.             newObj("Selectors", number, x + 1, objects[number].y, x + width - 2, objects[number].y + 2)
  603.  
  604.         elseif objectType == "separator" then
  605.             ecs.separator(x, objects[number].y, width, background, objects[number][2])
  606.        
  607.         elseif objectType == "textfield" then
  608.             newObj("TextFields", number, x + 1, objects[number].y, x + width - 2, objects[number].y + objects[number][2] - 1)
  609.             if not objects[number].strings then objects[number].strings = string.wrap({objects[number][7]}, width - 3) end
  610.             objects[number].displayFrom = objects[number].displayFrom or 1
  611.             ecs.textField(x, objects[number].y, width, objects[number][2], objects[number].strings, objects[number].displayFrom, objects[number][3], objects[number][4], objects[number][5], objects[number][6])
  612.        
  613.         elseif objectType == "wrappedtext" then
  614.             component.gpu.setBackground(background)
  615.             component.gpu.setForeground(objects[number][2])
  616.             for i = 1, #objects[number].wrapped do
  617.                 component.gpu.set(x + 2, objects[number].y + i - 1, objects[number].wrapped[i])
  618.             end
  619.  
  620.         elseif objectType == "button" then
  621.  
  622.             obj["MultiButtons"] = obj["MultiButtons"] or {}
  623.             obj["MultiButtons"][number] = {}
  624.  
  625.             local widthOfButton = math.floor(width / (#objects[number] - 1))
  626.  
  627.             local xPos, yPos = x, objects[number].y
  628.             for i = 1, #objects[number] do
  629.                 if type(objects[number][i]) == "table" then
  630.                     local x1, y1, x2, y2 = ecs.drawButton(xPos, yPos, widthOfButton, 3, objects[number][i][3], objects[number][i][1], objects[number][i][2])
  631.                     table.insert(obj["MultiButtons"][number], {x1, y1, x2, y2, widthOfButton})
  632.                     xPos = x2 + 1
  633.  
  634.                     if i == #objects[number] then
  635.                         ecs.square(xPos, yPos, x + width - xPos, 3, objects[number][i][1])
  636.                         obj["MultiButtons"][number][i - 1][5] = obj["MultiButtons"][number][i - 1][5] + x + width - xPos
  637.                     end
  638.  
  639.                     x1, y1, x2, y2 = nil, nil, nil, nil
  640.                 end
  641.             end
  642.  
  643.         elseif objectType == "switch" then
  644.  
  645.             local xPos, yPos = x + 2, objects[number].y
  646.             local activeColor, passiveColor, textColor, text, state = objects[number][2], objects[number][3], objects[number][4], objects[number][5], objects[number][6]
  647.             local switchWidth = 8
  648.             ecs.colorTextWithBack(xPos, yPos, textColor, background, text)
  649.  
  650.             xPos = x + width - switchWidth - 2
  651.             if state then
  652.                 ecs.square(xPos, yPos, switchWidth, 1, activeColor)
  653.                 ecs.square(xPos + switchWidth - 2, yPos, 2, 1, passiveColor)
  654.                 --ecs.colorTextWithBack(xPos + 4, yPos, passiveColor, activeColor, "ON")
  655.             else
  656.                 ecs.square(xPos, yPos, switchWidth, 1, passiveColor - 0x444444)
  657.                 ecs.square(xPos, yPos, 2, 1, passiveColor)
  658.                 --ecs.colorTextWithBack(xPos + 4, yPos, passiveColor, passiveColor - 0x444444, "OFF")
  659.             end
  660.             newObj("Switches", number, xPos, yPos, xPos + switchWidth - 1, yPos)
  661.  
  662.         elseif objectType == "color" then
  663.             local xPos, yPos = x + 1, objects[number].y
  664.             local blendedColor = require("colorlib").alphaBlend(objects[number][3], 0xFFFFFF, 180)
  665.             local w = width - 2
  666.  
  667.             ecs.colorTextWithBack(xPos, yPos + 2, blendedColor, background, string.rep("-", w))
  668.             ecs.colorText(xPos, yPos, objects[number][3], string.rep("-", w))
  669.             ecs.square(xPos, yPos + 1, w, 1, objects[number][3])       
  670.  
  671.             ecs.colorText(xPos + 1, yPos + 1, 0xffffff - objects[number][3], objects[number][2])
  672.             newObj("Colors", number, xPos, yPos, x + width - 2, yPos + 2)
  673.         end
  674.     end
  675.  
  676.     --Отображение всех объектов
  677.     local function displayAllObjects()
  678.         for i = 1, countOfObjects do
  679.             displayObject(i)
  680.         end
  681.     end
  682.  
  683.     --Подготовить массив возвращаемый
  684.     local function getReturn()
  685.         local massiv = {}
  686.  
  687.         for i = 1, countOfObjects do
  688.             local type = string.lower(objects[i][1])
  689.  
  690.             if type == "button" then
  691.                 table.insert(massiv, pressedButton)
  692.             elseif type == "input" then
  693.                 table.insert(massiv, objects[i][4])
  694.             elseif type == "select" then
  695.                 table.insert(massiv, objects[i][objects[i].selectedData + 3])
  696.             elseif type == "selector" then
  697.                 table.insert(massiv, objects[i].selectedElement)
  698.             elseif type == "slider" then
  699.                 table.insert(massiv, objects[i][6])
  700.             elseif type == "switch" then
  701.                 table.insert(massiv, objects[i][6])
  702.             elseif type == "color" then
  703.                 table.insert(massiv, objects[i][3])
  704.             else
  705.                 table.insert(massiv, nil)
  706.             end
  707.         end
  708.  
  709.         return massiv
  710.     end
  711.  
  712.     local function redrawBeforeClose()
  713.         if closeWindowAfter then
  714.             ecs.drawOldPixels(oldPixels)
  715.             component.gpu.setBackground(oldBackground)
  716.             component.gpu.setForeground(oldForeground)
  717.         end
  718.     end
  719.  
  720.     --Рисуем окно
  721.     ecs.square(x, y, width, height, background)
  722.     displayAllObjects()
  723.  
  724.     while true do
  725.         local e = {event.pull()}
  726.         if e[1] == "touch" or e[1] == "drag" then
  727.  
  728.             --Анализируем клик на кнопки
  729.             if obj["MultiButtons"] then
  730.                 for key in pairs(obj["MultiButtons"]) do
  731.                     for i = 1, #obj["MultiButtons"][key] do
  732.                         if ecs.clickedAtArea(e[3], e[4], obj["MultiButtons"][key][i][1], obj["MultiButtons"][key][i][2], obj["MultiButtons"][key][i][3], obj["MultiButtons"][key][i][4]) then
  733.                             ecs.drawButton(obj["MultiButtons"][key][i][1], obj["MultiButtons"][key][i][2], obj["MultiButtons"][key][i][5], 3, objects[key][i + 1][3], objects[key][i + 1][2], objects[key][i + 1][1])
  734.                             os.sleep(0.3)
  735.                             pressedButton = objects[key][i + 1][3]
  736.                             redrawBeforeClose()
  737.                             return getReturn()
  738.                         end
  739.                     end
  740.                 end
  741.             end
  742.  
  743.             --А теперь клик на инпуты!
  744.             if obj["Inputs"] then
  745.                 for key in pairs(obj["Inputs"]) do
  746.                     if ecs.clickedAtArea(e[3], e[4], obj["Inputs"][key][1], obj["Inputs"][key][2], obj["Inputs"][key][3], obj["Inputs"][key][4]) then
  747.                         displayObject(key, true)
  748.                         displayObject(key)
  749.                         break
  750.                     end
  751.                 end
  752.             end
  753.  
  754.             --А теперь галочковыбор!
  755.             if obj["Selects"] then
  756.                 for key in pairs(obj["Selects"]) do
  757.                     for i in pairs(obj["Selects"][key]) do
  758.                         if ecs.clickedAtArea(e[3], e[4], obj["Selects"][key][i][1], obj["Selects"][key][i][2], obj["Selects"][key][i][3], obj["Selects"][key][i][4]) then
  759.                             objects[key].selectedData = i
  760.                             displayObject(key)
  761.                             break
  762.                         end
  763.                     end
  764.                 end
  765.             end
  766.  
  767.             --Хм, а вот и селектор подъехал!
  768.             if obj["Selectors"] then
  769.                 for key in pairs(obj["Selectors"]) do
  770.                     if ecs.clickedAtArea(e[3], e[4], obj["Selectors"][key][1], obj["Selectors"][key][2], obj["Selectors"][key][3], obj["Selectors"][key][4]) then
  771.                         displayObject(key, true)
  772.                         displayObject(key)
  773.                         break
  774.                     end
  775.                 end
  776.             end
  777.  
  778.             --Слайдеры, епта! "Потный матан", все делы
  779.             if obj["Sliders"] then
  780.                 for key in pairs(obj["Sliders"]) do
  781.                     if ecs.clickedAtArea(e[3], e[4], obj["Sliders"][key][1], obj["Sliders"][key][2], obj["Sliders"][key][3], obj["Sliders"][key][4]) then
  782.                         local xOfSlider, dolya = obj["Sliders"][key][1], obj["Sliders"][key][5]
  783.                         local currentPixels = e[3] - xOfSlider
  784.                         local currentValue = math.floor(currentPixels / dolya)
  785.                         --Костыль
  786.                         if e[3] == obj["Sliders"][key][3] then currentValue = objects[key][5] end
  787.                         objects[key][6] = currentValue or objects[key][6]
  788.                         displayObject(key)
  789.                         break
  790.                     end
  791.                 end
  792.             end
  793.  
  794.             if obj["Switches"] then
  795.                 for key in pairs(obj["Switches"]) do
  796.                     if ecs.clickedAtArea(e[3], e[4], obj["Switches"][key][1], obj["Switches"][key][2], obj["Switches"][key][3], obj["Switches"][key][4]) then
  797.                         objects[key][6] = not objects[key][6]
  798.                         displayObject(key)
  799.                         break
  800.                     end
  801.                 end
  802.             end
  803.  
  804.             if obj["Colors"] then
  805.                 for key in pairs(obj["Colors"]) do
  806.                     if ecs.clickedAtArea(e[3], e[4], obj["Colors"][key][1], obj["Colors"][key][2], obj["Colors"][key][3], obj["Colors"][key][4]) then
  807.                         local oldColor = objects[key][3]
  808.                         objects[key][3] = 0xffffff - objects[key][3]
  809.                         displayObject(key)
  810.                         os.sleep(0.3)
  811.                         objects[key][3] = oldColor
  812.                         displayObject(key)
  813.                         local color = loadfile("lib/palette.lua")().draw("auto", "auto", objects[key][3])
  814.                         objects[key][3] = color or oldColor
  815.                         displayObject(key)
  816.                         break
  817.                     end
  818.                 end
  819.             end
  820.  
  821.         elseif e[1] == "scroll" then
  822.             if obj["TextFields"] then
  823.                 for key in pairs(obj["TextFields"]) do
  824.                     if ecs.clickedAtArea(e[3], e[4], obj["TextFields"][key][1], obj["TextFields"][key][2], obj["TextFields"][key][3], obj["TextFields"][key][4]) then
  825.                         if e[5] == 1 then
  826.                             if objects[key].displayFrom > 1 then objects[key].displayFrom = objects[key].displayFrom - 1; displayObject(key) end
  827.                         else
  828.                             if objects[key].displayFrom < #objects[key].strings then objects[key].displayFrom = objects[key].displayFrom + 1; displayObject(key) end
  829.                         end
  830.                     end
  831.                 end
  832.             end
  833.         elseif e[1] == "key_down" then
  834.             if e[4] == 28 then
  835.                 redrawBeforeClose()
  836.                 return getReturn()
  837.             end
  838.         end
  839.     end
  840. end
  841.  
  842. return ecs
Add Comment
Please, Sign In to add comment