local advancedLua = require("advancedLua") local component = require("component") local fs = require("filesystem") local color = require("color") local image = require("image") local buffer = require("doubleBuffering") local GUI = require("GUI") local MineOSPaths = require("MineOSPaths") -------------------------------------------------------------------------------------------------------------- local palette = {} local pathToFavouritesConfig, favourites = MineOSPaths.applicationData .. "Palette/Favourites.cfg" -------------------------------------------------------------------------------------------------------------- local function saveFavourites() table.toFile(pathToFavouritesConfig, favourites) end -------------------------------------------------------------------------------------------------------------- local function changeInputsValueToCurrentColor(window) window.inputs[1].inputField.text = tostring(window.color.rgb.red) window.inputs[2].inputField.text = tostring(window.color.rgb.green) window.inputs[3].inputField.text = tostring(window.color.rgb.blue) window.inputs[4].inputField.text = tostring(math.floor(window.color.hsb.hue)) window.inputs[5].inputField.text = tostring(math.floor(window.color.hsb.saturation)) window.inputs[6].inputField.text = tostring(math.floor(window.color.hsb.brightness)) window.inputs[7].inputField.text = string.format("%06X", window.color.hex) window.colorPanel.colors.background = window.color.hex end local function switchColorFromHex(window, hex) window.color.hex = hex window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = color.HEXToRGB(hex) window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = color.RGBToHSB(window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue) changeInputsValueToCurrentColor(window) end local function switchColorFromHsb(window, hue, saturation, brightness) window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = hue, saturation, brightness window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = color.HSBToRGB(hue, saturation, brightness) window.color.hex = color.RGBToHEX(window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue) changeInputsValueToCurrentColor(window) end local function switchColorFromRgb(window, red, green, blue) window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = red, green, blue window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = color.RGBToHSB(red, green, blue) window.color.hex = color.RGBToHEX(red, green, blue) changeInputsValueToCurrentColor(window) end -------------------------------------------------------------------------------------------------------------- local function refreshBigRainbow(window) local saturationStep, brightnessStep, saturation, brightness = 100 / image.getWidth(window.bigRainbow.image), 100 / (image.getHeight(window.bigRainbow.image)), 0, 100 for j = 1, image.getHeight(window.bigRainbow.image) do for i = 1, image.getWidth(window.bigRainbow.image) do image.set(window.bigRainbow.image, i, j, color.optimize(color.HSBToHEX(window.color.hsb.hue, saturation, brightness)), 0x0, 0x0, " ") saturation = saturation + saturationStep end saturation, brightness = 0, brightness - brightnessStep end end local function refreshMiniRainbow(window) local hueStep, hue = 360 / (image.getHeight(window.miniRainbow.image)), 0 for j = 1, image.getHeight(window.miniRainbow.image) do for i = 1, image.getWidth(window.miniRainbow.image) do image.set(window.miniRainbow.image, i, j, color.optimize(color.HSBToHEX(hue, 100, 100)), 0x0, 0x0, " ") end hue = hue + hueStep end end -------------------------------------------------------------------------------------------------------------- local function createCrestsCoordinates(window) window.bigCrest.localPosition.x = math.floor((window.bigRainbow.width - 1) * window.color.hsb.saturation / 100) - 1 window.bigCrest.localPosition.y = math.floor((window.bigRainbow.height - 1) - (window.bigRainbow.height - 1) * window.color.hsb.brightness / 100) window.miniCrest.localPosition.y = math.floor(window.color.hsb.hue / 360 * window.miniRainbow.height) end local function drawBigCrestPixel(window, x, y, symbol) if window.bigRainbow:isClicked(x, y) then local background, foreground = buffer.get(x, y) if background >= 0x888888 then foreground = 0x000000 else foreground = 0xFFFFFF end buffer.set(x, y, background, foreground, symbol) end end -------------------------------------------------------------------------------------------------------------- function palette.window(x, y, startColor) local window = GUI.window(x, y, 71, 25) window.color = {hsb = {}, rgb = {}} window:addChild(GUI.panel(1, 1, window.width, window.height, 0xEEEEEE)) window.bigRainbow = window:addChild(GUI.image(1, 1, image.create(50, 25))) window.bigCrest = window:addChild(GUI.object(1, 1, 5, 3)) window.bigCrest.draw = function(object) drawBigCrestPixel(window, object.x, object.y + 1, "─") drawBigCrestPixel(window, object.x + 1, object.y + 1, "─") drawBigCrestPixel(window, object.x + 3, object.y + 1, "─") drawBigCrestPixel(window, object.x + 4, object.y + 1, "─") drawBigCrestPixel(window, object.x + 2, object.y, "│") drawBigCrestPixel(window, object.x + 2, object.y + 2, "│") end window.bigRainbow.eventHandler = function(mainContainer, object, eventData) if eventData[1] == "touch" or eventData[1] == "drag" and window.bigRainbow:isClicked(eventData[3], eventData[4]) then window.bigCrest.localPosition.x, window.bigCrest.localPosition.y = eventData[3] - window.x - 1, eventData[4] - window.y switchColorFromHex(window, select(3, component.gpu.get(eventData[3], eventData[4]))) mainContainer:draw() buffer.draw() end end window.bigCrest.eventHandler = window.bigRainbow.eventHandler window.miniRainbow = window:addChild(GUI.image(53, 1, image.create(3, 25))) window.miniCrest = window:addChild(GUI.object(52, 1, 5, 1)) window.miniCrest.draw = function(object) buffer.text(object.x, object.y, 0x0, ">") buffer.text(object.x + 4, object.y, 0x0, "<") end window.miniRainbow.eventHandler = function(mainContainer, object, eventData) if eventData[1] == "touch" or eventData[1] == "drag" then window.miniCrest.localPosition.y = eventData[4] - window.y + 1 switchColorFromHsb(window, (eventData[4] - window.miniRainbow.y) * 360 / window.miniRainbow.height, window.color.hsb.saturation, window.color.hsb.brightness) refreshBigRainbow(window) mainContainer:draw() buffer.draw() end end window.colorPanel = window:addChild(GUI.panel(58, 2, 12, 3, 0x0)) window.OKButton = window:addChild(GUI.button(58, 6, 12, 1, 0x444444, 0xFFFFFF, 0x88FF88, 0xFFFFFF, "OK")) window.cancelButton = window:addChild(GUI.button(58, 8, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "Cancel")) local function onAnyInputFinished() refreshBigRainbow(window) createCrestsCoordinates(window) window:getFirstParent():draw() buffer.draw() end local function onHexInputFinished() switchColorFromHex(window, tonumber("0x" .. window.inputs[7].inputField.text)) onAnyInputFinished() end local function onRgbInputFinished() switchColorFromRgb(window, tonumber(window.inputs[1].inputField.text), tonumber(window.inputs[2].inputField.text), tonumber(window.inputs[3].inputField.text)) onAnyInputFinished() end local function onHsbInputFinished() switchColorFromHsb(window, tonumber(window.inputs[4].inputField.text), tonumber(window.inputs[5].inputField.text), tonumber(window.inputs[6].inputField.text)) onAnyInputFinished() end local function rgbValidaror(text) local num = tonumber(text) if num and num >= 0 and num <= 255 then return true end end local function hValidator(text) local num = tonumber(text) if num and num >= 0 and num <= 359 then return true end end local function sbValidator(text) local num = tonumber(text) if num and num >= 0 and num <= 100 then return true end end local function hexValidator(text) if string.match(text, "^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$") then return true end end window.inputs = { { shortcut = "R:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, { shortcut = "G:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, { shortcut = "B:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, { shortcut = "H:", validator = hValidator, onInputFinished = onHsbInputFinished }, { shortcut = "S:", validator = sbValidator, onInputFinished = onHsbInputFinished }, { shortcut = "L:", validator = sbValidator, onInputFinished = onHsbInputFinished }, { shortcut = "0x", validator = hexValidator, onInputFinished = onHexInputFinished } } local y = 10 for i = 1, #window.inputs do window:addChild(GUI.label(58, y, 2, 1, 0x000000, window.inputs[i].shortcut)) window.inputs[i].inputField = window:addChild(GUI.inputField(61, y, 9, 1, 0xFFFFFF, 0x444444, 0x444444, 0xFFFFFF, 0x000000, "", "", true)) window.inputs[i].inputField.validator = window.inputs[i].validator window.inputs[i].inputField.onInputFinished = window.inputs[i].onInputFinished y = y + 2 end if fs.exists(pathToFavouritesConfig) then favourites = table.fromFile(pathToFavouritesConfig) else favourites = {} for i = 1, 6 do favourites[i] = math.random(0x000000, 0xFFFFFF) end saveFavourites() end palette.favouritesContainer = window:addChild(GUI.container(58, 24, 12, 1)) for i = 1, #favourites do local button = palette.favouritesContainer:addChild(GUI.button(i * 2 - 1, 1, 2, 1, favourites[i], 0x0, 0x0, 0x0, " ")) button.onTouch = function(mainContainer, object, eventData) switchColorFromHex(window, button.colors.default.background) refreshBigRainbow(window) createCrestsCoordinates(window) mainContainer:draw() buffer.draw() end end window:addChild(GUI.button(58, 25, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "+")).onTouch = function(mainContainer, object, eventData) local favouriteExists = false for i = 1, #favourites do if favourites[i] == window.color.hex then favouriteExists = true break end end if not favouriteExists then table.insert(favourites, 1, window.color.hex) table.remove(favourites, #favourites) for i = 1, #favourites do palette.favouritesContainer.children[i].colors.default.background = favourites[i] palette.favouritesContainer.children[i].colors.pressed.background = 0x0 end saveFavourites() mainContainer:draw() buffer.draw() end end switchColorFromHex(window, startColor) createCrestsCoordinates(window) refreshBigRainbow(window) refreshMiniRainbow(window) return window end function palette.show(x, y, startColor) local mainContainer = GUI.container(1, 1, buffer.width, buffer.height) local selectedColor local window = mainContainer:addChild(palette.window(x, y, startColor)) window.eventHandler = nil window.OKButton.onTouch = function(mainContainer, object, eventData) mainContainer:stopEventHandling() selectedColor = window.color.hex end window.cancelButton.onTouch = function(mainContainer, object, eventData) mainContainer:stopEventHandling() end mainContainer:draw() buffer.draw() mainContainer:startEventHandling() return selectedColor end -------------------------------------------------------------------------------------------------------------- -- buffer.start() -- buffer.draw(true) -- GUI.error(tostring(palette.show(5, 5, 0xFF00FF))) -------------------------------------------------------------------------------------------------------------- return palette