mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-03-04 10:38:12 +00:00
commit
c611b20db8
@ -1,5 +1,15 @@
|
||||
local setPos, write, setCol, blit = term.setCursorPos, term.write, term.setBackgroundColour, term.blit
|
||||
|
||||
local maxn = table.maxn or function( tTable )
|
||||
local maxn = 0
|
||||
for n in pairs( tTable ) do
|
||||
if type( n ) == "number" and n > max then
|
||||
maxn = n
|
||||
end
|
||||
end
|
||||
return maxn
|
||||
end
|
||||
|
||||
local tColourLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ string.sub( "0123456789abcdef",n,n ) ] = 2^(n-1)
|
||||
@ -33,15 +43,22 @@ function saveImage( tImage, sPath )
|
||||
end
|
||||
|
||||
local file = fs.open(sPath, "w" )
|
||||
if not file then return false end
|
||||
|
||||
for y=1,#tImage do
|
||||
local tOld, tNew = tImage[y], {}
|
||||
for x=1,#tOld do
|
||||
tNew[x] = tColourLookup[ tOld[x] ] or " "
|
||||
end
|
||||
file.writeLine( table.concat( tNew ) )
|
||||
for y=1,maxn( tImage ) do
|
||||
local tOld, tNew, last = tImage[y], {}, 0
|
||||
if tOld then for x=1,maxn( tOld ) do
|
||||
local thisCol = tColourLookup[ tOld[x] ]
|
||||
if thisCol then
|
||||
tNew[x], last = thisCol, x
|
||||
else
|
||||
tNew[x] = " "
|
||||
end
|
||||
end end
|
||||
file.writeLine( table.concat( tNew, "", 1, last ) )
|
||||
end
|
||||
file.close()
|
||||
return true
|
||||
end
|
||||
|
||||
function drawPixel( xPos, yPos, nColour )
|
||||
@ -93,9 +110,8 @@ function drawLine( startX, startY, endX, endY, nColour )
|
||||
local yDiff = maxY - minY
|
||||
|
||||
if minY == maxY then
|
||||
local sStr = string.rep( " ", xDiff + 1 )
|
||||
setPos( minX, minY )
|
||||
write( sStr )
|
||||
write( string.rep( " ", xDiff + 1 ) )
|
||||
return
|
||||
end
|
||||
|
||||
@ -193,9 +209,9 @@ function drawImage( tImage, xPos, yPos )
|
||||
if type( tImage ) ~= "table" or type( xPos ) ~= "number" or type( yPos ) ~= "number" then
|
||||
error( "Expected image, x, y", 2 )
|
||||
end
|
||||
for y=1,#tImage do
|
||||
for y=1,maxn( tImage ) do
|
||||
local tLine, sBG, counter = tImage[y], {}, 0
|
||||
for x=1,#tLine+1 do
|
||||
if tLine then for x=1,maxn( tLine )+1 do
|
||||
local px = tLine[x] or 0
|
||||
if px > 0 then
|
||||
counter = counter + 1
|
||||
@ -206,6 +222,6 @@ function drawImage( tImage, xPos, yPos )
|
||||
blit( sT, sT, table.concat( sBG ) )
|
||||
sBG, counter = {}, 0
|
||||
end
|
||||
end
|
||||
end end
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
-- Paint created by nitrogenfingers (edited by dan200)
|
||||
-- Paint created by nitrogenfingers (edited by dan200 & co)
|
||||
-- http://www.youtube.com/user/NitrogenFingers
|
||||
|
||||
------------
|
||||
@ -21,9 +21,15 @@ local mChoices = { "Save","Exit" }
|
||||
-- The message displayed in the footer bar
|
||||
local fMessage = "Press Ctrl to access menu"
|
||||
|
||||
-------------------------
|
||||
-- Initialisation --
|
||||
-------------------------
|
||||
-- Colour to character conversions
|
||||
local tColourLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ 2^(n-1) ] = string.sub( "0123456789abcdef",n,n )
|
||||
end
|
||||
|
||||
-----------------------
|
||||
-- Pre-Flight Checks --
|
||||
-----------------------
|
||||
|
||||
-- Determine if we can even run this
|
||||
if not term.isColour() then
|
||||
@ -32,14 +38,13 @@ if not term.isColour() then
|
||||
end
|
||||
|
||||
-- Determines if the file exists, and can be edited on this computer
|
||||
local tArgs = {...}
|
||||
if #tArgs == 0 then
|
||||
local sPath = ...
|
||||
if not sPath then
|
||||
print("Usage: paint <path>")
|
||||
return
|
||||
end
|
||||
local sPath = shell.resolve(tArgs[1])
|
||||
local bReadOnly = fs.isReadOnly(sPath)
|
||||
if fs.exists(sPath) and fs.isDir(sPath) then
|
||||
sPath = shell.resolve( sPath )
|
||||
if fs.isDir( sPath ) then
|
||||
print("Cannot edit a directory.")
|
||||
return
|
||||
end
|
||||
@ -52,117 +57,14 @@ if not fs.exists( sPath ) and not string.find( sPath, "%." ) then
|
||||
end
|
||||
end
|
||||
|
||||
local bReadOnly = fs.isReadOnly(sPath)
|
||||
|
||||
---------------
|
||||
-- Functions --
|
||||
---------------
|
||||
|
||||
local function getCanvasPixel( x, y )
|
||||
if canvas[y] then
|
||||
return canvas[y][x]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--[[
|
||||
Converts a colour value to a text character
|
||||
params: colour = the number to convert to a hex value
|
||||
returns: a string representing the chosen colour
|
||||
]]
|
||||
local function getCharOf( colour )
|
||||
-- Incorrect values always convert to nil
|
||||
if type(colour) == "number" then
|
||||
local value = math.floor( math.log(colour) / math.log(2) ) + 1
|
||||
if value >= 1 and value <= 16 then
|
||||
return string.sub( "0123456789abcdef", value, value )
|
||||
end
|
||||
end
|
||||
return " "
|
||||
end
|
||||
|
||||
--[[
|
||||
Converts a text character to colour value
|
||||
params: char = the char (from string.byte) to convert to number
|
||||
returns: the colour number of the hex value
|
||||
]]
|
||||
local tColourLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
|
||||
end
|
||||
local function getColourOf( char )
|
||||
-- Values not in the hex table are transparent (canvas coloured)
|
||||
return tColourLookup[char]
|
||||
end
|
||||
|
||||
--[[
|
||||
Loads the file into the canvas
|
||||
params: path = the path of the file to open
|
||||
returns: nil
|
||||
]]
|
||||
local function load(path)
|
||||
-- Load the file
|
||||
if fs.exists(path) then
|
||||
local file = fs.open(sPath, "r")
|
||||
local sLine = file.readLine()
|
||||
while sLine do
|
||||
local line = {}
|
||||
for x=1,w-2 do
|
||||
line[x] = getColourOf( string.byte(sLine,x,x) )
|
||||
end
|
||||
table.insert( canvas, line )
|
||||
sLine = file.readLine()
|
||||
end
|
||||
file.close()
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Saves the current canvas to file
|
||||
params: path = the path of the file to save
|
||||
returns: true if save was successful, false otherwise
|
||||
]]
|
||||
local function save(path)
|
||||
-- Open file
|
||||
local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))
|
||||
if not fs.exists(sDir) then
|
||||
fs.makeDir(sDir)
|
||||
end
|
||||
|
||||
local file = fs.open( path, "w" )
|
||||
if not file then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Encode (and trim)
|
||||
local tLines = {}
|
||||
local nLastLine = 0
|
||||
for y=1,h-1 do
|
||||
local sLine = ""
|
||||
local nLastChar = 0
|
||||
for x=1,w-2 do
|
||||
local c = getCharOf( getCanvasPixel( x, y ) )
|
||||
sLine = sLine .. c
|
||||
if c ~= " " then
|
||||
nLastChar = x
|
||||
end
|
||||
end
|
||||
sLine = string.sub( sLine, 1, nLastChar )
|
||||
tLines[y] = sLine
|
||||
if string.len( sLine ) > 0 then
|
||||
nLastLine = y
|
||||
end
|
||||
end
|
||||
|
||||
-- Save out
|
||||
for n=1,nLastLine do
|
||||
file.writeLine( tLines[ n ] )
|
||||
end
|
||||
file.close()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
Draws colour picker sidebar, the pallette and the footer
|
||||
Draws colour picker sidebar, the palette and the footer
|
||||
returns: nil
|
||||
]]
|
||||
local function drawInterface()
|
||||
@ -186,24 +88,22 @@ local function drawInterface()
|
||||
term.write("\127\127")
|
||||
|
||||
-- Left and Right Selected Colours
|
||||
for i=18,18 do
|
||||
term.setCursorPos(w-1, i)
|
||||
if leftColour ~= nil then
|
||||
term.setBackgroundColour( leftColour )
|
||||
term.write(" ")
|
||||
else
|
||||
term.setBackgroundColour( canvasColour )
|
||||
term.setTextColour( colours.grey )
|
||||
term.write("\127")
|
||||
end
|
||||
if rightColour ~= nil then
|
||||
term.setBackgroundColour( rightColour )
|
||||
term.write(" ")
|
||||
else
|
||||
term.setBackgroundColour( canvasColour )
|
||||
term.setTextColour( colours.grey )
|
||||
term.write("\127")
|
||||
end
|
||||
term.setCursorPos(w-1, 18)
|
||||
if leftColour ~= nil then
|
||||
term.setBackgroundColour( leftColour )
|
||||
term.write(" ")
|
||||
else
|
||||
term.setBackgroundColour( canvasColour )
|
||||
term.setTextColour( colours.grey )
|
||||
term.write("\127")
|
||||
end
|
||||
if rightColour ~= nil then
|
||||
term.setBackgroundColour( rightColour )
|
||||
term.write(" ")
|
||||
else
|
||||
term.setBackgroundColour( canvasColour )
|
||||
term.setTextColour( colours.grey )
|
||||
term.write("\127")
|
||||
end
|
||||
|
||||
-- Padding
|
||||
@ -214,41 +114,24 @@ local function drawInterface()
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Converts a single pixel of a single line of the canvas and draws it
|
||||
returns: nil
|
||||
]]
|
||||
local function drawCanvasPixel( x, y )
|
||||
local pixel = getCanvasPixel( x, y )
|
||||
if pixel then
|
||||
term.setBackgroundColour( pixel or canvasColour )
|
||||
term.setCursorPos(x, y)
|
||||
term.write(" ")
|
||||
else
|
||||
term.setBackgroundColour( canvasColour )
|
||||
term.setTextColour( colours.grey )
|
||||
term.setCursorPos(x, y)
|
||||
term.write("\127")
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Converts each colour in a single line of the canvas and draws it
|
||||
returns: nil
|
||||
]]
|
||||
local function drawCanvasLine( y )
|
||||
for x = 1, w-2 do
|
||||
drawCanvasPixel( x, y )
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Converts each colour in the canvas and draws it
|
||||
returns: nil
|
||||
]]
|
||||
local function drawCanvas()
|
||||
local TC = string.rep( "7", w-2 )
|
||||
for y = 1, h-1 do
|
||||
drawCanvasLine( y )
|
||||
local T, BC = {}, {}
|
||||
for x = 1, w-2 do
|
||||
local pixel = canvas[y] and canvas[y][x]
|
||||
if pixel and pixel ~= 0 then
|
||||
T[x], BC[x] = " ", tColourLookup[pixel]
|
||||
else
|
||||
T[x], BC[x] = "\127", tColourLookup[canvasColour]
|
||||
end
|
||||
end
|
||||
term.setCursorPos( 1, y )
|
||||
term.blit( table.concat( T ), TC, table.concat( BC ) )
|
||||
end
|
||||
end
|
||||
|
||||
@ -259,22 +142,15 @@ end
|
||||
local function accessMenu()
|
||||
-- Selected menu option
|
||||
local selection = 1
|
||||
|
||||
term.setTextColour(colours.white)
|
||||
term.setBackgroundColour(colours.black)
|
||||
while true do
|
||||
-- Draw the menu
|
||||
term.setCursorPos(1,h)
|
||||
term.clearLine()
|
||||
term.setTextColour(colours.white)
|
||||
for k,v in pairs(mChoices) do
|
||||
if selection==k then
|
||||
term.setTextColour(colours.yellow)
|
||||
local ox,_ = term.getCursorPos()
|
||||
term.write("["..string.rep(" ",#v).."]")
|
||||
term.setCursorPos(ox+1,h)
|
||||
term.setTextColour(colours.white)
|
||||
term.write(v)
|
||||
term.setCursorPos(term.getCursorPos()+1,h)
|
||||
term.blit( "["..v.."]", "4"..string.rep(" ",#v).."4", string.rep("f",#v+2) )
|
||||
else
|
||||
term.write(" "..v.." ")
|
||||
end
|
||||
@ -282,51 +158,39 @@ local function accessMenu()
|
||||
|
||||
-- Handle input in the menu
|
||||
local id,key = os.pullEvent("key")
|
||||
if id == "key" then
|
||||
-- S and E are shortcuts
|
||||
if key == keys.s then
|
||||
selection = 1
|
||||
key = keys.enter
|
||||
elseif key == keys.e then
|
||||
selection = 2
|
||||
key = keys.enter
|
||||
end
|
||||
|
||||
if key == keys.right then
|
||||
-- Move right
|
||||
selection = selection + 1
|
||||
if selection > #mChoices then
|
||||
selection = 1
|
||||
end
|
||||
|
||||
elseif key == keys.left and selection > 1 then
|
||||
-- Move left
|
||||
selection = selection - 1
|
||||
if selection < 1 then
|
||||
selection = #mChoices
|
||||
end
|
||||
|
||||
elseif key == keys.enter then
|
||||
-- Select an option
|
||||
if mChoices[selection]=="Save" then
|
||||
if bReadOnly then
|
||||
fMessage = "Access Denied"
|
||||
return false
|
||||
end
|
||||
local success = save(sPath)
|
||||
if success then
|
||||
fMessage = "Saved to "..sPath
|
||||
else
|
||||
fMessage = "Error saving to "..sPath
|
||||
end
|
||||
-- S and E are shortcuts
|
||||
if key == keys.s then
|
||||
selection = 1
|
||||
key = keys.enter
|
||||
elseif key == keys.e then
|
||||
selection = 2
|
||||
key = keys.enter
|
||||
end
|
||||
|
||||
if key == keys.right then
|
||||
-- Move right
|
||||
selection = selection == #mChoices and 1 or (selection + 1)
|
||||
|
||||
elseif key == keys.left then
|
||||
-- Move left
|
||||
selection = selection == 1 and #mChoices or (selection - 1)
|
||||
|
||||
elseif key == keys.enter then
|
||||
-- Select an option
|
||||
if mChoices[selection]=="Save" then
|
||||
if bReadOnly then
|
||||
fMessage = "Access Denied"
|
||||
return false
|
||||
elseif mChoices[selection]=="Exit" then
|
||||
return true
|
||||
end
|
||||
elseif key == keys.leftCtrl or keys == keys.rightCtrl then
|
||||
-- Cancel the menu
|
||||
return false
|
||||
fMessage = (paintutils.saveImage( canvas, sPath ) and "Saved to " or "Error saving to ")..sPath
|
||||
return false
|
||||
elseif mChoices[selection]=="Exit" then
|
||||
return true
|
||||
end
|
||||
elseif key == keys.leftCtrl or keys == keys.rightCtrl then
|
||||
-- Cancel the menu
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -337,11 +201,10 @@ end
|
||||
returns: nil
|
||||
]]
|
||||
local function handleEvents()
|
||||
local programActive = true
|
||||
while programActive do
|
||||
while true do
|
||||
local id,p1,p2,p3 = os.pullEvent()
|
||||
if id=="mouse_click" or id=="mouse_drag" then
|
||||
if p2 >= w-1 and p3 >= 1 and p3 <= 17 then
|
||||
if id=="mouse_click" or id=="mouse_drag" and p1 < 3 and p2 > 0 and p2 <= w and p3 > 0 and p3 < h then
|
||||
if p2 >= w-1 and p3 <= 17 then
|
||||
if id ~= "mouse_drag" then
|
||||
-- Selecting an items in the colour picker
|
||||
if p3 <= 16 then
|
||||
@ -357,15 +220,14 @@ local function handleEvents()
|
||||
rightColour = nil
|
||||
end
|
||||
end
|
||||
--drawCanvas()
|
||||
drawInterface()
|
||||
end
|
||||
elseif p2 < w-1 and p3 <= h-1 then
|
||||
elseif p2 < w-1 then
|
||||
-- Clicking on the canvas
|
||||
local paintColour = nil
|
||||
local paintColour
|
||||
if p1==1 then
|
||||
paintColour = leftColour
|
||||
elseif p1==2 then
|
||||
else
|
||||
paintColour = rightColour
|
||||
end
|
||||
if not canvas[p3] then
|
||||
@ -373,11 +235,16 @@ local function handleEvents()
|
||||
end
|
||||
canvas[p3][p2] = paintColour
|
||||
|
||||
drawCanvasPixel( p2, p3 )
|
||||
term.setCursorPos( p2, p3 )
|
||||
if paintColour then
|
||||
term.blit( " ", " ", tColourLookup[paintColour] )
|
||||
else
|
||||
term.blit( "\127", "7", tColourLookup[canvasColour] )
|
||||
end
|
||||
end
|
||||
elseif id=="key" then
|
||||
if p1==keys.leftCtrl or p1==keys.rightCtrl then
|
||||
programActive = not accessMenu()
|
||||
if accessMenu() then return end
|
||||
drawInterface()
|
||||
end
|
||||
elseif id=="term_resize" then
|
||||
@ -388,15 +255,24 @@ local function handleEvents()
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
load(sPath)
|
||||
--------------------
|
||||
-- Initialisation --
|
||||
--------------------
|
||||
|
||||
if fs.exists( sPath ) then canvas = paintutils.loadImage( sPath ) end
|
||||
drawCanvas()
|
||||
drawInterface()
|
||||
|
||||
-- Main loop
|
||||
---------------
|
||||
-- Main Loop --
|
||||
---------------
|
||||
|
||||
handleEvents()
|
||||
|
||||
-- Shutdown
|
||||
--------------
|
||||
-- Shutdown --
|
||||
--------------
|
||||
|
||||
term.setBackgroundColour(colours.black)
|
||||
term.setTextColour(colours.white)
|
||||
term.clear()
|
||||
|
Loading…
x
Reference in New Issue
Block a user