diff --git a/Applications/PictureEdit/Icon.pic b/Applications/PictureEdit/Icon.pic new file mode 100644 index 00000000..a4e9df47 Binary files /dev/null and b/Applications/PictureEdit/Icon.pic differ diff --git a/Applications/PictureEdit/Main.lua b/Applications/PictureEdit/Main.lua new file mode 100644 index 00000000..a2682a21 --- /dev/null +++ b/Applications/PictureEdit/Main.lua @@ -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() \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/1.lua b/Applications/PictureEdit/Tools/1.lua new file mode 100644 index 00000000..f52c8a17 --- /dev/null +++ b/Applications/PictureEdit/Tools/1.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/2.lua b/Applications/PictureEdit/Tools/2.lua new file mode 100644 index 00000000..421333b7 --- /dev/null +++ b/Applications/PictureEdit/Tools/2.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/3.lua b/Applications/PictureEdit/Tools/3.lua new file mode 100644 index 00000000..b2dd0bcc --- /dev/null +++ b/Applications/PictureEdit/Tools/3.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/4.lua b/Applications/PictureEdit/Tools/4.lua new file mode 100644 index 00000000..89b30252 --- /dev/null +++ b/Applications/PictureEdit/Tools/4.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/5.lua b/Applications/PictureEdit/Tools/5.lua new file mode 100644 index 00000000..01b169b6 --- /dev/null +++ b/Applications/PictureEdit/Tools/5.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/6.lua b/Applications/PictureEdit/Tools/6.lua new file mode 100644 index 00000000..db234704 --- /dev/null +++ b/Applications/PictureEdit/Tools/6.lua @@ -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 \ No newline at end of file diff --git a/Applications/PictureEdit/Tools/7.lua b/Applications/PictureEdit/Tools/7.lua new file mode 100644 index 00000000..08254804 --- /dev/null +++ b/Applications/PictureEdit/Tools/7.lua @@ -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 \ No newline at end of file diff --git a/Files.cfg b/Files.cfg index 6a4d0ed6..ca95b607 100644 --- a/Files.cfg +++ b/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", }, -- {