mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2026-01-09 12:42:39 +01:00
Новый пиздатый фотошоп
This commit is contained in:
parent
25e7038381
commit
e69d694558
BIN
Applications/PictureEdit/Icon.pic
Normal file
BIN
Applications/PictureEdit/Icon.pic
Normal file
Binary file not shown.
442
Applications/PictureEdit/Main.lua
Normal file
442
Applications/PictureEdit/Main.lua
Normal file
@ -0,0 +1,442 @@
|
||||
|
||||
local args, options = require("shell").parse(...)
|
||||
local GUI = require("GUI")
|
||||
local MineOSCore = require("MineOSCore")
|
||||
local fs = require("filesystem")
|
||||
local image = require("image")
|
||||
local color = require("color")
|
||||
local buffer = require("doubleBuffering")
|
||||
local MineOSPaths = require("MineOSPaths")
|
||||
local MineOSInterface = require("MineOSInterface")
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
local resourcesPath = MineOSCore.getCurrentScriptDirectory()
|
||||
local toolsPath = resourcesPath .. "Tools/"
|
||||
local configPath = MineOSPaths.applicationData .. "Picture Edit/Config.cfg"
|
||||
local savePath
|
||||
|
||||
local config = {
|
||||
recentColors = {},
|
||||
transparencyBackground = 0xFFFFFF,
|
||||
transparencyForeground = 0xD2D2D2,
|
||||
}
|
||||
|
||||
local recentColorsLimit = 52
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
local function saveConfig()
|
||||
table.toFile(configPath, config)
|
||||
end
|
||||
|
||||
local function loadConfig()
|
||||
if fs.exists(configPath) then
|
||||
config = table.fromFile(configPath)
|
||||
else
|
||||
local perLine = 13
|
||||
local value, step = 0, 360 / (recentColorsLimit - perLine)
|
||||
for i = 1, recentColorsLimit - perLine do
|
||||
table.insert(config.recentColors, color.HSBToInteger(value, 1, 1))
|
||||
value = value + step
|
||||
end
|
||||
|
||||
value, step = 0, 255 / perLine
|
||||
for i = 1, perLine do
|
||||
table.insert(config.recentColors, color.RGBToInteger(math.floor(value), math.floor(value), math.floor(value)))
|
||||
value = value + step
|
||||
end
|
||||
|
||||
saveConfig()
|
||||
end
|
||||
end
|
||||
|
||||
loadConfig()
|
||||
|
||||
local mainContainer = GUI.fullScreenContainer()
|
||||
|
||||
mainContainer.menu = mainContainer:addChild(GUI.menu(1, 1, mainContainer.width, 0xE1E1E1, 0x5A5A5A, 0x3366CC, 0xFFFFFF, nil))
|
||||
|
||||
mainContainer.toolsPanel = mainContainer:addChild(GUI.panel(1, 2, 6, mainContainer.height - 1, 0x3C3C3C))
|
||||
|
||||
local function addTitle(container, text)
|
||||
local titleContainer = container:addChild(GUI.container(1, 1, container.width, 1))
|
||||
titleContainer:addChild(GUI.panel(1, 1, titleContainer.width, 1, 0x2D2D2D))
|
||||
titleContainer:addChild(GUI.text(2, 1, 0xD2D2D2, text))
|
||||
|
||||
return titleContainer
|
||||
end
|
||||
|
||||
local pizdaWidth = 28
|
||||
mainContainer.sidebarPanel = mainContainer:addChild(GUI.panel(mainContainer.width - pizdaWidth + 1, 2, pizdaWidth, mainContainer.height - 1, 0x3C3C3C))
|
||||
mainContainer.sidebarLayout = mainContainer:addChild(GUI.layout(mainContainer.sidebarPanel.localX, 2, mainContainer.sidebarPanel.width, mainContainer.sidebarPanel.height, 1, 1))
|
||||
mainContainer.sidebarLayout:setCellAlignment(1, 1, GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
|
||||
|
||||
addTitle(mainContainer.sidebarLayout, "Recent colors")
|
||||
|
||||
local recentColorsContainer = mainContainer.sidebarLayout:addChild(GUI.container(1, 1, mainContainer.sidebarLayout.width - 2, 4))
|
||||
local x, y = 1, 1
|
||||
for i = 1, #config.recentColors do
|
||||
local button = recentColorsContainer:addChild(GUI.button(x, y, 2, 1, 0x0, 0x0, 0x0, 0x0, " "))
|
||||
button.onTouch = function()
|
||||
mainContainer.primaryColorSelector.color = config.recentColors[i]
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
x = x + 2
|
||||
if x > recentColorsContainer.width - 1 then
|
||||
x, y = 1, y + 1
|
||||
end
|
||||
end
|
||||
|
||||
local currentToolTitle = addTitle(mainContainer.sidebarLayout, "Tool properties")
|
||||
|
||||
mainContainer.currentToolLayout = mainContainer.sidebarLayout:addChild(GUI.layout(1, 1, mainContainer.sidebarLayout.width - 2, 1, 1, 1))
|
||||
mainContainer.currentToolLayout:setCellAlignment(1, 1, GUI.alignment.horizontal.center, GUI.alignment.vertical.top)
|
||||
mainContainer.currentToolLayout:setCellFitting(1, 1, true, false)
|
||||
|
||||
local aboutToolTitle = addTitle(mainContainer.sidebarLayout, "About tool")
|
||||
local aboutToolTextBox = mainContainer.sidebarLayout:addChild(GUI.textBox(1, 1, mainContainer.sidebarLayout.width - 2, 1, nil, 0x787878, {}, 1, 0, 0))
|
||||
|
||||
mainContainer.backgroundPanel = mainContainer:addChild(GUI.panel(mainContainer.toolsPanel.width + 1, 2, mainContainer.width - mainContainer.toolsPanel.width - mainContainer.sidebarPanel.width, mainContainer.height - 1, 0x1E1E1E))
|
||||
|
||||
mainContainer.image = mainContainer:addChild(GUI.object(1, 1, 1, 1))
|
||||
|
||||
mainContainer.toolsLayout = mainContainer:addChild(GUI.layout(1, 2, mainContainer.toolsPanel.width, mainContainer.toolsPanel.height, 1, 1))
|
||||
mainContainer.toolsLayout:setCellAlignment(1, 1, GUI.alignment.horizontal.left, GUI.alignment.vertical.top)
|
||||
mainContainer.toolsLayout:setCellSpacing(1, 1, 0)
|
||||
|
||||
local function pressToolButton(button)
|
||||
for i = 1, #mainContainer.toolsLayout.children do
|
||||
mainContainer.toolsLayout.children[i].pressed = mainContainer.toolsLayout.children[i] == button
|
||||
end
|
||||
|
||||
mainContainer.currentToolLayout:deleteChildren()
|
||||
|
||||
currentToolTitle.hidden = not button.tool.onSelection
|
||||
mainContainer.currentToolLayout.hidden = currentToolTitle.hidden
|
||||
if button.tool.onSelection then
|
||||
local result, reason = pcall(button.tool.onSelection, mainContainer)
|
||||
if result then
|
||||
mainContainer.currentToolLayout:update()
|
||||
local lastChild = mainContainer.currentToolLayout.children[#mainContainer.currentToolLayout.children]
|
||||
if lastChild then
|
||||
mainContainer.currentToolLayout.height = lastChild.localY + lastChild.height - 1
|
||||
end
|
||||
else
|
||||
GUI.error(reason)
|
||||
end
|
||||
end
|
||||
|
||||
aboutToolTitle.hidden = not button.tool.about
|
||||
aboutToolTextBox.hidden = aboutToolTitle.hidden
|
||||
if button.tool.about then
|
||||
aboutToolTextBox.lines = string.wrap({button.tool.about}, aboutToolTextBox.width)
|
||||
aboutToolTextBox.height = #aboutToolTextBox.lines
|
||||
end
|
||||
end
|
||||
|
||||
local modules = fs.sortedList(toolsPath, "name", false)
|
||||
for i = 1, #modules do
|
||||
local result, reason = loadfile(toolsPath .. modules[i])
|
||||
if result then
|
||||
result, reason = pcall(result)
|
||||
if result then
|
||||
local button = mainContainer.toolsLayout:addChild(GUI.button(1, 1, mainContainer.toolsLayout.width, 3, nil, 0xD2D2D2, 0x2D2D2D, 0xD2D2D2, reason.shortcut))
|
||||
button.switchMode = true
|
||||
button.animated = false
|
||||
button.tool = reason
|
||||
button.onTouch = function()
|
||||
pressToolButton(button)
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
else
|
||||
error("Failed to perform pcall() on module " .. modules[i] .. ": " .. reason)
|
||||
end
|
||||
else
|
||||
error("Failed to perform loadfile() on module " .. modules[i] .. ": " .. reason)
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer.image.draw = function(object)
|
||||
GUI.windowShadow(object.x, object.y, object.width, object.height, nil, true)
|
||||
|
||||
local x, y, step, notStep, background, foreground, symbol = object.x, object.y, false, mainContainer.image.width % 2
|
||||
for i = 3, #mainContainer.image.data, 4 do
|
||||
|
||||
if mainContainer.image.data[i + 2] == 0 then
|
||||
background = mainContainer.image.data[i]
|
||||
foreground = mainContainer.image.data[i + 1]
|
||||
symbol = mainContainer.image.data[i + 3]
|
||||
elseif mainContainer.image.data[i + 2] < 1 then
|
||||
background = color.blend(config.transparencyBackground, mainContainer.image.data[i], mainContainer.image.data[i + 2])
|
||||
foreground = mainContainer.image.data[i + 1]
|
||||
symbol = mainContainer.image.data[i + 3]
|
||||
else
|
||||
if mainContainer.image.data[i + 3] == " " then
|
||||
background = config.transparencyBackground
|
||||
foreground = config.transparencyForeground
|
||||
symbol = step and "▒" or "░"
|
||||
else
|
||||
background = config.transparencyBackground
|
||||
foreground = mainContainer.image.data[i + 1]
|
||||
symbol = mainContainer.image.data[i + 3]
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
buffer.set(x, y, background, foreground, symbol)
|
||||
|
||||
x, step = x + 1, not step
|
||||
if x > object.x + object.width - 1 then
|
||||
x, y = object.x, y + 1
|
||||
if notStep == 0 then
|
||||
step = not step
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function getCurrentTool()
|
||||
for i = 1, #mainContainer.toolsLayout.children do
|
||||
if mainContainer.toolsLayout.children[i].pressed then
|
||||
return mainContainer.toolsLayout.children[i]
|
||||
end
|
||||
end
|
||||
|
||||
error("No current tool found")
|
||||
end
|
||||
|
||||
local function updateRecentColorsButtons()
|
||||
for i = 1, #config.recentColors do
|
||||
recentColorsContainer.children[i].colors.default.background = config.recentColors[i]
|
||||
recentColorsContainer.children[i].colors.pressed.background = 0xFFFFFF - config.recentColors[i]
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer.secondaryColorSelector = mainContainer:addChild(GUI.colorSelector(3, mainContainer.toolsPanel.height - 2, 3, 2, 0xFFFFFF, " "))
|
||||
mainContainer.primaryColorSelector = mainContainer:addChild(GUI.colorSelector(2, mainContainer.toolsPanel.height - 3, 3, 2, 0x880000, " "))
|
||||
|
||||
local function colorSelectorOnTouch(what)
|
||||
for i = 1, #config.recentColors do
|
||||
if config.recentColors[i] == mainContainer[what].color then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(config.recentColors, 1, mainContainer[what].color)
|
||||
table.remove(config.recentColors, #config.recentColors)
|
||||
updateRecentColorsButtons()
|
||||
|
||||
saveConfig()
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
mainContainer.primaryColorSelector.onTouch = function()
|
||||
colorSelectorOnTouch("primaryColorSelector")
|
||||
end
|
||||
|
||||
mainContainer.secondaryColorSelector.onTouch = function()
|
||||
colorSelectorOnTouch("secondaryColorSelector")
|
||||
end
|
||||
|
||||
mainContainer.secondaryColorSelector.drawLine, mainContainer.primaryColorSelector.drawLine = false, false
|
||||
|
||||
mainContainer.image.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "key_down" then
|
||||
-- D
|
||||
if eventData[4] == 32 then
|
||||
mainContainer.primaryColorSelector.color, mainContainer.secondaryColorSelector.color = 0x0, 0xFFFFFF
|
||||
mainContainer:drawOnScreen()
|
||||
-- X
|
||||
elseif eventData[4] == 45 then
|
||||
mainContainer.primaryColorSelector.color, mainContainer.secondaryColorSelector.color = mainContainer.secondaryColorSelector.color, mainContainer.primaryColorSelector.color
|
||||
mainContainer:drawOnScreen()
|
||||
else
|
||||
for i = 1, #mainContainer.toolsLayout.children do
|
||||
if eventData[4] == mainContainer.toolsLayout.children[i].tool.keyCode then
|
||||
pressToolButton(mainContainer.toolsLayout.children[i])
|
||||
mainContainer:drawOnScreen()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local button = getCurrentTool()
|
||||
local result, reason = pcall(button.tool.eventHandler, mainContainer, object, eventData)
|
||||
if not result then
|
||||
GUI.error("Tool eventHandler() failed: " .. reason)
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer.image.reposition = function()
|
||||
mainContainer.image.width, mainContainer.image.height = mainContainer.image.data[1], mainContainer.image.data[2]
|
||||
if mainContainer.image.width <= mainContainer.backgroundPanel.width then
|
||||
mainContainer.image.localX = math.floor(mainContainer.backgroundPanel.x + mainContainer.backgroundPanel.width / 2 - mainContainer.image.width / 2)
|
||||
mainContainer.image.localY = math.floor(mainContainer.backgroundPanel.y + mainContainer.backgroundPanel.height / 2 - mainContainer.image.height / 2)
|
||||
else
|
||||
mainContainer.image.localX, mainContainer.image.localY = 9, 3
|
||||
end
|
||||
end
|
||||
|
||||
local function newNoGUI(width, height)
|
||||
mainContainer.image.data = {width, height}
|
||||
mainContainer.image.reposition()
|
||||
|
||||
for i = 1, width * height do
|
||||
table.insert(mainContainer.image.data, 0x0)
|
||||
table.insert(mainContainer.image.data, 0x0)
|
||||
table.insert(mainContainer.image.data, 1)
|
||||
table.insert(mainContainer.image.data, " ")
|
||||
end
|
||||
end
|
||||
|
||||
local function new()
|
||||
local container = MineOSInterface.addUniversalContainer(mainContainer, "New picture")
|
||||
|
||||
local widthInput = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x696969, 0x696969, 0xE1E1E1, 0x2D2D2D, "51", "Width"))
|
||||
local heightInput = container.layout:addChild(GUI.input(1, 1, 36, 3, 0xE1E1E1, 0x696969, 0x696969, 0xE1E1E1, 0x2D2D2D, "19", "Height"))
|
||||
|
||||
widthInput.validator = function(text)
|
||||
return tonumber(text)
|
||||
end
|
||||
heightInput.validator = widthInput.validator
|
||||
|
||||
container.panel.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
newNoGUI(tonumber(widthInput.text), tonumber(heightInput.text))
|
||||
container:delete()
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
local function loadImage(path)
|
||||
local result, reason = image.load(path)
|
||||
if result then
|
||||
savePath = path
|
||||
mainContainer.image.data = result
|
||||
mainContainer.image.reposition()
|
||||
else
|
||||
GUI.error(reason)
|
||||
end
|
||||
end
|
||||
|
||||
local function saveImage(path)
|
||||
local result, reason = image.save(path, mainContainer.image.data, 6)
|
||||
if result then
|
||||
savePath = path
|
||||
else
|
||||
GUI.error(reason)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
mainContainer.menu:addItem("PE", 0x00B6FF)
|
||||
|
||||
local fileItem = mainContainer.menu:addItem("File")
|
||||
fileItem.onTouch = function()
|
||||
local menu = GUI.contextMenu(fileItem.x, fileItem.y + 1)
|
||||
|
||||
menu:addItem("New").onTouch = new
|
||||
|
||||
menu:addSeparator()
|
||||
|
||||
menu:addItem("Open").onTouch = function()
|
||||
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, 50, math.floor(mainContainer.height * 0.8), true, "Open", "Cancel", "File name", "/")
|
||||
filesystemDialog:setMode(GUI.filesystemModes.open, GUI.filesystemModes.file)
|
||||
filesystemDialog:addExtensionFilter(".pic")
|
||||
filesystemDialog:expandPath(MineOSPaths.desktop)
|
||||
filesystemDialog:show()
|
||||
|
||||
filesystemDialog.onSubmit = function(path)
|
||||
loadImage(path)
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
menu:addItem("Save", not savePath).onTouch = function()
|
||||
saveImage(savePath)
|
||||
end
|
||||
|
||||
menu:addItem("Save as").onTouch = function()
|
||||
local filesystemDialog = GUI.addFilesystemDialogToContainer(mainContainer, 50, math.floor(mainContainer.height * 0.8), true, "Save", "Cancel", "File name", "/")
|
||||
filesystemDialog:setMode(GUI.filesystemModes.save, GUI.filesystemModes.file)
|
||||
filesystemDialog:addExtensionFilter(".pic")
|
||||
filesystemDialog:expandPath(MineOSPaths.desktop)
|
||||
filesystemDialog.filesystemTree.selectedItem = MineOSPaths.desktop
|
||||
filesystemDialog:show()
|
||||
|
||||
filesystemDialog.onSubmit = function(path)
|
||||
saveImage(path)
|
||||
end
|
||||
end
|
||||
|
||||
menu:addSeparator()
|
||||
|
||||
menu:addItem("Exit").onTouch = function()
|
||||
mainContainer:stopEventHandling()
|
||||
end
|
||||
|
||||
menu:show()
|
||||
end
|
||||
|
||||
mainContainer.menu:addItem("View").onTouch = function()
|
||||
local container = MineOSInterface.addUniversalContainer(mainContainer, "View")
|
||||
|
||||
local colorSelector1 = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, config.transparencyBackground, "Transparency background"))
|
||||
local colorSelector2 = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, config.transparencyForeground, "Transparency foreground"))
|
||||
|
||||
container.panel.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
config.transparencyBackground, config.transparencyForeground = colorSelector1.color, colorSelector2.color
|
||||
|
||||
container:delete()
|
||||
mainContainer:drawOnScreen()
|
||||
saveConfig()
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
mainContainer.menu:addItem("Hotkeys").onTouch = function()
|
||||
local container = MineOSInterface.addUniversalContainer(mainContainer, "Hotkeys")
|
||||
local lines = {
|
||||
"There are some hotkeys that works exactly like in real Photoshop:",
|
||||
" ",
|
||||
"M - selection tool",
|
||||
"V - move tool",
|
||||
"B - brush tool",
|
||||
"E - eraser tool",
|
||||
"T - text tool",
|
||||
"G - fill tool",
|
||||
"F - braille tool",
|
||||
" ",
|
||||
"X - switch colors",
|
||||
"D - make colors B/W",
|
||||
}
|
||||
|
||||
container.layout:addChild(GUI.textBox(1, 1, 36, 1, nil, 0x787878, lines, 1, 0, 0, true, true)).eventHandler = nil
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
mainContainer.image:moveToBack()
|
||||
mainContainer.backgroundPanel:moveToBack()
|
||||
|
||||
updateRecentColorsButtons()
|
||||
pressToolButton(mainContainer.toolsLayout.children[3])
|
||||
|
||||
if options.o or options.open and args[1] and fs.exists(args[1]) then
|
||||
loadImage(args[1])
|
||||
else
|
||||
newNoGUI(51, 19)
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen(true)
|
||||
mainContainer:startEventHandling()
|
||||
110
Applications/PictureEdit/Tools/1.lua
Normal file
110
Applications/PictureEdit/Tools/1.lua
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
local GUI = require("GUI")
|
||||
local buffer = require("doubleBuffering")
|
||||
local image = require("image")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Se"
|
||||
tool.keyCode = 50
|
||||
tool.about = "Selection tool allows you select preferred zone on image and perform some operations on it. For example, to crop, to fill, to clear and to outline in via selected primary color"
|
||||
|
||||
local xOld, yOld, selector
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
xOld, yOld = eventData[3], eventData[4]
|
||||
selector = mainContainer:addChild(GUI.object(eventData[3], eventData[4], 1, 1))
|
||||
selector.eventHandler = tool.eventHandler
|
||||
selector.draw = function()
|
||||
local step = true
|
||||
for x = selector.x + 1, selector.x + selector.width - 2 do
|
||||
buffer.text(x, selector.y, step and 0xFFFFFF or 0x0, "━")
|
||||
buffer.text(x, selector.y + selector.height - 1, step and 0xFFFFFF or 0x0, "━")
|
||||
step = not step
|
||||
end
|
||||
|
||||
step = true
|
||||
for y = selector.y + 1, selector.y + selector.height - 2 do
|
||||
buffer.text(selector.x, y, step and 0xFFFFFF or 0x0, "┃")
|
||||
buffer.text(selector.x + selector.width - 1, y, step and 0xFFFFFF or 0x0, "┃")
|
||||
step = not step
|
||||
end
|
||||
|
||||
buffer.text(selector.x, selector.y, 0x0, "┏")
|
||||
buffer.text(selector.x + selector.width - 1, selector.y, 0x0, "┓")
|
||||
buffer.text(selector.x + selector.width - 1, selector.y + selector.height - 1, 0x0, "┛")
|
||||
buffer.text(selector.x, selector.y + selector.height - 1, 0x0, "┗")
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
elseif eventData[1] == "drag" and selector then
|
||||
local x, y, width, height
|
||||
if eventData[3] - xOld >= 0 then
|
||||
x, width = xOld, eventData[3] - xOld + 1
|
||||
else
|
||||
x, width = eventData[3], xOld - eventData[3] + 1
|
||||
end
|
||||
|
||||
if eventData[4] - yOld >= 0 then
|
||||
y, height = yOld, eventData[4] - yOld + 1
|
||||
else
|
||||
y, height = eventData[4], yOld - eventData[4] + 1
|
||||
end
|
||||
|
||||
selector.localX, selector.localY, selector.width, selector.height = x, y, width, height
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
elseif eventData[1] == "drop" and selector then
|
||||
local menu = GUI.contextMenu(eventData[3], eventData[4])
|
||||
|
||||
menu:addItem("Fill").onTouch = function()
|
||||
for j = selector.y, selector.y + selector.height - 1 do
|
||||
for i = selector.x, selector.x + selector.width - 1 do
|
||||
image.set(mainContainer.image.data, i - mainContainer.image.x + 1, j - mainContainer.image.y + 1, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
menu:addItem("Clear").onTouch = function()
|
||||
for j = selector.y, selector.y + selector.height - 1 do
|
||||
for i = selector.x, selector.x + selector.width - 1 do
|
||||
image.set(mainContainer.image.data, i - mainContainer.image.x + 1, j - mainContainer.image.y + 1, 0x0, 0x0, 1, " ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
menu:addItem("Outline").onTouch = function()
|
||||
local x1, y1 = selector.x - mainContainer.image.x + 1, selector.y - mainContainer.image.y + 1
|
||||
local x2, y2 = x1 + selector.width - 1, y1 + selector.height - 1
|
||||
|
||||
for x = x1, x2 do
|
||||
image.set(mainContainer.image.data, x, y1, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
image.set(mainContainer.image.data, x, y2, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
end
|
||||
|
||||
for y = y1 + 1, y2 - 1 do
|
||||
image.set(mainContainer.image.data, x1, y, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
image.set(mainContainer.image.data, x2, y, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
end
|
||||
end
|
||||
|
||||
menu:addSeparator()
|
||||
|
||||
menu:addItem("Crop").onTouch = function()
|
||||
mainContainer.image.data = image.crop(mainContainer.image.data, selector.x - mainContainer.image.x + 1, selector.y - mainContainer.image.y + 1, selector.width, selector.height)
|
||||
mainContainer.image.reposition()
|
||||
end
|
||||
|
||||
menu:show()
|
||||
|
||||
selector:delete()
|
||||
xOld, yOld, selector = nil, nil, nil
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
29
Applications/PictureEdit/Tools/2.lua
Normal file
29
Applications/PictureEdit/Tools/2.lua
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
local image = require("image")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Mv"
|
||||
tool.keyCode = 47
|
||||
tool.about = "Move tool allows you to move image as you wish. But be careful: large images will take a time to shift and redraw. Hello, shitty GPUs!"
|
||||
|
||||
local xOld, yOld
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
xOld, yOld = eventData[3], eventData[4]
|
||||
elseif eventData[1] == "drag" and xOld and yOld then
|
||||
mainContainer.image.localX = mainContainer.image.localX + (eventData[3] - xOld)
|
||||
mainContainer.image.localY = mainContainer.image.localY + (eventData[4] - yOld)
|
||||
xOld, yOld = eventData[3], eventData[4]
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
elseif eventData[1] == "drop" then
|
||||
xOld, yOld = nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
81
Applications/PictureEdit/Tools/3.lua
Normal file
81
Applications/PictureEdit/Tools/3.lua
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
local unicode = require("unicode")
|
||||
local image = require("image")
|
||||
local GUI = require("GUI")
|
||||
local keyboard = require("keyboard")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Bs"
|
||||
tool.keyCode = 48
|
||||
tool.about = "Classic brush tool to perform drawing with specified radius. Affecting on background and foreground can be configured. You can specify single symbol to draw with. Hold Alt key and click on image to pictk it's colors. You can specify what colors to pick."
|
||||
|
||||
local backgroundSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Draw background:", true)
|
||||
local foregroundSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Draw foreground:", true)
|
||||
local alphaSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Draw alpha:", true)
|
||||
local symbolSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Draw symbol:", true)
|
||||
local symbolInput = GUI.input(1, 1, width, 1, 0xEEEEEE, 0x555555, 0x999999, 0xFFFFFF, 0x2D2D2D, "", "Type symbol")
|
||||
symbolInput.onInputFinished = function()
|
||||
symbolInput.text = unicode.sub(symbolInput.text, 1, 1)
|
||||
end
|
||||
local alphaSlider = GUI.slider(1, 1, width, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, 0, 255, 0, false, "Alpha value: ", "")
|
||||
alphaSlider.roundValues = true
|
||||
local pickBackgroundSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Pick background:", true)
|
||||
local pickForegroundSwitch = GUI.switchAndLabel(1, 1, width, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Pick foreground:", true)
|
||||
|
||||
local radiusSlider = GUI.slider(1, 1, width, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, 1, 8, 1, false, "Radius: ", " px")
|
||||
radiusSlider.height = 2
|
||||
radiusSlider.roundValues = true
|
||||
|
||||
tool.onSelection = function(mainContainer)
|
||||
mainContainer.currentToolLayout:addChild(backgroundSwitch)
|
||||
mainContainer.currentToolLayout:addChild(foregroundSwitch)
|
||||
mainContainer.currentToolLayout:addChild(alphaSwitch)
|
||||
mainContainer.currentToolLayout:addChild(symbolSwitch)
|
||||
mainContainer.currentToolLayout:addChild(symbolInput)
|
||||
mainContainer.currentToolLayout:addChild(alphaSlider)
|
||||
mainContainer.currentToolLayout:addChild(radiusSlider)
|
||||
mainContainer.currentToolLayout:addChild(pickBackgroundSwitch)
|
||||
mainContainer.currentToolLayout:addChild(pickForegroundSwitch)
|
||||
end
|
||||
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" or eventData[1] == "drag" then
|
||||
local x, y = eventData[3] - mainContainer.image.x + 1, eventData[4] - mainContainer.image.y + 1
|
||||
|
||||
if keyboard.isKeyDown(56) then
|
||||
local background, foreground = image.get(mainContainer.image.data, x, y)
|
||||
|
||||
if pickBackgroundSwitch.switch.state then
|
||||
mainContainer.secondaryColorSelector.color = background
|
||||
end
|
||||
|
||||
if pickForegroundSwitch.switch.state then
|
||||
mainContainer.primaryColorSelector.color = foreground
|
||||
end
|
||||
else
|
||||
local meow = math.floor(radiusSlider.value)
|
||||
|
||||
for j = y - meow + 1, y + meow - 1 do
|
||||
for i = x - meow + 1, x + meow - 1 do
|
||||
if i >= 1 and i <= mainContainer.image.width and j >= 1 and j <= mainContainer.image.height then
|
||||
local background, foreground, alpha, symbol = image.get(mainContainer.image.data, i, j)
|
||||
image.set(mainContainer.image.data, i, j,
|
||||
backgroundSwitch.switch.state and mainContainer.primaryColorSelector.color or background,
|
||||
foregroundSwitch.switch.state and mainContainer.secondaryColorSelector.color or foreground,
|
||||
alphaSwitch.switch.state and alphaSlider.value / 255 or alpha,
|
||||
symbolSwitch.switch.state and (symbolInput.text == "" and " " or symbolInput.text) or symbol
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
39
Applications/PictureEdit/Tools/4.lua
Normal file
39
Applications/PictureEdit/Tools/4.lua
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
local GUI = require("GUI")
|
||||
local image = require("image")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Er"
|
||||
tool.keyCode = 18
|
||||
tool.about = "Eraser tool will erase all your pixels just like brush tool. But it's eraser!!1"
|
||||
|
||||
local radiusSlider = GUI.slider(1, 1, 1, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, 1, 8, 1, false, "Radius: ", " px")
|
||||
radiusSlider.height = 2
|
||||
radiusSlider.roundValues = true
|
||||
|
||||
tool.onSelection = function(mainContainer)
|
||||
mainContainer.currentToolLayout:addChild(radiusSlider)
|
||||
end
|
||||
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" or eventData[1] == "drag" then
|
||||
local x, y = eventData[3] - mainContainer.image.x + 1, eventData[4] - mainContainer.image.y + 1
|
||||
local meow = math.floor(radiusSlider.value)
|
||||
|
||||
for j = y - meow + 1, y + meow - 1 do
|
||||
for i = x - meow + 1, x + meow - 1 do
|
||||
if i >= 1 and i <= mainContainer.image.width and j >= 1 and j <= mainContainer.image.height then
|
||||
image.set(mainContainer.image.data, i, j, 0x0, 0x0, 1, " ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
53
Applications/PictureEdit/Tools/5.lua
Normal file
53
Applications/PictureEdit/Tools/5.lua
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
local unicode = require("unicode")
|
||||
local image = require("image")
|
||||
local GUI = require("GUI")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Tx"
|
||||
tool.keyCode = 20
|
||||
tool.about = "Text tool allows you to type some text data with selected primary color right on your image! It's time to say \"ur mom gay\" to everyone <3"
|
||||
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
local input = mainContainer:addChild(GUI.input(
|
||||
eventData[3] - 1,
|
||||
eventData[4],
|
||||
mainContainer.image.x + mainContainer.image.width - eventData[3] + 2,
|
||||
1,
|
||||
nil,
|
||||
mainContainer.primaryColorSelector.color,
|
||||
mainContainer.primaryColorSelector.color,
|
||||
nil,
|
||||
mainContainer.primaryColorSelector.color,
|
||||
""
|
||||
))
|
||||
|
||||
input.onInputFinished = function()
|
||||
if #input.text > 0 then
|
||||
local x, y = eventData[3] - mainContainer.image.x + 1, eventData[4] - mainContainer.image.y + 1
|
||||
for i = 1, unicode.len(input.text) do
|
||||
if x <= mainContainer.image.width then
|
||||
local background, foreground, alpha = image.get(mainContainer.image.data, x, y)
|
||||
image.set(mainContainer.image.data, x, y, background, mainContainer.primaryColorSelector.color, alpha, unicode.sub(input.text, i, i))
|
||||
x = x + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
input:delete()
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
|
||||
input:startInput()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
46
Applications/PictureEdit/Tools/6.lua
Normal file
46
Applications/PictureEdit/Tools/6.lua
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
local image = require("image")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Fl"
|
||||
tool.keyCode = 34
|
||||
tool.about = "Fill tool allows you to automatically fill areas with selected primary color just like in Paint. Oh God, where is my RAM...?"
|
||||
|
||||
|
||||
local function check(x, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS)
|
||||
if x >= 1 and x <= picture[1] and y >= 1 and y <= picture[2] then
|
||||
local currentB, currentF, currentA, currentS = image.get(picture, x, y)
|
||||
if
|
||||
currentB == sourceB
|
||||
and
|
||||
currentB ~= newB
|
||||
then
|
||||
image.set(picture, x, y, newB, newF, newA, newS)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function pizda(x, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS)
|
||||
if check(x, y - 1, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) then pizda(x, y - 1, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) end
|
||||
if check(x + 1, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) then pizda(x + 1, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) end
|
||||
if check(x, y + 1, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) then pizda(x, y + 1, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) end
|
||||
if check(x - 1, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) then pizda(x - 1, y, picture, sourceB, sourceF, sourceA, sourceS, newB, newF, newA, newS) end
|
||||
end
|
||||
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" then
|
||||
local x, y = eventData[3] - mainContainer.image.x + 1, eventData[4] - mainContainer.image.y + 1
|
||||
local sourceB, sourceF, sourceA, sourceS = image.get(mainContainer.image.data, x, y)
|
||||
pizda(x, y, mainContainer.image.data, sourceB, sourceF, sourceA, sourceS, mainContainer.primaryColorSelector.color, 0x0, 0, " ")
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
59
Applications/PictureEdit/Tools/7.lua
Normal file
59
Applications/PictureEdit/Tools/7.lua
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
local image = require("image")
|
||||
local GUI = require("GUI")
|
||||
local tool = {}
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
tool.shortcut = "Br"
|
||||
tool.keyCode = 33
|
||||
tool.about = "Braille font tool allows you to draw pixels with Braille symbols on your image. Select preferred semi-pixels on menu, configure transparency affecting and \"Let's go fellas!\""
|
||||
|
||||
local layout = GUI.layout(1, 1, 1, 8, 1, 1)
|
||||
local container, char, step = layout:addChild(GUI.container(1, 1, 8, 8)), " ", false
|
||||
for y = 1, 8, 2 do
|
||||
for x = 1, 8, 4 do
|
||||
local button = container:addChild(GUI.button(x, y, 4, 2, step and 0xFFFFFF or 0xD2D2D2, 0x0, step and 0x0 or 0x1E1E1E, 0x0, " "))
|
||||
button.switchMode = true
|
||||
button.onTouch = function()
|
||||
local data = {}
|
||||
for i = 1, #container.children do
|
||||
data[i] = container.children[i].pressed and 1 or 0
|
||||
end
|
||||
|
||||
char = string.brailleChar(table.unpack(data))
|
||||
end
|
||||
|
||||
step = not step
|
||||
end
|
||||
|
||||
step = not step
|
||||
end
|
||||
|
||||
local transparencySwitch = GUI.switchAndLabel(1, 1, 1, 6, 0x66DB80, 0x2D2D2D, 0xE1E1E1, 0x878787, "Transparency:", false)
|
||||
|
||||
tool.onSelection = function(mainContainer)
|
||||
mainContainer.currentToolLayout:addChild(layout)
|
||||
mainContainer.currentToolLayout:addChild(transparencySwitch)
|
||||
end
|
||||
|
||||
tool.eventHandler = function(mainContainer, object, eventData)
|
||||
if eventData[1] == "touch" or eventData[1] == "drag" then
|
||||
local x, y = eventData[3] - mainContainer.image.x + 1, eventData[4] - mainContainer.image.y + 1
|
||||
local background, foreground, alpha, symbol = image.get(mainContainer.image.data, x, y)
|
||||
|
||||
image.set(mainContainer.image.data, x, y,
|
||||
transparencySwitch.switch.state and background or mainContainer.secondaryColorSelector.color,
|
||||
mainContainer.primaryColorSelector.color,
|
||||
transparencySwitch.switch.state and 1 or 0,
|
||||
char
|
||||
)
|
||||
|
||||
mainContainer:drawOnScreen()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
return tool
|
||||
36
Files.cfg
36
Files.cfg
@ -284,21 +284,41 @@
|
||||
},
|
||||
--
|
||||
{
|
||||
path="/MineOS/Applications/Photoshop.app/Main.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Photoshop/Photoshop.lua",
|
||||
path="/MineOS/Applications/Picture Edit.app/Main.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Main.lua",
|
||||
fileID=381,
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Photoshop.app/Icon.pic",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Photoshop/Icon.pic",
|
||||
path="/MineOS/Applications/Picture Edit.app/Icon.pic",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Icon.pic",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Photoshop.app/Localizations/Russian.lang",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Photoshop/Localization/Russian.lang",
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/1.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/1.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Photoshop.app/Localizations/English.lang",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Photoshop/Localization/English.lang",
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/2.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/2.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/3.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/3.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/4.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/4.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/5.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/5.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/6.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/6.lua",
|
||||
},
|
||||
{
|
||||
path="/MineOS/Applications/Picture Edit.app/Tools/7.lua",
|
||||
url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/PictureEdit/Tools/7.lua",
|
||||
},
|
||||
--
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user