CharlyZM

Untitled

Feb 10th, 2023
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 112.06 KB | None | 0 0
  1.  
  2. -- Адаптивная загрузка необходимых библиотек и компонентов
  3. local libraries = {
  4. advancedLua = "advancedLua",
  5. component = "component",
  6. term = "term",
  7. unicode = "unicode",
  8. event = "event",
  9. fs = "filesystem",
  10. shell = "shell",
  11. keyboard = "keyboard",
  12. computer = "computer",
  13. serialization = "serialization",
  14. }
  15.  
  16. for library in pairs(libraries) do if not _G[library] then _G[library] = require(libraries[library]) end end; libraries = nil
  17. _G.gpu = component.gpu
  18.  
  19. local ecs = {}
  20.  
  21. ----------------------------------------------------------------------------------------------------
  22.  
  23. ecs.windowColors = {
  24. background = 0xeeeeee,
  25. usualText = 0x444444,
  26. subText = 0x888888,
  27. tab = 0xaaaaaa,
  28. title = 0xffffff,
  29. shadow = 0x444444,
  30. }
  31.  
  32. ecs.colors = {
  33. white = 0xffffff,
  34. orange = 0xF2B233,
  35. magenta = 0xE57FD8,
  36. lightBlue = 0x99B2F2,
  37. yellow = 0xDEDE6C,
  38. lime = 0x7FCC19,
  39. pink = 0xF2B2CC,
  40. gray = 0x4C4C4C,
  41. lightGray = 0x999999,
  42. cyan = 0x4C99B2,
  43. purple = 0xB266E5,
  44. blue = 0x3366CC,
  45. brown = 0x7F664C,
  46. green = 0x57A64E,
  47. red = 0xCC4C4C,
  48. black = 0x000000,
  49. ["0"] = 0xffffff,
  50. ["1"] = 0xF2B233,
  51. ["2"] = 0xE57FD8,
  52. ["3"] = 0x99B2F2,
  53. ["4"] = 0xDEDE6C,
  54. ["5"] = 0x7FCC19,
  55. ["6"] = 0xF2B2CC,
  56. ["7"] = 0x4C4C4C,
  57. ["8"] = 0x999999,
  58. ["9"] = 0x4C99B2,
  59. ["a"] = 0xB266E5,
  60. ["b"] = 0x3366CC,
  61. ["c"] = 0x7F664C,
  62. ["d"] = 0x57A64E,
  63. ["e"] = 0xCC4C4C,
  64. ["f"] = 0x000000
  65. }
  66.  
  67. ----------------------------------------------------------------------------------------------------
  68.  
  69. --Адекватный запрос к веб-серверу вместо стандартного Internet API, бросающего stderr, когда ему вздумается
  70. function ecs.internetRequest(url)
  71. local success, response = pcall(component.internet.request, url)
  72. if success then
  73. local responseData = ""
  74. while true do
  75. local data, responseChunk = response.read()
  76. if data then
  77. responseData = responseData .. data
  78. else
  79. if responseChunk then
  80. return false, responseChunk
  81. else
  82. return true, responseData
  83. end
  84. end
  85. end
  86. else
  87. return false, reason
  88. end
  89. end
  90.  
  91. --Загрузка файла с инета
  92. function ecs.getFileFromUrl(url, path)
  93. local success, response = ecs.internetRequest(url)
  94. if success then
  95. fs.makeDirectory(fs.path(path) or "")
  96. local file = io.open(path, "w")
  97. file:write(response)
  98. file:close()
  99. else
  100. ecs.error("Could not connect to to URL address \"" .. url .. "\"")
  101. return
  102. end
  103. end
  104.  
  105. --Отключение принудительного завершения программ
  106. function ecs.disableInterrupting()
  107. _G.eventInterruptBackup = package.loaded.event.shouldInterrupt
  108. _G.eventSoftInterruptBackup = package.loaded.event.shouldSoftInterrupt
  109.  
  110. package.loaded.event.shouldInterrupt = function () return false end
  111. package.loaded.event.shouldSoftInterrupt = function () return false end
  112. end
  113.  
  114. --Включение принудительного завершения программ
  115. function ecs.enableInterrupting()
  116. if _G.eventInterruptBackup then
  117. package.loaded.event.shouldInterrupt = _G.eventInterruptBackup
  118. package.loaded.event.shouldSoftInterrupt = _G.eventSoftInterruptBackup
  119. else
  120. error("Cant't enable interrupting beacause of it's already enabled.")
  121. end
  122. end
  123.  
  124. function ecs.getScaledResolution(scale, debug)
  125. --Базовая коррекция масштаба, чтобы всякие умники не писали своими погаными ручонками, чего не следует
  126. if scale > 1 then
  127. scale = 1
  128. elseif scale < 0.1 then
  129. scale = 0.1
  130. end
  131.  
  132. --Просчет монитора в псевдопикселях - забей, даже объяснять не буду, работает как часы
  133. local function calculateAspect(screens)
  134. local abc = 12
  135.  
  136. if screens == 2 then
  137. abc = 28
  138. elseif screens > 2 then
  139. abc = 28 + (screens - 2) * 16
  140. end
  141.  
  142. return abc
  143. end
  144.  
  145. --Рассчитываем пропорцию монитора в псевдопикселях
  146. local xScreens, yScreens = component.proxy(component.gpu.getScreen()).getAspectRatio()
  147. local xPixels, yPixels = calculateAspect(xScreens), calculateAspect(yScreens)
  148. local proportion = xPixels / yPixels
  149.  
  150. --Получаем максимально возможное разрешение данной видеокарты
  151. local xMax, yMax = component.gpu.maxResolution()
  152.  
  153. --Получаем теоретическое максимальное разрешение монитора с учетом его пропорции, но без учета лимита видеокарты
  154. local newWidth, newHeight
  155. if proportion >= 1 then
  156. newWidth = xMax
  157. newHeight = math.floor(newWidth / proportion / 2)
  158. else
  159. newHeight = yMax
  160. newWidth = math.floor(newHeight * proportion * 2)
  161. end
  162.  
  163. --Получаем оптимальное разрешение для данного монитора с поддержкой видеокарты
  164. local optimalNewWidth, optimalNewHeight = newWidth, newHeight
  165.  
  166. if optimalNewWidth > xMax then
  167. local difference = newWidth / xMax
  168. optimalNewWidth = xMax
  169. optimalNewHeight = math.ceil(newHeight / difference)
  170. end
  171.  
  172. if optimalNewHeight > yMax then
  173. local difference = newHeight / yMax
  174. optimalNewHeight = yMax
  175. optimalNewWidth = math.ceil(newWidth / difference)
  176. end
  177.  
  178. --Корректируем идеальное разрешение по заданному масштабу
  179. local finalNewWidth, finalNewHeight = math.floor(optimalNewWidth * scale), math.floor(optimalNewHeight * scale)
  180.  
  181. --Выводим инфу, если нужно
  182. if debug then
  183. print(" ")
  184. print("Максимальное разрешение: "..xMax.."x"..yMax)
  185. print("Пропорция монитора: "..xPixels.."x"..yPixels)
  186. print("Коэффициент пропорции: "..proportion)
  187. print(" ")
  188. print("Теоретическое разрешение: "..newWidth.."x"..newHeight)
  189. print("Оптимизированное разрешение: "..optimalNewWidth.."x"..optimalNewHeight)
  190. print(" ")
  191. print("Новое разрешение: "..finalNewWidth.."x"..finalNewHeight)
  192. print(" ")
  193. end
  194.  
  195. return finalNewWidth, finalNewHeight
  196. end
  197.  
  198. --Установка масштаба монитора
  199. function ecs.setScale(scale, debug)
  200. --Устанавливаем выбранное разрешение
  201. component.gpu.setResolution(ecs.getScaledResolution(scale, debug))
  202. end
  203.  
  204. function ecs.rebindGPU(address)
  205. component.gpu.bind(address)
  206. end
  207.  
  208. --Получаем всю инфу об оперативку в килобайтах
  209. function ecs.getInfoAboutRAM()
  210. local free = math.floor(computer.freeMemory() / 1024)
  211. local total = math.floor(computer.totalMemory() / 1024)
  212. local used = total - free
  213.  
  214. return free, total, used
  215. end
  216.  
  217. --Получить информацию о жестких дисках
  218. function ecs.getHDDs()
  219. local candidates = {}
  220. for address in component.list("filesystem") do
  221. local proxy = component.proxy(address)
  222. if proxy.address ~= computer.tmpAddress() and proxy.getLabel() ~= "internet" then
  223. local isFloppy, spaceTotal = false, math.floor(proxy.spaceTotal() / 1024)
  224. if spaceTotal < 600 then isFloppy = true end
  225. table.insert(candidates, {
  226. ["spaceTotal"] = spaceTotal,
  227. ["spaceUsed"] = math.floor(proxy.spaceUsed() / 1024),
  228. ["label"] = proxy.getLabel(),
  229. ["address"] = proxy.address,
  230. ["isReadOnly"] = proxy.isReadOnly(),
  231. ["isFloppy"] = isFloppy,
  232. })
  233. end
  234. end
  235. return candidates
  236. end
  237.  
  238. --Форматировать диск
  239. function ecs.formatHDD(address)
  240. local proxy = component.proxy(address)
  241. local list = proxy.list("")
  242. ecs.info("auto", "auto", "", "Formatting disk...")
  243. for _, file in pairs(list) do
  244. if type(file) == "string" then
  245. if not proxy.isReadOnly(file) then proxy.remove(file) end
  246. end
  247. end
  248. list = nil
  249. end
  250.  
  251. --Установить имя жесткого диска
  252. function ecs.setHDDLabel(address, label)
  253. local proxy = component.proxy(address)
  254. proxy.setLabel(label or "Untitled")
  255. end
  256.  
  257. --Найти монтированный путь конкретного адреса диска
  258. function ecs.findMount(address)
  259. for fs1, path in fs.mounts() do
  260. if fs1.address == component.get(address) then
  261. return path
  262. end
  263. end
  264. end
  265.  
  266. function ecs.getArraySize(array)
  267. local size = 0
  268. for key in pairs(array) do
  269. size = size + 1
  270. end
  271. return size
  272. end
  273.  
  274. --Скопировать файлы с одного диска на другой с заменой
  275. function ecs.duplicateFileSystem(fromAddress, toAddress)
  276. local source, destination = ecs.findMount(fromAddress), ecs.findMount(toAddress)
  277. ecs.info("auto", "auto", "", "Copying file system...")
  278. shell.execute("bin/cp -rx "..source.."* "..destination)
  279. end
  280.  
  281. --Загрузка файла с пастебина
  282. function ecs.getFromPastebin(paste, path)
  283. local url = "http://pastebin.com/raw.php?i=" .. paste
  284. ecs.getFileFromUrl(url, path)
  285. end
  286.  
  287. --Загрузка файла с гитхаба
  288. function ecs.getFromGitHub(url, path)
  289. url = "https://raw.githubusercontent.com/" .. url
  290. ecs.getFileFromUrl(url, path)
  291. end
  292.  
  293. --Загрузить ОС-приложение
  294. function ecs.getOSApplication(application)
  295. --Если это приложение
  296. if application.type == "Application" then
  297. --Удаляем приложение, если оно уже существовало и создаем все нужные папочки
  298. fs.remove(application.name .. ".app")
  299. fs.makeDirectory(application.name .. ".app/Resources")
  300.  
  301. --Загружаем основной исполняемый файл и иконку
  302. ecs.getFromGitHub(application.url, application.name .. ".app/" .. fs.name(application.name .. ".lua"))
  303. ecs.getFromGitHub(application.icon, application.name .. ".app/Resources/Icon.pic")
  304.  
  305. --Если есть ресурсы, то загружаем ресурсы
  306. if application.resources then
  307. for i = 1, #application.resources do
  308. ecs.getFromGitHub(application.resources[i].url, application.name .. ".app/Resources/" .. application.resources[i].name)
  309. end
  310. end
  311.  
  312. --Если есть файл "о программе", то грузим и его
  313. if application.about then
  314. ecs.getFromGitHub(application.about .. _G.OSSettings.language .. ".txt", application.name .. ".app/Resources/About/" .. _G.OSSettings.language .. ".txt")
  315. end
  316.  
  317. --Если имеется режим создания ярлыка, то создаем его
  318. if application.createShortcut then
  319. local desktopPath = "MineOS/Desktop/"
  320. local dockPath = "MineOS/System/OS/Dock/"
  321.  
  322. if application.createShortcut == "dock" then
  323. ecs.createShortCut(dockPath .. fs.name(application.name) .. ".lnk", application.name .. ".app")
  324. else
  325. ecs.createShortCut(desktopPath .. fs.name(application.name) .. ".lnk", application.name .. ".app")
  326. end
  327. end
  328.  
  329. --Если тип = другой, чужой, а мб и свой пастебин
  330. elseif application.type == "Pastebin" then
  331. ecs.getFromPastebin(application.url, application.name)
  332.  
  333. --Если просто какой-то скрипт
  334. elseif application.type == "Script" or application.type == "Library" or application.type == "Icon" or application.type == "Wallpaper" then
  335. ecs.getFromGitHub(application.url, application.name)
  336.  
  337. --А если ваще какая-то абстрактная хуйня, либо ссылка на веб, то загружаем по УРЛ-ке
  338. else
  339. ecs.getFileFromUrl(application.url, application.name)
  340. end
  341. end
  342.  
  343. --Получить список приложений, которые требуется обновить
  344. function ecs.getAppsToUpdate(debug)
  345. --Задаем стартовые пути
  346. local pathToApplicationsFile = "MineOS/System/OS/Applications.txt"
  347. local pathToSecondApplicationsFile = "MineOS/System/OS/Applications2.txt"
  348. --Путь к файл-листу на пастебине
  349. local paste = "3j2x4dDn"
  350. --Выводим инфу
  351. local oldPixels
  352. if debug then oldPixels = ecs.info("auto", "auto", " ", "Checking for updates...") end
  353. --Получаем свеженький файл
  354. ecs.getFromPastebin(paste, pathToSecondApplicationsFile)
  355. --Читаем оба файла
  356. local file = io.open(pathToApplicationsFile, "r")
  357. local applications = serialization.unserialize(file:read("*a"))
  358. file:close()
  359. --И второй
  360. file = io.open(pathToSecondApplicationsFile, "r")
  361. local applications2 = serialization.unserialize(file:read("*a"))
  362. file:close()
  363.  
  364. local countOfUpdates = 0
  365.  
  366. --Просматриваем свеженький файлик и анализируем, че в нем нового, все старое удаляем
  367. local i = 1
  368. while true do
  369. --Разрыв цикла
  370. if i > #applications2 then break end
  371. --Новая версия файла
  372. local newVersion, oldVersion = applications2[i].version, 0
  373. --Получаем старую версию этого файла
  374. for j = 1, #applications do
  375. if applications2[i].name == applications[j].name then
  376. oldVersion = applications[j].version or 0
  377. break
  378. end
  379. end
  380. --Если новая версия новее, чем старая, то добавить в массив то, что нужно обновить
  381. if newVersion > oldVersion then
  382. applications2[i].needToUpdate = true
  383. countOfUpdates = countOfUpdates + 1
  384. end
  385.  
  386. i = i + 1
  387. end
  388. --Если чет рисовалось, то стереть на хер
  389. if oldPixels then ecs.drawOldPixels(oldPixels) end
  390. --Возвращаем массив с тем, че нужно обновить и просто старый аппликашнс на всякий случай
  391. return applications2, countOfUpdates
  392. end
  393.  
  394. --Сделать строку пригодной для отображения в ОпенКомпах
  395. --Заменяет табсы на пробелы и виндовый возврат каретки на человеческий UNIX-овский
  396. function ecs.stringOptimize(sto4ka, indentatonWidth)
  397. sto4ka = string.gsub(sto4ka, "\r\n", "\n")
  398. sto4ka = string.gsub(sto4ka, " ", string.rep(" ", indentatonWidth or 2))
  399. return stro4ka
  400. end
  401.  
  402. --ИЗ ДЕСЯТИЧНОЙ В ШЕСТНАДЦАТИРИЧНУЮ
  403. function ecs.decToBase(IN,BASE)
  404. local hexCode = "0123456789ABCDEFGHIJKLMNOPQRSTUVW"
  405. OUT = ""
  406. local ostatok = 0
  407. while IN>0 do
  408. ostatok = math.fmod(IN,BASE) + 1
  409. IN = math.floor(IN/BASE)
  410. OUT = string.sub(hexCode,ostatok,ostatok)..OUT
  411. end
  412. if #OUT == 1 then OUT = "0"..OUT end
  413. if OUT == "" then OUT = "00" end
  414. return OUT
  415. end
  416.  
  417. --Правильное конвертирование HEX-переменной в строковую
  418. function ecs.HEXtoString(color, bitCount, withNull)
  419. local stro4ka = string.format("%X",color)
  420. local sStro4ka = unicode.len(stro4ka)
  421. if sStro4ka < bitCount then
  422. stro4ka = string.rep("0", bitCount - sStro4ka) .. stro4ka
  423. end
  424. sStro4ka = nil
  425. if withNull then return "0x"..stro4ka else return stro4ka end
  426. end
  427.  
  428. --КЛИКНУЛИ ЛИ В ЗОНУ
  429. function ecs.clickedAtArea(x,y,sx,sy,ex,ey)
  430. if (x >= sx) and (x <= ex) and (y >= sy) and (y <= ey) then return true end
  431. return false
  432. end
  433.  
  434. --Заливка всего экрана указанным цветом
  435. function ecs.clearScreen(color)
  436. if color then component.gpu.setBackground(color) end
  437. term.clear()
  438. end
  439.  
  440. --Установка пикселя нужного цвета
  441. function ecs.setPixel(x,y,color)
  442. component.gpu.setBackground(color)
  443. component.gpu.set(x,y," ")
  444. end
  445.  
  446. --Простая установка цветов в одну строку, ибо я ленивый
  447. function ecs.setColor(background, foreground)
  448. component.gpu.setBackground(background)
  449. component.gpu.setForeground(foreground)
  450. end
  451.  
  452. --Цветной текст
  453. function ecs.colorText(x,y,textColor,text)
  454. component.gpu.setForeground(textColor)
  455. component.gpu.set(x,y,text)
  456. end
  457.  
  458. --Цветной текст с жопкой!
  459. function ecs.colorTextWithBack(x,y,textColor,backColor,text)
  460. component.gpu.setForeground(textColor)
  461. component.gpu.setBackground(backColor)
  462. component.gpu.set(x,y,text)
  463. end
  464.  
  465. --Инверсия цвета
  466. function ecs.invertColor(color)
  467. return 0xffffff - color
  468. end
  469.  
  470. --Адаптивный текст, подстраивающийся под фон
  471. function ecs.adaptiveText(x,y,text,textColor)
  472. component.gpu.setForeground(textColor)
  473. x = x - 1
  474. for i=1,unicode.len(text) do
  475. local info = {component.gpu.get(x+i,y)}
  476. component.gpu.setBackground(info[3])
  477. component.gpu.set(x+i,y,unicode.sub(text,i,i))
  478. end
  479. end
  480.  
  481. --Костыльная замена обычному string.find()
  482. --Работает медленнее, но хотя бы поддерживает юникод
  483. function unicode.find(str, pattern, init, plain)
  484. if init then
  485. if init < 0 then
  486. init = -#unicode.sub(str,init)
  487. elseif init > 0 then
  488. init = #unicode.sub(str,1,init-1)+1
  489. end
  490. end
  491.  
  492. a, b = string.find(str, pattern, init, plain)
  493.  
  494. if a then
  495. local ap,bp = str:sub(1,a-1), str:sub(a,b)
  496. a = unicode.len(ap)+1
  497. b = a + unicode.len(bp)-1
  498. return a,b
  499. else
  500. return a
  501. end
  502. end
  503.  
  504. --Умный текст по аналогии с майнчатовским. Ставишь символ параграфа, указываешь хуйню - и хуякс! Работает!
  505. function ecs.smartText(x, y, text)
  506. local sText = unicode.len(text)
  507. local specialSymbol = "В§"
  508. --Разбираем по кусочкам строку и получаем цвета
  509. local massiv = {}
  510. local iterator = 1
  511. local currentColor = component.gpu.getForeground()
  512. while iterator <= sText do
  513. local symbol = unicode.sub(text, iterator, iterator)
  514. if symbol == specialSymbol then
  515. currentColor = ecs.colors[unicode.sub(text, iterator + 1, iterator + 1) or "f"]
  516. iterator = iterator + 1
  517. else
  518. table.insert(massiv, {symbol, currentColor})
  519. end
  520. symbol = nil
  521. iterator = iterator + 1
  522. end
  523. x = x - 1
  524. for i = 1, #massiv do
  525. if currentColor ~= massiv[i][2] then currentColor = massiv[i][2]; component.gpu.setForeground(massiv[i][2]) end
  526. component.gpu.set(x + i, y, massiv[i][1])
  527. end
  528. end
  529.  
  530. --Аналог умного текста, но использующий HEX-цвета для кодировки
  531. function ecs.formattedText(x, y, text, limit)
  532. --Ограничение длины строки
  533. limit = limit or math.huge
  534. --Стартовая позиция курсора для отрисовки
  535. local xPos = x
  536. --Создаем массив символов данной строки
  537. local symbols = {}
  538. for i = 1, unicode.len(text) do table.insert(symbols, unicode.sub(text, i, i)) end
  539. --Перебираем все символы строки, пока не переберем все или не достигнем указанного лимита
  540. local i = 1
  541. while i <= #symbols and i <= limit do
  542. --Если находим символ параграфа, то
  543. if symbols[i] == "В§" then
  544. --Меняем цвет текста на указанный
  545. component.gpu.setForeground(tonumber("0x" .. symbols[i+1] .. symbols[i+2] .. symbols[i+3] .. symbols[i+4] .. symbols[i+5] .. symbols[i+6]))
  546. --Увеличиваем лимит на 7, т.к.
  547. limit = limit + 7
  548. --Сдвигаем итератор цикла на 7
  549. i = i + 7
  550. end
  551. --Рисуем символ на нужной позиции
  552. component.gpu.set(xPos, y, symbols[i])
  553. --Увеличиваем позицию курсора и итератор на 1
  554. xPos = xPos + 1
  555. i = i + 1
  556. end
  557. end
  558.  
  559. --Инвертированный текст на основе цвета фона
  560. function ecs.invertedText(x,y,symbol)
  561. local info = {component.gpu.get(x,y)}
  562. ecs.adaptiveText(x,y,symbol,ecs.invertColor(info[3]))
  563. end
  564.  
  565. --Адаптивное округление числа
  566. function ecs.adaptiveRound(chislo)
  567. local celaya,drobnaya = math.modf(chislo)
  568. if drobnaya >= 0.5 then
  569. return (celaya + 1)
  570. else
  571. return celaya
  572. end
  573. end
  574.  
  575. --Округление до опред. кол-ва знаков после запятой
  576. function ecs.round(num, idp)
  577. local mult = 10^(idp or 0)
  578. return math.floor(num * mult + 0.5) / mult
  579. end
  580.  
  581. --Обычный квадрат указанного цвета
  582. function ecs.square(x,y,width,height,color)
  583. component.gpu.setBackground(color)
  584. component.gpu.fill(x,y,width,height," ")
  585. end
  586.  
  587. --Юникодовская рамка
  588. function ecs.border(x, y, width, height, back, fore)
  589. local stringUp = "в”Њ"..string.rep("в”Ђ", width - 2).."в”ђ"
  590. local stringDown = "└"..string.rep("─", width - 2).."┘"
  591. component.gpu.setForeground(fore)
  592. component.gpu.setBackground(back)
  593. component.gpu.set(x, y, stringUp)
  594. component.gpu.set(x, y + height - 1, stringDown)
  595.  
  596. local yPos = 1
  597. for i = 1, (height - 2) do
  598. component.gpu.set(x, y + yPos, "в”‚")
  599. component.gpu.set(x + width - 1, y + yPos, "в”‚")
  600. yPos = yPos + 1
  601. end
  602. end
  603.  
  604. --Кнопка в виде текста в рамке
  605. function ecs.drawFramedButton(x, y, width, height, text, color)
  606. ecs.border(x, y, width, height, component.gpu.getBackground(), color)
  607. component.gpu.fill(x + 1, y + 1, width - 2, height - 2, " ")
  608. x = x + math.floor(width / 2 - unicode.len(text) / 2)
  609. y = y + math.floor(width / 2 - 1)
  610. component.gpu.set(x, y, text)
  611. end
  612.  
  613. --Юникодовский разделитель
  614. function ecs.separator(x, y, width, back, fore)
  615. ecs.colorTextWithBack(x, y, fore, back, string.rep("в”Ђ", width))
  616. end
  617.  
  618. --Автоматическое центрирование текста по указанной координате (x, y, xy)
  619. function ecs.centerText(mode,coord,text)
  620. local dlina = unicode.len(text)
  621. local xSize,ySize = component.gpu.getResolution()
  622.  
  623. if mode == "x" then
  624. component.gpu.set(math.floor(xSize/2-dlina/2),coord,text)
  625. elseif mode == "y" then
  626. component.gpu.set(coord,math.floor(ySize/2),text)
  627. else
  628. component.gpu.set(math.floor(xSize/2-dlina/2),math.floor(ySize/2),text)
  629. end
  630. end
  631.  
  632. --Отрисовка "изображения" по указанному массиву
  633. function ecs.drawCustomImage(x,y,pixels)
  634. x = x - 1
  635. y = y - 1
  636. local pixelsWidth = #pixels[1]
  637. local pixelsHeight = #pixels
  638. local xEnd = x + pixelsWidth
  639. local yEnd = y + pixelsHeight
  640.  
  641. for i=1,pixelsHeight do
  642. for j=1,pixelsWidth do
  643. if pixels[i][j][3] ~= "#" then
  644. if component.gpu.getBackground() ~= pixels[i][j][1] then component.gpu.setBackground(pixels[i][j][1]) end
  645. if component.gpu.getForeground() ~= pixels[i][j][2] then component.gpu.setForeground(pixels[i][j][2]) end
  646. component.gpu.set(x+j,y+i,pixels[i][j][3])
  647. end
  648. end
  649. end
  650.  
  651. return (x+1),(y+1),xEnd,yEnd
  652. end
  653.  
  654. --Корректировка стартовых координат. Core-функция для всех моих программ
  655. function ecs.correctStartCoords(xStart,yStart,xWindowSize,yWindowSize)
  656. local xSize,ySize = component.gpu.getResolution()
  657. if xStart == "auto" then
  658. xStart = math.floor(xSize/2 - xWindowSize/2)
  659. end
  660. if yStart == "auto" then
  661. yStart = math.ceil(ySize/2 - yWindowSize/2)
  662. end
  663. return xStart,yStart
  664. end
  665.  
  666. --Запомнить область пикселей и возвратить ее в виде массива
  667. function ecs.rememberOldPixels(x, y, x2, y2)
  668. local newPNGMassiv = { ["backgrounds"] = {} }
  669. local xSize, ySize = component.gpu.getResolution()
  670. newPNGMassiv.x, newPNGMassiv.y = x, y
  671.  
  672. --Перебираем весь массив стандартного PNG-вида по высоте
  673. local xCounter, yCounter = 1, 1
  674. for j = y, y2 do
  675. xCounter = 1
  676. for i = x, x2 do
  677.  
  678. if (i > xSize or i < 0) or (j > ySize or j < 0) then
  679. error("Can't remember pixel, because it's located behind the screen: x("..i.."), y("..j..") out of xSize("..xSize.."), ySize("..ySize..")\n")
  680. end
  681.  
  682. local symbol, fore, back = component.gpu.get(i, j)
  683.  
  684. newPNGMassiv["backgrounds"][back] = newPNGMassiv["backgrounds"][back] or {}
  685. newPNGMassiv["backgrounds"][back][fore] = newPNGMassiv["backgrounds"][back][fore] or {}
  686.  
  687. table.insert(newPNGMassiv["backgrounds"][back][fore], {xCounter, yCounter, symbol} )
  688.  
  689. xCounter = xCounter + 1
  690. back, fore, symbol = nil, nil, nil
  691. end
  692.  
  693. yCounter = yCounter + 1
  694. end
  695.  
  696. xSize, ySize = nil, nil
  697. return newPNGMassiv
  698. end
  699.  
  700. --Нарисовать запомненные ранее пиксели из массива
  701. function ecs.drawOldPixels(massivSudaPihay)
  702. --Перебираем массив с фонами
  703. for back, backValue in pairs(massivSudaPihay["backgrounds"]) do
  704. component.gpu.setBackground(back)
  705. for fore, foreValue in pairs(massivSudaPihay["backgrounds"][back]) do
  706. component.gpu.setForeground(fore)
  707. for pixel = 1, #massivSudaPihay["backgrounds"][back][fore] do
  708. if massivSudaPihay["backgrounds"][back][fore][pixel][3] ~= transparentSymbol then
  709. 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])
  710. end
  711. end
  712. end
  713. end
  714. end
  715.  
  716. --Ограничение длины строки. Маст-хев функция.
  717. function ecs.stringLimit(mode, text, size, noDots)
  718. if unicode.len(text) <= size then return text end
  719. local length = unicode.len(text)
  720. if mode == "start" then
  721. if noDots then
  722. return unicode.sub(text, length - size + 1, -1)
  723. else
  724. return "…" .. unicode.sub(text, length - size + 2, -1)
  725. end
  726. else
  727. if noDots then
  728. return unicode.sub(text, 1, size)
  729. else
  730. return unicode.sub(text, 1, size - 1) .. "…"
  731. end
  732. end
  733. end
  734.  
  735. --Получить текущее реальное время компьютера, хостящего сервер майна
  736. function ecs.getHostTime(timezone)
  737. timezone = timezone or 2
  738. --Создаем файл с записанной в него парашей
  739. local file = io.open("HostTime.tmp", "w")
  740. file:write("")
  741. file:close()
  742. --Коррекция времени на основе часового пояса
  743. local timeCorrection = timezone * 3600
  744. --Получаем дату изменения файла в юникс-виде
  745. local lastModified = tonumber(string.sub(fs.lastModified("HostTime.tmp"), 1, -4)) + timeCorrection
  746. --Удаляем файл, ибо на хуй он нам не нужен
  747. fs.remove("HostTime.tmp")
  748. --Конвертируем юникс-время в норм время
  749. local year, month, day, hour, minute, second = os.date("%Y", lastModified), os.date("%m", lastModified), os.date("%d", lastModified), os.date("%H", lastModified), os.date("%M", lastModified), os.date("%S", lastModified)
  750. --Возвращаем все
  751. return tonumber(day), tonumber(month), tonumber(year), tonumber(hour), tonumber(minute), tonumber(second)
  752. end
  753.  
  754. --Получить спискок файлов из конкретной директории, костыль
  755. function ecs.getFileList(path)
  756. local list = fs.list(path)
  757. local massiv = {}
  758. for file in list do
  759. --if string.find(file, "%/$") then file = unicode.sub(file, 1, -2) end
  760. table.insert(massiv, file)
  761. end
  762. list = nil
  763. return massiv
  764. end
  765.  
  766. --Получить файловое древо. Сильно нагружает систему, только для дебага!
  767. function ecs.getFileTree(path)
  768. local massiv = {}
  769. local list = ecs.getFileList(path)
  770. for key, file in pairs(list) do
  771. if fs.isDirectory(path.."/"..file) then
  772. table.insert(massiv, getFileTree(path.."/"..file))
  773. else
  774. table.insert(massiv, file)
  775. end
  776. end
  777. list = nil
  778.  
  779. return massiv
  780. end
  781.  
  782. --Поиск по файловой системе
  783. function ecs.find(path, cheBudemIskat)
  784. --Массив, в котором будут находиться все найденные соответствия
  785. local massivNaydennogoGovna = {}
  786. --Костыль, но удобный
  787. local function dofind(path, cheBudemIskat)
  788. --Получаем список файлов в директории
  789. local list = ecs.getFileList(path)
  790. --Перебираем все элементы файл листа
  791. for key, file in pairs(list) do
  792. --Путь к файлу
  793. local pathToFile = path..file
  794. --Если нашло совпадение в имени файла, то выдает путь к этому файлу
  795. if string.find(unicode.lower(file), unicode.lower(cheBudemIskat)) then
  796. table.insert(massivNaydennogoGovna, pathToFile)
  797. end
  798. --Анализ, что делать дальше
  799. if fs.isDirectory(pathToFile) then
  800. dofind(pathToFile, cheBudemIskat)
  801. end
  802. --Очищаем оперативку
  803. pathToFile = nil
  804. end
  805. --Очищаем оперативку
  806. list = nil
  807. end
  808. --Выполняем функцию
  809. dofind(path, cheBudemIskat)
  810. --Возвращаем, че нашло
  811. return massivNaydennogoGovna
  812. end
  813.  
  814. --Получение формата файла
  815. function ecs.getFileFormat(path)
  816. local name = fs.name(path)
  817. local starting, ending = string.find(name, "(.)%.[%d%w]*$")
  818. if starting == nil then
  819. return nil
  820. else
  821. return unicode.sub(name,starting + 1, -1)
  822. end
  823. name, starting, ending = nil, nil, nil
  824. end
  825.  
  826. --Проверить, скрытый ли файл (.пидор, .хуй = true; пидор, хуй = false)
  827. function ecs.isFileHidden(path)
  828. local name = fs.name(path)
  829. local starting, ending = string.find(name, "^%.(.*)$")
  830. if starting == nil then
  831. return false
  832. else
  833. return true
  834. end
  835. name, starting, ending = nil, nil, nil
  836. end
  837.  
  838. --Скрыть формат файла
  839. function ecs.hideFileFormat(path)
  840. local name = fs.name(path)
  841. local fileFormat = ecs.getFileFormat(name)
  842. if fileFormat == nil then
  843. return name
  844. else
  845. return unicode.sub(name, 1, unicode.len(name) - unicode.len(fileFormat))
  846. end
  847. end
  848.  
  849. --Ожидание клика либо нажатия какой-либо клавиши
  850. function ecs.waitForTouchOrClick()
  851. while true do
  852. local e = { event.pull() }
  853. if e[1] == "key_down" or e[1] == "touch" then break end
  854. end
  855. end
  856.  
  857. --То же самое, но в сокращенном варианте
  858. function ecs.wait()
  859. ecs.waitForTouchOrClick()
  860. end
  861.  
  862. --Нарисовать кнопочки закрытия окна
  863. function ecs.drawCloses(x, y, active)
  864. local symbol = "в®ѕ"
  865. ecs.colorText(x, y , (active == 1 and ecs.colors.blue) or 0xCC4C4C, symbol)
  866. ecs.colorText(x + 2, y , (active == 2 and ecs.colors.blue) or 0xDEDE6C, symbol)
  867. ecs.colorText(x + 4, y , (active == 3 and ecs.colors.blue) or 0x57A64E, symbol)
  868. end
  869.  
  870. --Нарисовать верхнюю оконную панель с выбором объектов
  871. function ecs.drawTopBar(x, y, width, selectedObject, background, foreground, ...)
  872. local objects = { ... }
  873. ecs.square(x, y, width, 3, background)
  874. local widthOfObjects = 0
  875. local spaceBetween = 2
  876. for i = 1, #objects do
  877. widthOfObjects = widthOfObjects + unicode.len(objects[i][1]) + spaceBetween
  878. end
  879. local xPos = x + math.floor(width / 2 - widthOfObjects / 2)
  880. for i = 1, #objects do
  881. if i == selectedObject then
  882. ecs.square(xPos, y, unicode.len(objects[i][1]) + spaceBetween, 3, ecs.colors.blue)
  883. component.gpu.setForeground(0xffffff)
  884. else
  885. component.gpu.setBackground(background)
  886. component.gpu.setForeground(foreground)
  887. end
  888. component.gpu.set(xPos + spaceBetween / 2, y + 2, objects[i][1])
  889. component.gpu.set(xPos + math.ceil(unicode.len(objects[i][1]) / 2), y + 1, objects[i][2])
  890.  
  891. xPos = xPos + unicode.len(objects[i][1]) + spaceBetween
  892. end
  893. end
  894.  
  895. --Нарисовать топ-меню, горизонтальная полоска такая с текстами
  896. function ecs.drawTopMenu(x, y, width, color, selectedObject, ...)
  897. local objects = { ... }
  898. local objectsToReturn = {}
  899. local xPos = x + 2
  900. local spaceBetween = 2
  901. ecs.square(x, y, width, 1, color)
  902. for i = 1, #objects do
  903. if i == selectedObject then
  904. ecs.square(xPos - 1, y, unicode.len(objects[i][1]) + spaceBetween, 1, ecs.colors.blue)
  905. component.gpu.setForeground(0xffffff)
  906. component.gpu.set(xPos, y, objects[i][1])
  907. component.gpu.setForeground(objects[i][2])
  908. component.gpu.setBackground(color)
  909. else
  910. if component.gpu.getForeground() ~= objects[i][2] then component.gpu.setForeground(objects[i][2]) end
  911. component.gpu.set(xPos, y, objects[i][1])
  912. end
  913. objectsToReturn[objects[i][1]] = { xPos, y, xPos + unicode.len(objects[i][1]) - 1, y, i }
  914. xPos = xPos + unicode.len(objects[i][1]) + spaceBetween
  915. end
  916. return objectsToReturn
  917. end
  918.  
  919. --Функция отрисовки кнопки указанной ширины
  920. function ecs.drawButton(x,y,width,height,text,backColor,textColor)
  921. x,y = ecs.correctStartCoords(x,y,width,height)
  922.  
  923. local textPosX = math.floor(x + width / 2 - unicode.len(text) / 2)
  924. local textPosY = math.floor(y + height / 2)
  925. ecs.square(x,y,width,height,backColor)
  926. ecs.colorText(textPosX,textPosY,textColor,text)
  927.  
  928. return x, y, (x + width - 1), (y + height - 1)
  929. end
  930.  
  931. --Отрисовка кнопки с указанными отступами от текста
  932. function ecs.drawAdaptiveButton(x,y,offsetX,offsetY,text,backColor,textColor)
  933. local length = unicode.len(text)
  934. local width = offsetX*2 + length
  935. local height = offsetY*2 + 1
  936.  
  937. x,y = ecs.correctStartCoords(x,y,width,height)
  938.  
  939. ecs.square(x,y,width,height,backColor)
  940. ecs.colorText(x+offsetX,y+offsetY,textColor,text)
  941.  
  942. return x,y,(x+width-1),(y+height-1)
  943. end
  944.  
  945. --Отрисовка оконной "тени"
  946. function ecs.windowShadow(x,y,width,height)
  947. component.gpu.setBackground(ecs.windowColors.shadow)
  948. component.gpu.fill(x+width,y+1,2,height," ")
  949. component.gpu.fill(x+1,y+height,width,1," ")
  950. end
  951.  
  952. --Просто белое окошко с тенью
  953. function ecs.blankWindow(x,y,width,height)
  954. local oldPixels = ecs.rememberOldPixels(x,y,x+width+1,y+height)
  955.  
  956. ecs.square(x,y,width,height,ecs.windowColors.background)
  957.  
  958. ecs.windowShadow(x,y,width,height)
  959.  
  960. return oldPixels
  961. end
  962.  
  963. --Белое окошко, но уже с титлом вверху!
  964. function ecs.emptyWindow(x,y,width,height,title)
  965.  
  966. local oldPixels = ecs.rememberOldPixels(x,y,x+width+1,y+height)
  967.  
  968. --РћРљРќРћ
  969. component.gpu.setBackground(ecs.windowColors.background)
  970. component.gpu.fill(x,y+1,width,height-1," ")
  971.  
  972. --ТАБ СВЕРХУ
  973. component.gpu.setBackground(ecs.windowColors.tab)
  974. component.gpu.fill(x,y,width,1," ")
  975.  
  976. --ТИТЛ
  977. component.gpu.setForeground(ecs.windowColors.title)
  978. local textPosX = x + math.floor(width/2-unicode.len(title)/2) -1
  979. component.gpu.set(textPosX,y,title)
  980.  
  981. --ТЕНЬ
  982. ecs.windowShadow(x,y,width,height)
  983.  
  984. return oldPixels
  985.  
  986. end
  987.  
  988. function ecs.getWordsArrayFromString(s)
  989. local words = {}
  990. for word in string.gmatch(s, "[^%s]+") do table.insert(words, word) end
  991. return words
  992. end
  993.  
  994. --Моя любимая функция ошибки C:
  995. function ecs.error(...)
  996. local args = {...}
  997. local text = ""
  998. if #args > 1 then
  999. for i = 1, #args do
  1000. --text = text .. "[" .. i .. "] = " .. tostring(args[i])
  1001. if type(args[i]) == "string" then args[i] = "\"" .. args[i] .. "\"" end
  1002. text = text .. tostring(args[i])
  1003. if i ~= #args then text = text .. ", " end
  1004. end
  1005. else
  1006. text = tostring(args[1])
  1007. end
  1008. 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!"}})
  1009. end
  1010.  
  1011. --Очистить экран, установить комфортные цвета и поставить курсок на 1, 1
  1012. function ecs.prepareToExit(color1, color2)
  1013. term.setCursor(1, 1)
  1014. ecs.clearScreen(color1 or 0x333333)
  1015. component.gpu.setForeground(color2 or 0xffffff)
  1016. component.gpu.set(1, 1, "")
  1017. end
  1018.  
  1019. --Конвертация из юникода в символ. Вроде норм, а вроде и не норм. Но полезно.
  1020. function ecs.convertCodeToSymbol(code)
  1021. local symbol
  1022. 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
  1023. symbol = unicode.char(code)
  1024. if keyboard.isShiftPressed then symbol = unicode.upper(symbol) end
  1025. end
  1026. return symbol
  1027. end
  1028.  
  1029. --Шкала прогресса - маст-хев!
  1030. function ecs.progressBar(x, y, width, height, background, foreground, percent)
  1031. local activeWidth = math.ceil(width * percent / 100)
  1032. ecs.square(x, y, width, height, background)
  1033. ecs.square(x, y, activeWidth, height, foreground)
  1034. end
  1035.  
  1036. --Окошко с прогрессбаром! Давно хотел
  1037. function ecs.progressWindow(x, y, width, percent, text, returnOldPixels)
  1038. local height = 6
  1039. local barWidth = width - 6
  1040.  
  1041. x, y = ecs.correctStartCoords(x, y, width, height)
  1042.  
  1043. local oldPixels
  1044. if returnOldPixels then
  1045. oldPixels = ecs.rememberOldPixels(x, y, x + width + 1, y + height)
  1046. end
  1047.  
  1048. ecs.emptyWindow(x, y, width, height, " ")
  1049. ecs.colorTextWithBack(x + math.floor(width / 2 - unicode.len(text) / 2), y + 4, 0x000000, ecs.windowColors.background, text)
  1050. ecs.progressBar(x + 3, y + 2, barWidth, 1, 0xCCCCCC, ecs.colors.blue, percent)
  1051.  
  1052. return oldPixels
  1053. end
  1054.  
  1055. --Функция для ввода текста в мини-поле.
  1056. function ecs.inputText(x, y, limit, cheBiloVvedeno, background, foreground, justDrawNotEvent, maskTextWith)
  1057. limit = limit or 10
  1058. cheBiloVvedeno = cheBiloVvedeno or ""
  1059. background = background or 0xffffff
  1060. foreground = foreground or 0x000000
  1061.  
  1062. component.gpu.setBackground(background)
  1063. component.gpu.setForeground(foreground)
  1064. component.gpu.fill(x, y, limit, 1, " ")
  1065.  
  1066. local text = cheBiloVvedeno
  1067.  
  1068. local function draw()
  1069. term.setCursorBlink(false)
  1070.  
  1071. local dlina = unicode.len(text)
  1072. local xCursor = x + dlina
  1073. if xCursor > (x + limit - 1) then xCursor = (x + limit - 1) end
  1074.  
  1075. if maskTextWith then
  1076. component.gpu.set(x, y, ecs.stringLimit("start", string.rep("в—Џ", dlina), limit))
  1077. else
  1078. component.gpu.set(x, y, ecs.stringLimit("start", text, limit))
  1079. end
  1080.  
  1081. term.setCursor(xCursor, y)
  1082.  
  1083. term.setCursorBlink(true)
  1084. end
  1085.  
  1086. draw()
  1087.  
  1088. if justDrawNotEvent then term.setCursorBlink(false); return cheBiloVvedeno end
  1089.  
  1090. while true do
  1091. local e = {event.pull()}
  1092. if e[1] == "key_down" then
  1093. if e[4] == 14 then
  1094. term.setCursorBlink(false)
  1095. text = unicode.sub(text, 1, -2)
  1096. if unicode.len(text) < limit then component.gpu.set(x + unicode.len(text), y, " ") end
  1097. draw()
  1098. elseif e[4] == 28 then
  1099. term.setCursorBlink(false)
  1100. return text
  1101. else
  1102. local symbol = ecs.convertCodeToSymbol(e[3])
  1103. if symbol then
  1104. text = text..symbol
  1105. draw()
  1106. end
  1107. end
  1108. elseif e[1] == "touch" then
  1109. term.setCursorBlink(false)
  1110. return text
  1111. elseif e[1] == "clipboard" then
  1112. if e[3] then
  1113. text = text..e[3]
  1114. draw()
  1115. end
  1116. end
  1117. end
  1118. end
  1119.  
  1120. --Спросить, заменять ли файл (если таковой уже имеется)
  1121. function ecs.askForReplaceFile(path, includeForAllButton)
  1122. local cyka = {
  1123. {"EmptyLine"},
  1124. {"CenterText", 0x262626, "Файл \"".. fs.name(path) .. "\" уже имеется в этом месте."},
  1125. {"CenterText", 0x262626, "Заменить его перемещаемым объектом?"},
  1126. {"EmptyLine"}
  1127. }
  1128. if includeForAllButton then table.insert(cyka, {"Switch", 0xF2B233, 0xffffff, 0x262626, "Для всех", true}) end
  1129. table.insert(cyka, {"Button", {0x444444, 0xFFFFFF, "Заменить"}, {0x666666, 0xFFFFFF, "Отмена"}})
  1130.  
  1131. local action = ecs.universalWindow("auto", "auto", 46, ecs.windowColors.background, true, table.unpack(cyka))
  1132. if action[includeForAllButton and 2 or 1] == "Заменить" then
  1133. return 1, action[includeForAllButton and 1]
  1134. else
  1135. return 2, action[includeForAllButton and 1]
  1136. end
  1137. end
  1138.  
  1139. --Проверить имя файла на соответствие критериям
  1140. function ecs.checkName(name, path)
  1141. --Если ввели хуйню какую-то, то
  1142. if name == "" or name == " " or name == nil then
  1143. ecs.error("Неверное имя файла.")
  1144. return false
  1145. else
  1146. --Если файл с новым путем уже существует, то
  1147. if fs.exists(path .. name) then
  1148. ecs.error("Файл \"".. name .. "\" уже имеется в этом месте.")
  1149. return false
  1150. --А если все заебок, то
  1151. else
  1152. return true
  1153. end
  1154. end
  1155. end
  1156.  
  1157. --Переименование файлов (для операционки)
  1158. function ecs.rename(mainPath)
  1159. --Задаем стартовую щнягу
  1160. local name = fs.name(mainPath)
  1161. path = fs.path(mainPath)
  1162. --Рисуем окошко ввода нового имени файла
  1163. local inputs = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Переименовать"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, name}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
  1164. --Переименовываем
  1165. if ecs.checkName(inputs[1], path) then
  1166. fs.rename(mainPath, path .. inputs[1])
  1167. end
  1168. end
  1169.  
  1170. --Создать новую папку (для операционки)
  1171. function ecs.newFolder(path)
  1172. --Рисуем окошко ввода нового имени файла
  1173. local inputs = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Новая папка"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, ""}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
  1174.  
  1175. if ecs.checkName(inputs[1], path) then
  1176. fs.makeDirectory(path .. inputs[1])
  1177. end
  1178. end
  1179.  
  1180. --Создать новый файл (для операционки)
  1181. function ecs.newFile(path)
  1182. --Рисуем окошко ввода нового имени файла
  1183. local inputs = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Новый файл"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, ""}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
  1184.  
  1185. if ecs.checkName(inputs[1], path) then
  1186. ecs.prepareToExit()
  1187. ecs.editFile(path .. inputs[1])
  1188. end
  1189. end
  1190.  
  1191. --Создать новое приложение (для операционки)
  1192. function ecs.newApplication(path, startName)
  1193. --Рисуем окошко ввода нового имени файла
  1194. local inputs
  1195. if not startName then
  1196. inputs = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Новое приложение"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Введите имя"}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
  1197. end
  1198.  
  1199. if ecs.checkName(inputs[1] .. ".app", path) then
  1200. local name = path .. inputs[1] .. ".app/Resources/"
  1201. fs.makeDirectory(name)
  1202. fs.copy("MineOS/System/OS/Icons/SampleIcon.pic", name .. "Icon.pic")
  1203. local file = io.open(path .. inputs[1] .. ".app/" .. inputs[1] .. ".lua", "w")
  1204. file:write("local ecs = require(\"ECSAPI\")", "\n")
  1205. file:write("ecs.universalWindow(\"auto\", \"auto\", 30, 0xeeeeee, true, {\"EmptyLine\"}, {\"CenterText\", 0x262626, \"Hello world!\"}, {\"EmptyLine\"}, {\"Button\", {0x880000, 0xffffff, \"Hello!\"}})", "\n")
  1206. file:close()
  1207. end
  1208. end
  1209.  
  1210. --Создать приложение на основе существующего ЛУА-файла
  1211. function ecs.newApplicationFromLuaFile(pathToLuaFile, pathWhereToCreateApplication)
  1212. local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x000000, "Новое приложение"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Имя приложения"}, {"Input", 0x262626, 0x880000, "Путь к иконке приложения"}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
  1213. data[1] = data[1] or "MyApplication"
  1214. data[2] = data[2] or "MineOS/System/OS/Icons/SampleIcon.pic"
  1215. if fs.exists(data[2]) then
  1216. fs.makeDirectory(pathWhereToCreateApplication .. "/" .. data[1] .. ".app/Resources")
  1217. fs.copy(pathToLuaFile, pathWhereToCreateApplication .. "/" .. data[1] .. ".app/" .. data[1] .. ".lua")
  1218. fs.copy(data[2], pathWhereToCreateApplication .. "/" .. data[1] .. ".app/Resources/Icon.pic")
  1219.  
  1220. --ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x000000, "Приложение создано!"}, {"EmptyLine"}, {"Button", {ecs.colors.green, 0xffffff, "OK"}})
  1221. else
  1222. ecs.error("Указанный файл иконки не существует.")
  1223. return
  1224. end
  1225. end
  1226.  
  1227. --Простое информационное окошечко. Возвращает старые пиксели - мало ли понадобится.
  1228. function ecs.info(x, y, title, text)
  1229. x = x or "auto"
  1230. y = y or "auto"
  1231. title = title or " "
  1232. text = text or "Sample text"
  1233.  
  1234. local width = unicode.len(text) + 4
  1235. local height = 4
  1236. x, y = ecs.correctStartCoords(x, y, width, height)
  1237.  
  1238. local oldPixels = ecs.rememberOldPixels(x, y, x + width + 1, y + height)
  1239.  
  1240. ecs.emptyWindow(x, y, width, height, title)
  1241. ecs.colorTextWithBack(x + 2, y + 2, ecs.windowColors.usualText, ecs.windowColors.background, text)
  1242.  
  1243. return oldPixels
  1244. end
  1245.  
  1246. --Вертикальный скроллбар. Маст-хев!
  1247. function ecs.srollBar(x, y, width, height, countOfAllElements, currentElement, backColor, frontColor)
  1248. local sizeOfScrollBar = math.ceil(1 / countOfAllElements * height)
  1249. local displayBarFrom = math.floor(y + height * ((currentElement - 1) / countOfAllElements))
  1250.  
  1251. ecs.square(x, y, width, height, backColor)
  1252. ecs.square(x, displayBarFrom, width, sizeOfScrollBar, frontColor)
  1253.  
  1254. sizeOfScrollBar, displayBarFrom = nil, nil
  1255. end
  1256.  
  1257. --Отрисовка поля с текстом. Сюда пихать массив вида {"строка1", "строка2", "строка3", ...}
  1258. function ecs.textField(x, y, width, height, lines, displayFrom, background, foreground, scrollbarBackground, scrollbarForeground)
  1259. x, y = ecs.correctStartCoords(x, y, width, height)
  1260.  
  1261. background = background or 0xffffff
  1262. foreground = foreground or ecs.windowColors.usualText
  1263.  
  1264. local sLines = #lines
  1265. local lineLimit = width - 3
  1266.  
  1267. --Парсим строки
  1268. local line = 1
  1269. while lines[line] do
  1270. local sLine = unicode.len(lines[line])
  1271. if sLine > lineLimit then
  1272. local part1, part2 = unicode.sub(lines[line], 1, lineLimit), unicode.sub(lines[line], lineLimit + 1, -1)
  1273. lines[line] = part1
  1274. table.insert(lines, line + 1, part2)
  1275. part1, part2 = nil, nil
  1276. end
  1277. line = line + 1
  1278. sLine = nil
  1279. end
  1280. line = nil
  1281.  
  1282. ecs.square(x, y, width - 1, height, background)
  1283. ecs.srollBar(x + width - 1, y, 1, height, sLines, displayFrom, scrollbarBackground, scrollbarForeground)
  1284.  
  1285. component.gpu.setBackground(background)
  1286. component.gpu.setForeground(foreground)
  1287. local yPos = y
  1288. for i = displayFrom, (displayFrom + height - 1) do
  1289. if lines[i] then
  1290. component.gpu.set(x + 1, yPos, lines[i])
  1291. yPos = yPos + 1
  1292. else
  1293. break
  1294. end
  1295. end
  1296.  
  1297. return sLines
  1298. end
  1299.  
  1300. --Получение верного имени языка. Просто для безопасности. (для операционки)
  1301. function ecs.getCorrectLangName(pathToLangs)
  1302. local language = _G.OSSettings.language .. ".lang"
  1303. if not fs.exists(pathToLangs .. "/" .. language) then
  1304. language = "English.lang"
  1305. end
  1306. return language
  1307. end
  1308.  
  1309. --Чтение языкового файла (для операционки)
  1310. function ecs.readCorrectLangFile(pathToLangs)
  1311. local lang
  1312.  
  1313. local language = ecs.getCorrectLangName(pathToLangs)
  1314.  
  1315. lang = config.readAll(pathToLangs .. "/" .. language)
  1316.  
  1317. return lang
  1318. end
  1319.  
  1320. -------------------------ВСЕ ДЛЯ ОСКИ-------------------------------------------------------------------------------
  1321.  
  1322. function ecs.searchInArray(array, textToSearch)
  1323. local newArray = {}
  1324. for i = 1, #array do
  1325. if string.find(unicode.lower(array[i]), unicode.lower(textToSearch)) then table.insert(newArray, array[i]) end
  1326. end
  1327. return newArray
  1328. end
  1329.  
  1330. function ecs.sortFiles(path, fileList, sortingMethod, showHiddenFiles)
  1331. local sortedFileList = {}
  1332. if sortingMethod == "type" or sortingMethod == 0 then
  1333. local typeList = {}
  1334. for i = 1, #fileList do
  1335. local fileFormat = ecs.getFileFormat(fileList[i]) or "Script"
  1336. if fs.isDirectory(path .. fileList[i]) and fileFormat ~= ".app" then fileFormat = "Folder" end
  1337. typeList[fileFormat] = typeList[fileFormat] or {}
  1338. table.insert(typeList[fileFormat], fileList[i])
  1339. end
  1340.  
  1341. if typeList["Folder"] then
  1342. for i = 1, #typeList["Folder"] do
  1343. table.insert(sortedFileList, typeList["Folder"][i])
  1344. end
  1345. typeList["Folder"] = nil
  1346. end
  1347.  
  1348. for fileFormat in pairs(typeList) do
  1349. for i = 1, #typeList[fileFormat] do
  1350. table.insert(sortedFileList, typeList[fileFormat][i])
  1351. end
  1352. end
  1353. elseif sortingMethod == "name" or sortingMethod == 1 then
  1354. sortedFileList = fileList
  1355. elseif sortingMethod == "date" or sortingMethod == 2 then
  1356. for i = 1, #fileList do
  1357. fileList[i] = {fileList[i], fs.lastModified(path .. fileList[i])}
  1358. end
  1359. table.sort(fileList, function(a,b) return a[2] > b[2] end)
  1360. for i = 1, #fileList do
  1361. table.insert(sortedFileList, fileList[i][1])
  1362. end
  1363. else
  1364. error("Unknown sorting method: " .. tostring(sortingMethod))
  1365. end
  1366.  
  1367. local i = 1
  1368. while i <= #sortedFileList do
  1369. if not showHiddenFiles and ecs.isFileHidden(sortedFileList[i]) then
  1370. table.remove(sortedFileList, i)
  1371. else
  1372. i = i + 1
  1373. end
  1374. end
  1375.  
  1376. return sortedFileList
  1377. end
  1378.  
  1379. --Сохранить файл конфигурации ОС
  1380. function ecs.saveOSSettings()
  1381. local pathToOSSettings = "MineOS/System/OS/OSSettings.cfg"
  1382. if not _G.OSSettings then error("Массив настроек ОС отсутствует в памяти!") end
  1383. fs.makeDirectory(fs.path(pathToOSSettings))
  1384. local file = io.open(pathToOSSettings, "w")
  1385. file:write(serialization.serialize(_G.OSSettings))
  1386. file:close()
  1387. end
  1388.  
  1389. --Загрузить файл конфигурации ОС, а если его не существует, то создать
  1390. function ecs.loadOSSettings()
  1391. local pathToOSSettings = "MineOS/System/OS/OSSettings.cfg"
  1392. if fs.exists(pathToOSSettings) then
  1393. local file = io.open(pathToOSSettings, "r")
  1394. _G.OSSettings = serialization.unserialize(file:read("*a"))
  1395. file:close()
  1396. else
  1397. _G.OSSettings = { showHelpOnApplicationStart = true, language = "Russian" }
  1398. ecs.saveOSSettings()
  1399. end
  1400. end
  1401.  
  1402. --Отобразить окно с содержимым файла информации о приложении
  1403. function ecs.applicationHelp(pathToApplication)
  1404. local pathToAboutFile = pathToApplication .. "/resources/About/" .. _G.OSSettings.language .. ".txt"
  1405. if _G.OSSettings and _G.OSSettings.showHelpOnApplicationStart and fs.exists(pathToAboutFile) then
  1406. local applicationName = fs.name(pathToApplication)
  1407. local file = io.open(pathToAboutFile, "r")
  1408. local text = ""
  1409. for line in file:lines() do text = text .. line .. " " end
  1410. file:close()
  1411.  
  1412. local data = ecs.universalWindow("auto", "auto", 30, 0xeeeeee, true,
  1413. {"EmptyLine"},
  1414. {"CenterText", 0x000000, "О приложении " .. applicationName},
  1415. {"EmptyLine"},
  1416. {"TextField", 16, 0xFFFFFF, 0x262626, 0xcccccc, 0x353535, text},
  1417. {"EmptyLine"},
  1418. {"Button", {ecs.colors.orange, 0x262626, "OK"}, {0x999999, 0xffffff, "Больше не показывать"}}
  1419. )
  1420. if data[1] ~= "OK" then
  1421. _G.OSSettings.showHelpOnApplicationStart = false
  1422. ecs.saveOSSettings()
  1423. end
  1424. end
  1425. end
  1426.  
  1427. function ecs.correctFileNameIfFileExists(path, requestedName)
  1428. local number = 1
  1429. local fileFormat = ecs.getFileFormat(requestedName) or ""
  1430. requestedName = ecs.hideFileFormat(requestedName)
  1431. while true do
  1432. local finalFileName = requestedName .. string.rep("-copy", number) .. fileFormat
  1433. if fs.exists(path .. "/" .. finalFileName) then
  1434. number = number + 1
  1435. else
  1436. return finalFileName
  1437. end
  1438. end
  1439. end
  1440.  
  1441. --Создать ярлык для конкретной проги (для операционки)
  1442. function ecs.createShortCut(pathToShortcut, pathToFile)
  1443. local pathToPathToShortcut = fs.path(pathToShortcut) or "/"
  1444. fs.makeDirectory(pathToPathToShortcut)
  1445. if fs.exists(pathToShortcut) then
  1446. pathToShortcut = ecs.correctFileNameIfFileExists(pathToPathToShortcut, pathToShortcut)
  1447. end
  1448.  
  1449. local file = io.open(pathToShortcut, "w")
  1450. file:write("return ", "\"", pathToFile, "\"")
  1451. file:close()
  1452. end
  1453.  
  1454. --Получить данные о файле из ярлыка (для операционки)
  1455. function ecs.readShortcut(path)
  1456. local success, filename = pcall(loadfile(path))
  1457. if success then
  1458. return filename
  1459. else
  1460. error("Ошибка чтения файла ярлыка. Вероятно, он создан криво, либо не существует в папке \"" .. fs.path(path) or "" .. "\"")
  1461. end
  1462. end
  1463.  
  1464. --Редактирование файла (для операционки)
  1465. function ecs.editFile(path)
  1466. ecs.prepareToExit()
  1467. shell.execute("edit " .. path)
  1468. end
  1469.  
  1470. --Копирование файлов и папок
  1471. function ecs.copy(from, toFolder)
  1472. fs.makeDirectory(toFolder)
  1473.  
  1474. if fs.isDirectory(from) then
  1475. local currentAction, yesToAllAction
  1476. local function recursiveFolderCopy(from, to)
  1477. for file in fs.list(from) do
  1478. local finalFromName = from .. "/" .. file
  1479. local finalToName = to .. "/" .. file
  1480.  
  1481. if fs.exists(finalToName) then
  1482. if not yesToAllAction then
  1483. currentAction, yesToAll = ecs.askForReplaceFile(finalToName, true)
  1484. if yesToAll == true then yesToAllAction = true end
  1485. end
  1486. else
  1487. currentAction = 1
  1488. end
  1489.  
  1490. if currentAction == 1 then
  1491. if fs.isDirectory(finalFromName) then
  1492. fs.makeDirectory(finalToName)
  1493. recursiveFolderCopy(finalFromName, finalToName)
  1494. else
  1495. fs.copy(finalFromName, finalToName)
  1496. end
  1497. end
  1498. end
  1499. end
  1500.  
  1501. recursiveFolderCopy(from, toFolder .. fs.name(from))
  1502. else
  1503. local to = toFolder .. "/" .. fs.name(from)
  1504. local action = 1
  1505. if fs.exists(to) then action = ecs.askForReplaceFile(to) end
  1506. if action == 1 then fs.copy(from, to) end
  1507. end
  1508. end
  1509.  
  1510. -- Анимация затухания экрана
  1511. function ecs.fadeOut(startColor, targetColor, speed)
  1512. local xSize, ySize = component.gpu.getResolution()
  1513. while startColor >= targetColor do
  1514. component.gpu.setBackground(startColor)
  1515. component.gpu.fill(1, 1, xSize, ySize, " ")
  1516. startColor = startColor - 0x111111
  1517. os.sleep(speed or 0)
  1518. end
  1519. end
  1520.  
  1521. -- Анимация загорания экрана
  1522. function ecs.fadeIn(startColor, targetColor, speed)
  1523. local xSize, ySize = component.gpu.getResolution()
  1524. while startColor <= targetColor do
  1525. component.gpu.setBackground(startColor)
  1526. component.gpu.fill(1, 1, xSize, ySize, " ")
  1527. startColor = startColor + 0x111111
  1528. os.sleep(speed or 0)
  1529. end
  1530. end
  1531.  
  1532. -- Анимация выхода в олдскул-телевизионном стиле
  1533. function ecs.TV(speed, targetColor)
  1534. local xSize, ySize = component.gpu.getResolution()
  1535. local xCenter, yCenter = math.floor(xSize / 2), math.floor(ySize / 2)
  1536. component.gpu.setBackground(targetColor or 0x000000)
  1537.  
  1538. for y = 1, yCenter do
  1539. component.gpu.fill(1, y - 1, xSize, 1, " ")
  1540. component.gpu.fill(1, ySize - y + 1, xSize, 1, " ")
  1541. os.sleep(speed or 0)
  1542. end
  1543.  
  1544. for x = 1, xCenter - 1 do
  1545. component.gpu.fill(x, yCenter, 1, 1, " ")
  1546. component.gpu.fill(xSize - x + 1, yCenter, 1, 1, " ")
  1547. os.sleep(speed or 0)
  1548. end
  1549. os.sleep(0.3)
  1550. component.gpu.fill(1, yCenter, xSize, 1, " ")
  1551. end
  1552.  
  1553.  
  1554.  
  1555. ---------------------------------------------ОКОШЕЧКИ------------------------------------------------------------
  1556.  
  1557.  
  1558. --Описание ниже, ебана. Ниже - это значит в самой жопе кода!
  1559. function ecs.universalWindow(x, y, width, background, closeWindowAfter, ...)
  1560. local objects = {...}
  1561. local countOfObjects = #objects
  1562.  
  1563. local pressedButton
  1564. local pressedMultiButton
  1565.  
  1566. --Задаем высотные константы для объектов
  1567. local objectsHeights = {
  1568. ["button"] = 3,
  1569. ["centertext"] = 1,
  1570. ["emptyline"] = 1,
  1571. ["input"] = 3,
  1572. ["slider"] = 3,
  1573. ["select"] = 3,
  1574. ["selector"] = 3,
  1575. ["separator"] = 1,
  1576. ["switch"] = 1,
  1577. ["color"] = 3,
  1578. }
  1579.  
  1580. --Скорректировать ширину, если нужно
  1581. local function correctWidth(newWidthForAnalyse)
  1582. width = math.max(width, newWidthForAnalyse)
  1583. end
  1584.  
  1585. --Корректируем ширину
  1586. for i = 1, countOfObjects do
  1587. local objectType = string.lower(objects[i][1])
  1588.  
  1589. if objectType == "centertext" then
  1590. correctWidth(unicode.len(objects[i][3]) + 2)
  1591. elseif objectType == "slider" then --!!!!!!!!!!!!!!!!!! ВОТ ТУТ НЕ ЗАБУДЬ ФИКСАНУТЬ
  1592. correctWidth(unicode.len(objects[i][7]..tostring(objects[i][5].." ")) + 2)
  1593. elseif objectType == "select" then
  1594. for j = 4, #objects[i] do
  1595. correctWidth(unicode.len(objects[i][j]) + 2)
  1596. end
  1597. --elseif objectType == "selector" then
  1598.  
  1599. --elseif objectType == "separator" then
  1600.  
  1601. elseif objectType == "textfield" then
  1602. correctWidth(5)
  1603. elseif objectType == "wrappedtext" then
  1604. correctWidth(6)
  1605. elseif objectType == "button" then
  1606. --Корректируем ширину
  1607. local widthOfButtons = 0
  1608. local maxButton = 0
  1609. for j = 2, #objects[i] do
  1610. maxButton = math.max(maxButton, unicode.len(objects[i][j][3]) + 2)
  1611. end
  1612. widthOfButtons = maxButton * #objects[i]
  1613. correctWidth(widthOfButtons)
  1614. elseif objectType == "switch" then
  1615. local dlina = unicode.len(objects[i][5]) + 2 + 10 + 4
  1616. correctWidth(dlina)
  1617. elseif objectType == "color" then
  1618. correctWidth(unicode.len(objects[i][2]) + 6)
  1619. end
  1620. end
  1621.  
  1622. --Считаем высоту этой хуйни
  1623. local height = 0
  1624. for i = 1, countOfObjects do
  1625. local objectType = string.lower(objects[i][1])
  1626. if objectType == "select" then
  1627. height = height + (objectsHeights[objectType] * (#objects[i] - 3))
  1628. elseif objectType == "textfield" then
  1629. height = height + objects[i][2]
  1630. elseif objectType == "wrappedtext" then
  1631. --Заранее парсим текст перенесенный
  1632. objects[i].wrapped = string.wrap({objects[i][3]}, width - 4)
  1633. objects[i].height = #objects[i].wrapped
  1634. height = height + objects[i].height
  1635. else
  1636. height = height + objectsHeights[objectType]
  1637. end
  1638. end
  1639.  
  1640. --Коорректируем стартовые координаты
  1641. x, y = ecs.correctStartCoords(x, y, width, height)
  1642. --Запоминаем инфу о том, что было нарисовано, если это необходимо
  1643. local oldPixels, oldBackground, oldForeground
  1644. if closeWindowAfter then
  1645. oldBackground = component.gpu.getBackground()
  1646. oldForeground = component.gpu.getForeground()
  1647. oldPixels = ecs.rememberOldPixels(x, y, x + width - 1, y + height - 1)
  1648. end
  1649. --Считаем все координаты объектов
  1650. objects[1].y = y
  1651. if countOfObjects > 1 then
  1652. for i = 2, countOfObjects do
  1653. local objectType = string.lower(objects[i - 1][1])
  1654. if objectType == "select" then
  1655. objects[i].y = objects[i - 1].y + (objectsHeights[objectType] * (#objects[i - 1] - 3))
  1656. elseif objectType == "textfield" then
  1657. objects[i].y = objects[i - 1].y + objects[i - 1][2]
  1658. elseif objectType == "wrappedtext" then
  1659. objects[i].y = objects[i - 1].y + objects[i - 1].height
  1660. else
  1661. objects[i].y = objects[i - 1].y + objectsHeights[objectType]
  1662. end
  1663. end
  1664. end
  1665.  
  1666. --Объекты для тача
  1667. local obj = {}
  1668. local function newObj(class, name, ...)
  1669. obj[class] = obj[class] or {}
  1670. obj[class][name] = {...}
  1671. end
  1672.  
  1673. --Отображение объекта по номеру
  1674. local function displayObject(number, active)
  1675. local objectType = string.lower(objects[number][1])
  1676.  
  1677. if objectType == "centertext" then
  1678. local xPos = x + math.floor(width / 2 - unicode.len(objects[number][3]) / 2)
  1679. component.gpu.setForeground(objects[number][2])
  1680. component.gpu.setBackground(background)
  1681. component.gpu.set(xPos, objects[number].y, objects[number][3])
  1682.  
  1683. elseif objectType == "input" then
  1684.  
  1685. if active then
  1686. --Рамочка
  1687. ecs.border(x + 1, objects[number].y, width - 2, objectsHeights.input, background, objects[number][3])
  1688. --Тестик
  1689. objects[number][4] = ecs.inputText(x + 3, objects[number].y + 1, width - 6, "", background, objects[number][3], false, objects[number][5])
  1690. else
  1691. --Рамочка
  1692. ecs.border(x + 1, objects[number].y, width - 2, objectsHeights.input, background, objects[number][2])
  1693. --Текстик
  1694. component.gpu.set(x + 3, objects[number].y + 1, ecs.stringLimit("start", objects[number][4], width - 6))
  1695. ecs.inputText(x + 3, objects[number].y + 1, width - 6, objects[number][4], background, objects[number][2], true, objects[number][5])
  1696. end
  1697.  
  1698. newObj("Inputs", number, x + 1, objects[number].y, x + width - 2, objects[number].y + 2)
  1699.  
  1700. elseif objectType == "slider" then
  1701. local widthOfSlider = width - 2
  1702. local xOfSlider = x + 1
  1703. local yOfSlider = objects[number].y + 1
  1704. local countOfSliderThings = objects[number][5] - objects[number][4]
  1705. local showSliderValue= objects[number][7]
  1706.  
  1707. local dolya = widthOfSlider / countOfSliderThings
  1708. local position = math.floor(dolya * objects[number][6])
  1709. --Костыль
  1710. if (xOfSlider + position) > (xOfSlider + widthOfSlider - 1) then position = widthOfSlider - 2 end
  1711.  
  1712. --Две линии
  1713. ecs.separator(xOfSlider, yOfSlider, position, background, objects[number][3])
  1714. ecs.separator(xOfSlider + position, yOfSlider, widthOfSlider - position, background, objects[number][2])
  1715. --Слудир
  1716. ecs.square(xOfSlider + position, yOfSlider, 2, 1, objects[number][3])
  1717.  
  1718. --Текстик под слудиром
  1719. if showSliderValue then
  1720. local text = showSliderValue .. tostring(objects[number][6]) .. (objects[number][8] or "")
  1721. local textPos = (xOfSlider + widthOfSlider / 2 - unicode.len(text) / 2)
  1722. ecs.square(x, yOfSlider + 1, width, 1, background)
  1723. ecs.colorText(textPos, yOfSlider + 1, objects[number][2], text)
  1724. end
  1725.  
  1726. newObj("Sliders", number, xOfSlider, yOfSlider, x + widthOfSlider, yOfSlider, dolya)
  1727.  
  1728. elseif objectType == "select" then
  1729. local usualColor = objects[number][2]
  1730. local selectionColor = objects[number][3]
  1731.  
  1732. objects[number].selectedData = objects[number].selectedData or 1
  1733.  
  1734. local symbol = "вњ”"
  1735. local yPos = objects[number].y
  1736. for i = 4, #objects[number] do
  1737. --Коробка для галочки
  1738. ecs.border(x + 1, yPos, 5, 3, background, usualColor)
  1739. --Текст
  1740. component.gpu.set(x + 7, yPos + 1, objects[number][i])
  1741. --Галочка
  1742. if objects[number].selectedData == (i - 3) then
  1743. ecs.colorText(x + 3, yPos + 1, selectionColor, symbol)
  1744. else
  1745. component.gpu.set(x + 3, yPos + 1, " ")
  1746. end
  1747.  
  1748. obj["Selects"] = obj["Selects"] or {}
  1749. obj["Selects"][number] = obj["Selects"][number] or {}
  1750. obj["Selects"][number][i - 3] = { x + 1, yPos, x + width - 2, yPos + 2 }
  1751.  
  1752. yPos = yPos + objectsHeights.select
  1753. end
  1754.  
  1755. elseif objectType == "selector" then
  1756. local borderColor = objects[number][2]
  1757. local arrowColor = objects[number][3]
  1758. local selectorWidth = width - 2
  1759. objects[number].selectedElement = objects[number].selectedElement or objects[number][4]
  1760.  
  1761. local topLine = "┌" .. string.rep("─", selectorWidth - 6) .. "┬───┐"
  1762. local midLine = "в”‚" .. string.rep(" ", selectorWidth - 6) .. "в”‚ в”‚"
  1763. local botLine = "└" .. string.rep("─", selectorWidth - 6) .. "┴───┘"
  1764.  
  1765. local yPos = objects[number].y
  1766.  
  1767. local function bordak(borderColor)
  1768. component.gpu.setBackground(background)
  1769. component.gpu.setForeground(borderColor)
  1770. component.gpu.set(x + 1, objects[number].y, topLine)
  1771. component.gpu.set(x + 1, objects[number].y + 1, midLine)
  1772. component.gpu.set(x + 1, objects[number].y + 2, botLine)
  1773. component.gpu.set(x + 3, objects[number].y + 1, ecs.stringLimit("start", objects[number].selectedElement, width - 6))
  1774. ecs.colorText(x + width - 4, objects[number].y + 1, arrowColor, "в–ј")
  1775. end
  1776.  
  1777. bordak(borderColor)
  1778.  
  1779. --Выпадающий список, самый гемор, блядь
  1780. if active then
  1781. local xPos, yPos = x + 1, objects[number].y + 3
  1782. local spisokWidth = width - 2
  1783. local countOfElements = #objects[number] - 3
  1784. local spisokHeight = countOfElements + 1
  1785. local oldPixels = ecs.rememberOldPixels( xPos, yPos, xPos + spisokWidth - 1, yPos + spisokHeight - 1)
  1786.  
  1787. local coords = {}
  1788.  
  1789. bordak(arrowColor)
  1790.  
  1791. --Рамку рисуем поверх фоника
  1792. local topLine = "├"..string.rep("─", spisokWidth - 6).."┴───┤"
  1793. local midLine = "в”‚"..string.rep(" ", spisokWidth - 2).."в”‚"
  1794. local botLine = "└"..string.rep("─", selectorWidth - 2) .. "┘"
  1795. ecs.colorTextWithBack(xPos, yPos - 1, arrowColor, background, topLine)
  1796. for i = 1, spisokHeight - 1 do
  1797. component.gpu.set(xPos, yPos + i - 1, midLine)
  1798. end
  1799. component.gpu.set(xPos, yPos + spisokHeight - 1, botLine)
  1800.  
  1801. --Элементы рисуем
  1802. xPos = xPos + 2
  1803. for i = 1, countOfElements do
  1804. ecs.colorText(xPos, yPos, borderColor, ecs.stringLimit("start", objects[number][i + 3], spisokWidth - 4))
  1805. coords[i] = {xPos - 1, yPos, xPos + spisokWidth - 4, yPos}
  1806. yPos = yPos + 1
  1807. end
  1808.  
  1809. --Обработка
  1810. local exit
  1811. while true do
  1812. if exit then break end
  1813. local e = {event.pull()}
  1814. if e[1] == "touch" then
  1815. for i = 1, #coords do
  1816. if ecs.clickedAtArea(e[3], e[4], coords[i][1], coords[i][2], coords[i][3], coords[i][4]) then
  1817. ecs.square(coords[i][1], coords[i][2], spisokWidth - 2, 1, ecs.colors.blue)
  1818. ecs.colorText(coords[i][1] + 1, coords[i][2], 0xffffff, objects[number][i + 3])
  1819. os.sleep(0.3)
  1820. objects[number].selectedElement = objects[number][i + 3]
  1821. exit = true
  1822. break
  1823. end
  1824. end
  1825. end
  1826. end
  1827.  
  1828. ecs.drawOldPixels(oldPixels)
  1829. end
  1830.  
  1831. newObj("Selectors", number, x + 1, objects[number].y, x + width - 2, objects[number].y + 2)
  1832.  
  1833. elseif objectType == "separator" then
  1834. ecs.separator(x, objects[number].y, width, background, objects[number][2])
  1835.  
  1836. elseif objectType == "textfield" then
  1837. newObj("TextFields", number, x + 1, objects[number].y, x + width - 2, objects[number].y + objects[number][2] - 1)
  1838. if not objects[number].strings then objects[number].strings = string.wrap({objects[number][7]}, width - 3) end
  1839. objects[number].displayFrom = objects[number].displayFrom or 1
  1840. 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])
  1841.  
  1842. elseif objectType == "wrappedtext" then
  1843. component.gpu.setBackground(background)
  1844. component.gpu.setForeground(objects[number][2])
  1845. for i = 1, #objects[number].wrapped do
  1846. component.gpu.set(x + 2, objects[number].y + i - 1, objects[number].wrapped[i])
  1847. end
  1848.  
  1849. elseif objectType == "button" then
  1850.  
  1851. obj["MultiButtons"] = obj["MultiButtons"] or {}
  1852. obj["MultiButtons"][number] = {}
  1853.  
  1854. local widthOfButton = math.floor(width / (#objects[number] - 1))
  1855.  
  1856. local xPos, yPos = x, objects[number].y
  1857. for i = 1, #objects[number] do
  1858. if type(objects[number][i]) == "table" then
  1859. local x1, y1, x2, y2 = ecs.drawButton(xPos, yPos, widthOfButton, 3, objects[number][i][3], objects[number][i][1], objects[number][i][2])
  1860. table.insert(obj["MultiButtons"][number], {x1, y1, x2, y2, widthOfButton})
  1861. xPos = x2 + 1
  1862.  
  1863. if i == #objects[number] then
  1864. ecs.square(xPos, yPos, x + width - xPos, 3, objects[number][i][1])
  1865. obj["MultiButtons"][number][i - 1][5] = obj["MultiButtons"][number][i - 1][5] + x + width - xPos
  1866. end
  1867.  
  1868. x1, y1, x2, y2 = nil, nil, nil, nil
  1869. end
  1870. end
  1871.  
  1872. elseif objectType == "switch" then
  1873.  
  1874. local xPos, yPos = x + 2, objects[number].y
  1875. local activeColor, passiveColor, textColor, text, state = objects[number][2], objects[number][3], objects[number][4], objects[number][5], objects[number][6]
  1876. local switchWidth = 8
  1877. ecs.colorTextWithBack(xPos, yPos, textColor, background, text)
  1878.  
  1879. xPos = x + width - switchWidth - 2
  1880. if state then
  1881. ecs.square(xPos, yPos, switchWidth, 1, activeColor)
  1882. ecs.square(xPos + switchWidth - 2, yPos, 2, 1, passiveColor)
  1883. --ecs.colorTextWithBack(xPos + 4, yPos, passiveColor, activeColor, "ON")
  1884. else
  1885. ecs.square(xPos, yPos, switchWidth, 1, passiveColor - 0x444444)
  1886. ecs.square(xPos, yPos, 2, 1, passiveColor)
  1887. --ecs.colorTextWithBack(xPos + 4, yPos, passiveColor, passiveColor - 0x444444, "OFF")
  1888. end
  1889. newObj("Switches", number, xPos, yPos, xPos + switchWidth - 1, yPos)
  1890.  
  1891. elseif objectType == "color" then
  1892. local xPos, yPos = x + 1, objects[number].y
  1893. local blendedColor = require("colorlib").alphaBlend(objects[number][3], 0xFFFFFF, 180)
  1894. local w = width - 2
  1895.  
  1896. ecs.colorTextWithBack(xPos, yPos + 2, blendedColor, background, string.rep("в–Ђ", w))
  1897. ecs.colorText(xPos, yPos, objects[number][3], string.rep("в–„", w))
  1898. ecs.square(xPos, yPos + 1, w, 1, objects[number][3])
  1899.  
  1900. ecs.colorText(xPos + 1, yPos + 1, 0xffffff - objects[number][3], objects[number][2])
  1901. newObj("Colors", number, xPos, yPos, x + width - 2, yPos + 2)
  1902. end
  1903. end
  1904.  
  1905. --Отображение всех объектов
  1906. local function displayAllObjects()
  1907. for i = 1, countOfObjects do
  1908. displayObject(i)
  1909. end
  1910. end
  1911.  
  1912. --Подготовить массив возвращаемый
  1913. local function getReturn()
  1914. local massiv = {}
  1915.  
  1916. for i = 1, countOfObjects do
  1917. local type = string.lower(objects[i][1])
  1918.  
  1919. if type == "button" then
  1920. table.insert(massiv, pressedButton)
  1921. elseif type == "input" then
  1922. table.insert(massiv, objects[i][4])
  1923. elseif type == "select" then
  1924. table.insert(massiv, objects[i][objects[i].selectedData + 3])
  1925. elseif type == "selector" then
  1926. table.insert(massiv, objects[i].selectedElement)
  1927. elseif type == "slider" then
  1928. table.insert(massiv, objects[i][6])
  1929. elseif type == "switch" then
  1930. table.insert(massiv, objects[i][6])
  1931. elseif type == "color" then
  1932. table.insert(massiv, objects[i][3])
  1933. else
  1934. table.insert(massiv, nil)
  1935. end
  1936. end
  1937.  
  1938. return massiv
  1939. end
  1940.  
  1941. local function redrawBeforeClose()
  1942. if closeWindowAfter then
  1943. ecs.drawOldPixels(oldPixels)
  1944. component.gpu.setBackground(oldBackground)
  1945. component.gpu.setForeground(oldForeground)
  1946. end
  1947. end
  1948.  
  1949. --Рисуем окно
  1950. ecs.square(x, y, width, height, background)
  1951. displayAllObjects()
  1952.  
  1953. while true do
  1954. local e = {event.pull()}
  1955. if e[1] == "touch" or e[1] == "drag" then
  1956.  
  1957. --Анализируем клик на кнопки
  1958. if obj["MultiButtons"] then
  1959. for key in pairs(obj["MultiButtons"]) do
  1960. for i = 1, #obj["MultiButtons"][key] do
  1961. 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
  1962. 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])
  1963. os.sleep(0.3)
  1964. pressedButton = objects[key][i + 1][3]
  1965. redrawBeforeClose()
  1966. return getReturn()
  1967. end
  1968. end
  1969. end
  1970. end
  1971.  
  1972. --А теперь клик на инпуты!
  1973. if obj["Inputs"] then
  1974. for key in pairs(obj["Inputs"]) do
  1975. if ecs.clickedAtArea(e[3], e[4], obj["Inputs"][key][1], obj["Inputs"][key][2], obj["Inputs"][key][3], obj["Inputs"][key][4]) then
  1976. displayObject(key, true)
  1977. displayObject(key)
  1978. break
  1979. end
  1980. end
  1981. end
  1982.  
  1983. --А теперь галочковыбор!
  1984. if obj["Selects"] then
  1985. for key in pairs(obj["Selects"]) do
  1986. for i in pairs(obj["Selects"][key]) do
  1987. 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
  1988. objects[key].selectedData = i
  1989. displayObject(key)
  1990. break
  1991. end
  1992. end
  1993. end
  1994. end
  1995.  
  1996. --Хм, а вот и селектор подъехал!
  1997. if obj["Selectors"] then
  1998. for key in pairs(obj["Selectors"]) do
  1999. if ecs.clickedAtArea(e[3], e[4], obj["Selectors"][key][1], obj["Selectors"][key][2], obj["Selectors"][key][3], obj["Selectors"][key][4]) then
  2000. displayObject(key, true)
  2001. displayObject(key)
  2002. break
  2003. end
  2004. end
  2005. end
  2006.  
  2007. --Слайдеры, епта! "Потный матан", все делы
  2008. if obj["Sliders"] then
  2009. for key in pairs(obj["Sliders"]) do
  2010. if ecs.clickedAtArea(e[3], e[4], obj["Sliders"][key][1], obj["Sliders"][key][2], obj["Sliders"][key][3], obj["Sliders"][key][4]) then
  2011. local xOfSlider, dolya = obj["Sliders"][key][1], obj["Sliders"][key][5]
  2012. local currentPixels = e[3] - xOfSlider
  2013. local currentValue = math.floor(currentPixels / dolya)
  2014. --Костыль
  2015. if e[3] == obj["Sliders"][key][3] then currentValue = objects[key][5] end
  2016. objects[key][6] = currentValue or objects[key][6]
  2017. displayObject(key)
  2018. break
  2019. end
  2020. end
  2021. end
  2022.  
  2023. if obj["Switches"] then
  2024. for key in pairs(obj["Switches"]) do
  2025. if ecs.clickedAtArea(e[3], e[4], obj["Switches"][key][1], obj["Switches"][key][2], obj["Switches"][key][3], obj["Switches"][key][4]) then
  2026. objects[key][6] = not objects[key][6]
  2027. displayObject(key)
  2028. break
  2029. end
  2030. end
  2031. end
  2032.  
  2033. if obj["Colors"] then
  2034. for key in pairs(obj["Colors"]) do
  2035. if ecs.clickedAtArea(e[3], e[4], obj["Colors"][key][1], obj["Colors"][key][2], obj["Colors"][key][3], obj["Colors"][key][4]) then
  2036. local oldColor = objects[key][3]
  2037. objects[key][3] = 0xffffff - objects[key][3]
  2038. displayObject(key)
  2039. os.sleep(0.3)
  2040. objects[key][3] = oldColor
  2041. displayObject(key)
  2042. local color = loadfile("lib/palette.lua")().draw("auto", "auto", objects[key][3])
  2043. objects[key][3] = color or oldColor
  2044. displayObject(key)
  2045. break
  2046. end
  2047. end
  2048. end
  2049.  
  2050. elseif e[1] == "scroll" then
  2051. if obj["TextFields"] then
  2052. for key in pairs(obj["TextFields"]) do
  2053. if ecs.clickedAtArea(e[3], e[4], obj["TextFields"][key][1], obj["TextFields"][key][2], obj["TextFields"][key][3], obj["TextFields"][key][4]) then
  2054. if e[5] == 1 then
  2055. if objects[key].displayFrom > 1 then objects[key].displayFrom = objects[key].displayFrom - 1; displayObject(key) end
  2056. else
  2057. if objects[key].displayFrom < #objects[key].strings then objects[key].displayFrom = objects[key].displayFrom + 1; displayObject(key) end
  2058. end
  2059. end
  2060. end
  2061. end
  2062. elseif e[1] == "key_down" then
  2063. if e[4] == 28 then
  2064. redrawBeforeClose()
  2065. return getReturn()
  2066. end
  2067. end
  2068. end
  2069. end
  2070.  
  2071. --Демонстрационное окно, показывающее всю мощь universalWindow
  2072. function ecs.demoWindow()
  2073. --Очищаем экран перед юзанием окна и ставим курсор на 1, 1
  2074. ecs.prepareToExit()
  2075. --Рисуем окно и получаем данные после взаимодействия с ним
  2076. local data = ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true,
  2077. {"EmptyLine"},
  2078. {"CenterText", 0x880000, "Здорово, ебана!"},
  2079. {"EmptyLine"},
  2080. {"Input", 0x262626, 0x880000, "Сюда вводить можно"},
  2081. {"Selector", 0x262626, 0x880000, "Выбор формата", "PNG", "JPG", "GIF", "PSD"},
  2082. {"EmptyLine"},
  2083. {"WrappedText", 0x262626, "Тест автоматического переноса букв в зависимости от ширины данного окна. Пока что тупо режет на куски, не особо красиво."},
  2084. {"EmptyLine"},
  2085. {"Select", 0x262626, 0x880000, "РЇ РїРёРґРѕСЂ", "РЇ РЅРµ РїРёРґРѕСЂ"},
  2086. {"Slider", 0x262626, 0x880000, 1, 100, 50, "Убито ", " младенцев"},
  2087. {"EmptyLine"},
  2088. {"Separator", 0xaaaaaa},
  2089. {"Switch", 0xF2B233, 0xffffff, 0x262626, "✈ Авиарежим", false},
  2090. {"EmptyLine"},
  2091. {"Switch", 0x3366CC, 0xffffff, 0x262626, "☾ Не беспокоить", true},
  2092. {"Separator", 0xaaaaaa},
  2093. {"EmptyLine"},
  2094. {"TextField", 5, 0xffffff, 0x262626, 0xcccccc, 0x3366CC, "Тест текстового информационного поля. По сути это тот же самый WrappedText, разве что эта хрень ограничена по высоте, и ее можно скроллить. Ну же, поскролль меня! Скролль меня полностью! Моя жадная пизда жаждет твой хуй!"},
  2095. {"Color", "Цвет фона", 0xFF0000},
  2096. {"EmptyLine"},
  2097. {"Button", {0x57A64E, 0xffffff, "Да"}, {0xF2B233, 0xffffff, "Нет"}, {0xCC4C4C, 0xffffff, "Отмена"}}
  2098. )
  2099. --Еще разок
  2100. ecs.prepareToExit()
  2101. --Выводим данные
  2102. print(" ")
  2103. print("Вывод данных из окна:")
  2104. for i = 1, #data do print("["..i.."] = "..tostring(data[i])) end
  2105. print(" ")
  2106. end
  2107.  
  2108. -- ecs.demoWindow()
  2109.  
  2110. --[[
  2111. Функция universalWindow(x, y, width, background, closeWindowAfter, ...)
  2112.  
  2113. Это универсальная модульная функция для максимально удобного и быстрого отображения
  2114. необходимой вам информации. С ее помощью вводить данные с клавиатуры, осуществлять выбор
  2115. из предложенных вариантов, рисовать красивые кнопки, отрисовывать обычный текст,
  2116. отрисовывать текстовые поля с возможностью прокрутки, рисовать разделители и прочее.
  2117. Любой объект выделяется с помощью клика мыши, после чего функция приступает к работе
  2118. с этим объектом.
  2119.  
  2120. Аргументы функции:
  2121.  
  2122. x и y: это числа, обозначающие стартовые координаты левого верхнего угла данного окна.
  2123. Вместо цифр вы также можете написать "auto" - и программа автоматически разместит окно
  2124. по центру экрана по выбранной координате. Или по обеим координатам, если вам угодно.
  2125.  
  2126. width: это ширина окна, которую вы можете задать по собственному желанию. Если некторые
  2127. объекты требуют расширения окна, то окно будет автоматически расширено до нужной ширины.
  2128. Да, вот такая вот тавтология ;)
  2129.  
  2130. background: базовый цвет окна (цвет фона, кому как понятнее).
  2131.  
  2132. closeWindowAfter: eсли true, то окно по завершению функции будет выгружено, а на его месте
  2133. отрисуются пиксели, которые имелись на экране до выполнения функции. Удобно, если не хочешь
  2134. париться с перерисовкой интерфейса.
  2135.  
  2136. ... : многоточием тут является перечень объектов, указанных через запятую. Каждый объект
  2137. является массивом и имеет собственный формат. Ниже перечислены все возможные типы объектов.
  2138.  
  2139. {"Button", {Цвет кнопки1, Цвет текста на кнопке1, Сам текст1}, {Цвет кнопки2, Цвет текста на кнопке2, Сам текст2}, ...}
  2140.  
  2141. Это объект для рисования кнопок. Каждая кнопка - это массив, состоящий из трех элементов:
  2142. цвета кнопки, цвета текста на кнопке и самого текста. Кнопок может быть неограниченное количество,
  2143. однако чем их больше, тем большее требуется разрешение экрана по ширине.
  2144.  
  2145. Интерактивный объект.
  2146.  
  2147. {"Input", Цвет рамки и текста, Цвет при выделении, Стартовый текст [, Маскировать символом]}
  2148.  
  2149. Объект для рисования полей ввода текстовой информации. Удобно для открытия или сохранения файлов,
  2150. Опциональный аргумент "Маскировать символом" полезен, если вы делаете поле для ввода пароля.
  2151. Никто не увидит ваш текст. В качестве данного аргумента передается символ, например "*".
  2152.  
  2153. Интерактивный объект.
  2154.  
  2155. {"Selector", Цвет рамки, Цвет при выделении, Выбор 1, Выбор 2, Выбор 3 ...}
  2156.  
  2157. Внешне схож с объектом "Input", однако в этом случае вы будете выбирать один из предложенных
  2158. вариантов из выпадающего списка. По умолчанию выбран первый вариант.
  2159.  
  2160. Интерактивный объект.
  2161.  
  2162. {"Select", Цвет рамки, Цвет галочки, Выбор 1, Выбор 2, Выбор 3 ...}
  2163.  
  2164. Объект выбора. Отличается от "Selector" тем, что здесь вы выбираете один из вариантов, отмечая
  2165. его галочкой. По умолчанию выбран первый вариант.
  2166.  
  2167. Интерактивный объект.
  2168.  
  2169. {"Slider", Цвет линии слайдера, Цвет пимпочки слайдера, Значения слайдера ОТ, Значения слайдера ДО, Текущее значение [, Текст-подсказка ДО] [, Текст-подсказка ПОСЛЕ]}
  2170.  
  2171. Ползунок, позволяющий задавать определенное количество чего-либо в указанном интервале. Имеются два
  2172. опциональных аргумента, позволяющих четко понимать, с чем именно мы имеем дело.
  2173.  
  2174. К примеру, если аргумент "Текст-подсказка ДО" будет равен "Съедено ", а аргумент "Текст-подсказка ПОСЛЕ"
  2175. будет равен " яблок", а значение слайдера будет равно 50, то на экране будет написано "Съедено 50 яблок".
  2176.  
  2177. Интерактивный объект.
  2178.  
  2179. {"Switch", Активный цвет, Пассивный цвет, Цвет текста, Текст, Состояние}
  2180.  
  2181. Переключатель, принимающий два состояния: true или false. Текст - это всего лишь информация, некое
  2182. название данного переключателя.
  2183.  
  2184. Интерактивный объект.
  2185.  
  2186. {"CenterText", Цвет текста, Сам текст}
  2187.  
  2188. Отображение текста указанного цвета по центру окна. Чисто для информативных целей.
  2189.  
  2190. {"WrappedText", Цвет текста, Текст}
  2191.  
  2192. Отображение большого количества текста с автоматическим переносом. Прото режет слова на кусочки,
  2193. перенос символический. Чисто для информативных целей.
  2194.  
  2195. {"TextField", Высота, Цвет фона, Цвет текста, Цвет скроллбара, Цвет пимпочки скроллбара, Сам текст}
  2196.  
  2197. Текстовое поле с возможностью прокрутки. Отличается от "WrappedText"
  2198. фиксированной высотой. Чисто для информативных целей.
  2199.  
  2200. {"Separator", Цвет разделителя}
  2201.  
  2202. Линия-разделитель, помогающая лучше отделять объекты друг от друга. Декоративный объект.
  2203.  
  2204. {"EmptyLine"}
  2205.  
  2206. Пустое пространство, помогающая лучше отделять объекты друг от друга. Декоративный объект.
  2207.  
  2208. Каждый из объектов рисуется по порядку сверху вниз. Каждый объект автоматически
  2209. увеличивает высоту окна до необходимого значения. Если объектов будет указано слишком много -
  2210. т.е. если окно вылезет за пределы экрана, то программа завершится с ошибкой.
  2211.  
  2212. Что возвращает функция:
  2213.  
  2214. Возвратом является массив, пронумерованный от 1 до <количества объектов>.
  2215. К примеру, 1 индекс данного массива соответствует 1 указанному объекту.
  2216. Каждый индекс данного массива несет в себе какие-то данные, которые вы
  2217. внесли в объект во время работы функции.
  2218. Например, если в 1-ый объект типа "Input" вы ввели фразу "Hello world",
  2219. то первый индекс в возвращенном массиве будет равен "Hello world".
  2220. Конкретнее это будет вот так: massiv[1] = "Hello world".
  2221.  
  2222. Если взаимодействие с объектом невозможно - например, как в случае
  2223. с EmptyLine, CenterText, TextField или Separator, то в возвращенном
  2224. массиве этот объект указываться не будет.
  2225.  
  2226. Готовые примеры использования функции указаны ниже и закомментированы.
  2227. Выбирайте нужный и раскомментируйте.
  2228. ]]
  2229.  
  2230. --Функция-демонстратор, показывающая все возможные объекты в одном окне. Код окна находится выше.
  2231. --ecs.demoWindow()
  2232.  
  2233. --Функция, предлагающая сохранить файл в нужном месте в нужном формате.
  2234. --ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Сохранить как"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Путь"}, {"Selector", 0x262626, 0x880000, "PNG", "JPG", "PSD"}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK!"}})
  2235.  
  2236. ----------------------------------------------------------------------------------------------------
  2237.  
  2238. return ecs
  2239.  
  2240.  
Advertisement
Add Comment
Please, Sign In to add comment