From 8dbb0e98d7d8f8614515679ede3fc6b622423a80 Mon Sep 17 00:00:00 2001 From: Igor Timofeev Date: Mon, 11 Jul 2016 13:46:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B0=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=B1=D0=B0=D0=B3=D0=B0=20=D1=81=20=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D0=BE?= =?UTF-8?q?=D1=82=D1=87=D0=B5=D1=82=20=D0=BE=D0=B1=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BA=D0=B5=20=D0=BB=D0=B8=D1=87=D0=BD=D0=BE=20=D0=BC?= =?UTF-8?q?=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Applications.txt | 6 +- lib/ECSAPI.lua | 142 ------------------------------ lib/MineOSCore.lua | 210 ++++++++++++++++++++++++++++++++++++++++++--- lib/syntax.lua | 206 ++++++++++++++++++++++---------------------- 4 files changed, 300 insertions(+), 264 deletions(-) diff --git a/Applications.txt b/Applications.txt index 882ab104..5df1edf1 100644 --- a/Applications.txt +++ b/Applications.txt @@ -272,7 +272,7 @@ url="IgorTimofeev/OpenComputers/master/lib/ECSAPI.lua", type="Library", preLoadFile=true, - version=1.00, + version=1.01, }, { name="lib/colorlib.lua", @@ -299,7 +299,7 @@ name="lib/MineOSCore.lua", url="IgorTimofeev/OpenComputers/master/lib/MineOSCore.lua", type="Library", - version=1.12, + version=1.13, }, { name="lib/GUI.lua", @@ -389,7 +389,7 @@ name="lib/syntax.lua", url="IgorTimofeev/OpenComputers/master/lib/syntax.lua", type="Library", - version=1.0, + version=1.01, }, { name="lib/palette.lua", diff --git a/lib/ECSAPI.lua b/lib/ECSAPI.lua index d152670e..1ca356b8 100644 --- a/lib/ECSAPI.lua +++ b/lib/ECSAPI.lua @@ -1183,148 +1183,6 @@ function ecs.inputText(x, y, limit, cheBiloVvedeno, background, foreground, just end end ---Функция парсинга сообщения об ошибке. Конвертирует из строки в массив и переводит на русский. -function ecs.parseErrorMessage(error, translate) - - local parsedError = {} - - --ПОИСК ЭНТЕРОВ - local starting, ending, searchFrom = nil, nil, 1 - for i = 1, unicode.len(error) do - starting, ending = string.find(error, "\n", searchFrom) - if starting then - table.insert(parsedError, unicode.sub(error, searchFrom, starting - 1)) - searchFrom = ending + 1 - else - break - end - end - - --На всякий случай, если сообщение об ошибке без энтеров вообще, т.е. однострочное - if #parsedError == 0 and error ~= "" and error ~= nil and error ~= " " then - table.insert(parsedError, error) - end - - --Замена /r/n и табсов - for i = 1, #parsedError do - parsedError[i] = string.gsub(parsedError[i], "\r\n", "\n") - parsedError[i] = string.gsub(parsedError[i], " ", " ") - end - - if translate then - for i = 1, #parsedError do - parsedError[i] = string.gsub(parsedError[i], "interrupted", "Выполнение программы прервано пользователем") - parsedError[i] = string.gsub(parsedError[i], " got ", " получена ") - parsedError[i] = string.gsub(parsedError[i], " expected,", " ожидается,") - parsedError[i] = string.gsub(parsedError[i], "bad argument #", "Неверный аргумент #") - parsedError[i] = string.gsub(parsedError[i], "stack traceback", "Отслеживание ошибки") - parsedError[i] = string.gsub(parsedError[i], "tail calls", "Дочерние вызовы") - parsedError[i] = string.gsub(parsedError[i], "in function", "в функции") - parsedError[i] = string.gsub(parsedError[i], "in main chunk", "в основной программе") - parsedError[i] = string.gsub(parsedError[i], "unexpected symbol near", "неожиданный символ рядом с") - parsedError[i] = string.gsub(parsedError[i], "attempt to index", "пытаюсь получить значение индекса массива") - parsedError[i] = string.gsub(parsedError[i], "attempt to get length of", "не удается получить длину") - parsedError[i] = string.gsub(parsedError[i], ": ", ", ") - parsedError[i] = string.gsub(parsedError[i], " module ", " модуль ") - parsedError[i] = string.gsub(parsedError[i], "not found", "не найден") - parsedError[i] = string.gsub(parsedError[i], "no field package.preload", "не найдена библиотека") - parsedError[i] = string.gsub(parsedError[i], "no file", "нет файла") - parsedError[i] = string.gsub(parsedError[i], "local", "локальной") - parsedError[i] = string.gsub(parsedError[i], "global", "глобальной") - parsedError[i] = string.gsub(parsedError[i], "no primary", "не найден компонент") - parsedError[i] = string.gsub(parsedError[i], "available", "в доступе") - parsedError[i] = string.gsub(parsedError[i], "attempt to concatenate", "не могу присоединить") - parsedError[i] = string.gsub(parsedError[i], "a nil value", "переменная равна nil") - end - end - - starting, ending = nil, nil - - return parsedError -end - ---Отображение сообщения об ошибке компиляции скрипта в красивом окошке. -function ecs.displayCompileMessage(y, reason, translate, withAnimation) - - local xSize, ySize = gpu.getResolution() - - --Переводим причину в массив - reason = ecs.parseErrorMessage(reason, translate) - - --Получаем ширину и высоту окошка - local width = math.floor(xSize * 7 / 10) - local textWidth = width - 11 - reason = ecs.stringWrap(reason, textWidth) - local height = #reason + 6 - - --Просчет вот этой хуйни, аааахаахах - local difference = ySize - (height + y) - if difference < 0 then - for i = 1, (math.abs(difference) + 1) do - table.remove(reason, #reason) - end - table.insert(reason, "…") - height = #reason + 6 - end - - local x = math.floor(xSize / 2 - width / 2) - - --Иконочка воскл знака на красном фоне - local errorImage = { - {{0xff0000,0xffffff,"#"},{0xff0000,0xffffff,"#"},{0xff0000,0xffffff," "},{0xff0000,0xffffff,"#"},{0xff0000,0xffffff,"#"}}, - {{0xff0000,0xffffff,"#"},{0xff0000,0xffffff," "},{0xff0000,0xffffff,"!"},{0xff0000,0xffffff," "},{0xff0000,0xffffff,"#"}}, - {{0xff0000,0xffffff," "},{0xff0000,0xffffff," "},{0xff0000,0xffffff," "},{0xff0000,0xffffff," "},{0xff0000,0xffffff," "}} - } - - --Запоминаем, че было отображено - local oldPixels - - local function drawCompileMessage(y) - ecs.square(x, y, width, height, ecs.windowColors.background) - ecs.windowShadow(x, y, width, height) - --Рисуем воскл знак - ecs.drawCustomImage(x + 2, y + 1, errorImage) - - --Рисуем текст - local yPos = y + 1 - local xPos = x + 9 - gpu.setBackground(ecs.windowColors.background) - - ecs.colorText(xPos, yPos, ecs.windowColors.usualText, "Код ошибки:") - yPos = yPos + 2 - - gpu.setForeground( 0xcc0000 ) - for i = 1, #reason do - gpu.set(xPos, yPos, reason[i]) - yPos = yPos + 1 - end - - yPos = yPos + 1 - ecs.colorText(xPos, yPos, ecs.windowColors.usualText, ecs.stringLimit("end", "Нажмите любую клавишу, чтобы продолжить", textWidth)) - end - - --Типа анимация, ога - if withAnimation then - oldPixels = ecs.rememberOldPixels(x, 1, x + width + 1, height + 1) - for i = -height, 1, 1 do - drawCompileMessage(i) - os.sleep(0.01) - end - else - oldPixels = ecs.rememberOldPixels(x, y, x + width + 1, y + height) - drawCompileMessage(y) - end - - --Пикаем звуком кароч - for i = 1, 3 do - computer.beep(1000) - end - --Ждем сам знаешь чего - ecs.wait() - --Рисуем, че было нарисовано - ecs.drawOldPixels(oldPixels) -end - --Спросить, заменять ли файл (если таковой уже имеется) function ecs.askForReplaceFile(path, includeForAllButton) local cyka = { diff --git a/lib/MineOSCore.lua b/lib/MineOSCore.lua index ce16252d..282896e2 100644 --- a/lib/MineOSCore.lua +++ b/lib/MineOSCore.lua @@ -10,7 +10,8 @@ local libraries = { buffer = "doubleBuffering", image = "image", GUI = "GUI", - zip = "archive" + zip = "archive", + syntax = "syntax", } for library in pairs(libraries) do if not _G[library] then _G[library] = require(libraries[library]) end end @@ -29,6 +30,7 @@ MineOSCore.paths = { icons = "MineOS/System/OS/Icons/", applications = "MineOS/Applications/", pictures = "MineOS/Pictures/", + applicationList = "MineOS/System/OS/Applications.txt", } MineOSCore.sortingMethods = { @@ -123,27 +125,207 @@ function MineOSCore.drawIcon(x, y, path, showFileFormat, nameColor, name) buffer.text(x, y + MineOSCore.iconHeight - 1, nameColor or 0xffffff, text) end -function MineOSCore.safeLaunch(command, ...) +----------------------------------------------------------------------------------------------------------------------------------- + +--Функция парсинга Lua-сообщения об ошибке. Конвертирует из строки в массив. +function MineOSCore.parseErrorMessage(error, indentationWidth) + local parsedError = {} + + --Замена /r/n и табсов + error = string.gsub(error, "\r\n", "\n") + error = string.gsub(error, " ", string.rep(" ", indentationWidth or 4)) + + --Удаление энтеров + local searchFrom, starting, ending = 1 + for i = 1, unicode.len(error) do + starting, ending = string.find(error, "\n", searchFrom) + if starting then + table.insert(parsedError, unicode.sub(error, searchFrom, starting - 1)) + searchFrom = ending + 1 + else + break + end + end + + --На всякий случай, если сообщение об ошибке без энтеров вообще, т.е. однострочное + if #parsedError == 0 then table.insert(parsedError, error) end + + return parsedError +end + +--Функция-оптимизатор говносимволов для урлек, пробелсы там в %20 и т.п. +function MineOSCore.optimizeStringForURLSending(code) + if code then + code = string.gsub(code, "([^%w ])", function (c) + return string.format("%%%02X", string.byte(c)) + end) + code = string.gsub(code, " ", "+") + end + return code +end + +local function drawErrorWindow(path, errorLine, reason, showSendToDeveloperButton) + local topbarColor = 0x383838 + local programName = "Ошибка при выполнении " .. fs.name(path) + local width, height = buffer.screen.width, math.floor(buffer.screen.height * 0.45) + local x, y = 1, math.floor(buffer.screen.height / 2 - height / 2) + local topbarHeight = 3 + local codeHeight = height - topbarHeight - 3 + local codeWidth = math.floor(width * 0.62) + local stackWidth = width - codeWidth + local buttons = {} + + --Фончик + buffer.square(1, 1, buffer.screen.width, buffer.screen.height, 0x000000, 0x000000, " ", 50) + + --Топбарчик + buffer.square(x, y, width, topbarHeight, topbarColor, 0xFFFFFF, " ") + buffer.text(math.floor(x + width / 2 - unicode.len(programName) / 2), y + 1, 0xFFFFFF, programName) + + --Кнопачки + buttons = GUI.windowActionButtons(x + 1, y + 1, false) + if showSendToDeveloperButton and component.isAvailable("internet") then buttons.sendToDeveloper = GUI.adaptiveButton(x + 8, y, 2, 1, 0x444444, 0xFFFFFF, 0x343434, 0xFFFFFF, "Отправить отчет") end + y = y + topbarHeight + + --Кодик + local strings = {} + local fromString = errorLine - math.floor((codeHeight - 1) / 2) + if fromString < 0 then fromString = 1 end + local toString = fromString + codeHeight - 1 + + local file = io.open(path, "r") + local lineCounter = 1 + for line in file:lines() do + if lineCounter >= fromString and lineCounter <= toString then + line = string.gsub(line, " ", " ") + table.insert(strings, line) + elseif lineCounter > toString then + break + end + lineCounter = lineCounter + 1 + end + file:close() + + syntax.viewCode( + { + x = x, + y = y, + width = codeWidth, + height = codeHeight, + strings = strings, + maximumStringWidth = 50, + fromSymbol = 1, + fromString = 1, + fromStringOnLineNumbers = fromString, + highlightLuaSyntax = true, + highlightedStrings = {[errorLine] = 0xFF4444}, + scrollbars = { + vertical = true, + horizontal = false, + } + } + ) + + --Стек + strings = GUI.stringWrap(MineOSCore.parseErrorMessage(reason, 4), stackWidth - 2) + x = x + codeWidth + buffer.square(x, y, stackWidth, codeHeight, 0xFFFFFF) + x = x + 1 + for i = 1, #strings do buffer.text(x, y, 0x000000, strings[i]); y = y + 1; if i > codeHeight - 1 then break end end + + buffer.draw() + for i = 1, 2 do component.computer.beep(1500, 0.1) end + + --Ивентовая параша + while true do + local e = {event.pull()} + if e[1] == "touch" then + for objectName, button in pairs(buttons) do + if button:isClicked(e[3], e[4]) then + button:press() + if objectName == "close" then + return + elseif objectName == "sendToDeveloper" then + local data = ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, + {"EmptyLine"}, + {"CenterText", 0x880000, "Отправить отчет"}, + {"EmptyLine"}, + {"Input", 0x262626, 0x880000, "Ваше имя"}, + {"Input", 0x262626, 0x880000, "Сообщение разработчику"}, + {"EmptyLine"}, + {"CenterText", 0x880000, "Стек ошибки"}, + {"EmptyLine"}, + {"TextField", 5, 0xFFFFFF, 0x000000, 0xcccccc, 0x3366CC, reason}, + {"Button", {0x999999, 0xffffff, "OK"}, {0x777777, 0xffffff, "Отмена"}} + ) + + if data[3] == "OK" then + if component.isAvailable("internet") then + local phpUrl = "http://igortimofeev.wallst.ru/MineOSErrorReports/Report.php" + local url = phpUrl .. "?path=" .. path .. "&errorMessage=" .. MineOSCore.optimizeStringForURLSending(reason) .. "&userMessage=" .. MineOSCore.optimizeStringForURLSending(data[2]) .. "&userContacts=" .. MineOSCore.optimizeStringForURLSending(data[1]) + local success, reason = component.internet.request(url) + if success then + success:close() + else + ecs.error(reason) + end + end + + return + end + end + + break + end + end + end + end +end + +function MineOSCore.safeLaunch(path, ...) + local args = {...} local oldResolutionWidth, oldResolutionHeight = component.gpu.getResolution() - local loadSuccess, loadReason = loadfile(command) + local finalSuccess, finalReason = true, true + local loadSuccess, loadReason = loadfile(path) + if loadSuccess then - local success, reason = pcall(loadSuccess, ...) - --Ебал я автора мода в задницу, кусок ебанутого говна - --Какого хуя я должен вставлять кучу костылей в свой прекрасный код только потому, что эта ублюдочная - --скотина захотела выдавать table из pcall? Что, блядь? Где это видано, сука? - --Почему тогда во всех случаях выдается string, а при os.exit выдается {reason = "terminated"}? - --Что за ебливая сучья логика? - if not success and type(reason) ~= "table" then - reason = ecs.parseErrorMessage(reason, false) - GUI.error(reason, {title = {color = 0xFFDB40, text = MineOSCore.localization.errorWhileRunningProgram}}) + local function launcher() + loadSuccess(table.unpack(args)) + end + + local runSuccess, runReason = xpcall(launcher, debug.traceback) + if not runSuccess then + if type(runReason) == "string" then + if not string.find(runReason, "interrupted", 1, 15) then + finalSuccess, finalReason = false, runReason + end + end end else - component.gpu.setResolution(oldResolutionWidth, oldResolutionHeight) - GUI.error(loadReason, {title = {color = 0xFFDB40, text = MineOSCore.localization.errorWhileRunningProgram}}) + finalSuccess, finalReason = false, loadReason end + + if not finalSuccess then + local errorLine = 1 + local starting, ending = string.find(finalReason, "%:%d+%:") + if starting and ending then + path = unicode.sub(finalReason, 2, starting - 1) + errorLine = tonumber(unicode.sub(finalReason, starting + 1, ending - 1)) + end + + local applications = files.loadTableFromFile(MineOSCore.paths.applicationList) + local applicationExists = false + for i = 1, #applications do if path == applications[i].name then applicationExists = true; break end end + + drawErrorWindow(path, errorLine, finalReason, applicationExists) + end + + component.gpu.setResolution(oldResolutionWidth, oldResolutionHeight) buffer.start() end +----------------------------------------------------------------------------------------------------------------------------------- + -- Запуск приложения function MineOSCore.launchIcon(path, translate) --Получаем файл формат заранее diff --git a/lib/syntax.lua b/lib/syntax.lua index fa282abb..b7e48bde 100644 --- a/lib/syntax.lua +++ b/lib/syntax.lua @@ -1,14 +1,13 @@ -_G.buffer = require("doubleBuffering") -_G.unicode = require("unicode") +if not _G.buffer then _G.buffer = require("doubleBuffering") end +if not _G.unicode then _G.unicode = require("unicode") end local syntax = {} ---------------------------------------------------------------------------------------------------------------------------------------- ---Стандартные цветовые схемы syntax.colorSchemes = { midnight = { - background = 0x262626, + background = 0x1b1b1b, text = 0xffffff, strings = 0xff2024, loops = 0xffff98, @@ -18,35 +17,15 @@ syntax.colorSchemes = { numbers = 0x24c0ff, functions = 0xffcc66, compares = 0xffff98, - lineNumbers = 0x444444, + lineNumbers = 0x262626, lineNumbersText = 0xDDDDDD, scrollBar = 0x444444, scrollBarPipe = 0x24c0ff, selection = 0x99B2F2, - }, - sunrise = { - background = 0xffffff, - text = 0x262626, - strings = 0x880000, - loops = 0x24c0ff, - comments = 0xa2ffb7, - boolean = 0x19c0cc, - logic = 0x880000, - numbers = 0x24c0ff, - functions = 0x24c0ff, - compares = 0x880000, - lineNumbers = 0x444444, - lineNumbersText = 0xDDDDDD, - scrollBar = 0x444444, - scrollBarPipe = 0x24c0ff, - selection = 0x99B2F2, - }, + } } ---Текущая цветовая схема -local currentColorScheme = {} ---Шаблоны поиска -local patterns +local currentColorScheme, patterns ---------------------------------------------------------------------------------------------------------------------------------------- @@ -117,13 +96,22 @@ local function definePatterns() } end +local function convertFileToStrings(path) + local array = {} + local maximumStringWidth = 0 + local file = io.open(path, "r") + for line in file:lines() do + line = string.gsub(line, " ", string.rep(" ", 4)) + maximumStringWidth = math.max(maximumStringWidth, unicode.len(line)) + table.insert(array, line) + end + file:close() + return array, maximumStringWidth +end + --Костыльная замена обычному string.find() --Работает медленнее, но хотя бы поддерживает юникод function unicode.find(str, pattern, init, plain) - -- checkArg(1, str, "string") - -- checkArg(2, pattern, "string") - -- checkArg(3, init, "number", "nil") - if init then if init < 0 then init = -#unicode.sub(str,init) @@ -146,16 +134,14 @@ end --Объявить новую цветовую схему function syntax.setColorScheme(colorScheme) - --Выбранная цветовая схема currentColorScheme = colorScheme - --Пересчитываем шаблоны definePatterns() end ---------------------------------------------------------------------------------------------------------------------------------------- ---Проанализировать строку и создать на ее основе цветовую карту -function syntax.highlight(x, y, text, fromSymbol, limit) +--Нарисовать и подсветить строку +function syntax.highlightString(x, y, text, fromSymbol, limit) --Кароч вооот, хыыы local searchFrom, starting, ending --Загоняем в буфер всю строку базового цвета @@ -177,106 +163,95 @@ function syntax.highlight(x, y, text, fromSymbol, limit) end end -function syntax.convertFileToStrings(path) - local array = {} - local maximumStringWidth = 0 - local file = io.open(path, "r") - for line in file:lines() do - line = string.gsub(line, " ", string.rep(" ", 4)) - maximumStringWidth = math.max(maximumStringWidth, unicode.len(line)) - table.insert(array, line) - end - file:close() - return array, maximumStringWidth -end - -- Открыть окно-просмотрщик кода -function syntax.viewCode(x, y, width, height, strings, maximumStringWidth, fromSymbol, fromString, highlightLuaSyntax, selection, highlightedStrings) +--x, y, width, height, strings, maximumStringWidth, fromSymbol, fromString, highlightLuaSyntax, selection, highlightedStrings +function syntax.viewCode(args) --Рассчитываем максимальное количество строк, которое мы будем отображать - local maximumNumberOfAvailableStrings, yPos - if strings[fromString + height - 1] then - maximumNumberOfAvailableStrings = fromString + height - 2 + local countOfStringsOnDisplay, maximumNumberOfAvailableStrings + if args.strings[args.fromString + args.height - 1] then + countOfStringsOnDisplay = args.scrollbars.horizontal and args.height - 1 or args.height + maximumNumberOfAvailableStrings = args.fromString + args.height - 1 else - maximumNumberOfAvailableStrings = #strings - 1 + countOfStringsOnDisplay = #args.strings + maximumNumberOfAvailableStrings = #args.strings end + --Рассчитываем ширину полоски с номерами строк - local widthOfStringCounter = unicode.len(maximumNumberOfAvailableStrings) + 2 + local lineNumbersWidth = unicode.len(args.fromStringOnLineNumbers + countOfStringsOnDisplay) + 2 + --Рассчитываем стратовую позицию текстового поля - local textFieldPosition = x + widthOfStringCounter - local widthOfText = width - widthOfStringCounter - 3 - local xEnd, yEnd = x + width - 1, y + height - 1 + local textFieldPosition = args.x + lineNumbersWidth + local widthOfText = args.width - lineNumbersWidth - 3 + local xEnd, yEnd = args.x + args.width - 1, args.y + args.height - 1 --Рисуем подложку под текст - buffer.square(x, y, width, height, currentColorScheme.background, 0xFFFFFF, " ") + buffer.square(args.x, args.y, args.width, args.height, currentColorScheme.background, 0xFFFFFF, " ") --Рисуем подложку под номера строк - buffer.square(x, y, widthOfStringCounter, height, currentColorScheme.lineNumbers, 0xFFFFFF, " ") - --Рисуем вертикальный скроллбар - buffer.scrollBar(xEnd, y, 1, height, #strings, fromString, currentColorScheme.scrollBar, currentColorScheme.scrollBarPipe) - --Рисуем горизонтальный скроллбар - buffer.horizontalScrollBar(x + widthOfStringCounter, yEnd, width - widthOfStringCounter - 1, maximumStringWidth, fromSymbol, currentColorScheme.scrollBar, currentColorScheme.scrollBarPipe) - + buffer.square(args.x, args.y, lineNumbersWidth, args.height, currentColorScheme.lineNumbers, 0xFFFFFF, " ") + --Подсвечиваем некоторые строки, если указано - if highlightedStrings then - for i = 1, #highlightedStrings do - if highlightedStrings[i].number >= fromString and highlightedStrings[i].number < fromString + height then - buffer.square(x, y + highlightedStrings[i].number - fromString, width - 1, 1, highlightedStrings[i].color, 0xFFFFFF, " ") - buffer.square(x, y + highlightedStrings[i].number - fromString, widthOfStringCounter, 1, currentColorScheme.lineNumbers, 0xFFFFFF, " ", 60) + if args.highlightedStrings then + for stringNumber, color in pairs(args.highlightedStrings) do + if stringNumber >= args.fromStringOnLineNumbers and stringNumber < args.fromStringOnLineNumbers + countOfStringsOnDisplay then + buffer.square(args.x, args.y + stringNumber - args.fromStringOnLineNumbers, args.width - 1, 1, color, 0xFFFFFF, " ") + buffer.square(args.x, args.y + stringNumber - args.fromStringOnLineNumbers, lineNumbersWidth, 1, currentColorScheme.lineNumbers, 0xFFFFFF, " ", 60) end end end --Рисуем номера строк - yPos = y - for i = fromString, maximumNumberOfAvailableStrings do - buffer.text(x + widthOfStringCounter - unicode.len(i) - 1, yPos, currentColorScheme.text, tostring(i)) + local yPos = args.y + for i = args.fromStringOnLineNumbers, args.fromStringOnLineNumbers + countOfStringsOnDisplay - 1 do + buffer.text(args.x + lineNumbersWidth - unicode.len(i) - 1, yPos, currentColorScheme.text, tostring(i)) yPos = yPos + 1 end --Рисуем выделение, если оно имеется - if selection then + if args.selection then --Считаем высоту выделения - local heightOfSelection = selection.to.y - selection.from.y + 1 + local heightOfSelection = args.selection.to.y - args.selection.from.y + 1 --Если высота выделения > 1 if heightOfSelection > 1 then --Верхнее выделение - if selection.from.x < fromSymbol + widthOfText and selection.from.y >= fromString and selection.from.y < fromString + height then - local cyka = textFieldPosition + selection.from.x - fromSymbol + if args.selection.from.x < args.fromSymbol + widthOfText and args.selection.from.y >= args.fromString and args.selection.from.y < args.fromString + args.height then + local cyka = textFieldPosition + args.selection.from.x - args.fromSymbol if cyka < textFieldPosition then cyka = textFieldPosition end - buffer.square(cyka, y + selection.from.y - fromString, widthOfText - cyka + widthOfStringCounter + 2 + x, 1, currentColorScheme.selection, 0xFFFFFF, " ") + buffer.square(cyka, args.y + args.selection.from.y - args.fromString, widthOfText - cyka + lineNumbersWidth + 2 + args.x, 1, currentColorScheme.selection, 0xFFFFFF, " ") end --Средние выделения if heightOfSelection > 2 then for i = 1, heightOfSelection - 2 do - if selection.from.y + i >= fromString and selection.from.y + i < fromString + height then - buffer.square(textFieldPosition, y + selection.from.y + i - fromString, widthOfText + 2, 1, currentColorScheme.selection, 0xFFFFFF, " ") + if args.selection.from.y + i >= args.fromString and args.selection.from.y + i < args.fromString + args.height then + buffer.square(textFieldPosition, args.y + args.selection.from.y + i - args.fromString, widthOfText + 2, 1, currentColorScheme.selection, 0xFFFFFF, " ") end end end --Нижнее выделение - if selection.to.x >= fromSymbol and selection.to.y >= fromString and selection.to.y < fromString + height then - buffer.square(textFieldPosition, y + selection.to.y - fromString, selection.to.x - fromSymbol + 1, 1, currentColorScheme.selection, 0xFFFFFF, " ") + if args.selection.to.x >= args.fromSymbol and args.selection.to.y >= args.fromString and args.selection.to.y < args.fromString + args.height then + buffer.square(textFieldPosition, args.y + args.selection.to.y - args.fromString, args.selection.to.x - args.fromSymbol + 1, 1, currentColorScheme.selection, 0xFFFFFF, " ") end elseif heightOfSelection == 1 then - local cyka = selection.to.x - if cyka > fromSymbol + widthOfText - 1 then cyka = fromSymbol + widthOfText - 1 end - buffer.square(textFieldPosition + selection.from.x, selection.from.y, cyka - selection.from.x, 1, currentColorScheme.selection, 0xFFFFFF, " ") + local cyka = args.selection.to.x + if cyka > args.fromSymbol + widthOfText - 1 then cyka = args.fromSymbol + widthOfText - 1 end + buffer.square(textFieldPosition + args.selection.from.x, args.selection.from.y, cyka - args.selection.from.x, 1, currentColorScheme.selection, 0xFFFFFF, " ") + end end --Выставляем ограничение прорисовки буфера textFieldPosition = textFieldPosition + 1 - buffer.setDrawLimit(textFieldPosition, y, widthOfText, height) + buffer.setDrawLimit(textFieldPosition, args.y, widthOfText, args.height) --Рисуем текст - yPos = y - for i = fromString, maximumNumberOfAvailableStrings do + yPos = args.y + for i = args.fromString, maximumNumberOfAvailableStrings do --Учитываем опциональную подсветку ситнаксиса - if highlightLuaSyntax then - syntax.highlight(textFieldPosition, yPos, strings[i], fromSymbol, widthOfText) + if args.highlightLuaSyntax then + syntax.highlightString(textFieldPosition, yPos, args.strings[i], args.fromSymbol, widthOfText) else - buffer.text(textFieldPosition, yPos, currentColorScheme.text, unicode.sub(strings[i], fromSymbol, widthOfText)) + buffer.text(textFieldPosition, yPos, currentColorScheme.text, unicode.sub(args.strings[i], args.fromSymbol, widthOfText)) end yPos = yPos + 1 @@ -285,6 +260,12 @@ function syntax.viewCode(x, y, width, height, strings, maximumStringWidth, fromS --Убираем ограничение отрисовки buffer.resetDrawLimit() + --Рисуем вертикальный скроллбар + if args.scrollbars.vertical then buffer.scrollBar(xEnd, args.y, 1, args.height, #args.strings, args.fromString, currentColorScheme.scrollBar, currentColorScheme.scrollBarPipe) end + --Рисуем горизонтальный скроллбар + if args.scrollbars.horizontal then buffer.horizontalScrollBar(args.x + lineNumbersWidth, yEnd, args.width - lineNumbersWidth - 1, args.maximumStringWidth, args.fromSymbol, currentColorScheme.scrollBar, currentColorScheme.scrollBarPipe) end + + --Для всяких майнкодов, чтоб курсор можно было ставит и ТОПЕ return textFieldPosition end @@ -293,25 +274,40 @@ end -- Стартовое объявление цветовой схемы при загрузке библиотеки syntax.setColorScheme(syntax.colorSchemes.midnight) --- -- Епты бля! --- local strings, maximumStringWidth = syntax.convertFileToStrings("MineOS/Applications/Highlight.app/Resources/TestFile.txt") --- local strings = syntax.convertFileToStrings("OS.lua") +---------------------------------------------------------------------------------------------------------------- --- local xSize, ySize = gpu.getResolution() --- buffer.square(1, 1, xSize, ySize, ecs.colors.red, 0xFFFFFF, " ") --- buffer.draw(true) +-- buffer.start() +-- buffer.clear(0xFF8888) --- local selection = { --- from = {x = 8, y = 6}, --- to = {x = 16, y = 12} +-- local strings, maximumStringWidth = convertFileToStrings("/OS.lua") + +-- local args = { +-- x = 1, +-- y = 1, +-- width = 100, +-- height = 40, +-- strings = strings, +-- fromString = 1, +-- fromSymbol = 1, +-- fromStringOnLineNumbers = 6, +-- maximumStringWidth = maximumStringWidth, +-- highlightLuaSyntax = true, +-- selection = { +-- from = {x = 8, y = 6}, +-- to = {x = 16, y = 12} +-- }, +-- highlightedStrings = { +-- [31] = 0xFF4444, +-- [33] = 0x55FF55, +-- }, +-- scrollbars = { +-- vertical = true, +-- horizontal = true, +-- } -- } --- local highlightedStrings = { --- {number = 31, color = 0xFF4444}, --- {number = 32, color = 0xFF4444}, --- } - --- syntax.viewCode(20, 5, 100, 40, strings, maximumStringWidth, 1, 20, true, selection, highlightedStrings) +-- syntax.viewCode(args) +-- buffer.draw() ----------------------------------------------------------------------------------------------------------------