diff --git a/Applications.txt b/Applications.txt index 11a03488..37a1471e 100644 --- a/Applications.txt +++ b/Applications.txt @@ -6,6 +6,7 @@ ["name"]="OS.lua", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/OS.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=3.0, }, { @@ -121,133 +122,127 @@ { ["name"]="MineOS/System/OS/Icons/3DModel.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/3DModel.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Computer.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Computer.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Robot.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Robot.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Tablet.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Tablet.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Pastebin.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Pastebin.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Love.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Love.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/HDD.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/HDD.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Floppy.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Floppy.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Steve.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Steve.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Folder.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Folder.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Finger.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Finger.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/FileNotExists.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/FileNotExists.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Script.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Script.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Text.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Text.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Update.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Update.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Security.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Security.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Config.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Config.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Image.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Image.pic", - ["type"]="Script", - ["version"]=1.0, - }, - { - ["name"]="MineOS/System/OS/Icons/RawImage.pic", - ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/RawImage.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Lua.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Lua.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/SampleIcon.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/SampleIcon.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, { ["name"]="MineOS/System/OS/Icons/Archive.pic", ["url"]="IgorTimofeev/OpenComputers/master/MineOS/Icons/Archive.pic", - ["type"]="Script", + ["type"]="Icon", ["version"]=1.0, }, @@ -398,12 +393,14 @@ ["name"]="init.lua", ["url"]="IgorTimofeev/OpenComputers/master/Applications/init.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="etc/profile", ["url"]="IgorTimofeev/OpenComputers/master/etc/profile", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { @@ -416,45 +413,61 @@ ["name"]="bin/event.lua", ["url"]="IgorTimofeev/OpenComputers/master/Applications/event.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="bin/clear.lua", ["url"]="IgorTimofeev/OpenComputers/master/Applications/clear.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="bin/scale.lua", ["url"]="IgorTimofeev/OpenComputers/master/Applications/scale.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="usr/misc/greetings/English.txt", ["url"]="IgorTimofeev/OpenComputers/master/Applications/Motd/English.txt", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="usr/misc/greetings/Russian.txt", ["url"]="IgorTimofeev/OpenComputers/master/Applications/Motd/Russian.txt", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="etc/motd", ["url"]="IgorTimofeev/OpenComputers/master/Applications/Motd/motd.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, { ["name"]="bin/archive.lua", ["url"]="IgorTimofeev/OpenComputers/master/Applications/archive.lua", ["type"]="Script", + ["forceDownload"]=true, ["version"]=1.0, }, ----------------------------------------------------- Приложения без ресурсов -------------------------------------------------------------------------- + { + ["name"]="MineOS/Applications/AppMarket", + ["url"]="IgorTimofeev/OpenComputers/master/Applications/AppMarket/AppMarket.lua", + ["type"]="Application", + ["icon"]="IgorTimofeev/OpenComputers/master/Applications/AppMarket/Icon.pic", + ["createShortcut"]="dock", + ["forceDownload"]=true, + ["version"]=1.0, + }, { ["name"]="MineOS/Applications/Graph", ["url"]="IgorTimofeev/OpenComputers/master/Applications/Graph/Graph.lua", @@ -584,6 +597,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Photoshop/Icon.pic", ["createShortcut"]="dock", + ["forceDownload"]=true, ["version"]=1.0, }, { @@ -625,6 +639,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Finder/Icon.pic", ["createShortcut"]="dock", + ["forceDownload"]=true, ["version"]=1.0, }, { @@ -633,7 +648,7 @@ ["about"]="IgorTimofeev/OpenComputers/master/Applications/Control/About.txt", ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Control/Icon.pic", - ["createShortcut"]="dock", + ["createShortcut"]="desktop", ["version"]=1.0, }, { @@ -651,6 +666,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Calendar/Icon.pic", ["createShortcut"]="dock", + ["forceDownload"]=true, ["version"]=1.0, }, { @@ -704,6 +720,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Autorun/Icon.pic", ["createShortcut"]="desktop", + ["forceDownload"]=true, ["version"]=1.0, }, { @@ -808,6 +825,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/VK/Icon.pic", ["createShortcut"]="dock", + ["forceDownload"]=true, ["version"]=1.0, ["resources"]={ { @@ -900,6 +918,7 @@ ["type"]="Application", ["icon"]="IgorTimofeev/OpenComputers/master/Applications/Viewer/Icon.pic", ["createShortcut"]="desktop", + ["forceDownload"]=true, ["version"]=1.0, ["resources"]={ { diff --git a/Applications/AppMarket/AppMarket.lua b/Applications/AppMarket/AppMarket.lua new file mode 100644 index 00000000..6b55d395 --- /dev/null +++ b/Applications/AppMarket/AppMarket.lua @@ -0,0 +1,433 @@ + +local libraries = { + buffer = "doubleBuffering", + MineOSCore = "MineOSCore", + image = "image", + GUI = "GUI", + fs = "filesystem", + component = "component", + unicode = "unicode", + files = "files", + ecs = "ECSAPI", +} + +for library in pairs(libraries) do if not _G[library] then _G[library] = require(libraries[library]) end end; libraries = nil + +------------------------------------------------------------------------------------------------------------------ + +local obj = {} +local sizes = {} +local colors = { + topBar = 0xDDDDDD, + main = 0xFFFFFF, + topBarElementText = 0x444444, + topBarElement = 0xCCCCCC, + statusBar = 0xDDDDDD, + statusBarText = 0x888888, + appName = 0x262626, + version = 0x555555, + description = 0x888888, + downloadButton = 0xAAAAAA, + downloadButtonText = 0xFFFFFF, + downloading = 0x009240, + downloadingText = 0xFFFFFF, + downloaded = 0xCCCCCC, + downloadedText = 0xFFFFFF, +} + +local typeFilters = { + "Application", + "Library", + "Wallpaper", + "Script", +} + +local appStorePath = "MineOS/System/AppStore/" +local pathToApplications = "MineOS/System/OS/Applications.txt" +local updateImage = image.load(MineOSCore.paths.icons .. "Update.pic") +-- local topBarElements = {{title = "Приложения", type = "Application"}, {title = "Библиотеки", type = "Library"}, {title = "Обои", type = "Wallpaper"}, {title = "Другое"}, {title = "Обновления"}} +local topBarElements = {"Приложения", "Библиотеки", "Обои", "Другое", "Обновления"} +local oldApplications, newApplications, changes = {}, {}, {} +local currentApps = {} + +local currentTopBarElement = 1 +local from, limit, fromY = 1, 8 + +------------------------------------------------------------------------------------------------------------------ + +local function correctDouble(number) + return string.format("%.1f", number) +end + +local function status(text) + text = unicode.sub(text, 1, sizes.width - 2) + local y = sizes.y + sizes.height - 1 + buffer.square(sizes.x, y, sizes.width, 1, colors.statusBar, colors.statusBarText, " ") + buffer.text(sizes.x + 1, y, colors.statusBarText, text) + buffer.draw() +end + +local function calculateSizes() + sizes.width, sizes.height = math.floor(buffer.screen.width * 0.6), math.floor(buffer.screen.height * 0.7) + sizes.x, sizes.y = math.floor(buffer.screen.width / 2 - sizes.width / 2), math.floor(buffer.screen.height / 2 - sizes.height / 2) + sizes.topBarHeight = 3 + sizes.yMain = sizes.y + sizes.topBarHeight + sizes.mainHeight = sizes.height - sizes.topBarHeight + sizes.downloadButtonWidth = 17 + sizes.descriptionTruncateSize = sizes.width - 6 - MineOSCore.iconWidth - sizes.downloadButtonWidth +end + +local function drawTopBar() + obj.topBarButtons = GUI.toolbar(sizes.x, sizes.y, sizes.width, sizes.topBarHeight, 2, currentTopBarElement, colors.topBar, colors.topBarElementText, colors.topBarElement, colors.topBarElementText, table.unpack(topBarElements)) + obj.windowActionButtons = GUI.windowActionButtons(sizes.x + 1, sizes.y) +end + +local function getIcon(url) + local success, response = ecs.internetRequest(url) + local path = appStorePath .. "TempIcon.pic" + if success then + local file = io.open(path, "w") + file:write(response) + file:close() + else + GUI.error(tostring(response), {title = {color = 0xFFDB40, text = "Ошибка при загрузке иконки"}}) + end + return image.load(path) +end + +local function getDescription(url) + local success, response = ecs.internetRequest(url) + if success then + return response + else + GUI.error(tostring(response), {title = {color = 0xFFDB40, text = "Ошибка при загрузке описания приложения"}}) + end +end + +local function getApplication(i) + currentApps[i] = {} + currentApps[i].name = fs.name(newApplications[i].name) + + if newApplications[i].icon then + currentApps[i].icon = getIcon(newApplications.GitHubUserURL .. newApplications[i].icon) + else + if newApplications[i].type == "Application" then + currentApps[i].icon = failureIcon + elseif newApplications[i].type == "Wallpaper" then + currentApps[i].icon = MineOSCore.icons.image + elseif newApplications[i].type == "Library" then + currentApps[i].icon = MineOSCore.icons.lua + else + currentApps[i].icon = MineOSCore.icons.script + end + end + + if newApplications[i].about then + currentApps[i].description = getDescription(newApplications.GitHubUserURL .. newApplications[i].about) + currentApps[i].description = ecs.stringWrap({currentApps[i].description}, sizes.descriptionTruncateSize ) + else + currentApps[i].description = {"Описание отсутствует"} + end + + if newApplications[i].version then + currentApps[i].version = "Версия: " .. correctDouble(newApplications[i].version) + else + currentApps[i].version = "Версия не указана" + end +end + +local function checkAppExists(name, type) + if type == "Application" then + name = name .. ".app" + end + return fs.exists(name) +end + +local function drawApplication(x, y, i, doNotDrawButton) + buffer.image(x, y, currentApps[i].icon) + buffer.text(x + 10, y, colors.appName, currentApps[i].name) + buffer.text(x + 10, y + 1, colors.version, currentApps[i].version) + local appExists = checkAppExists(newApplications[i].name, newApplications[i].type) + local text = appExists and "Обновить" or "Загрузить" + + if not doNotDrawButton then + local xButton, yButton = sizes.x + sizes.width - sizes.downloadButtonWidth - 2, y + 1 + if currentApps[i].buttonObject then + currentApps[i].buttonObject.x, currentApps[i].buttonObject.y = xButton, yButton + currentApps[i].buttonObject:draw() + else + currentApps[i].buttonObject = GUI.button(xButton, yButton, sizes.downloadButtonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x555555, 0xFFFFFF, text) + end + end + + for j = 1, #currentApps[i].description do + buffer.text(x + 10, y + j + 1, colors.description, currentApps[i].description[j]) + end + y = y + (#currentApps[i].description > 2 and #currentApps[i].description - 2 or 0) + y = y + 5 + + return x, y +end + +local function drawPageSwitchButtons(y) + local text = "Приложения с " .. from .. " по " .. from + limit - 1 + local textLength = unicode.len(text) + local buttonWidth = 5 + local width = buttonWidth * 2 + textLength + 2 + local x = math.floor(sizes.x + sizes.width / 2 - width / 2) + obj.prevPageButton = GUI.button(x, y, buttonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x262626, 0xFFFFFF, "<") + x = x + obj.prevPageButton.width + 1 + buffer.text(x, y, colors.version, text) + x = x + textLength + 1 + obj.nextPageButton = GUI.button(x, y, buttonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x262626, 0xFFFFFF, ">") +end + +local function clearMainZone() + buffer.square(sizes.x, sizes.yMain, sizes.width, sizes.mainHeight, 0xFFFFFF) +end + +local function drawMain(refreshData) + clearMainZone() + local x, y = sizes.x + 2, fromY + + buffer.setDrawLimit(sizes.x, sizes.yMain, sizes.width, sizes.mainHeight) + + local matchCount = 1 + for i = 1, #newApplications do + if newApplications[i].type == typeFilters[currentTopBarElement] then + if matchCount >= from and matchCount <= from + limit - 1 then + if refreshData and not currentApps[i] then + status("Загрузка информации о приложении \"" .. newApplications[i].name .. "\"") + getApplication(i) + end + x, y = drawApplication(x, y, i) + -- else + -- ecs.error(matchCount, from, from + limit - 1) + -- break + end + matchCount = matchCount + 1 + end + end + + if matchCount > limit then + drawPageSwitchButtons(y) + end + + buffer.resetDrawLimit() +end + +local function getNewApplications() + local pathToNewApplications = "MineOS/System/OS/AppStore/NewApplications.txt" + ecs.getFileFromUrl(oldApplications.GitHubApplicationListURL, pathToNewApplications) + newApplications = files.loadTableFromFile(pathToNewApplications) +end + +local function getChanges() + changes = {} + for i = 1, #oldApplications do + -- local fileExistsInNewApplications + for j = 1, #newApplications do + if oldApplications[i].name == newApplications[j].name then + if oldApplications[i].version < newApplications[j].version then + table.insert(changes, newApplications[j]) + changes[#changes].newApplicationsIndex = j + end + end + end + end +end + +local function updates() + clearMainZone() + + if #changes > 0 then + buffer.setDrawLimit(sizes.x, sizes.yMain, sizes.width, sizes.mainHeight) + local x, y = sizes.x + 2, fromY + obj.updateAllButton = GUI.button(math.floor(sizes.x + sizes.width / 2 - sizes.downloadButtonWidth / 2), y, 20, 1, colors.downloadButton, colors.downloadButtonText, 0x555555, 0xFFFFFF, "Обновить все") + y = y + 2 + + for i = from, (from + limit) do + if not changes[i] then break end + if not currentApps[changes[i].newApplicationsIndex] then + status("Загрузка информации о приложении \"" .. changes[i].name .. "\"") + getApplication(changes[i].newApplicationsIndex) + end + x, y = drawApplication(x, y, changes[i].newApplicationsIndex, true) + end + + if #changes > limit then + drawPageSwitchButtons(y) + end + buffer.resetDrawLimit() + else + local text = "У вас самое новое ПО" + buffer.text(math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2), math.floor(sizes.yMain + sizes.mainHeight / 2 - 1), colors.description, text) + end +end + +local function flush() + fromY = sizes.yMain + 1 + from = 1 + fs.makeDirectory(appStorePath) + currentApps = {} + changes = {} +end + +local function loadOldApplications() + oldApplications = files.loadTableFromFile(pathToApplications) +end + +local function saveOldApplications() + files.saveTableToFile(pathToApplications, oldApplications) +end + +local function drawAll(refreshIcons, force) + drawTopBar() + if currentTopBarElement == 5 then + updates() + else + drawMain(refreshIcons) + end + buffer.draw(force) +end + +local function updateImageWindow() + clearMainZone() + local x, y = math.floor(sizes.x + sizes.width / 2 - updateImage.width / 2), math.floor(sizes.yMain + sizes.mainHeight / 2 - updateImage.height / 2 - 2) + buffer.image(x, y, updateImage) + return y + updateImage.height +end + +local function updateImageWindowWithText(text) + local y = updateImageWindow() + 2 + local x = math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2) + buffer.text(x, y, colors.description, text) +end + +local function updateAll() + local y = updateImageWindow() + local barWidth = math.floor(sizes.width * 0.6) + local xBar = math.floor(sizes.x + sizes.width / 2 - barWidth / 2) + y = y + 2 + for i = 1, #changes do + local text = "Обновление " .. fs.name(changes[i].name) + local xText = math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2) + buffer.square(sizes.x, y + 1, sizes.width, 1, 0xFFFFFF) + buffer.text(xText, y + 1, colors.description, text) + GUI.progressBar(xBar, y, barWidth, 1, 0xAAAAAA, 0x55FF55, i, #changes, true) + buffer.draw() + ecs.getOSApplication(newApplications[changes[i].newApplicationsIndex], true) + end + oldApplications = newApplications + saveOldApplications() +end + +------------------------------------------------------------------------------------------------------------------ + +-- buffer.start() +-- buffer.clear(0xFF8888) + +calculateSizes() +flush() +loadOldApplications() +drawTopBar() +GUI.windowShadow(sizes.x, sizes.y, sizes.width, sizes.height, 50) +updateImageWindowWithText("Загрузка списка приложений") +buffer.draw() +getNewApplications() +drawAll(true, false) + +while true do + local e = {event.pull()} + if e[1] == "touch" then + if currentTopBarElement < 5 then + for appIndex, app in pairs(currentApps) do + if app.buttonObject:isClicked(e[3], e[4]) then + app.buttonObject:press(0.3) + if app.buttonObject.text == "Обновить" or app.buttonObject.text == "Загрузить" then + app.buttonObject.text = "Загрузка" + app.buttonObject.disabled = true + app.buttonObject.colors.disabled.button, app.buttonObject.colors.disabled.text = colors.downloading, colors.downloadingText + app.buttonObject:draw() + buffer.draw() + ecs.getOSApplication(newApplications[appIndex], true) + app.buttonObject.text = "Установлено" + app.buttonObject.colors.disabled.button, app.buttonObject.colors.disabled.text = colors.downloaded, colors.downloadedText + app.buttonObject:draw() + buffer.draw() + end + break + end + end + else + if obj.updateAllButton and obj.updateAllButton:isClicked(e[3], e[4]) then + obj.updateAllButton:press() + updateAll() + flush() + drawAll() + end + end + + if obj.nextPageButton then + if obj.nextPageButton:isClicked(e[3], e[4]) then + obj.nextPageButton:press() + fromY = sizes.yMain + 1 + from = from + limit + drawAll(true, false) + elseif obj.prevPageButton:isClicked(e[3], e[4]) then + if from > limit then + fromY = sizes.yMain + 1 + from = from - limit + drawAll(true, false) + end + end + end + + if obj.windowActionButtons.close:isClicked(e[3], e[4]) then + obj.windowActionButtons.close:press() + return + end + + for key, button in pairs(obj.topBarButtons) do + if button:isClicked(e[3], e[4]) then + currentTopBarElement = key + flush() + if key < 5 then + drawAll(true, false) + else + status("Получаю изменения") + getChanges() + drawAll(false, false) + end + break + end + end + elseif e[1] == "scroll" then + -- if currentTopBarElement < 5 then + if e[5] == 1 then + if (fromY < sizes.yMain) then + fromY = fromY + 2 + drawAll(false, false) + end + else + fromY = fromY - 2 + drawAll(false, false) + end + -- else + -- if e[5] == 1 then + + -- else + -- end + -- end + end +end + + + + + + + + + + diff --git a/Applications/AppMarket/Icon.pic b/Applications/AppMarket/Icon.pic new file mode 100644 index 00000000..4e9fec95 Binary files /dev/null and b/Applications/AppMarket/Icon.pic differ diff --git a/Installer/Installer.lua b/Installer/Installer.lua index 4f40116e..1e9fa5a6 100644 --- a/Installer/Installer.lua +++ b/Installer/Installer.lua @@ -207,7 +207,7 @@ end ecs.prepareToExit() -local downloadWallpapers, showHelpTips = false, false +local downloadWallpapers, showHelpTips, downloadAllApps = false, false, false do @@ -220,8 +220,23 @@ do waitForClickOnButton("Select language") - local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", ecs.colors.orange, "Select language"}, {"EmptyLine"}, {"Select", 0xFFFFFF, ecs.colors.green, "Russian", "English"}, {"EmptyLine"}, {"CenterText", ecs.colors.orange, "Change some OS properties"}, {"EmptyLine"}, {"Switch", 0xF2B233, 0xffffff, 0xFFFFFF, "Download wallpapers", true}, {"EmptyLine"}, {"Switch", 0xF2B233, 0xffffff, 0xFFFFFF, "Show help tips in OS", true}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0x262626, "OK"}}) - downloadWallpapers, showHelpTips = data[2], data[3] + local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, + {"EmptyLine"}, + {"CenterText", ecs.colors.orange, "Select language"}, + {"EmptyLine"}, + {"Select", 0xFFFFFF, ecs.colors.green, "Russian", "English"}, + {"EmptyLine"}, + {"CenterText", ecs.colors.orange, "Change some OS properties"}, + {"EmptyLine"}, + {"Switch", 0xF2B233, 0xffffff, 0xFFFFFF, "Download all Apps", true}, + {"EmptyLine"}, + {"Switch", 0xF2B233, 0xffffff, 0xFFFFFF, "Download wallpapers", true}, + {"EmptyLine"}, + {"Switch", 0xF2B233, 0xffffff, 0xFFFFFF, "Show help tips in OS", true}, + {"EmptyLine"}, + {"Button", {ecs.colors.orange, 0x262626, "OK"}} + ) + downloadAllApps, downloadWallpapers, showHelpTips = data[2], data[3], data[4] --УСТАНАВЛИВАЕМ НУЖНЫЙ ЯЗЫК _G.OSSettings = { showHelpOnApplicationStart = showHelpTips, language = data[1] } @@ -338,13 +353,27 @@ do ecs.progressBar(xBar, yBar, barWidth, 1, 0xcccccc, ecs.colors.blue, 0) os.sleep(timing) - for app = 1, #applications do + local thingsToDownload = {} + for i = 1, #applications do + if + (applications[i].type == "Wallpaper" and downloadWallpapers) + or + (applications[i].type == "Application" and (downloadAllApps or applications[i].forceDownload)) + or + (applications[i].type == "Library" or applications[i].type == "Icon") + or + (applications[i].forceDownload) + then + table.insert(thingsToDownload, applications[i]) + end + + for app = 1, #thingsToDownload do --ВСЕ ДЛЯ ГРАФОНА - drawInfo(xBar, yBar + 1, lang.downloading .. " " .. applications[app]["name"]) - local percent = app / #applications * 100 + drawInfo(xBar, yBar + 1, lang.downloading .. " " .. thingsToDownload[app]["name"]) + local percent = app / #thingsToDownload * 100 ecs.progressBar(xBar, yBar, barWidth, 1, 0xcccccc, ecs.colors.blue, percent) - ecs.getOSApplication(applications[app], downloadWallpapers) + ecs.getOSApplication(thingsToDownload[app]) end os.sleep(timing) diff --git a/lib/ECSAPI.lua b/lib/ECSAPI.lua index e56ca4c2..16198815 100644 --- a/lib/ECSAPI.lua +++ b/lib/ECSAPI.lua @@ -94,6 +94,20 @@ function ecs.internetRequest(url) end end +--Загрузка файла с инета +function ecs.getFileFromUrl(url, path) + local success, response = ecs.internetRequest(url) + if success then + fs.makeDirectory(fs.path(path) or "") + local file = io.open(path, "w") + file:write(response) + file:close() + else + ecs.error("Could not connect to to URL address \"" .. url .. "\"") + return + end +end + --Отключение принудительного завершения программ function ecs.disableInterrupting() _G.eventInterruptBackup = package.loaded.event.shouldInterrupt @@ -270,27 +284,6 @@ function ecs.duplicateFileSystem(fromAddress, toAddress) shell.execute("bin/cp -rx "..source.."* "..destination) end ---Загрузка файла с инета -function ecs.getFileFromUrl(url, path) - if not _G.internet then _G.internet = require("internet") end - - local result, response = pcall(internet.request, url) - if not result then - ecs.error("Could not connect to to URL address \"" .. url .. "\"") - return - end - - fs.remove(path) - fs.makeDirectory(fs.path(path)) - local file = io.open(path, "w") - - for chunk in response do - file:write(chunk) - end - - file:close() -end - --Загрузка файла с пастебина function ecs.getFromPastebin(paste, path) local url = "http://pastebin.com/raw.php?i=" .. paste @@ -304,8 +297,7 @@ function ecs.getFromGitHub(url, path) end --Загрузить ОС-приложение -function ecs.getOSApplication(application, downloadWallpapers) - if downloadWallpapers == nil then downloadWallpapers = true end +function ecs.getOSApplication(application) --Если это приложение if application.type == "Application" then --Удаляем приложение, если оно уже существовало и создаем все нужные папочки @@ -343,13 +335,7 @@ function ecs.getOSApplication(application, downloadWallpapers) --Если тип = другой, чужой, а мб и свой пастебин elseif application.type == "Pastebin" then ecs.getFromPastebin(application.url, application.name) - - --Если обои - elseif application.type == "Wallpaper" then - if downloadWallpapers then - ecs.getFromGitHub(application.url, application.name) - end - + --Если просто какой-то скрипт elseif application.type == "Script" or application.type == "Library" then ecs.getFromGitHub(application.url, application.name) @@ -1090,6 +1076,7 @@ end --Очистить экран, установить комфортные цвета и поставить курсок на 1, 1 function ecs.prepareToExit(color1, color2) + term.setCursor(1, 1) ecs.clearScreen(color1 or 0x333333) gpu.setForeground(color2 or 0xffffff) gpu.set(1, 1, "") diff --git a/lib/GUI.lua b/lib/GUI.lua index 340dbb5c..22be2829 100644 --- a/lib/GUI.lua +++ b/lib/GUI.lua @@ -187,6 +187,42 @@ function GUI.windowActionButtons(x, y, fatSymbol) return windowActionButtons end +function GUI.toolbar(x, y, width, height, spaceBetweenElements, currentElement, toolbarColor, elementTextColor, activeElementColor, activeElementTextColor, ...) + local elements, objects, elementLength, isCurrent, elementWidth = {...}, {} + local totalWidth = 0; for i = 1, #elements do totalWidth = totalWidth + unicode.len(elements[i]) + 2 + spaceBetweenElements end; totalWidth = totalWidth - spaceBetweenElements + buffer.square(x, y, width, height, toolbarColor) + x = math.floor(x + width / 2 - totalWidth / 2) + local yText = math.floor(y + height / 2) + + for i = 1, #elements do + elementLength, isCurrent = unicode.len(elements[i]), i == currentElement + elementWidth = elementLength + 2 + if isCurrent then buffer.square(x, y, elementWidth, height, activeElementColor) end + buffer.text(x + 1, yText, isCurrent and activeElementTextColor or elementTextColor, elements[i]) + table.insert(objects, GUI.object(x, y, elementWidth, height)) + x = x + elementWidth + spaceBetweenElements + end + + return objects +end + +function GUI.progressBar(x, y, width, height, firstColor, secondColor, value, maxValue, thin) + local percent = value / maxValue + local activeWidth = math.floor(percent * width) + if thin then + buffer.text(x, y, firstColor, string.rep("━", width)) + buffer.text(x, y, secondColor, string.rep("━", activeWidth)) + else + buffer.square(x, y, width, height, firstColor) + buffer.square(x, y, activeWidth, height, secondColor) + end +end + +function GUI.windowShadow(x, y, width, height, transparency) + buffer.square(x + width, y + 1, 2, height, 0x000000, 0x000000, " ", transparency) + buffer.square(x + 2, y + height, width - 2, 1, 0x000000, 0x000000, " ", transparency) +end + ------------------------------------------------- Окна ------------------------------------------------------------------- -- Красивое окошко для отображения сообщения об ошибке. Аргумент errorWindowParameters может принимать следующие значения: diff --git a/lib/MineOSCore.lua b/lib/MineOSCore.lua index af66f458..fc826383 100644 --- a/lib/MineOSCore.lua +++ b/lib/MineOSCore.lua @@ -125,16 +125,21 @@ end function MineOSCore.safeLaunch(command, ...) local oldResolutionWidth, oldResolutionHeight = component.gpu.getResolution() - local success, reason = pcall(loadfile(command), ...) - component.gpu.setResolution(oldResolutionWidth, oldResolutionHeight) - --Ебал я автора мода в задницу, кусок ебанутого говна - --Какого хуя я должен вставлять кучу костылей в свой прекрасный код только потому, что эта ублюдочная - --скотина захотела выдавать 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 loadSuccess, loadReason = loadfile(command) + 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}}) + end + else + component.gpu.setResolution(oldResolutionWidth, oldResolutionHeight) + GUI.error(loadReason, {title = {color = 0xFFDB40, text = MineOSCore.localization.errorWhileRunningProgram}}) end buffer.start() end