Новый пиздатый фотошоп

This commit is contained in:
Igor Timofeev 2018-04-12 13:48:44 +03:00
parent 25e7038381
commit e69d694558
10 changed files with 887 additions and 8 deletions

Binary file not shown.

View 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()

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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",
},
--
{