Обновленное приложение HEX

This commit is contained in:
Igor Timofeev 2017-10-17 23:36:55 +03:00
parent 74b960c913
commit 6c885bf204
6 changed files with 435 additions and 429 deletions

View File

@ -308,7 +308,7 @@
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/GUI.lua",
type="Library",
preloadFile=true,
version=1.90,
version=1.91,
},
{
path="/lib/rayEngine.lua",
@ -481,15 +481,6 @@
},
}
},
{
path="/MineOS/Applications/Finder",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/Main.lua",
about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/About/",
type="Application",
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/Icon.pic",
forceDownload=true,
version=1.25,
},
{
path="/MineOS/Applications/3DTest",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/3DTest/3DTest.lua",
@ -500,6 +491,15 @@
forceDownload=true,
version=1.22,
},
{
path="/MineOS/Applications/HEX",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/Main.lua",
about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/About/",
type="Application",
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/Icon.pic",
createShortcut=true,
version=1.04,
},
{
path="/MineOS/Applications/Spinner",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Spinner/Main.lua",
@ -596,6 +596,15 @@
},
},
},
{
path="/MineOS/Applications/Finder",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/Main.lua",
about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/About/",
type="Application",
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Finder/Icon.pic",
forceDownload=true,
version=1.25,
},
{
path="/MineOS/Applications/Weather",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/Weather.lua",
@ -1001,15 +1010,6 @@
createShortcut=true,
version=1.01,
},
{
path="/MineOS/Applications/HEX",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/HEX.lua",
about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/About/",
type="Application",
icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/HEX/Icon.pic",
createShortcut=true,
version=1.03,
},
{
path="/MineOS/Applications/ChristmasTree",
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/ChristmasTree/ChristmasTree.lua",

View File

@ -1,402 +0,0 @@
require("advancedLua")
local unicode = require("unicode")
local buffer = require("doubleBuffering")
local event = require("event")
local fs = require("filesystem")
local context = require("context")
local ecs = require("ECSAPI")
--------------------------------------------------------------------------------------------------------------------------------
local xSize, ySize = buffer.width, buffer.height
local file = {}
local config = {
x = 1,
y = 1,
width = 98,
height = 25,
heightOfTopBar = 3,
fromString = 1,
xCurrentByte = 1,
yCurrentByte = 1,
pathToFile = "bin/resolution.lua",
sizeOfFile = 1,
transparency = 30,
colors = {
background = 0xdddddd,
topBar = 0xdddddd,
topBarText = 0x262626,
topBarButton = 0x444444,
hexText = 0x262626,
hexSelection = 0x880000,
hexSelectionText = 0xffffff,
numberBar = 0x262626,
numberBarText = 0xcccccc,
infoPanel = 0x880000,
infoPanelText = 0xffffff,
}
}
--------------------------------------------------------------------------------------------------------------------------------
local obj = {}
local function newObj(class, name, ...)
obj[class] = obj[class] or {}
obj[class][name] = {...}
end
local function convertIndexToCoords(index)
local ostatok = index % 16
local x = (ostatok == 0) and 16 or ostatok
local y = math.ceil(index / 16)
return x, y
end
local function convertCoordsToIndex(xByte, yByte)
return (yByte - 1) * 16 + xByte
end
local function readFile()
config.fromString = 1
config.CurrentByte = 1
config.CurrentByte = 1
file = {}
local fileStream = io.open(config.pathToFile, "rb")
while true do
local readedByte = fileStream:read(1)
if not readedByte then break end
table.insert(file, string.format("%02X", string.byte(readedByte)))
end
fileStream:close()
config.sizeOfFile = math.ceil(fs.size(config.pathToFile) / 1024)
end
local function drawInfoPanel()
local x = config.x
local y = config.y
local width = 30
local xPos = x + math.floor(config.width / 2 - width / 2) - 1
buffer.square(xPos, y, width, config.heightOfTopBar, config.colors.infoPanel, 0x000000, " ")
local text = fs.name(config.pathToFile)
xPos = x + math.floor(config.width / 2 - unicode.len(text) / 2) - 1
buffer.text(xPos, y, config.colors.infoPanelText, unicode.sub(text, 1, width - 2))
text = "Размер файла: " .. config.sizeOfFile .. " КБ"
xPos = x + math.floor(config.width / 2 - unicode.len(text) / 2) - 1
buffer.text(xPos, y + 1, 0xffaaaa, unicode.sub(text, 1, width - 2))
text = "Текущий байт: " .. convertCoordsToIndex(config.xCurrentByte, config.yCurrentByte)
xPos = x + math.floor(config.width / 2 - unicode.len(text) / 2) - 1
buffer.text(xPos, y + 2, 0xffaaaa, unicode.sub(text, 1, width - 2))
end
local function drawTopBar()
local x = config.x
local y = config.y
buffer.square(x, y, config.width, 3, 0xffffff, 0xffffff, " ", config.transparency)
newObj("Buttons", 1, buffer.button(x, y, 10, 3, 0xdddddd, 0x000000, "Файл"))
drawInfoPanel()
end
local function printDebug(line, text)
if debug then
ecs.square(1, line, buffer.width, 1, 0x262626)
ecs.colorText(2, line, 0xFFFFFF, text)
end
end
local function drawHexAndText()
local x, y = config.x, config.y + 3
local textOffset = 67
local hexOffset = 12
local xHex, yHex = x + hexOffset, y + 2
local xText, yText = xHex + textOffset, y + 2
obj["hex"] = {}
obj["text"] = {}
--Главный белый
buffer.square(config.x, config.y + 3, config.width, config.height - 3, config.colors.background, 0x000000, " ")
--Левый серый
buffer.square(x, y, 10, config.height - 3, config.colors.numberBar, 0xffffff, " ")
--Верхний серый
buffer.square(x, y, config.width, 1, config.colors.numberBar, 0xffffff, " ")
--Вертикальная полоска
buffer.square(xText - 3, y + 1, 1, config.height - 4, config.colors.background, 0xaaaaaa, "")
--Скроллбар
buffer.scrollBar(x + config.width - 1, y + 1, 1, config.height - 4, math.ceil(#file / 16), config.fromString, 0x262626, ecs.colors.lightBlue)
--Рисуем верхние номерки
local xCyka = xHex
for i = 1, 16 do
if i == config.xCurrentByte then
buffer.square(xCyka - 1, y, 4, 1, config.colors.hexSelection, 0xffffff, " ")
buffer.text(xCyka, y, config.colors.hexSelectionText, string.format("%02X", i - 1))
else
buffer.text(xCyka, y, config.colors.numberBarText, string.format("%02X", i - 1))
end
xCyka = xCyka + 4
end
--Рисуем хекс и текст
local xByte, yByte, text
local byteCounter = 1
local fromByte = config.fromString * 16 - 15
for byte = fromByte, fromByte + 10 * 16 - 1 do
if not file[byte] then break end
xByte, yByte = convertIndexToCoords(byte)
text = unicode.char(tonumber("0x" .. file[byte]))
if unicode.isWide(text) then text = "." end
if config.xCurrentByte == xByte and config.yCurrentByte == yByte then
buffer.square(xHex - 1, yHex, 4, 1, config.colors.hexSelection, 0xffffff, " ")
buffer.set(xText, yText, config.colors.hexSelection, 0xffffff, " ")
buffer.text(xHex, yHex, config.colors.hexSelectionText, file[byte])
buffer.text(xText, yText, config.colors.hexSelectionText, text)
else
buffer.text(xHex, yHex, config.colors.hexText, file[byte])
buffer.text(xText, yText, config.colors.hexText, text)
end
--Рисуем левые номерки
if yByte == config.yCurrentByte then
buffer.square(x, yHex, 10, 1, config.colors.hexSelection, 0xffffff, " ")
buffer.text(x + 1, yHex, config.colors.hexSelectionText, string.format("%07X", yByte - 1) .. "0")
else
buffer.text(x + 1, yHex, config.colors.numberBarText, string.format("%07X", yByte - 1) .. "0")
end
--Обжектыыы!! Ы!
newObj("hex", byteCounter, xHex, yHex, xByte, yByte)
newObj("text", byteCounter, xText, yText, xByte, yByte)
byteCounter = byteCounter + 1
--Коорды!
if xByte == 16 then
xHex = x + hexOffset
xText = xHex + textOffset
yHex = yHex + 2
yText = yText + 2
else
xHex = xHex + 4
xText = xText + 1
end
end
end
local function drawAll(force)
drawTopBar()
drawHexAndText()
--Тень
buffer.square(config.x + config.width, config.y + 1, 2, config.height, 0x000000, 0xffffff, " ", 50)
buffer.square(config.x + 2, config.y + config.height, config.width - 2, 1, 0x000000, 0xffffff, " ", 50)
buffer.draw(force)
end
local function getCenterOfScreen()
config.x = math.floor(xSize / 2 - config.width / 2)
config.y = math.floor(ySize / 2 - config.height / 2)
end
local function checkInput(text, pattern)
if string.find(text, pattern) then
return true
else
ecs.error("Что за говно ты сюда ввел? Переделывай на хуй!")
end
end
local function editByte(xByte, yByte)
local index = convertCoordsToIndex(xByte, yByte)
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", 0xffffff, "Редактировать байт"}, {"EmptyLine"}, {"Input", 0xffffff, 0xff5555, "Введите значение HEX"}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "Принять"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[2] == "Принять" and checkInput(data[1], "^[1234567890abcdefABCDEF][1234567890abcdefABCDEF]$") then
file[index] = data[1]
end
end
local function editText(xByte, yByte)
local index = convertCoordsToIndex(xByte, yByte)
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", 0xffffff, "Редактировать байт"}, {"EmptyLine"}, {"Input", 0xffffff, 0xff5555, "Введите значение CHAR"}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "Принять"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[2] == "Принять" and checkInput(data[1], "^.$") then
file[index] = string.format("%02X", string.byte(byteValue))
end
end
local function insertByte(xByte, yByte)
local index = convertCoordsToIndex(xByte, yByte)
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", 0xffffff, "Вставить байт"}, {"EmptyLine"}, {"Input", 0xffffff, 0xff5555, "Введите значение HEX"}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "Вставить"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[2] == "Вставить" and checkInput(data[1], "^[1234567890abcdefABCDEF][1234567890abcdefABCDEF]$") then
table.insert(file, index, data[1])
end
end
local function invertByte(xByte, yByte)
local index = convertCoordsToIndex(xByte, yByte)
file[index] = bit32.band( bit32.bnot(tonumber("0x" .. file[index])), 0xff )
file[index] = string.format("%02X", string.byte(file[index]))
end
local function askForWhatToDoWithByte(x, y, xByte, yByte, asByte)
local action = context.menu(x, y, {"Редактировать байт"}, {"Инвертировать байт"}, {"Вставить байт"}, "-", {"Удалить байт"})
if action == "Редактировать байт" then
if asByte then
editByte(xByte, yByte)
else
editText(xByte, yByte)
end
elseif action == "Инвертировать байт" then
local index = convertCoordsToIndex(xByte, yByte)
invertByte(xByte, yByte)
elseif action == "Вставить байт" then
insertByte(xByte, yByte)
elseif action == "Удалить байт" then
local index = convertCoordsToIndex(xByte, yByte)
table.remove(file, index)
end
end
local function save(path)
fs.makeDirectory(fs.path(path) or "")
local fileStream = io.open(path, "w")
for i = 1, #file do
fileStream:write(unicode.char(tonumber(table.concat({"0x", file[i]}))))
end
fileStream:close()
end
--------------------------------------------------------------------------------------------------------------------------------
readFile()
--buffer.square(1, 1, xSize, ySize, ecs.colors.red, 0x000000, " ")
getCenterOfScreen()
local oldPixels = buffer.copy(config.x, config.y, config.width + 2, config.height + 1)
drawAll(true)
while true do
local e = {event.pull()}
if e[1] == "touch" then
for key in pairs(obj["hex"]) do
if e[3] >= obj["hex"][key][1] - 1 and e[3] <= obj["hex"][key][1] + 2 and e[4] == obj["hex"][key][2] then
if config.xCurrentByte == obj["hex"][key][3] and config.yCurrentByte == obj["hex"][key][4] then
if e[5] == 0 then
editByte(obj["hex"][key][3], obj["hex"][key][4])
else
askForWhatToDoWithByte(obj["hex"][key][1] - 1, obj["hex"][key][2] + 1, obj["hex"][key][3], obj["hex"][key][4], true)
end
else
config.xCurrentByte = obj["hex"][key][3]
config.yCurrentByte = obj["hex"][key][4]
end
drawHexAndText()
drawInfoPanel()
buffer.draw()
break
end
end
for key in pairs(obj["text"]) do
if e[3] == obj["text"][key][1] and e[4] == obj["text"][key][2] then
if config.xCurrentByte == obj["text"][key][3] and config.yCurrentByte == obj["text"][key][4] then
if e[5] == 0 then
editText(obj["text"][key][3], obj["text"][key][4])
else
askForWhatToDoWithByte(obj["text"][key][1], obj["text"][key][2] + 1, obj["text"][key][3], obj["text"][key][4], true)
end
else
config.xCurrentByte = obj["text"][key][3]
config.yCurrentByte = obj["text"][key][4]
end
drawHexAndText()
drawInfoPanel()
buffer.draw()
break
end
end
if ecs.clickedAtArea(e[3], e[4], obj["Buttons"][1][1], obj["Buttons"][1][2], obj["Buttons"][1][3], obj["Buttons"][1][4]) then
buffer.button(obj["Buttons"][1][1], obj["Buttons"][1][2], 10, 3, 0x333333, 0xdddddd, "Файл")
buffer.draw()
local action = context.menu(obj["Buttons"][1][1], obj["Buttons"][1][2] + 3, {"Открыть"}, {"Сохранить"}, {"Сохранить как"}, "-", {"Выход"})
buffer.button(obj["Buttons"][1][1], obj["Buttons"][1][2], 10, 3, 0xdddddd, 0x000000, "Файл")
buffer.draw()
if action == "Открыть" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", 0xffffff, "Открыть файл"}, {"EmptyLine"}, {"Input", 0xffffff, 0x880000, "Путь к файлу"}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "Открыть"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[2] == "Открыть" then
if fs.exists(data[1]) then
config.pathToFile = data[1]
readFile()
drawHexAndText()
drawInfoPanel()
buffer.draw()
else
ecs.error("Файл \"" .. data[1] .. "\" не существует!")
end
end
elseif action == "Сохранить" then
save(config.pathToFile)
elseif action == "Сохранить как" then
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", 0xffffff, "Сохранить как"}, {"EmptyLine"}, {"Input", 0xffffff, 0x880000, "Путь к файлу"}, {"EmptyLine"}, {"Button", {0x880000, 0xffffff, "Сохранить"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[2] == "Сохранить" then
save(data[1])
end
elseif action == "Выход" then
buffer.paste(config.x, config.y, oldPixels)
buffer.draw()
return
end
end
elseif e[1] == "scroll" then
if e[5] == 1 then
if config.fromString > 1 then
config.fromString = config.fromString - 1
drawHexAndText()
buffer.draw()
end
else
if config.fromString <= math.ceil(#file / 16) - 1 then
config.fromString = config.fromString + 1
drawHexAndText()
buffer.draw()
end
end
end
end

BIN
Applications/HEX/Icon.pic Normal file → Executable file

Binary file not shown.

379
Applications/HEX/Main.lua Executable file
View File

@ -0,0 +1,379 @@
require("advancedLua")
local bit32 = require("bit32")
local fs = require("filesystem")
local GUI = require("GUI")
local buffer = require("doubleBuffering")
local unicode = require("unicode")
local MineOSInterface = require("MineOSInterface")
------------------------------------------------------------------------------------------------------------------
local colors = {
background = 0xF0F0F0,
backgroundText = 0x555555,
panel = 0x2D2D2D,
panelText = 0x999999,
panelSeleciton = 0x444444,
panelSelecitonText = 0xE1E1E1,
selectionFrom = 0x990000,
selectionTo = 0x990000,
selectionText = 0xFFFFFF,
selectionBetween = 0xD2D2D2,
selectionBetweenText = 0x000000,
separator = 0xCCCCCC,
titleBackground = 0xCC4940,
titleText = 0xFFFFFF,
titleText2 = 0xE1E1E1,
}
local bytes = {}
local offset = 0
local selection = {
from = 1,
to = 1,
}
local scrollBar, titleTextBox
------------------------------------------------------------------------------------------------------------------
local mainContainer, window = MineOSInterface.addWindow(GUI.filledWindow(nil, nil, 98, 25, colors.background))
window.backgroundPanel.localPosition.x, window.backgroundPanel.localPosition.y = 11, 5
window.backgroundPanel.width, window.backgroundPanel.height = window.width - 10, window.height - 4
local function status()
titleTextBox.lines[1] = "Selected byte" .. (selection.from == selection.to and "" or "s") .. ": " .. selection.from .. "-" .. selection.to
titleTextBox.lines[2].text = "UTF-8: \"" .. string.char(table.unpack(bytes, selection.from, selection.to)) .. "\""
titleTextBox.lines[3].text = "INT: " .. bit32.byteArrayToNumber({table.unpack(bytes, selection.from, selection.to)})
end
local function byteFieldDraw(object)
local x, y, index = object.x, object.y, 1 + offset
local xCount, yCount = math.ceil(object.width / object.elementWidth), math.ceil(object.height / object.elementHeight)
for j = 1, yCount do
for i = 1, xCount do
if bytes[index] then
local textColor = colors.backgroundText
if index == selection.from or index == selection.to then
buffer.square(x - object.offset, y, object.elementWidth, 1, index == selection.from and colors.selectionFrom or colors.selectionTo, colors.selectionText, " ")
textColor = colors.selectionText
elseif index > selection.from and index < selection.to then
buffer.square(x - object.offset, y, object.elementWidth, 1, colors.selectionBetween, colors.selectionText, " ")
textColor = colors.selectionBetweenText
end
buffer.text(x, y, textColor, object.asChar and string.char(bytes[index]) or string.format("%02X", bytes[index]))
else
return object
end
x, index = x + object.elementWidth, index + 1
end
local lastLineIndex = index - 1
if lastLineIndex >= selection.from and lastLineIndex < selection.to then
buffer.square(object.x - object.offset, y + 1, object.width, 1, colors.selectionBetween, colors.selectionText, " ")
end
x, y = object.x, y + object.elementHeight
end
return object
end
local function byteFieldEventHandler(mainContainer, object, eventData)
if eventData[1] == "touch" or eventData[1] == "drag" then
if eventData[5] == 1 then
local menu = GUI.contextMenu(eventData[3], eventData[4])
menu:addItem("Select all").onTouch = function()
selection.from = 1
selection.to = #bytes
mainContainer:draw()
buffer.draw()
end
menu:addSeparator()
menu:addItem("Edit").onTouch = function()
local container = MineOSInterface.addUniversalContainer(mainContainer, "Fill byte range [" .. selection.from .. "; " .. selection.to .. "]")
local input = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, string.format("%02X" , bytes[selection.from]), "Type byte value"))
input.onInputFinished = function(text)
local number = tonumber("0x" .. input.text)
if number and number >= 0 and number <= 255 then
for i = selection.from, selection.to do
bytes[i] = number
end
container:delete()
mainContainer:draw()
buffer.draw()
end
end
mainContainer:draw()
buffer.draw()
end
menu:addItem("Insert").onTouch = function()
local container = MineOSInterface.addUniversalContainer(mainContainer, "Insert bytes at position " .. selection.from .. "")
local input = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x666666, 0x666666, 0xE1E1E1, 0x2D2D2D, "", "Type byte values separated by space", true))
local switch = container.layout:addChild(GUI.switchAndLabel(1, 1, 36, 8, 0x66DB80, 0x1E1E1E, 0xE1E1E1, 0xBBBBBB, "Select inserted bytes:", true)).switch
input.onInputFinished = function()
if input.text:match("[a-fA-F%d%s]+") then
local insertionPosition, count = selection.from, 0
for word in input.text:gmatch("[^%s]+") do
local number = tonumber("0x" .. word)
if number > 255 then number = 255 end
table.insert(bytes, insertionPosition + count, number)
selection.from, selection.to, count = selection.from + 1, selection.to + 1, count + 1
end
if switch.state then
selection.from, selection.to = insertionPosition, insertionPosition + count - 1
end
container:delete()
mainContainer:draw()
buffer.draw()
end
end
mainContainer:draw()
buffer.draw()
end
menu:addSeparator()
menu:addItem("Delete").onTouch = function()
for i = selection.from, selection.to do
table.remove(bytes, selection.from)
end
if #bytes == 0 then
selection.from, selection.to = 1, 1
else
selection.to = selection.from
end
end
menu:show()
else
local index = (math.ceil((eventData[4] - object.y + 1) / 2) - 1) * 16 + math.ceil((eventData[3] - object.x + 1 + object.offset) / object.elementWidth) + offset
if bytes[index] then
if eventData[1] == "touch" then
selection.to = index
selection.from = index
selection.touchIndex = index
else
if not selection.touchIndex then selection.touchIndex = index end
if index < selection.touchIndex then
selection.from = index
selection.to = selection.touchIndex
elseif index > selection.touchIndex then
selection.to = index
selection.from = selection.touchIndex
end
end
status()
mainContainer:draw()
buffer.draw()
end
end
elseif eventData[1] == "scroll" then
offset = offset - 16 * eventData[5]
if offset < 0 then
offset = 0
elseif offset > math.floor(#bytes / 16) * 16 then
offset = math.floor(#bytes / 16) * 16
end
scrollBar.value = offset
mainContainer:draw()
buffer.draw()
end
end
local function newByteField(x, y, width, height, elementWidth, elementHeight, asChar)
local object = GUI.object(x, y, width, height)
object.elementWidth = elementWidth
object.elementHeight = elementHeight
object.offset = asChar and 0 or 1
object.asChar = asChar
object.draw = byteFieldDraw
object.eventHandler = byteFieldEventHandler
return object
end
------------------------------------------------------------------------------------------------------------------
window:addChild(GUI.panel(1, 1, window.width, 3, 0xFFFFFF, 0.3)):moveToBack()
local byteField = window:addChild(newByteField(13, 6, 64, 20, 4, 2, false))
local charField = window:addChild(newByteField(byteField.localPosition.x + byteField.width + 3, 6, 16, 20, 1, 2, true))
local separator = window:addChild(GUI.object(byteField.localPosition.x + byteField.width, 5, 1, 21))
separator.draw = function(object)
for i = object.y, object.y + object.height - 1 do
buffer.text(object.x, i, colors.separator, "")
end
end
window:addChild(GUI.panel(11, 4, window.width - 10, 1, colors.panel))
-- Vertical
local verticalCounter = window:addChild(GUI.object(1, 4, 10, window.height - 3))
verticalCounter.draw = function(object)
buffer.square(object.x, object.y, object.width, object.height, colors.panel, colors.panelText, " ")
local index = offset
for y = 2, object.height - 1, 2 do
local textColor = colors.panelText
if index > selection.from and index < selection.to then
buffer.square(object.x, object.y + y - 1, object.width, 2, colors.panelSeleciton, colors.panelSelecitonText, " ")
textColor = colors.panelSelecitonText
end
if selection.from >= index and selection.from <= index + 15 or selection.to >= index and selection.to <= index + 15 then
buffer.square(object.x, object.y + y, object.width, 1, colors.selectionFrom, colors.selectionText, " ")
textColor = colors.selectionText
end
buffer.text(object.x + 1, object.y + y, textColor, string.format("%08X", index))
index = index + 16
end
end
-- Horizontal
window:addChild(GUI.object(13, 4, 62, 1)).draw = function(object)
local counter = 0
local restFrom, restTo = selection.from % 16, selection.to % 16
for x = 1, object.width, 4 do
local textColor = colors.panelText
if counter + 1 > restFrom and counter + 1 < restTo then
buffer.square(object.x + x - 2, object.y, 4, 1, colors.panelSeleciton, colors.selectionText, " ")
textColor = colors.panelSelecitonText
elseif restFrom == counter + 1 or restTo == counter + 1 then
buffer.square(object.x + x - 2, object.y, 4, 1, colors.selectionFrom, colors.selectionText, " ")
textColor = colors.selectionText
end
buffer.text(object.x + x - 1, object.y, textColor, string.format("%02X", counter))
counter = counter + 1
end
end
scrollBar = window:addChild(GUI.scrollBar(window.width, 5, 1, window.height - 4, 0xC3C3C3, 0x393939, 0, 1, 1, 160, 1, true))
scrollBar.eventHandler = nil
titleTextBox = window:addChild(
GUI.textBox(
1, 1, math.floor(window.width * 0.36), 3,
colors.titleBackground,
colors.titleText,
{
"",
{text = "", color = colors.titleText2},
{text = "", color = colors.titleText2}
},
1, 1, 0
)
)
titleTextBox.localPosition.x = math.floor(window.width / 2 - titleTextBox.width / 2)
titleTextBox:setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
titleTextBox.eventHandler = nil
local saveFileButton = window:addChild(GUI.adaptiveRoundedButton(titleTextBox.localPosition.x - 11, 2, 2, 0, colors.panel, colors.panelSelecitonText, colors.panelSelecitonText, colors.panel, "Save"))
local openFileButton = window:addChild(GUI.adaptiveRoundedButton(saveFileButton.localPosition.x - 11, 2, 2, 0, colors.panel, colors.panelSelecitonText, colors.panelSelecitonText, colors.panel, "Open"))
------------------------------------------------------------------------------------------------------------------
local function load(path)
local file, reason = io.open(path, "rb")
if file then
bytes = {}
local char
while true do
local char = file:read(1)
if char then
table.insert(bytes, string.byte(char))
else
break
end
end
file:close()
offset = 0
selection.from, selection.to = 1, 1
scrollBar.value, scrollBar.maximumValue = 0, #bytes
status()
else
GUI.error("Failed to open file for reading: " .. tostring(reason))
end
end
openFileButton.onTouch = function()
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, "Open", "Cancel", "File name", "/")
filesystemDialog:setMode(GUI.filesystemModes.open, GUI.filesystemModes.file)
filesystemDialog:show()
filesystemDialog.onSubmit = function(path)
load(path)
mainContainer:draw()
buffer.draw()
end
end
saveFileButton.onTouch = function()
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, "Save", "Cancel", "File name", "/")
filesystemDialog:setMode(GUI.filesystemModes.save, GUI.filesystemModes.file)
filesystemDialog:show()
filesystemDialog.onSubmit = function(path)
local file = io.open(path, "wb")
if file then
for i = 1, #bytes do
file:write(string.char(bytes[i]))
end
file:close()
else
GUI.error("Failed to open file for writing: " .. tostring(reason))
end
end
end
window.actionButtons.maximize.onTouch = function()
window.height = window.parent.height
byteField.height = window.height - 6
charField.height = byteField.height
scrollBar.height = byteField.height
window.backgroundPanel.height = window.height - 4
verticalCounter.height = window.backgroundPanel.height + 1
separator.height = byteField.height + 2
window.localPosition.y = 1
mainContainer:draw()
buffer.draw()
end
------------------------------------------------------------------------------------------------------------------
load("/bin/resolution.lua")
mainContainer:draw()
buffer.draw()

View File

@ -260,10 +260,12 @@ local image = require("image")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
------------------------------------------------------------------------------------------
-- Создаем полноэкранный контейнер, добавляем на него загруженное изображение и полупрозрачную черную панель
local mainContainer = GUI.fullScreenContainer()
mainContainer:addChild(GUI.image(1, 1, image.load("/MineOS/Pictures/Raspberry.pic")))
mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x000000, 40))
mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x000000, 0.4))
-- Добавляем в созданный контейнер layout с сеткой размером 5x1
local layout = mainContainer:addChild(GUI.layout(1, 1, mainContainer.width, mainContainer.height, 5, 1))
@ -281,6 +283,8 @@ layout:setCellPosition(4, 1, layout:addChild(GUI.button(1, 1, 26, 3, 0xEEEEEE, 0
layout:setCellPosition(4, 1, layout:addChild(GUI.button(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 8")))
layout:setCellPosition(5, 1, layout:addChild(GUI.button(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 9")))
------------------------------------------------------------------------------------------
mainContainer:draw()
buffer.draw(true)
mainContainer:startEventHandling()

View File

@ -2298,8 +2298,8 @@ local function filesystemDialogSetMode(filesystemDialog, IOMode, filesystemMode)
if filesystemDialog.IOMode == GUI.filesystemModes.save then
filesystemDialog.filesystemTree.showMode = GUI.filesystemModes.directory
filesystemDialog.filesystemTree.selectionMode = GUI.filesystemModes.directory
filesystemDialog.input.eventHandler = inputEventHandler
filesystemDialog.extensionComboBox.hidden = not (filesystemDialog.filesystemMode == GUI.filesystemModes.file)
filesystemDialog.input.disabled = false
filesystemDialog.extensionComboBox.hidden = filesystemDialog.filesystemMode ~= GUI.filesystemModes.file or not filesystemDialog.filesystemTree.extensionFilters
else
if filesystemDialog.filesystemMode == GUI.filesystemModes.file then
filesystemDialog.filesystemTree.showMode = GUI.filesystemModes.both
@ -2309,7 +2309,7 @@ local function filesystemDialogSetMode(filesystemDialog, IOMode, filesystemMode)
filesystemDialog.filesystemTree.selectionMode = GUI.filesystemModes.directory
end
filesystemDialog.input.eventHandler = nil
filesystemDialog.input.disabled = true
filesystemDialog.extensionComboBox.hidden = true
end
@ -2320,8 +2320,9 @@ local function filesystemDialogAddExtensionFilter(filesystemDialog, extension)
filesystemDialog.extensionComboBox:addItem(extension)
filesystemDialog.extensionComboBox.width = math.max(filesystemDialog.extensionComboBox.width, unicode.len(extension) + 3)
filesystemDialog.extensionComboBox.localPosition.x = filesystemDialog.cancelButton.localPosition.x - filesystemDialog.extensionComboBox.width - 2
filesystemDialog.filesystemTree:addExtensionFilter(extension)
filesystemDialog:setMode(filesystemDialog.IOMode, filesystemDialog.filesystemMode)
end
function GUI.filesystemDialog(x, y, width, height, submitButtonText, cancelButtonText, placeholderText, path)
@ -2334,10 +2335,10 @@ function GUI.filesystemDialog(x, y, width, height, submitButtonText, cancelButto
filesystemDialog.submitButton.localPosition.x = filesystemDialog.width - filesystemDialog.submitButton.width - 1
filesystemDialog.cancelButton.localPosition.x = filesystemDialog.submitButton.localPosition.x - filesystemDialog.cancelButton.width - 2
filesystemDialog.extensionComboBox = filesystemDialog:addChild(GUI.comboBox(1, height - 1, 1, 1, 0xE1E1E1, 0x555555, 0xC3C3C3, 0x888888))
filesystemDialog.extensionComboBox = filesystemDialog:addChild(GUI.comboBox(1, height - 1, 1, 1, 0xE1E1E1, 0x666666, 0xC3C3C3, 0x888888))
filesystemDialog.extensionComboBox.hidden = true
filesystemDialog.input = filesystemDialog:addChild(GUI.input(2, height - 1, 1, 1, 0xE1E1E1, 0x555555, 0x888888, 0xE1E1E1, 0x777777, "", placeholderText))
filesystemDialog.input = filesystemDialog:addChild(GUI.input(2, height - 1, 1, 1, 0xE1E1E1, 0x666666, 0x999999, 0xE1E1E1, 0x3C3C3C, "", placeholderText))
filesystemDialog.filesystemTree = filesystemDialog:addChild(GUI.filesystemTree(1, 1, width, height - 3, 0xE1E1E1, 0x3C3C3C, 0x3C3C3C, 0xAAAAAA, 0x3C3C3C, 0xE1E1E1, 0xBBBBBB, 0xAAAAAA, 0xC3C3C3, 0x444444))
filesystemDialog.filesystemTree.workPath = path
@ -2394,7 +2395,8 @@ function GUI.addFilesystemDialogToContainer(parentContainer, ...)
path = path .. filesystemDialog.input.text
if filesystemDialog.filesystemMode == GUI.filesystemModes.file then
path = path .. filesystemDialog.extensionComboBox:getItem(filesystemDialog.extensionComboBox.selectedItem).text
local selectedItem = filesystemDialog.extensionComboBox:getItem(filesystemDialog.extensionComboBox.selectedItem)
path = path .. (selectedItem and selectedItem.text or "")
else
path = path .. "/"
end
@ -3487,6 +3489,29 @@ function GUI.autoComplete(x, y, width, maximumHeight, backgroundColor, textColor
return object
end
--------------------------------------------------------------------------------------------------------------------------------
-- buffer.clear()
-- buffer.draw(true)
-- -- Создаем полноэкранный контейнер, добавляем на него загруженное изображение и полупрозрачную черную панель
-- local mainContainer = GUI.fullScreenContainer()
-- mainContainer:addChild(GUI.image(1, 1, image.load("/MineOS/Pictures/Raspberry.pic")))
-- local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, "Save", "Cancel", "File name", "/")
-- filesystemDialog:setMode(GUI.filesystemModes.save, GUI.filesystemModes.file)
-- filesystemDialog:addExtensionFilter(".pic")
-- filesystemDialog:show()
-- filesystemDialog.onSubmit = function(path)
-- GUI.error(path)
-- end
-- mainContainer:draw()
-- buffer.draw(true)
-- mainContainer:startEventHandling()
--------------------------------------------------------------------------------------------------------------------------------
return GUI