MineOS/lib/MineOSInterface.lua
2017-10-14 20:14:59 +03:00

1433 lines
49 KiB
Lua
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local component = require("component")
local computer = require("computer")
local keyboard = require("keyboard")
local event = require("event")
local term = require("term")
local MineOSCore = require("MineOSCore")
local MineOSPaths = require("MineOSPaths")
local image = require("image")
local GUI = require("GUI")
local fs = require("filesystem")
local unicode = require("unicode")
local buffer = require("doubleBuffering")
local MineOSInterface = {}
-----------------------------------------------------------------------------------------------------------------------------------
MineOSInterface.iconsCache = {}
MineOSInterface.iconWidth = 12
MineOSInterface.iconHeight = 6
MineOSInterface.iconClickDelay = 0.2
MineOSInterface.iconConfigFileName = ".icons"
-----------------------------------------------------------------------------------------------------------------------------------
function MineOSInterface.clearTerminal()
local gpu = component.gpu
gpu.setBackground(0x1D1D1D)
gpu.setForeground(0xFFFFFF)
local width, height = gpu.getResolution()
gpu.fill(1, 1, width, height, " ")
term.setCursor(1, 1)
end
function MineOSInterface.waitForPressingAnyKey()
print(" ")
print(MineOSCore.localization.pressAnyKeyToContinue)
while true do
local eventType = event.pull()
if eventType == "key_down" or eventType == "touch" then
break
end
end
end
function MineOSInterface.launchScript(path)
MineOSInterface.clearTerminal()
if MineOSInterface.safeLaunch(path) then
MineOSInterface.waitForPressingAnyKey()
end
end
-----------------------------------------------------------------------------------------------------------------------------------
function MineOSInterface.cacheIconSource(name, path)
if not MineOSInterface.iconsCache[name] then
MineOSInterface.iconsCache[name] = image.load(path)
end
return MineOSInterface.iconsCache[name]
end
local function iconDraw(icon)
local text = string.limit(MineOSCore.properties.showExtension and fs.name(icon.path) or fs.hideExtension(fs.name(icon.path)), icon.width, "center")
local textLength = unicode.len(text)
local textX, textY = math.floor(icon.x + icon.width / 2 - unicode.len(text) / 2), icon.y + icon.height - 1
if icon.selected then
local x, width = icon.x + 1, icon.width - 2
buffer.text(x, icon.y - 1, icon.colors.selection, string.rep("", width), icon.colors.selectionTransparency)
buffer.square(x, icon.y, width, icon.height - 2, icon.colors.selection, 0x000000, " ", icon.colors.selectionTransparency)
buffer.text(x, icon.y + icon.height - 2, icon.colors.selection, string.rep("", width), icon.colors.selectionTransparency)
buffer.square(textX, textY, textLength, 1, icon.colors.selection, 0x000000, " ", icon.colors.selectionTransparency)
end
buffer.text(textX, textY, icon.colors.text, text)
if icon.image then
if icon.cut then
if not icon.semiTransparentImage then
icon.semiTransparentImage = image.copy(icon.image)
for i = 3, #icon.semiTransparentImage, 4 do
icon.semiTransparentImage[i + 2] = icon.semiTransparentImage[i + 2] + 0.6
if icon.semiTransparentImage[i + 2] > 1 then
icon.semiTransparentImage[i + 2] = 1
end
end
end
buffer.image(icon.x + 2, icon.y, icon.semiTransparentImage, true)
else
buffer.image(icon.x + 2, icon.y, icon.image)
end
elseif icon.liveImage then
icon.liveImage(icon.x + 2, icon.y)
end
if icon.isShortcut then
buffer.set(icon.x + 9, icon.y + 3, 0xFFFFFF, 0x000000, "<")
end
if icon.windows then
buffer.text(icon.x + 5, icon.y + 4, 0x66DBFF, "╺╸")
end
end
local function iconEventHandler(mainContainer, object, eventData)
if eventData[1] == "touch" then
object.lastTouchPosition = object.lastTouchPosition or {}
object.lastTouchPosition.x, object.lastTouchPosition.y = eventData[3], eventData[4]
object:moveToFront()
object.selected = true
mainContainer:draw()
buffer.draw()
if eventData[5] == 0 then
object.parent.parent.onLeftClick(object, eventData)
else
object.parent.parent.onRightClick(object, eventData)
object.selected = false
mainContainer:draw()
buffer.draw()
end
elseif eventData[1] == "double_touch" and object:isClicked(eventData[3], eventData[4]) and eventData[5] == 0 then
object.parent.parent.onDoubleClick(object, eventData)
elseif eventData[1] == "drag" and object.parent.parent.iconConfigEnabled and object.lastTouchPosition then
object.localPosition.x = object.localPosition.x + eventData[3] - object.lastTouchPosition.x
object.localPosition.y = object.localPosition.y + eventData[4] - object.lastTouchPosition.y
object.lastTouchPosition.x, object.lastTouchPosition.y = eventData[3], eventData[4]
mainContainer:draw()
buffer.draw()
elseif eventData[1] == "drop" and object.parent.parent.iconConfigEnabled then
object.parent.parent.iconConfig[fs.name(object.path) .. (object.isDirectory and "/" or "")] = {
x = object.localPosition.x,
y = object.localPosition.y
}
object.parent.parent:saveIconConfig()
object.lastTouchPosition = nil
end
end
function MineOSInterface.icon(x, y, path, textColor, selectionColor)
local icon = GUI.object(x, y, MineOSInterface.iconWidth, MineOSInterface.iconHeight)
icon.colors = {
text = textColor,
selection = selectionColor,
selectionTransparency = 0.6
}
icon.path = path
icon.isDirectory = fs.isDirectory(icon.path)
icon.extension = fs.extension(icon.path) or "script"
icon.isShortcut = false
icon.selected = false
icon.draw = iconDraw
icon.launchers = table.copy(MineOSInterface.iconLaunchers)
icon.analyseExtension = iconAnalyseExtension
return icon
end
local function iconFieldUpdate(iconField)
iconField.backgroundObject.width, iconField.backgroundObject.height = iconField.width, iconField.height
iconField.iconsContainer.width, iconField.iconsContainer.height = iconField.width, iconField.height
iconField.iconCount.horizontal = math.floor((iconField.width - iconField.xOffset) / (MineOSInterface.iconWidth + iconField.spaceBetweenIcons.horizontal))
iconField.iconCount.vertical = math.floor((iconField.height - iconField.yOffset) / (MineOSInterface.iconHeight + iconField.spaceBetweenIcons.vertical))
iconField.iconCount.total = iconField.iconCount.horizontal * iconField.iconCount.vertical
return iconField
end
local function iconFieldLoadIconConfig(iconField)
if fs.exists(iconField.workpath .. MineOSInterface.iconConfigFileName) then
iconField.iconConfig = table.fromFile(iconField.workpath .. MineOSInterface.iconConfigFileName)
else
iconField.iconConfig = {}
end
end
local function iconFieldSaveIconConfig(iconField)
table.toFile(iconField.workpath .. MineOSInterface.iconConfigFileName, iconField.iconConfig)
end
local function iconFieldDeleteIconConfig(iconField)
iconField.iconConfig = {}
fs.remove(iconField.workpath .. MineOSInterface.iconConfigFileName, iconField.iconConfig)
end
-----------------------------------------------------------------------------------------------------------------------------------
MineOSInterface.iconLaunchers = {}
function MineOSInterface.iconLaunchers.application(icon)
MineOSInterface.applicationHelp(MineOSInterface.mainContainer, icon.path)
end
function MineOSInterface.iconLaunchers.directory(icon)
icon.parent.parent:setWorkpath(icon.path)
end
function MineOSInterface.iconLaunchers.shortcut(icon)
local oldPath = icon.path
icon.path = icon.shortcutPath
icon:shortcutLaunch()
icon.path = oldPath
end
function MineOSInterface.iconLaunchers.corrupted(icon)
GUI.error("Application is corrupted")
end
function MineOSInterface.iconLaunchers.extension(icon)
MineOSInterface.safeLaunch(MineOSCore.properties.extensionAssociations[icon.extension].launcher, icon.path, "-o")
end
function MineOSInterface.iconLaunchers.script(icon)
MineOSInterface.launchScript(icon.path)
end
function MineOSInterface.iconLaunchers.showPackageContent(icon)
icon.parent.parent:setWorkpath(icon.path)
icon.parent.parent:updateFileList()
icon:getFirstParent():draw()
buffer.draw()
end
function MineOSInterface.iconLaunchers.showContainingFolder(icon)
icon.parent.parent:setWorkpath(fs.path(icon.shortcutPath))
icon.parent.parent:updateFileList()
icon:getFirstParent():draw()
buffer.draw()
end
function iconAnalyseExtension(icon)
if icon.isDirectory then
if icon.extension == ".app" then
if MineOSCore.properties.showApplicationIcons then
if fs.exists(icon.path .. "/Resources/Icon.pic") then
icon.image = image.load(icon.path .. "/Resources/Icon.pic")
elseif fs.exists(icon.path .. "/Resources/Icon.lua") then
local data, reason = loadfile(icon.path .. "/Resources/Icon.lua")
if data then
data, reason = data()
if data then
icon.liveImage = data
else
error("Failed to load live icon image: " .. tostring(reason))
end
else
error("Failed to load live icon image: " .. tostring(reason))
end
else
icon.image = MineOSInterface.iconsCache.fileNotExists
end
else
icon.image = MineOSInterface.iconsCache.application
end
icon.launch = icon.launchers.application
else
icon.image = MineOSInterface.iconsCache.folder
icon.launch = icon.launchers.directory
end
else
if icon.extension == ".lnk" then
icon.shortcutPath = MineOSCore.readShortcut(icon.path)
icon.shortcutExtension = fs.extension(icon.shortcutPath)
icon.shortcutIsDirectory = fs.isDirectory(icon.shortcutPath)
icon.isShortcut = true
local shortcutIcon = iconAnalyseExtension({
path = icon.shortcutPath,
extension = icon.shortcutExtension,
isDirectory = icon.shortcutIsDirectory,
iconImage = icon.iconImage,
launchers = icon.launchers
})
icon.image = shortcutIcon.image
icon.shortcutLaunch = shortcutIcon.launch
icon.launch = icon.launchers.shortcut
shortcutIcon = nil
elseif not fs.exists(icon.path) then
icon.image = MineOSInterface.iconsCache.fileNotExists
icon.launch = icon.launchers.corrupted
else
if MineOSCore.properties.extensionAssociations[icon.extension] then
icon.launch = icon.launchers.extension
icon.image = MineOSInterface.cacheIconSource(icon.extension, MineOSCore.properties.extensionAssociations[icon.extension].icon)
else
icon.launch = icon.launchers.script
icon.image = MineOSInterface.iconsCache.script
end
end
end
return icon
end
-----------------------------------------------------------------------------------------------------------------------------------
local function getCykaIconPosition(iconField)
local y = iconField.yOffset
for i = 1, #iconField.iconsContainer.children do
y = math.max(y, iconField.iconsContainer.children[i].localPosition.y)
end
local x = iconField.xOffset
for i = 1, #iconField.iconsContainer.children do
if iconField.iconsContainer.children[i].localPosition.y == y then
x = math.max(x, iconField.iconsContainer.children[i].localPosition.x)
end
end
x = x + MineOSInterface.iconWidth + iconField.spaceBetweenIcons.horizontal
if x + MineOSInterface.iconWidth + iconField.spaceBetweenIcons.horizontal > iconField.iconsContainer.width then
x, y = iconField.xOffset, y + MineOSInterface.iconHeight + iconField.spaceBetweenIcons.vertical
end
return x, y
end
local function iconFieldUpdateFileList(iconField)
-- GUI.error(debug.traceback())
iconField.fileList = fs.sortedList(iconField.workpath, MineOSCore.properties.sortingMethod or "type", MineOSCore.properties.showHiddenFiles)
iconField:update()
-- Грузим инфу об иконочках
if iconField.iconConfigEnabled then
iconField:loadIconConfig()
end
local configList, notConfigList = {}, {}
for i = iconField.fromFile, iconField.fromFile + iconField.iconCount.total - 1 do
if iconField.fileList[i] then
if not iconField.filenameMatcher or string.unicodeFind(unicode.lower(iconField.fileList[i]), unicode.lower(iconField.filenameMatcher)) then
if iconField.iconConfigEnabled and iconField.iconConfig[iconField.fileList[i]] then
table.insert(configList, iconField.fileList[i])
else
table.insert(notConfigList, iconField.fileList[i])
end
end
else
break
end
end
local function checkClipboard(icon)
if MineOSCore.clipboard and MineOSCore.clipboard.cut then
for i = 1, #MineOSCore.clipboard do
if MineOSCore.clipboard[i] == icon.path then
icon.cut = true
end
end
end
end
-- Заполнение дочернего контейнера
iconField.iconsContainer:deleteChildren()
for i = 1, #configList do
local icon = iconField.iconsContainer:addChild(MineOSInterface.icon(
iconField.iconConfig[configList[i]].x,
iconField.iconConfig[configList[i]].y,
iconField.workpath .. configList[i],
iconField.colors.text,
iconField.colors.selection
))
checkClipboard(icon)
icon.eventHandler = iconEventHandler
icon.launchers = iconField.launchers
icon:analyseExtension()
end
local x, y
if #configList > 0 then
x, y = getCykaIconPosition(iconField, configList)
else
x, y = iconField.xOffset, iconField.yOffset
end
for i = 1, #notConfigList do
local icon = iconField.iconsContainer:addChild(MineOSInterface.icon(x, y, iconField.workpath .. notConfigList[i], iconField.colors.text, iconField.colors.selection))
iconField.iconConfig[notConfigList[i]] = {x = x, y = y}
checkClipboard(icon)
icon.eventHandler = iconEventHandler
icon.launchers = iconField.launchers
icon:analyseExtension()
x = x + MineOSInterface.iconWidth + iconField.spaceBetweenIcons.horizontal
if x + MineOSInterface.iconWidth + iconField.spaceBetweenIcons.horizontal - 1 > iconField.iconsContainer.width then
x, y = iconField.xOffset, y + MineOSInterface.iconHeight + iconField.spaceBetweenIcons.vertical
end
end
if iconField.iconConfigEnabled then
iconField:saveIconConfig()
end
return iconField
end
local function iconFieldBackgroundObjectEventHandler(mainContainer, object, eventData)
if eventData[1] == "touch" then
if eventData[5] == 0 then
object.parent:deselectAll()
object.parent.selection = {
x1 = eventData[3],
y1 = eventData[4]
}
mainContainer:draw()
buffer.draw()
else
local menu = MineOSInterface.contextMenu(eventData[3], eventData[4])
local subMenu = menu:addSubMenu(MineOSCore.localization.create)
subMenu:addItem(MineOSCore.localization.newFile).onTouch = function()
MineOSInterface.newFile(MineOSInterface.mainContainer, object.parent, eventData[3], eventData[4], object.parent.workpath)
end
subMenu:addItem(MineOSCore.localization.newFolder).onTouch = function()
MineOSInterface.newFolder(MineOSInterface.mainContainer, object.parent, eventData[3], eventData[4], object.parent.workpath)
end
subMenu:addItem(MineOSCore.localization.newFileFromURL, not component.isAvailable("internet")).onTouch = function()
MineOSInterface.newFileFromURL(MineOSInterface.mainContainer, object.parent, eventData[3], eventData[4], object.parent.workpath)
end
subMenu:addSeparator()
subMenu:addItem(MineOSCore.localization.newApplication).onTouch = function()
MineOSInterface.newApplication(MineOSInterface.mainContainer, object.parent, eventData[3], eventData[4], object.parent.workpath)
end
menu:addSeparator()
local subMenu = menu:addSubMenu(MineOSCore.localization.view)
subMenu:addItem(MineOSCore.properties.showExtension and MineOSCore.localization.hideExtension or MineOSCore.localization.showExtension).onTouch = function()
MineOSCore.properties.showExtension = not MineOSCore.properties.showExtension
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
subMenu:addItem(MineOSCore.properties.showHiddenFiles and MineOSCore.localization.hideHiddenFiles or MineOSCore.localization.showHiddenFiles).onTouch = function()
MineOSCore.properties.showHiddenFiles = not MineOSCore.properties.showHiddenFiles
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
subMenu:addItem(MineOSCore.properties.showApplicationIcons and MineOSCore.localization.hideApplicationIcons or MineOSCore.localization.showApplicationIcons).onTouch = function()
MineOSCore.properties.showApplicationIcons = not MineOSCore.properties.showApplicationIcons
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
local subMenu = menu:addSubMenu(MineOSCore.localization.sortBy)
subMenu:addItem(MineOSCore.localization.sortByName).onTouch = function()
object.parent:deleteIconConfig()
MineOSCore.properties.sortingMethod = "name"
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
subMenu:addItem(MineOSCore.localization.sortByDate).onTouch = function()
object.parent:deleteIconConfig()
MineOSCore.properties.sortingMethod = "date"
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
subMenu:addItem(MineOSCore.localization.sortByType).onTouch = function()
object.parent:deleteIconConfig()
MineOSCore.properties.sortingMethod = "type"
MineOSCore.saveProperties()
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addItem(MineOSCore.localization.sortAutomatically).onTouch = function()
object.parent:deleteIconConfig()
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addItem(MineOSCore.localization.update).onTouch = function()
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addSeparator()
menu:addItem(MineOSCore.localization.paste, not MineOSCore.clipboard).onTouch = function()
local i = 1
while i <= #MineOSCore.clipboard do
if fs.exists(MineOSCore.clipboard[i]) then
i = i + 1
else
table.remove(MineOSCore.clipboard, i)
end
end
MineOSInterface.copy(MineOSCore.clipboard, object.parent.workpath)
if MineOSCore.clipboard.cut then
for i = 1, #MineOSCore.clipboard do
fs.remove(MineOSCore.clipboard[i])
end
MineOSCore.clipboard = nil
end
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:show()
end
elseif eventData[1] == "drag" then
if object.parent.selection then
object.parent.selection.x2 = eventData[3]
object.parent.selection.y2 = eventData[4]
object:moveToFront()
mainContainer:draw()
buffer.draw()
end
elseif eventData[1] == "drop" then
object.parent.selection = nil
object:moveToBack()
mainContainer:draw()
buffer.draw()
end
end
local function iconFieldBackgroundObjectDraw(object)
if object.parent.selection and object.parent.selection.x2 then
local x1, y1, x2, y2 = object.parent.selection.x1, object.parent.selection.y1, object.parent.selection.x2, object.parent.selection.y2
if x2 < x1 then
x1, x2 = x2, x1
end
if y2 < y1 then
y1, y2 = y2, y1
end
buffer.square(x1, y1, x2 - x1 + 1, y2 - y1 + 1, object.parent.colors.selection, 0x0, " ", 0.6)
for i = 1, #object.parent.iconsContainer.children do
local xCenter, yCenter = object.parent.iconsContainer.children[i].x + MineOSInterface.iconWidth / 2, object.parent.iconsContainer.children[i].y + MineOSInterface.iconHeight / 2
object.parent.iconsContainer.children[i].selected =
xCenter >= x1 and
xCenter <= x2 and
yCenter >= y1 and
yCenter <= y2
end
end
end
local function iconFieldDeselectAll(iconField)
for i = 1, #iconField.iconsContainer.children do
iconField.iconsContainer.children[i].selected = false
end
end
local function iconFieldGetSelectedIcons(iconField)
local selectedIcons = {}
for i = 1, #iconField.iconsContainer.children do
if iconField.iconsContainer.children[i].selected then
table.insert(selectedIcons, iconField.iconsContainer.children[i])
end
end
return selectedIcons
end
local function iconFieldSetWorkpath(iconField, path)
iconField.workpath = path
iconField.filenameMatcher = nil
iconField.fromFile = 1
return iconField
end
function MineOSInterface.iconField(x, y, width, height, xSpaceBetweenIcons, ySpaceBetweenIcons, xOffset, yOffset, textColor, selectionColor, workpath)
local iconField = GUI.container(x, y, width, height)
iconField.colors = {
text = textColor,
selection = selectionColor
}
iconField.spaceBetweenIcons = {
horizontal = xSpaceBetweenIcons,
vertical = ySpaceBetweenIcons
}
iconField.iconConfig = {}
iconField.iconCount = {}
iconField.fileList = {}
iconField.fromFile = 1
iconField.iconConfigEnabled = false
iconField.xOffset = xOffset
iconField.yOffset = yOffset
iconField.workpath = workpath
iconField.filenameMatcher = nil
iconField.backgroundObject = iconField:addChild(GUI.object(1, 1, width, height))
iconField.backgroundObject.eventHandler = iconFieldBackgroundObjectEventHandler
iconField.backgroundObject.draw = iconFieldBackgroundObjectDraw
iconField.iconsContainer = iconField:addChild(GUI.container(1, 1, width, height))
iconField.updateFileList = iconFieldUpdateFileList
iconField.update = iconFieldUpdate
iconField.eventHandler = iconFieldEventHandler
iconField.deselectAll = iconFieldDeselectAll
iconField.loadIconConfig = iconFieldLoadIconConfig
iconField.saveIconConfig = iconFieldSaveIconConfig
iconField.deleteIconConfig = iconFieldDeleteIconConfig
iconField.getSelectedIcons = iconFieldGetSelectedIcons
iconField.setWorkpath = iconFieldSetWorkpath
iconField.onLeftClick = MineOSInterface.iconLeftClick
iconField.onRightClick = MineOSInterface.iconRightClick
iconField.onDoubleClick = MineOSInterface.iconDoubleClick
iconField.launchers = table.copy(MineOSInterface.iconLaunchers)
return iconField
end
----------------------------------------------------------------------------------------------------------------
function MineOSInterface.contextMenu(...)
local menu = GUI.contextMenu(...)
menu.colors.transparency.background = MineOSCore.properties.transparencyEnabled and GUI.colors.contextMenu.transparency.background
menu.colors.transparency.shadow = MineOSCore.properties.transparencyEnabled and GUI.colors.contextMenu.transparency.shadow
return menu
end
function MineOSInterface.iconLeftClick(icon, eventData)
if not keyboard.isKeyDown(29) and not keyboard.isKeyDown(219) then
icon.parent.parent:deselectAll()
end
icon.selected = true
MineOSInterface.OSDraw()
end
function MineOSInterface.iconDoubleClick(icon, eventData)
icon:launch()
computer.pushSignal("MineOSCore", "updateFileList")
end
function MineOSInterface.iconRightClick(icon, eventData)
icon.selected = true
MineOSInterface.OSDraw()
local selectedIcons = icon.parent.parent:getSelectedIcons()
local menu = MineOSInterface.contextMenu(eventData[3], eventData[4])
if #selectedIcons == 1 then
if icon.isDirectory then
if icon.extension == ".app" then
menu:addItem(MineOSCore.localization.showPackageContent).onTouch = function()
icon.parent.parent.launchers.showPackageContent(icon)
end
menu:addItem(MineOSCore.localization.launchWithArguments).onTouch = function()
MineOSCore.launchWithArguments(MineOSInterface.mainContainer, icon.path)
end
end
menu:addItem(MineOSCore.localization.archive).onTouch = function()
require("compressor").pack(fs.path(icon.path) .. fs.hideExtension(fs.name(icon.path)) .. ".pkg", icon.path)
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addSeparator()
else
if icon.isShortcut then
menu:addItem(MineOSCore.localization.editShortcut).onTouch = function()
MineOSInterface.editShortcut(MineOSInterface.mainContainer, icon.path)
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addItem(MineOSCore.localization.showContainingFolder).onTouch = function()
icon.parent.parent.launchers.showContainingFolder(icon)
end
menu:addSeparator()
else
if MineOSCore.properties.extensionAssociations[icon.extension] and MineOSCore.properties.extensionAssociations[icon.extension].contextMenu then
pcall(loadfile(MineOSCore.properties.extensionAssociations[icon.extension].contextMenu), icon, menu)
menu:addSeparator()
end
-- local subMenu = menu:addSubMenu(MineOSCore.localization.openWith)
-- local fileList = fs.sortedList(MineOSPaths.applications, "name")
-- subMenu:addItem(MineOSCore.localization.select)
-- subMenu:addSeparator()
-- for i = 1, #fileList do
-- subMenu:addItem(fs.hideExtension(fileList[i]))
-- end
end
end
end
if #selectedIcons > 1 then
menu:addItem(MineOSCore.localization.newFolderFromChosen .. " (" .. #selectedIcons .. ")").onTouch = function()
MineOSInterface.newFolderFromChosen(MineOSInterface.mainContainer, icon.parent.parent, eventData[3], eventData[4], selectedIcons)
end
menu:addSeparator()
end
local function cutOrCopy(cut)
for i = 1, #icon.parent.children do
icon.parent.children[i].cut = nil
end
MineOSCore.clipboard = {cut = cut}
for i = 1, #selectedIcons do
selectedIcons[i].cut = cut
table.insert(MineOSCore.clipboard, selectedIcons[i].path)
end
end
menu:addItem(MineOSCore.localization.cut).onTouch = function()
cutOrCopy(true)
end
menu:addItem(MineOSCore.localization.copy).onTouch = function()
cutOrCopy()
end
if not icon.isShortcut or #selectedIcons > 1 then
local subMenu = menu:addSubMenu(MineOSCore.localization.createShortcut)
subMenu:addItem(MineOSCore.localization.inCurrentDirectory).onTouch = function()
for i = 1, #selectedIcons do
if not selectedIcons[i].isShortcut then
MineOSCore.createShortcut(
fs.path(selectedIcons[i].path) .. "/" .. fs.hideExtension(fs.name(selectedIcons[i].path)) .. ".lnk",
selectedIcons[i].path
)
end
end
computer.pushSignal("MineOSCore", "updateFileList")
end
subMenu:addItem(MineOSCore.localization.onDesktop).onTouch = function()
for i = 1, #selectedIcons do
if not selectedIcons[i].isShortcut then
MineOSCore.createShortcut(
MineOSPaths.desktop .. "/" .. fs.hideExtension(fs.name(selectedIcons[i].path)) .. ".lnk",
selectedIcons[i].path
)
end
end
computer.pushSignal("MineOSCore", "updateFileList")
end
end
if #selectedIcons == 1 then
menu:addItem(MineOSCore.localization.rename).onTouch = function()
MineOSInterface.rename(MineOSInterface.mainContainer, icon.path)
end
end
menu:addItem(MineOSCore.localization.delete).onTouch = function()
for i = 1, #selectedIcons do
if fs.path(selectedIcons[i].path) == MineOSPaths.trash then
fs.remove(selectedIcons[i].path)
else
local newName = MineOSPaths.trash .. fs.name(selectedIcons[i].path)
local clearName = fs.hideExtension(fs.name(selectedIcons[i].path))
local repeats = 1
while fs.exists(newName) do
newName, repeats = MineOSPaths.trash .. clearName .. string.rep("-copy", repeats) .. selectedIcons[i].extension, repeats + 1
end
fs.rename(selectedIcons[i].path, newName)
end
end
computer.pushSignal("MineOSCore", "updateFileList")
end
menu:addSeparator()
if #selectedIcons == 1 then
menu:addItem(MineOSCore.localization.addToDock).onTouch = function()
MineOSInterface.mainContainer.dockContainer.addIcon(icon.path).keepInDock = true
MineOSInterface.mainContainer.dockContainer.saveToOSSettings()
end
end
menu:addItem(MineOSCore.localization.properties).onTouch = function()
for i = 1, #selectedIcons do
MineOSInterface.propertiesWindow(eventData[3], eventData[4], 40, selectedIcons[i])
end
end
menu:show()
icon.parent.parent:deselectAll()
MineOSInterface.OSDraw()
end
-----------------------------------------------------------------------------------------------------------------------------------
function MineOSInterface.addUniversalContainer(parentContainer, title)
local container = parentContainer:addChild(GUI.container(1, 1, parentContainer.width, parentContainer.height))
container.panel = container:addChild(GUI.panel(1, 1, container.width, container.height, MineOSCore.properties.transparencyEnabled and 0x0 or (MineOSCore.properties.backgroundColor or 0x0F0F0F), MineOSCore.properties.transparencyEnabled and 0.2))
container.layout = container:addChild(GUI.layout(1, 1, container.width, container.height, 1, 1))
if title then
container.layout:addChild(GUI.label(1, 1, unicode.len(title), 1, 0xEEEEEE, title)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
end
container.panel.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "touch" then
container:delete()
mainContainer:draw()
buffer.draw()
end
end
return container
end
local function addUniversalContainerWithInputTextBox(parentWindow, text, title, placeholder)
local container = MineOSInterface.addUniversalContainer(parentWindow, title)
container.inputField = container.layout:addChild(GUI.inputField(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0x666666, 0xEEEEEE, 0x262626, text, placeholder, false))
container.label = container.layout:addChild(GUI.label(1, 1, 36, 1, 0xFF4940, MineOSCore.localization.file .. " " .. MineOSCore.localization.alreadyExists)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
container.label.hidden = true
return container
end
local function checkFileToExists(container, path)
if fs.exists(path) then
container.label.hidden = false
container.parent:draw()
buffer.draw()
else
container:delete()
fs.makeDirectory(fs.path(path))
return true
end
end
local function checkIconConfigCanSavePosition(iconField, x, y, filename)
if iconField.iconConfigEnabled then
iconField.iconConfig[filename] = { x = x, y = y }
iconField:saveIconConfig()
end
end
function MineOSInterface.newFile(parentWindow, iconField, x, y, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, MineOSCore.localization.newFile, MineOSCore.localization.fileName)
container.inputField.onInputFinished = function()
if checkFileToExists(container, path .. container.inputField.text) then
local file = io.open(path .. container.inputField.text, "w")
file:close()
checkIconConfigCanSavePosition(iconField, x, y, container.inputField.text)
MineOSInterface.safeLaunch(MineOSPaths.editor, path .. container.inputField.text)
computer.pushSignal("MineOSCore", "updateFileList")
end
end
parentWindow:draw()
buffer.draw()
end
function MineOSInterface.newFolder(parentWindow, iconField, x, y, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, MineOSCore.localization.newFolder, MineOSCore.localization.folderName)
container.inputField.onInputFinished = function()
if checkFileToExists(container, path .. container.inputField.text) then
fs.makeDirectory(path .. container.inputField.text)
checkIconConfigCanSavePosition(iconField, x, y, container.inputField.text .. "/")
computer.pushSignal("MineOSCore", "updateFileList")
end
end
parentWindow:draw()
buffer.draw()
return container
end
function MineOSInterface.newFileFromURL(parentWindow, iconField, x, y, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, "Загрузить файл по URL", MineOSCore.localization.fileName)
container.inputFieldURL = container.layout:addChild(GUI.inputField(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0x666666, 0xEEEEEE, 0x262626, nil, "URL", false))
container.inputField.onInputFinished = function()
if container.inputField.text then
if fs.exists(path .. container.inputField.text) then
container.label.hidden = false
parentWindow:draw()
buffer.draw()
else
if container.inputFieldURL.text then
local success, reason = require("web").downloadFile(container.inputFieldURL.text, path .. container.inputField.text)
if not success then
GUI.error(reason)
end
container:delete()
checkIconConfigCanSavePosition(iconField, x, y, container.inputField.text)
computer.pushSignal("MineOSCore", "updateFileList")
end
end
end
end
container.inputFieldURL.onInputFinished = container.inputField.onInputFinished
parentWindow:draw()
buffer.draw()
end
function MineOSInterface.newApplication(parentWindow, iconField, x, y, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, MineOSCore.localization.newApplication, MineOSCore.localization.applicationName)
local filesystemChooser = container.layout:addChild(GUI.filesystemChooser(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0x444444, 0x999999, nil, MineOSCore.localization.open, MineOSCore.localization.cancel, MineOSCore.localization.iconPath, "/"))
filesystemChooser:addExtensionFilter(".pic")
filesystemChooser:moveBackward()
container.panel.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "touch" then
container:delete()
if container.inputField.text then
local finalPath = path .. container.inputField.text .. ".app/"
if checkFileToExists(container, finalPath) then
fs.makeDirectory(finalPath .. "/Resources/")
fs.copy(filesystemChooser.path or MineOSPaths.icons .. "SampleIcon.pic", finalPath .. "/Resources/Icon.pic")
local file = io.open(finalPath .. "Main.lua", "w")
file:write("require(\"GUI\").error(\"Hello world\")")
file:close()
checkIconConfigCanSavePosition(iconField, x, y, container.inputField.text .. ".app/")
computer.pushSignal("MineOSCore", "updateFileList")
end
else
parentWindow:draw()
buffer.draw()
end
end
end
parentWindow:draw()
buffer.draw()
end
function MineOSInterface.newFolderFromChosen(parentWindow, iconField, x, y, selectedIcons)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, MineOSCore.localization.newFolderFromChosen .. " (" .. #selectedIcons .. ")", MineOSCore.localization.folderName)
container.inputField.onInputFinished = function()
local path = fs.path(selectedIcons[1].path) .. container.inputField.text
if checkFileToExists(container, path) then
fs.makeDirectory(path)
for i = 1, #selectedIcons do
fs.rename(selectedIcons[i].path, path .. "/" .. fs.name(selectedIcons[i].path))
end
checkIconConfigCanSavePosition(iconField, x, y, container.inputField.text)
computer.pushSignal("MineOSCore", "updateFileList")
end
end
parentWindow:draw()
buffer.draw()
return container
end
function MineOSInterface.rename(parentWindow, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, fs.name(path), MineOSCore.localization.rename, MineOSCore.localization.newName)
container.inputField.onInputFinished = function()
if checkFileToExists(container, fs.path(path) .. container.inputField.text) then
fs.rename(path, fs.path(path) .. container.inputField.text)
computer.pushSignal("MineOSCore", "updateFileList")
end
end
parentWindow:draw()
buffer.draw()
container.inputField:startInput()
end
function MineOSInterface.editShortcut(parentWindow, path)
local text = MineOSCore.readShortcut(path)
local container = addUniversalContainerWithInputTextBox(parentWindow, text, MineOSCore.localization.editShortcut, MineOSCore.localization.rename)
container.panel.eventHandler = nil
container.inputField.onInputFinished = function()
if fs.exists(container.inputField.text) then
MineOSCore.createShortcut(path, container.inputField.text)
container:delete()
computer.pushSignal("MineOSCore", "updateFileList")
else
container.label.text = MineOSCore.localization.shortcutIsCorrupted
container.label.hidden = false
MineOSInterface.OSDraw()
end
end
parentWindow:draw()
buffer.draw()
container.inputField:startInput()
end
function MineOSInterface.launchWithArguments(parentWindow, path)
local container = addUniversalContainerWithInputTextBox(parentWindow, nil, MineOSCore.localization.launchWithArguments)
container.inputField.onInputFinished = function()
local args = {}
if container.inputField.text then
for arg in container.inputField.text:gmatch("[^%s]+") do
table.insert(args, arg)
end
end
container:delete()
MineOSInterface.clearTerminal()
if MineOSInterface.safeLaunch(path, table.unpack(args)) then
MineOSInterface.waitForPressingAnyKey()
end
parentWindow:draw()
buffer.draw(true)
end
end
function MineOSInterface.applicationHelp(parentWindow, path)
local pathToAboutFile = path .. "/resources/About/" .. MineOSCore.properties.language .. ".txt"
if MineOSCore.properties.showHelpOnApplicationStart and fs.exists(pathToAboutFile) then
local container = MineOSInterface.addUniversalContainer(parentWindow, MineOSCore.localization.applicationHelp .. " \"" .. fs.name(path) .. "\"")
local lines = {}
for line in io.lines(pathToAboutFile) do
table.insert(lines, line)
end
container.layout:addChild(GUI.textBox(1, 1, 50, 1, nil, 0xcccccc, lines, 1, 0, 0, true, true))
local button = container.layout:addChild(GUI.button(1, 1, 30, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.dontShowAnymore))
container.panel.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "touch" then
container:delete()
MineOSInterface.safeLaunch(path .. "/Main.lua")
end
end
button.onTouch = function()
MineOSCore.properties.showHelpOnApplicationStart = false
MineOSCore.saveProperties()
container:delete()
MineOSInterface.safeLaunch(path .. "/Main.lua")
end
else
MineOSInterface.safeLaunch(path .. "/Main.lua")
end
parentWindow:draw()
buffer.draw()
end
----------------------------------------- Windows patterns -----------------------------------------
local function windowResize(window, width, height)
window.width, window.height = width, height
if window.onResize then window.onResize(width, height) end
return window
end
function MineOSInterface.addWindow(window)
window.x = window.x or math.floor(MineOSInterface.mainContainer.windowsContainer.width / 2 - window.width / 2)
window.y = window.y or math.floor(MineOSInterface.mainContainer.windowsContainer.height / 2 - window.height / 2)
MineOSInterface.mainContainer.windowsContainer:addChild(window)
-- Получаем путь исполняемого файла
local dockPath = MineOSCore.lastLaunchPath or "/OS.lua"
local dockPathPath = fs.path(dockPath)
if fs.extension(dockPathPath) == ".app" then
dockPath = dockPathPath
end
-- Хуячим иконку в докыч, если такой еще не существует
local dockIcon
for i = 1, #MineOSInterface.mainContainer.dockContainer.children do
if MineOSInterface.mainContainer.dockContainer.children[i].path == dockPath then
dockIcon = MineOSInterface.mainContainer.dockContainer.children[i]
break
end
end
dockIcon = dockIcon or MineOSInterface.mainContainer.dockContainer.addIcon(dockPath, window)
-- Ебурим ссылку на окно в иконку
dockIcon.windows = dockIcon.windows or {}
dockIcon.windows[window] = true
window.resize = windowResize
window.close = function(window)
local sameIconExists = false
for i = 1, #MineOSInterface.mainContainer.dockContainer.children do
if
MineOSInterface.mainContainer.dockContainer.children[i].path == dockPath and
MineOSInterface.mainContainer.dockContainer.children[i].windows and
table.size(MineOSInterface.mainContainer.dockContainer.children[i].windows) > 1
then
MineOSInterface.mainContainer.dockContainer.children[i].windows[window] = nil
sameIconExists = true
break
end
end
if not sameIconExists then
dockIcon.windows = nil
if not dockIcon.keepInDock then
dockIcon:delete()
MineOSInterface.mainContainer.dockContainer.sort()
end
end
window:delete()
MineOSInterface.OSDraw()
end
window.maximize = function(window)
if window.maximized then
window.localPosition.x = window.oldGeometry.x
window.localPosition.y = window.oldGeometry.y
window:resize(window.oldGeometry.width, window.oldGeometry.height)
else
window.oldGeometry = {
x = window.localPosition.x,
y = window.localPosition.y,
width = window.width,
height = window.height
}
window.localPosition.x, window.localPosition.y = 1, 1
window:resize(window.parent.width, window.parent.height)
end
window.maximized = not window.maximized
MineOSInterface.OSDraw()
end
window.minimize = function(window)
window.hidden = true
MineOSInterface.OSDraw()
end
if window.actionButtons then
window.actionButtons.close.onTouch = function()
window.close(window)
end
window.actionButtons.maximize.onTouch = function()
window.maximize(window)
end
window.actionButtons.minimize.onTouch = function()
window.minimize(window)
end
end
MineOSCore.lastLaunchPath = nil
return MineOSInterface.mainContainer, window
end
-----------------------------------------------------------------------------------------------------------------------------------
local function addKeyAndValue(window, x, y, key, value)
x = x + window:addChild(GUI.label(x, y, unicode.len(key) + 1, 1, 0x333333, key .. ":")).width + 1
return window:addChild(GUI.label(x, y, unicode.len(value), 1, 0x555555, value))
end
function MineOSInterface.propertiesWindow(x, y, width, icon)
local mainContainer, window = MineOSInterface.addWindow(GUI.titledWindow(x, y, width, 1, package.loaded.MineOSCore.localization.properties))
-- window.backgroundPanel.colors.transparency = 0.25
window:addChild(GUI.image(2, 3, icon.image))
local x, y = 11, 3
addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.type, icon.extension and icon.extension or (icon.isDirectory and package.loaded.MineOSCore.localization.folder or package.loaded.MineOSCore.localization.unknown)); y = y + 1
local fileSizeLabel = addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.size, icon.isDirectory and package.loaded.MineOSCore.localization.calculatingSize or string.format("%.2f", fs.size(icon.path) / 1024) .. " KB"); y = y + 1
addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.date, os.date("%d.%m.%y, %H:%M", math.floor(fs.lastModified(icon.path) / 1000))); y = y + 1
addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.path, " ")
local textBox = window:addChild(GUI.textBox(17, y, window.width - 18, 1, nil, 0x555555, {icon.path}, 1, 0, 0, true, true))
window.onResize = function(width, height)
window.backgroundPanel.width, window.backgroundPanel.height = width, height
end
window:resize(window.width, textBox.y + textBox.height)
textBox.eventHandler = nil
mainContainer:draw()
buffer.draw()
if icon.isDirectory then
fileSizeLabel.text = string.format("%.2f", fs.directorySize(icon.path) / 1024) .. " KB"
mainContainer:draw()
buffer.draw()
end
end
-----------------------------------------------------------------------------------------------------------------------------------
local function GUICopy(parentContainer, fileList, toPath)
local applyYes, breakRecursion
local container = MineOSInterface.addUniversalContainer(parentContainer, MineOSCore.localization.copying)
local textBox = container.layout:addChild(GUI.textBox(1, 1, container.width, 1, nil, 0x777777, {}, 1, 0, 0, true, true):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top))
local switchAndLabel = container.layout:addChild(GUI.switchAndLabel(1, 1, 37, 8, 0x66DB80, 0x1E1E1E, 0xEEEEEE, 0x777777, MineOSCore.localization.applyToAll .. ":", false))
container.panel.eventHandler = nil
local buttonsLayout = container.layout:addChild(GUI.layout(1, 1, 1, 1, 1, 1))
buttonsLayout:addChild(GUI.button(1, 1, 11, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.yes)).onTouch = function()
applyYes = true
parentContainer:stopEventHandling()
end
buttonsLayout:addChild(GUI.button(1, 1, 11, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.no)).onTouch = function()
parentContainer:stopEventHandling()
end
buttonsLayout:addChild(GUI.button(1, 1, 11, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.cancel)).onTouch = function()
breakRecursion = true
parentContainer:stopEventHandling()
end
buttonsLayout:setCellDirection(1, 1, GUI.directions.horizontal)
buttonsLayout:setCellSpacing(1, 1, 2)
buttonsLayout:fitToChildrenSize(1, 1)
local function copyOrMove(path, finalPath)
switchAndLabel.hidden = true
buttonsLayout.hidden = true
textBox.lines = {
MineOSCore.localization.copying .. " " .. MineOSCore.localization.faylaBlyad .. " " .. fs.name(path) .. " " .. MineOSCore.localization.toDirectory .. " " .. string.canonicalPath(toPath),
}
textBox.height = #textBox.lines
parentContainer:draw()
buffer.draw()
fs.remove(finalPath)
fs.copy(path, finalPath)
end
local function recursiveCopy(path, toPath)
local finalPath = toPath .. "/" .. fs.name(path)
if fs.isDirectory(path) then
fs.makeDirectory(finalPath)
for file in fs.list(path) do
if breakRecursion then
return
end
recursiveCopy(path .. "/" .. file, finalPath)
end
else
if fs.exists(finalPath) then
if not switchAndLabel.switch.state then
switchAndLabel.hidden = false
buttonsLayout.hidden = false
applyYes = false
textBox.lines = {
MineOSCore.localization.file .. " " .. fs.name(path) .. " " .. MineOSCore.localization.alreadyExists .. " " .. MineOSCore.localization.inDirectory .. " " .. string.canonicalPath(toPath),
MineOSCore.localization.needReplace,
}
textBox.height = #textBox.lines
parentContainer:draw()
buffer.draw()
parentContainer:startEventHandling()
parentContainer:draw()
buffer.draw()
end
if applyYes then
copyOrMove(path, finalPath)
end
else
copyOrMove(path, finalPath)
end
end
end
for i = 1, #fileList do
recursiveCopy(fileList[i], toPath)
end
container:delete()
parentContainer:draw()
buffer.draw()
end
function MineOSInterface.copy(what, toPath)
if type(what) == "string" then
what = {what}
end
GUICopy(MineOSInterface.mainContainer, what, toPath)
end
function MineOSInterface.addMenuWidget(object)
MineOSInterface.mainContainer.menuLayout:addChild(object)
object:moveToBack()
return object
end
-----------------------------------------------------------------------------------------------------------------------------------
function MineOSInterface.showErrorWindow(path, line, traceback)
buffer.clear(0x0, 0.5)
local mainContainer = GUI.container(1, 1, buffer.width, math.floor(buffer.height * 0.45))
mainContainer.y = math.floor(buffer.height / 2 - mainContainer.height / 2)
mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, 3, 0x383838))
mainContainer:addChild(GUI.label(1, 2, mainContainer.width, 1, 0xFFFFFF, MineOSCore.localization.errorWhileRunningProgram .. "\"" .. fs.name(path) .. "\"")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
local actionButtons = mainContainer:addChild(GUI.actionButtons(2, 2, false))
local sendToDeveloperButton = mainContainer:addChild(GUI.adaptiveButton(9, 1, 2, 1, 0x444444, 0xFFFFFF, 0x343434, 0xFFFFFF, MineOSCore.localization.sendFeedback))
local codeView = mainContainer:addChild(GUI.codeView(1, 4, math.floor(mainContainer.width * 0.62), mainContainer.height - 3, {}, 1, 1, 100, {}, {[line] = 0xFF4444}, true, 2))
codeView.scrollBars.horizontal.hidden = true
codeView.fromLine = line - math.floor((mainContainer.height - 3) / 2) + 1
if codeView.fromLine <= 0 then
codeView.fromLine = 1
end
local toLine, lineCounter = codeView.fromLine + codeView.height - 1, 1
for line in io.lines(path) do
if lineCounter >= codeView.fromLine and lineCounter <= toLine then
codeView.lines[lineCounter] = string.gsub(line, " ", " ")
elseif lineCounter < codeView.fromLine then
codeView.lines[lineCounter] = " "
elseif lineCounter > toLine then
break
end
lineCounter = lineCounter + 1
end
mainContainer:addChild(GUI.textBox(codeView.width + 1, 4, mainContainer.width - codeView.width, codeView.height, 0xFFFFFF, 0x000000, string.wrap(MineOSCore.parseErrorMessage(traceback, 4), mainContainer.width - codeView.width - 2), 1, 1, 0))
actionButtons.close.onTouch = function()
mainContainer:stopEventHandling()
end
mainContainer.eventHandler = function(mainContainer, object, eventData)
if eventData[1] == "key_down" and eventData[4] == 28 then
actionButtons.close.onTouch()
end
end
sendToDeveloperButton.onTouch = function()
if component.isAvailable("internet") then
local url = "https://api.mcmodder.ru/ECS/report.php?path=" .. path .. "&errorMessage=" .. string.optimizeForURLRequests(traceback)
local success, reason = component.internet.request(url)
if success then
success:close()
end
sendToDeveloperButton.text = MineOSCore.localization.sendedFeedback
mainContainer:draw()
buffer.draw()
os.sleep(1)
end
actionButtons.close.onTouch()
end
mainContainer:draw()
buffer.draw()
for i = 1, 3 do
component.computer.beep(1500, 0.08)
end
mainContainer:startEventHandling()
end
function MineOSInterface.safeLaunch(...)
local success, path, line, traceback = MineOSCore.safeLaunch(...)
if not success then
MineOSInterface.showErrorWindow(path, line, traceback)
end
return success, path, line, traceback
end
-----------------------------------------------------------------------------------------------------------------------------------
MineOSInterface.cacheIconSource("folder", MineOSPaths.icons .. "Folder.pic")
MineOSInterface.cacheIconSource("fileNotExists", MineOSPaths.icons .. "FileNotExists.pic")
MineOSInterface.cacheIconSource("application", MineOSPaths.icons .. "Application.pic")
MineOSInterface.cacheIconSource("trash", MineOSPaths.icons .. "Trash.pic")
MineOSInterface.cacheIconSource("script", MineOSPaths.icons .. "Script.pic")
-----------------------------------------------------------------------------------------------------------------------------------
return MineOSInterface