MineOS/Applications/Photoshop/Photoshop.lua
Igor Timofeev 51e6c20fc8 afaef
2016-01-12 16:31:15 +03:00

856 lines
30 KiB
Lua
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 copyright = [[
Photoshop v3.0 (закрытая бета)
Автор: IT
Контакты: https://vk.com/id7799889
Соавтор: Pornogion
Контакты: https://vk.com/id88323331
]]
------------------------------------------------ Библиотеки --------------------------------------------------------------
--Не требующиеся для MineOS
local ecs = require("ECSAPI")
local fs = require("filesystem")
local unicode = require("unicode")
local context = require("context")
local image = require("image")
local component = require("component")
local keyboard = require("keyboard")
--Обязательные
local colorlib = require("colorlib")
local palette = require("palette")
local event = require("event")
local gpu = component.gpu
------------------------------------------------ Переменные --------------------------------------------------------------
--Массив главного изображения
local masterPixels = {
width = 0,
height = 0,
}
--Базовая цветовая схема программы
local colors = {
toolbar = 0x535353,
toolbarInfo = 0x3d3d3d,
toolbarButton = 0x3d3d3d,
toolbarButtonText = 0xeeeeee,
drawingArea = 0x262626,
console = 0x3d3d3d,
consoleText = 0x999999,
transparencyWhite = 0xffffff,
transparencyGray = 0xcccccc,
transparencyVariable = 0xffffff,
oldBackground = 0x0,
oldForeground = 0x0,
topMenu = 0xeeeeee,
topMenuText = 0x262626,
}
--Различные константы и размеры тулбаров и кликабельных зон
local sizes = {
widthOfLeftBar = 6,
}
sizes.heightOfTopBar = 3
sizes.xSize, sizes.ySize = gpu.getResolution()
sizes.xStartOfDrawingArea = sizes.widthOfLeftBar + 1
sizes.xEndOfDrawingArea = sizes.xSize
sizes.yStartOfDrawingArea = 2 + sizes.heightOfTopBar
sizes.yEndOfDrawingArea = sizes.ySize - 1
sizes.widthOfDrawingArea = sizes.xEndOfDrawingArea - sizes.xStartOfDrawingArea + 1
sizes.heightOfDrawingArea = sizes.yEndOfDrawingArea - sizes.yStartOfDrawingArea + 1
sizes.heightOfLeftBar = sizes.ySize - 1
--Для изображения
local function reCalculateImageSizes()
sizes.widthOfImage = masterPixels.width
sizes.heightOfImage = masterPixels.height
sizes.sizeOfPixelData = 4
sizes.xStartOfImage = 9
sizes.yStartOfImage = 6
sizes.xEndOfImage = sizes.xStartOfImage + sizes.widthOfImage - 1
sizes.yEndOfImage = sizes.yStartOfImage + sizes.heightOfImage - 1
end
reCalculateImageSizes()
--Инструменты
sizes.heightOfInstrument = 3
sizes.yStartOfInstruments = 2 + sizes.heightOfTopBar
local instruments = {
-- {"⮜", "Move"},
-- {"✄", "Crop"},
{"", "Brush"},
{"", "Eraser"},
{"", "Fill"},
{"", "Text"},
}
local currentInstrument = 1
local currentBackground = 0x6649ff
local currentForeground = 0x3ff80
local currentAlpha = 0x00
local currentSymbol = " "
local currentBrushSize = 1
local savePath
--Верхний тулбар
local topToolbar = {{"PS", ecs.colors.blue}, {"Файл"}, {"Изображение"}, {"Инструменты"}, {"О программе"}}
------------------------------------------------ Функции отрисовки --------------------------------------------------------------
--Объекты для тача
local obj = {}
local function newObj(class, name, ...)
obj[class] = obj[class] or {}
obj[class][name] = {...}
end
local function drawTransparentPixel(xPos, yPos, i, j)
if j % 2 == 0 then
if i % 2 == 0 then
colors.transparencyVariable = colors.transparencyWhite
else
colors.transparencyVariable = colors.transparencyGray
end
else
if i % 2 == 0 then
colors.transparencyVariable = colors.transparencyGray
else
colors.transparencyVariable = colors.transparencyWhite
end
end
gpu.setBackground(colors.transparencyVariable)
gpu.set(xPos, yPos, " ")
end
local function drawBackground()
ecs.square(sizes.xStartOfDrawingArea, sizes.yStartOfDrawingArea, sizes.widthOfDrawingArea, sizes.heightOfDrawingArea, colors.drawingArea)
end
local function drawInstruments()
local yPos = sizes.yStartOfInstruments
for i = 1, #instruments do
if currentInstrument == i then
ecs.square(1, yPos, sizes.widthOfLeftBar, sizes.heightOfInstrument, colors.toolbarButton)
else
ecs.square(1, yPos, sizes.widthOfLeftBar, sizes.heightOfInstrument, colors.toolbar)
end
ecs.colorText(3, yPos + 1, colors.toolbarButtonText, instruments[i][1])
newObj("Instruments", i, 1, yPos, sizes.widthOfLeftBar, yPos + sizes.heightOfInstrument - 1)
yPos = yPos + sizes.heightOfInstrument
end
end
local function drawColors()
local xPos, yPos = 2, sizes.ySize - 4
ecs.square(xPos, yPos, 3, 2, currentBackground)
ecs.square(xPos + 3, yPos + 1, 1, 2, currentForeground)
ecs.square(xPos + 1, yPos + 2, 2, 1, currentForeground)
ecs.colorTextWithBack(xPos + 1, yPos + 3, 0xaaaaaa, colors.toolbar, "←→")
newObj("Colors", 1, xPos, yPos, xPos + 2, yPos + 1)
newObj("Colors", 2, xPos + 3, yPos + 1, xPos + 3, yPos + 2)
newObj("Colors", 3, xPos + 1, yPos + 2, xPos + 3, yPos + 2)
newObj("Colors", 4, xPos + 1, yPos + 3, xPos + 2, yPos + 3)
end
local function drawLeftBar()
ecs.square(1, 2, sizes.widthOfLeftBar, sizes.heightOfLeftBar, colors.toolbar)
drawInstruments()
drawColors()
end
local function drawTopMenu()
ecs.square(1, 1, sizes.xSize, 1, colors.topMenu)
local xPos = 3
for i = 1, #topToolbar do
ecs.colorText(xPos, 1, topToolbar[i][2] or colors.topMenuText, topToolbar[i][1])
if i > 1 then
newObj("TopMenu", topToolbar[i][1], xPos, 1, xPos + unicode.len(topToolbar[i][1]) - 1, 1)
end
xPos = xPos + unicode.len(topToolbar[i][1]) + 2
end
end
local function drawTopBar()
local topBarInputs = { {"Размер кисти", currentBrushSize}, {"Прозрачность", math.floor(currentAlpha)}}
ecs.square(1, 2, sizes.xSize, sizes.heightOfTopBar, colors.toolbar)
local xPos, yPos = 3, 3
local limit = 8
--ecs.error("сукак")
for i = 1, #topBarInputs do
ecs.colorTextWithBack(xPos, yPos, 0xeeeeee, colors.toolbar, topBarInputs[i][1])
xPos = xPos + unicode.len(topBarInputs[i][1]) + 1
ecs.inputText(xPos, yPos, limit, tostring(topBarInputs[i][2]), 0xffffff, 0x262626, true)
newObj("TopBarInputs", i, xPos, yPos, xPos + limit - 1, yPos, limit)
if i == 2 then xPos = xPos + 3 end
xPos = xPos + limit + 2
end
end
local function createEmptyMasterPixels()
--Очищаем мастерпиксельс и задаем ширину с высотой
masterPixels = {}
masterPixels.width = sizes.widthOfImage
masterPixels.height = sizes.heightOfImage
--Создаем пустой мастерпиксельс
for j = 1, sizes.heightOfImage * sizes.widthOfImage do
table.insert(masterPixels, 0x000000)
table.insert(masterPixels, 0x000000)
table.insert(masterPixels, 0xFF)
table.insert(masterPixels, " ")
end
end
--Формула конвертации итератора массива в абсолютные координаты пикселя изображения
local function convertIteratorToCoords(iterator)
--Приводим итератор к корректному виду (1 = 1, 5 = 2, 9 = 3, 13 = 4, 17 = 5, ...)
iterator = (iterator + sizes.sizeOfPixelData - 1) / sizes.sizeOfPixelData
--Получаем остаток от деления итератора на ширину изображения
local ostatok = iterator % sizes.widthOfImage
--Если остаток равен 0, то х равен ширине изображения, а если нет, то х равен остатку
local x = (ostatok == 0) and sizes.widthOfImage or ostatok
--А теперь как два пальца получаем координату по Y
local y = math.ceil(iterator / sizes.widthOfImage)
--Очищаем остаток из оперативки
ostatok = nil
--Возвращаем координаты
return x, y
end
--Формула конвертации абсолютных координат пикселя изображения в итератор для массива
local function convertCoordsToIterator(x, y)
--Конвертируем координаты в итератор
return (sizes.widthOfImage * (y - 1) + x) * sizes.sizeOfPixelData - sizes.sizeOfPixelData + 1
end
local function console(text)
ecs.square(sizes.xStartOfDrawingArea, sizes.ySize, sizes.widthOfDrawingArea, 1, colors.console)
local _, total, used = ecs.getInfoAboutRAM()
ecs.colorText(sizes.xEndOfDrawingArea - 15, sizes.ySize, colors.consoleText, used.."/"..total.." KB RAM")
gpu.set(sizes.xStartOfDrawingArea + 1, sizes.ySize, text)
_, total, used = nil, nil, nil
end
local function drawPixel(x, y, i, j, iterator)
--Получаем данные о пикселе
local background, foreground, alpha, symbol = masterPixels[iterator], masterPixels[iterator + 1], masterPixels[iterator + 2], masterPixels[iterator + 3]
--Если пиксель не прозрачный
if alpha == 0x00 then
gpu.setBackground(background)
gpu.setForeground(foreground)
gpu.set(x, y, symbol)
--Если пиксель прозрачнее непрозрачного
elseif alpha > 0x00 then
--Рисуем прозрачный пиксель
drawTransparentPixel(x, y, i, j)
--Ебать я красавчик! Даже без гпу.гет() сделал!
gpu.setBackground(colorlib.alphaBlend(colors.transparencyVariable, background, alpha))
gpu.setForeground(foreground)
gpu.set(x, y, symbol)
end
background, foreground, alpha, symbol = nil, nil, nil, nil
end
local function drawImage()
--Стартовые нужности
local xPixel, yPixel = 1, 1
local xPos, yPos = sizes.xStartOfImage, sizes.yStartOfImage
--Перебираем массив мастерпиксельса
for i = 1, #masterPixels, 4 do
--Если пиксель входит в разрешенную зону рисования
if xPos >= sizes.xStartOfDrawingArea and xPos <= sizes.xEndOfDrawingArea and yPos >= sizes.yStartOfDrawingArea and yPos <= sizes.yEndOfDrawingArea then
--Рисуем пиксель
drawPixel(xPos, yPos, xPixel, yPixel, i)
end
--Всякие расчеты координат
xPixel = xPixel + 1
xPos = xPos + 1
if xPixel > sizes.widthOfImage then xPixel = 1; xPos = sizes.xStartOfImage; yPixel = yPixel + 1; yPos = yPos + 1 end
end
end
local function drawBackgroundAndImage()
drawBackground()
drawImage()
end
local function drawAll()
--Очищаем экран
ecs.prepareToExit()
--И консольку!
console("Весь интерфейс перерисован!")
--Рисуем тулбары
drawBackground()
drawLeftBar()
drawTopBar()
drawTopMenu()
--Рисуем картинку
drawBackgroundAndImage()
end
------------------------------------------------ Функции расчета --------------------------------------------------------------
local function move(direction)
if direction == "up" then
sizes.yStartOfImage = sizes.yStartOfImage - 2
elseif direction == "down" then
sizes.yStartOfImage = sizes.yStartOfImage + 2
elseif direction == "left" then
sizes.xStartOfImage = sizes.xStartOfImage - 2
elseif direction == "right" then
sizes.xStartOfImage = sizes.xStartOfImage + 2
end
drawBackgroundAndImage()
end
local function setPixel(iterator, background, foreground, alpha, symbol)
masterPixels[iterator] = background
masterPixels[iterator + 1] = foreground
masterPixels[iterator + 2] = alpha
masterPixels[iterator + 3] = symbol
end
local function swapColors()
local tempColor = currentForeground
currentForeground = currentBackground
currentBackground = tempColor
tempColor = nil
drawColors()
console("Цвета поменяны местами.")
end
local function inputText(x, y, limit)
local oldPixels = ecs.rememberOldPixels(x,y-1,x+limit-1,y+1)
local text = ""
local inputPos = 1
local function drawThisShit()
for i=1,inputPos do
ecs.invertedText(x + i - 1, y + 1, "")
ecs.adaptiveText(x + i - 1, y - 1, " ", currentBackground)
end
ecs.invertedText(x + inputPos - 1, y + 1, "")--"▲","▼"
ecs.invertedText(x + inputPos - 1, y - 1, "")
ecs.adaptiveText(x, y, ecs.stringLimit("start", text, limit, false), currentBackground)
end
drawThisShit()
while true do
local e = {event.pull()}
if e[1] == "key_down" then
if e[4] == 14 then
if unicode.len(text) >= 1 then
text = unicode.sub(text, 1, -2)
if unicode.len(text) < (limit - 1) then
inputPos = inputPos - 1
end
ecs.drawOldPixels(oldPixels)
drawThisShit()
end
elseif e[4] == 28 then
break
else
local symbol = ecs.convertCodeToSymbol(e[3])
if symbol ~= nil then
text = text .. symbol
if unicode.len(text) < limit then
inputPos = inputPos + 1
end
drawThisShit()
end
end
elseif e[1] == "clipboard" then
if e[3] then
text = text .. e[3]
if unicode.len(text) < limit then
inputPos = inputPos + unicode.len(e[3])
end
drawThisShit()
end
end
end
ecs.drawOldPixels(oldPixels)
if text == "" then text = " " end
return text
end
local function saveTextToPixels(x, y, text)
local sText = unicode.len(text)
local iterator
x = x - 1
for i = 1, sText do
if x + i > sizes.widthOfImage then break end
iterator = convertCoordsToIterator(x + i, y)
setPixel(iterator, masterPixels[iterator], currentBackground, masterPixels[iterator + 2], unicode.sub(text, i, i))
end
end
local function flipVertical(massiv)
local newMassiv = {}
newMassiv.width, newMassiv.height = massiv.width, massiv.height
local iterator = #masterPixels
while iterator >= 1 do
table.insert(newMassiv, masterPixels[iterator - 3])
table.insert(newMassiv, masterPixels[iterator - 2])
table.insert(newMassiv, masterPixels[iterator - 1])
table.insert(newMassiv, masterPixels[iterator])
masterPixels[iterator], masterPixels[iterator - 1], masterPixels[iterator - 2], masterPixels[iterator - 3] = nil, nil, nil, nil
iterator = iterator - 4
end
return newMassiv
end
local function flipHorizontal( picture )
local blockSize = picture.width * 4
local buffer = nil
local startBlock = nil
local endPixel = nil
for j=1, picture.height, 1 do
startBlock = picture.width * 4 * (j-1)
for pixel=4, blockSize/2, 4 do
endPixel = blockSize-(pixel-4)
--Foreground
buffer = picture[pixel-3+startBlock]
picture[pixel-3+startBlock] = picture[endPixel-3+startBlock]
picture[endPixel-3+startBlock] = buffer
--Background
buffer = picture[pixel-2+startBlock]
picture[pixel-2+startBlock] = picture[endPixel-2+startBlock]
picture[endPixel-2+startBlock] = buffer
--Alpha
buffer = picture[pixel-1+startBlock]
picture[pixel-1+startBlock] = picture[endPixel-1+startBlock]
picture[endPixel-1+startBlock] = buffer
--Char
buffer = picture[pixel-0+startBlock]
picture[pixel-0+startBlock] = picture[endPixel-0+startBlock]
picture[endPixel-0+startBlock] = buffer
end
end
end
local function doFlip(horizontal)
if horizontal then
flipHorizontal(masterPixels)
else
masterPixels = flipVertical(masterPixels)
end
drawImage()
end
local function invertColors()
for i = 1, #masterPixels, 4 do
masterPixels[i] = 0xFFFFFF - masterPixels[i]
masterPixels[i + 1] = 0xFFFFFF - masterPixels[i + 1]
end
drawImage()
end
local function blackAndWhite()
for i = 1, #masterPixels, 4 do
local hh, ss, bb = colorlib.HEXtoHSB(masterPixels[i]); ss = 0
masterPixels[i] = colorlib.HSBtoHEX(hh, ss, bb)
hh, ss, bb = colorlib.HEXtoHSB(masterPixels[i + 1]); ss = 0
masterPixels[i + 1] = colorlib.HSBtoHEX(hh, ss, bb)
end
drawImage()
end
local function new()
local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, false, {"EmptyLine"}, {"CenterText", 0x262626, "Новый документ"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Ширина"}, {"Input", 0x262626, 0x880000, "Высота"}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "Ok!"}})
data[1] = tonumber(data[1]) or 51
data[2] = tonumber(data[2]) or 19
sizes.widthOfImage, sizes.heightOfImage = data[1], data[2]
sizes.xStartOfImage = 9
sizes.yStartOfImage = 6
sizes.xEndOfImage = sizes.xStartOfImage + sizes.widthOfImage - 1
sizes.yEndOfImage = sizes.yStartOfImage + sizes.heightOfImage - 1
createEmptyMasterPixels()
drawAll()
end
--Обычная рекурсивная заливка
local function fill(x, y, startColor, fillColor)
local function doFill(xStart, yStart)
local iterator = convertCoordsToIterator(xStart, yStart)
--Завершаем функцию, если цвет в массиве не такой, какой мы заливаем
if masterPixels[iterator] ~= startColor or masterPixels[iterator] == fillColor then return end
--Заливаем в память
masterPixels[iterator] = fillColor
masterPixels[iterator + 2] = currentAlpha
doFill(xStart + 1, yStart)
doFill(xStart - 1, yStart)
doFill(xStart, yStart + 1)
doFill(xStart, yStart - 1)
iterator = nil
end
doFill(x, y)
end
--Кисть
local function brush(x, y, background, foreground, alpha, symbol)
--Смещение влево и вправо относительно указанного центра кисти
local position = math.floor(currentBrushSize / 2)
local newIterator
--Сдвигаем х и у на смещение
x, y = x - position, y - position
--Считаем ширину/высоту кисти
local brushSize = position * 2 + 1
--Перебираем кисть по ширине и высоте
for cyka = 1, brushSize do
for pidor = 1, brushSize do
--Если этот кусочек входит в границы рисовабельной зоны, то
if x >= 1 and x <= sizes.widthOfImage and y >= 1 and y <= sizes.heightOfImage then
--Считаем новый итератор для кусочка кисти
newIterator = convertCoordsToIterator(x, y)
--Если указанная прозрачность не максимальна
if alpha < 0xFF then
--Если пиксель в массиве ни хуя не прозрачный, то оставляем его таким же, разве что цвет меняем на сблендированный
if masterPixels[newIterator + 2] == 0x00 then
local gettedBackground = colorlib.alphaBlend(masterPixels[newIterator], background, alpha)
setPixel(newIterator, gettedBackground, foreground, 0x00, symbol)
--А если прозрачный
else
--Если его прозоачность максимальная
if masterPixels[newIterator + 2] == 0xFF then
setPixel(newIterator, background, foreground, alpha, symbol)
--Если не максимальная
else
local newAlpha = masterPixels[newIterator + 2] - (0xFF - alpha)
if newAlpha < 0x00 then newAlpha = 0x00 end
setPixel(newIterator, background, foreground, newAlpha, symbol)
end
end
--Если указанная прозрачность максимальна, т.е. равна 0xFF
else
setPixel(newIterator, 0x000000, 0x000000, 0xFF, " ")
end
--Рисуем пиксель из мастерпиксельса
drawPixel(x + sizes.xStartOfImage - 1, y + sizes.yStartOfImage - 1, x, y, newIterator)
end
x = x + 1
end
x = x - brushSize
y = y + 1
end
end
------------------------------------------------ Старт программы --------------------------------------------------------------
local args = {...}
--Рисуем весь интерфейс
drawAll()
if args[1] == "o" or args[1] == "open" or args[1] == "-o" or args[1] == "load" then
masterPixels = image.load(args[2])
savePath = args[2]
reCalculateImageSizes()
drawBackgroundAndImage()
else
new()
end
while true do
local e = {event.pull()}
if e[1] == "touch" or e[1] == "drag" then
--Левый клик
if e[5] == 0 then
--Если кликнули на рисовабельную зонку
if ecs.clickedAtArea(e[3], e[4], sizes.xStartOfImage, sizes.yStartOfImage, sizes.xEndOfImage, sizes.yEndOfImage) then
local x, y = e[3] - sizes.xStartOfImage + 1, e[4] - sizes.yStartOfImage + 1
local iterator = convertCoordsToIterator(x, y)
--Кисть
if currentInstrument == 1 then
--Если нажата клавиша альт
if keyboard.isKeyDown(56) then
local _, _, gettedBackground = gpu.get(e[3], e[4])
currentBackground = gettedBackground
drawColors()
--Если обычная кисть, просто кисть, вообще всем кистям кисть
else
brush(x, y, currentBackground, currentForeground, currentAlpha, currentSymbol)
--Пишем что-то в консоли
console("Кисть: клик на точку "..e[3].."x"..e[4]..", координаты в изображении: "..x.."x"..y..", индекс массива изображения: "..iterator)
end
--Ластик
elseif currentInstrument == 2 then
brush(x, y, currentBackground, currentForeground, 0xFF, currentSymbol)
console("Ластик: клик на точку "..e[3].."x"..e[4]..", координаты в изображении: "..x.."x"..y..", индекс массива изображения: "..iterator)
--Текст
elseif currentInstrument == 4 then
local limit = sizes.widthOfImage - x + 1
local text = inputText(e[3], e[4], limit)
saveTextToPixels(x, y, text)
drawImage()
--Заливка
elseif currentInstrument == 3 then
fill(x, y, masterPixels[iterator], currentBackground)
drawImage()
end
iterator, x, y = nil, nil, nil
end
--Цвета
for key in pairs(obj["Colors"]) do
if ecs.clickedAtArea(e[3], e[4], obj["Colors"][key][1], obj["Colors"][key][2], obj["Colors"][key][3], obj["Colors"][key][4]) then
if key == 1 then
currentBackground = palette.draw("auto", "auto", currentBackground) or currentBackground
drawColors()
elseif key == 2 or key == 3 then
currentForeground = palette.draw("auto", "auto", currentForeground) or currentForeground
drawColors()
elseif key == 4 then
ecs.colorTextWithBack(obj["Colors"][key][1], obj["Colors"][key][2], 0xFF0000, colors.toolbar, "←→")
os.sleep(0.2)
swapColors()
end
break
end
end
--Инструменты
for key in pairs(obj["Instruments"]) do
if ecs.clickedAtArea(e[3], e[4], obj["Instruments"][key][1], obj["Instruments"][key][2], obj["Instruments"][key][3], obj["Instruments"][key][4]) then
currentInstrument = key
drawInstruments()
break
end
end
--Верхний меню-бар
for key in pairs(obj["TopMenu"]) do
if ecs.clickedAtArea(e[3], e[4], obj["TopMenu"][key][1], obj["TopMenu"][key][2], obj["TopMenu"][key][3], obj["TopMenu"][key][4]) then
ecs.square(obj["TopMenu"][key][1] - 1, obj["TopMenu"][key][2], unicode.len(key) + 2, 1, ecs.colors.blue)
ecs.colorText(obj["TopMenu"][key][1], obj["TopMenu"][key][2], 0xffffff, key)
local action
if key == "Файл" then
action = context.menu(obj["TopMenu"][key][1] - 1, obj["TopMenu"][key][2] + 1, {"Новый"}, {"Открыть"}, "-", {"Сохранить", (savePath == nil)}, {"Сохранить как"}, "-", {"Выход"})
elseif key == "Изображение" then
action = context.menu(obj["TopMenu"][key][1] - 1, obj["TopMenu"][key][2] + 1, {"Отразить по горизонтали"}, {"Отразить по вертикали"}, "-", {"Инвертировать цвета"}, {"Черно-белый фильтр"})
elseif key == "Инструменты" then
action = context.menu(obj["TopMenu"][key][1] - 1, obj["TopMenu"][key][2] + 1, {"Кисть"}, {"Ластик"}, {"Заливка"}, {"Текст"})
elseif key == "О программе" then
ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x880000, "Photoshop v3.0 (public beta)"}, {"EmptyLine"}, {"CenterText", 0x262626, "Авторы:"}, {"CenterText", 0x555555, "Тимофеев Игорь"}, {"CenterText", 0x656565, "vk.com/id7799889"}, {"CenterText", 0x656565, "Трифонов Глеб"}, {"CenterText", 0x656565, "vk.com/id88323331"}, {"EmptyLine"}, {"CenterText", 0x262626, "Тестеры:"}, {"CenterText", 0x656565, "Шестаков Тимофей"}, {"CenterText", 0x656565, "vk.com/id113499693"}, {"CenterText", 0x656565, "Вечтомов Роман"}, {"CenterText", 0x656565, "vk.com/id83715030"}, {"CenterText", 0x656565, "Омелаенко Максим"}, {"CenterText", 0x656565, "vk.com/paladincvm"}, {"EmptyLine"},{"Button", {0xbbbbbb, 0xffffff, "OK"}})
end
if action == "Выход" then
ecs.prepareToExit()
return
elseif action == "Отразить по горизонтали" then
doFlip(true)
elseif action == "Отразить по вертикали" then
doFlip(false)
elseif action == "Инвертировать цвета" then
invertColors()
elseif action == "Черно-белый фильтр" then
blackAndWhite()
elseif action == "Ластик" then
currentInstrument = 2
drawInstruments()
elseif action == "Кисть" then
currentInstrument = 1
drawInstruments()
elseif action == "Текст" then
currentInstrument = 4
drawInstruments()
elseif action == "Заливка" then
currentInstrument = 3
drawInstruments()
elseif action == "Новый" then
new()
elseif action == "Сохранить как" then
local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Сохранить как"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Путь"}, {"Selector", 0x262626, 0x880000, "OCIF3", "OCIF2", "OCIF1", "RAW"}, {"CenterText", 0x262626, "Рекомендуется использовать"}, {"CenterText", 0x262626, "метод кодирования OCIF3"}, {"EmptyLine"}, {"Button", {0x888888, 0xffffff, "OK"}, {0xaaaaaa, 0xffffff, "Отмена"}})
if data[3] == "OK" then
data[1] = data[1] or "Untitled"
data[2] = data[2] or "OCIF3"
if data[2] == "RAW" then
data[2] = 0
elseif data[2] == "OCIF1" then
data[2] = 1
elseif data[2] == "OCIF1" then
data[2] = 2
elseif data[2] == "OCIF1" then
data[2] = 3
else
data[2] = 3
end
local filename = data[1] .. ".pic"
local encodingMethod = data[2]
image.save(filename, masterPixels, encodingMethod)
savePath = fileName
end
elseif action == "Сохранить" then
image.save(savePath, masterPixels, 3)
elseif action == "Открыть" then
local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, "Открыть"}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Путь"}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})
local fileFormat = ecs.getFileFormat(data[1])
if not data[1] then
ecs.error("Некорректное имя файла!")
elseif not fs.exists(data[1]) then
ecs.error("Файл\""..data[1].."\" не существует!")
elseif fileFormat ~= ".pic" and fileFormat ~= ".rawpic" and fileFormat ~= ".png" then
ecs.error("Формат файла \""..fileFormat.."\" не поддерживается!")
else
masterPixels = image.load(data[1])
reCalculateImageSizes()
drawBackgroundAndImage()
end
end
drawTopMenu()
break
end
end
--Топбар
for key in pairs(obj["TopBarInputs"]) do
if ecs.clickedAtArea(e[3], e[4], obj["TopBarInputs"][key][1], obj["TopBarInputs"][key][2], obj["TopBarInputs"][key][3], obj["TopBarInputs"][key][4]) then
local input = ecs.inputText(obj["TopBarInputs"][key][1], obj["TopBarInputs"][key][2], obj["TopBarInputs"][key][5], "", 0xffffff, 0x262626)
input = tonumber(input)
if input then
if key == 1 then
if input > 0 and input < 10 then currentBrushSize = input end
elseif key == 2 then
if input > 0 and input <= 255 then currentAlpha = input end
end
end
drawTopBar()
break
end
end
else
--Если кликнули на рисовабельную зонку
if ecs.clickedAtArea(e[3], e[4], sizes.xStartOfImage, sizes.yStartOfImage, sizes.xEndOfImage, sizes.yEndOfImage) then
local x, y, width, height = e[3], e[4], 30, 12
--А это чтоб за края экрана не лезло
if y + height >= sizes.ySize then y = sizes.ySize - height end
if x + width + 1 >= sizes.xSize then x = sizes.xSize - width - 1 end
currentBrushSize, currentAlpha = table.unpack(ecs.universalWindow(x, y, width, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x880000, "Параметры кисти"}, {"Slider", 0x262626, 0x880000, 1, 10, currentBrushSize, "Размер: ", " px"}, {"Slider", 0x262626, 0x880000, 0, 255, currentAlpha, "Прозрачность: ", ""}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}}))
drawTopBar()
end
end
elseif e[1] == "key_down" then
--Стрелки
if e[4] == 200 then
move("up")
elseif e[4] == 208 then
move("down")
elseif e[4] == 203 then
move("left")
elseif e[4] == 205 then
move("right")
--Пробел
elseif e[4] == 57 then
drawAll()
--X
elseif e[4] == 45 then
swapColors()
--B
elseif e[4] == 48 then
currentInstrument = 1
drawInstruments()
--E
elseif e[4] == 18 then
currentInstrument = 2
drawInstruments()
--T
elseif e[4] == 20 then
currentInstrument = 4
drawInstruments()
--G
elseif e[4] == 34 then
currentInstrument = 3
drawInstruments()
--D
elseif e[4] == 32 then
currentBackground = 0x000000
currentForeground = 0xFFFFFF
currentAlpha = 0x00
drawColors()
end
elseif e[1] == "scroll" then
end
end
------------------------------------------------ Выход из программы --------------------------------------------------------------