-- _G.syntax = nil -- _G.filemanager = nil -- _G.doubleBuffering = nil -- package.loaded.doubleBuffering = nil -- package.loaded.syntax = nil -- package.loaded.filemanager = nil -- Адаптивная загрузка необходимых библиотек и компонентов local libraries = { ecs = "ECSAPI", fs = "fs", syntax = "syntax", buffer = "buffer", unicode = "unicode", context = "context", event = "event", component = "component", filemanager = "filemanager", } local components = { gpu = "gpu", } for library in pairs(libraries) do if not _G[library] then _G[library] = require(libraries[library]) end end for comp in pairs(components) do if not _G[comp] then _G[comp] = _G.component[components[comp]] end end libraries, components = nil, nil --------------------------------------------------- Константы ------------------------------------------------------------------ local pathToFile = "OS.lua" local fileSize = 0 local indentationWidth = 4 local strings local maximumStringWidth local fromString = 1 local fromSymbol = 1 local scrollSpeed = 8 local showLuaSyntax = true local showFilemanager = true local xCursor, yCursor = 1, 1 local textFieldPosition local selection = { from = { x = 18, y = 6 }, to = { x = 4, y = 8 } } local highlightedStrings = { [31] = 0xFF4444, [32] = 0xFF4444, [34] = 0x66FF66, } local colors = { infoPanel = 0xCCCCCC, infoPanelText = 0x262626, topBar = 0xDDDDDD, topBarButton = 0xCCCCCC, topBarButtonText = 0x262626, topMenu = 0xFFFFFF, topMenuText = 0x262626, } local topButtonsSymbols = { launch = "‣", toggleSyntax = "*", } local sizes = { yTopBar = 2, topBarHeight = 3, filemanagerWidth = math.floor(buffer.screen.width * 0.16), } --------------------------------------------------- Функции ------------------------------------------------------------------ local function recalculateSizes() sizes.yCode = sizes.yTopBar + sizes.topBarHeight sizes.codeHeight = buffer.screen.height - 1 - sizes.topBarHeight if showFilemanager then sizes.codeWidth = buffer.screen.width - sizes.filemanagerWidth sizes.xCode = sizes.filemanagerWidth + 1 else sizes.codeWidth = buffer.screen.width sizes.xCode = 1 end end --Объекты для тача local obj = {} local function newObj(class, name, ...) obj[class] = obj[class] or {} obj[class][name] = {...} end local function readFile(path) if fs.exists(path) then maximumStringWidth = 0 strings = {} fileSize = math.floor(fs.size(path) / 1024) local file = io.open(path, "r") for line in file:lines() do line = string.gsub(line, " ", string.rep(" ", indentationWidth)) maximumStringWidth = math.max(maximumStringWidth, unicode.len(line)) table.insert(strings, line) end file:close() else ecs.error("Файл \"" .. path .. "\" не существует") end end local function drawInfoPanel() local width = math.floor(buffer.screen.width * 0.3) local x, y = math.floor(buffer.screen.width / 2 - width / 2), 2 buffer.square(x, y, width, 3, colors.infoPanel, 0x000000, " ") local textArray = { "Файл: " .. pathToFile .. ", " .. fileSize .. "KB", "Позиция курсора: " .. xCursor .. "x" .. yCursor, } for i = 1, #textArray do textArray[i] = ecs.stringLimit("end", textArray[i], width) x = math.floor(buffer.screen.width / 2 - unicode.len(textArray[i]) / 2) buffer.text(x, y, colors.infoPanelText, textArray[i]) y = y + 1 end end local function drawTopBar() obj["TopBarButtons"] = {} local x, y = 1, sizes.yTopBar local buttonWidth = 7 buffer.square(x, y, buffer.screen.width, sizes.topBarHeight, colors.topBar, 0x000000, " ") local buttonNames = { topButtonsSymbols.launch, topButtonsSymbols.toggleSyntax, } for i = 1, #buttonNames do newObj("TopBarButtons", buttonNames[i], buffer.button(x, y, buttonWidth, 3, colors.topBarButton, colors.topBarButtonText, buttonNames[i])) x = x + buttonWidth + 1 end end local function drawTopMenu() local x, y = 1, 1 buffer.square(x, y, buffer.screen.width, 1, colors.topMenu, 0x000000, " ") local buttonNames = { "Файл", "Правка", "Вид", "О программе" } for i = 1, #buttonNames do local length = unicode.len(buttonNames[i]) + 2 buffer.button(x, y, length, 1, colors.topMenu, colors.topMenuText, buttonNames[i]) x = x + length end end local function drawCode() textFieldPosition = syntax.viewCode( { x = sizes.xCode, y = sizes.yCode, width = sizes.codeWidth, height = sizes.codeHeight, strings = strings, maximumStringWidth = maximumStringWidth, fromSymbol = fromSymbol, fromString = fromString, fromStringOnLineNumbers = fromString, highlightLuaSyntax = showLuaSyntax, selection = selection, highlightedStrings = highlightedStrings, scrollbars = { vertical = true, horizontal = true, } } ) end local function launch() local callback, reason = loadfile(pathToFile) if callback then ecs.prepareToExit() local success, reason = pcall(callback) if success then ecs.prepareToExit() print("Программа успешно выполнена!") else ecs.error("Ошибка при выполнении программы: " .. reason) end else ecs.error("Ошибка при запуске программы: " .. reason) end end -- local function convertCoordsToCursor(x, y) -- end local function drawFileManager() filemanager.draw(1, sizes.yCode, sizes.filemanagerWidth, buffer.screen.height - 4, fs.path(pathToFile), 1) end local function drawAll(force) drawTopBar() drawInfoPanel() drawTopMenu() if showFilemanager then drawFileManager() end drawCode() buffer.draw(force) end local function scroll(direction, count) if direction == "up" then if fromString > count then fromString = fromString - count drawInfoPanel(); drawCode(); buffer.draw() end elseif direction == "down" then if fromString < (#strings - count) then fromString = fromString + count drawInfoPanel(); drawCode(); buffer.draw() end elseif direction == "left" then if fromSymbol > count then fromSymbol = fromSymbol - count drawInfoPanel(); drawCode(); buffer.draw() end elseif direction == "right" then if fromSymbol < (maximumStringWidth - count) then fromSymbol = fromSymbol + count drawInfoPanel(); drawCode(); buffer.draw() end end end --------------------------------------------------- Начало работы скрипта ------------------------------------------------------------------ local args = { ... } if args[1] == "open" then pathToFile = args[2] end buffer.square(1, 1, buffer.screen.width, buffer.screen.height, ecs.colors.red, 0xFFFFFF, " ") buffer.draw(true) recalculateSizes() readFile(pathToFile) drawAll() while true do local e = { event.pull() } if e[1] == "touch" then for key in pairs(obj.TopBarButtons) do if ecs.clickedAtArea(e[3], e[4], obj.TopBarButtons[key][1], obj.TopBarButtons[key][2], obj.TopBarButtons[key][3], obj.TopBarButtons[key][4]) then buffer.button(obj.TopBarButtons[key][1], obj.TopBarButtons[key][2], 7, 3, ecs.colors.blue, ecs.colors.white, key) buffer.draw() os.sleep(0.2) buffer.button(obj.TopBarButtons[key][1], obj.TopBarButtons[key][2], 7, 3, colors.topBarButton, colors.topBarButtonText, key) buffer.draw() if key == topButtonsSymbols.launch then launch() drawAll() elseif key == topButtonsSymbols.toggleSyntax then showLuaSyntax = not showLuaSyntax drawAll() end break end end elseif e[1] == "key_down" then if e[4] == 200 then scroll("up", 1) elseif e[4] == 208 then scroll("down", 1) elseif e[4] == 203 then scroll("left", 1) elseif e[4] == 205 then scroll("right", 1) end elseif e[1] == "scroll" then if e[5] == 1 then scroll("up", scrollSpeed) else scroll("down", scrollSpeed) end end end