MineOS/lib/palette.lua

288 lines
12 KiB
Lua
Executable File

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