mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-04-15 07:13:13 +00:00
Reverting requested changes. Take 1
Reverting rewrites to painutils, paint and edit - keept the paste logic change in edit. Changed and removed misc parts as requested in PR.
This commit is contained in:
parent
6255314ba8
commit
bf533dd00a
@ -900,7 +900,6 @@ settings.set( "shell.allow_disk_startup", (commands == nil) )
|
||||
settings.set( "shell.autocomplete", true )
|
||||
settings.set( "edit.autocomplete", true )
|
||||
settings.set( "edit.default_extension", "lua" )
|
||||
settings.set( "edit.advanced_functionality", false )
|
||||
settings.set( "paint.default_extension", "nfp" )
|
||||
settings.set( "lua.autocomplete", true )
|
||||
settings.set( "list.show_hidden", false )
|
||||
|
@ -1,20 +1,12 @@
|
||||
local setPos, write, setCol, blit, rep, concat = term.setCursorPos, term.write, term.setBackgroundColour, term.blit, string.rep, table.concat
|
||||
|
||||
local maxn = table.maxn or function( tTable )
|
||||
local maxn = 0
|
||||
for n in pairs( tTable ) do
|
||||
if type( n ) == "number" and n > maxn then
|
||||
maxn = n
|
||||
end
|
||||
end
|
||||
return maxn
|
||||
local function drawPixelInternal( xPos, yPos )
|
||||
term.setCursorPos( xPos, yPos )
|
||||
term.write(" ")
|
||||
end
|
||||
|
||||
local tColourLookup = {}
|
||||
local tColourReverseLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
|
||||
tColourReverseLookup[ 2^(n-1) ] = string.sub( "0123456789abcdef",n,n )
|
||||
end
|
||||
|
||||
function loadImage( sPath )
|
||||
@ -24,64 +16,30 @@ function loadImage( sPath )
|
||||
|
||||
local tImage = {}
|
||||
if fs.exists( sPath ) then
|
||||
for sLine in io.lines(sPath) do
|
||||
local file = io.open(sPath, "r" )
|
||||
local sLine = file:read()
|
||||
while sLine do
|
||||
local tLine = {}
|
||||
for x=1,#sLine do
|
||||
tLine[x] = tColourLookup[ string.byte( sLine,x ) ] or 0
|
||||
for x=1,sLine:len() do
|
||||
tLine[x] = tColourLookup[ string.byte(sLine,x,x) ] or 0
|
||||
end
|
||||
table.insert( tImage, tLine )
|
||||
sLine = file:read()
|
||||
end
|
||||
file:close()
|
||||
return tImage
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function saveImage( tImage, sPath )
|
||||
if type( tImage ) ~= "table" then error( "bad argument #1 (expected table, got " .. type( tImage ) .. ")", 2 ) end
|
||||
if type( sPath ) ~= "string" then error( "bad argument #2 (expected string, got " .. type( sPath ) .. ")", 2 ) end
|
||||
|
||||
local file, lines, lastRow = fs.open(sPath, "w" ), {}, 0
|
||||
if not file then return false end
|
||||
|
||||
for y=1,maxn( tImage ) do
|
||||
local tIn, tOut, lastCol = tImage[y], {}, 0
|
||||
|
||||
if tIn then
|
||||
for x=1,maxn( tIn ) do
|
||||
local pixel = tColourReverseLookup[ tIn[x] ]
|
||||
if pixel then
|
||||
tOut[x], lastCol = pixel, x
|
||||
else
|
||||
tOut[x] = " "
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if lastCol > 0 then
|
||||
lines[y], lastRow = concat( tOut, "", 1, lastCol ), y
|
||||
else
|
||||
lines[y] = ""
|
||||
end
|
||||
end
|
||||
|
||||
for y=1,lastRow do
|
||||
file.writeLine(lines[y])
|
||||
end
|
||||
|
||||
file.close()
|
||||
return true
|
||||
end
|
||||
|
||||
function drawPixel( xPos, yPos, nColour )
|
||||
if type( xPos ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( xPos ) .. ")", 2 ) end
|
||||
if type( yPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( yPos ) .. ")", 2 ) end
|
||||
if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nColour ) .. ")", 2 ) end
|
||||
|
||||
if nColour then
|
||||
setCol( nColour )
|
||||
term.setBackgroundColor( nColour )
|
||||
end
|
||||
setPos( xPos, yPos )
|
||||
write( " " )
|
||||
drawPixelInternal( xPos, yPos )
|
||||
end
|
||||
|
||||
function drawLine( startX, startY, endX, endY, nColour )
|
||||
@ -97,15 +55,14 @@ function drawLine( startX, startY, endX, endY, nColour )
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
setCol( nColour )
|
||||
term.setBackgroundColor( nColour )
|
||||
end
|
||||
if startX == endX and startY == endY then
|
||||
setPos( startX, startY )
|
||||
write(" ")
|
||||
drawPixelInternal( startX, startY )
|
||||
return
|
||||
end
|
||||
|
||||
local minX, minY, maxX, maxY = math.min( startX, endX )
|
||||
local minX = math.min( startX, endX )
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
@ -120,28 +77,27 @@ function drawLine( startX, startY, endX, endY, nColour )
|
||||
|
||||
local xDiff = maxX - minX
|
||||
local yDiff = maxY - minY
|
||||
|
||||
if minY == maxY then
|
||||
setPos( minX, minY )
|
||||
write( rep( " ", xDiff + 1 ) )
|
||||
return
|
||||
end
|
||||
|
||||
if xDiff > math.abs(yDiff) then
|
||||
local y = minY
|
||||
local dy = yDiff / xDiff
|
||||
for x=minX,maxX do
|
||||
setPos( x, math.floor( y + 0.5 ) )
|
||||
write( " " )
|
||||
drawPixelInternal( x, math.floor( y + 0.5 ) )
|
||||
y = y + dy
|
||||
end
|
||||
else
|
||||
local x, mul = minX, maxY >= minY and 1 or -1
|
||||
local dx = xDiff / yDiff * mul
|
||||
for y=minY,maxY,mul do
|
||||
setPos( math.floor( x + 0.5 ), y )
|
||||
write( " " )
|
||||
x = x + dx
|
||||
local x = minX
|
||||
local dx = xDiff / yDiff
|
||||
if maxY >= minY then
|
||||
for y=minY,maxY do
|
||||
drawPixelInternal( math.floor( x + 0.5 ), y )
|
||||
x = x + dx
|
||||
end
|
||||
else
|
||||
for y=minY,maxY,-1 do
|
||||
drawPixelInternal( math.floor( x + 0.5 ), y )
|
||||
x = x - dx
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -159,29 +115,34 @@ function drawBox( startX, startY, endX, endY, nColour )
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
setCol( nColour )
|
||||
term.setBackgroundColor( nColour )
|
||||
end
|
||||
if startX == endX and startY == endY then
|
||||
setPos( startX, startY )
|
||||
write( " " )
|
||||
drawPixelInternal( startX, startY )
|
||||
return
|
||||
end
|
||||
|
||||
local minX, minY, maxX, maxY
|
||||
if startX < endX then minX, maxX = startX, endX else minX, maxX = endX, startX end
|
||||
if startY < endY then minY, maxY = startY, endY else minY, maxY = endY, startY end
|
||||
|
||||
local sStr = rep( " ", maxX - minX + 1 )
|
||||
setPos( minX, minY )
|
||||
write( sStr )
|
||||
setPos( minX, maxY )
|
||||
write( sStr )
|
||||
|
||||
for y=(minY+1),(maxY-1) do
|
||||
setPos( minX, y )
|
||||
write( " " )
|
||||
setPos( maxX, y )
|
||||
write( " " )
|
||||
local minX = math.min( startX, endX )
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
maxY = endY
|
||||
else
|
||||
minY = endY
|
||||
maxX = startX
|
||||
maxY = startY
|
||||
end
|
||||
|
||||
for x=minX,maxX do
|
||||
drawPixelInternal( x, minY )
|
||||
drawPixelInternal( x, maxY )
|
||||
end
|
||||
|
||||
if (maxY - minY) >= 2 then
|
||||
for y=(minY+1),(maxY-1) do
|
||||
drawPixelInternal( minX, y )
|
||||
drawPixelInternal( maxX, y )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -198,22 +159,28 @@ function drawFilledBox( startX, startY, endX, endY, nColour )
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
setCol( nColour )
|
||||
term.setBackgroundColor( nColour )
|
||||
end
|
||||
if startX == endX and startY == endY then
|
||||
setPos( startX, startY )
|
||||
write( " " )
|
||||
drawPixelInternal( startX, startY )
|
||||
return
|
||||
end
|
||||
|
||||
local minX, minY, maxX, maxY
|
||||
if startX < endX then minX, maxX = startX, endX else minX, maxX = endX, startX end
|
||||
if startY < endY then minY, maxY = startY, endY else minY, maxY = endY, startY end
|
||||
local minX = math.min( startX, endX )
|
||||
if minX == startX then
|
||||
minY = startY
|
||||
maxX = endX
|
||||
maxY = endY
|
||||
else
|
||||
minY = endY
|
||||
maxX = startX
|
||||
maxY = startY
|
||||
end
|
||||
|
||||
local sStr = rep( " ", maxX - minX + 1 )
|
||||
for y=minY,maxY do
|
||||
setPos( minX, y )
|
||||
write( sStr )
|
||||
for x=minX,maxX do
|
||||
for y=minY,maxY do
|
||||
drawPixelInternal( x, y )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -222,18 +189,12 @@ function drawImage( tImage, xPos, yPos )
|
||||
if type( xPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( xPos ) .. ")", 2 ) end
|
||||
if type( yPos ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( yPos ) .. ")", 2 ) end
|
||||
for y=1,#tImage do
|
||||
local tLine, sBG, counter = tImage[y], {}, 0
|
||||
if tLine then for x=1,#tLine+1 do
|
||||
local px = tLine[x] or 0
|
||||
if px > 0 then
|
||||
counter = counter + 1
|
||||
sBG[counter] = tColourReverseLookup[ px ]
|
||||
elseif counter > 0 then
|
||||
setPos( x + xPos - 1 - counter, y + yPos - 1 )
|
||||
local sT = rep( " ", counter )
|
||||
blit( sT, sT, concat( sBG ) )
|
||||
sBG, counter = {}, 0
|
||||
local tLine = tImage[y]
|
||||
for x=1,#tLine do
|
||||
if tLine[x] > 0 then
|
||||
term.setBackgroundColor( tLine[x] )
|
||||
drawPixelInternal( x + xPos - 1, y + yPos - 1 )
|
||||
end
|
||||
end end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -7,14 +7,14 @@ local tReceivedMessageTimeouts = {}
|
||||
local tHostnames = {}
|
||||
|
||||
function open( sModem )
|
||||
if type( sModem ) ~= "string" then
|
||||
error( "expected string", 2 )
|
||||
end
|
||||
if peripheral.getType( sModem ) ~= "modem" then
|
||||
error( "No such modem: "..sModem, 2 )
|
||||
end
|
||||
peripheral.call( sModem, "open", os.getComputerID() )
|
||||
peripheral.call( sModem, "open", CHANNEL_BROADCAST )
|
||||
if type( sModem ) ~= "string" then
|
||||
error( "expected string", 2 )
|
||||
end
|
||||
if peripheral.getType( sModem ) ~= "modem" then
|
||||
error( "No such modem: "..sModem, 2 )
|
||||
end
|
||||
peripheral.call( sModem, "open", os.getComputerID() )
|
||||
peripheral.call( sModem, "open", CHANNEL_BROADCAST )
|
||||
end
|
||||
|
||||
function close( sModem )
|
||||
@ -55,7 +55,7 @@ function isOpen( sModem )
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
return false
|
||||
end
|
||||
|
||||
function send( nRecipient, message, sProtocol )
|
||||
@ -93,7 +93,7 @@ function send( nRecipient, message, sProtocol )
|
||||
end
|
||||
|
||||
function broadcast( message, sProtocol )
|
||||
send( CHANNEL_BROADCAST, message, sProtocol )
|
||||
send( CHANNEL_BROADCAST, message, sProtocol )
|
||||
end
|
||||
|
||||
function receive( sProtocolFilter, nTimeout )
|
||||
@ -103,31 +103,31 @@ function receive( sProtocolFilter, nTimeout )
|
||||
end
|
||||
|
||||
-- Start the timer
|
||||
local timer = nil
|
||||
local sFilter = nil
|
||||
if nTimeout then
|
||||
timer = os.startTimer( nTimeout )
|
||||
sFilter = nil
|
||||
else
|
||||
sFilter = "rednet_message"
|
||||
end
|
||||
local timer = nil
|
||||
local sFilter = nil
|
||||
if nTimeout then
|
||||
timer = os.startTimer( nTimeout )
|
||||
sFilter = nil
|
||||
else
|
||||
sFilter = "rednet_message"
|
||||
end
|
||||
|
||||
-- Wait for events
|
||||
while true do
|
||||
local sEvent, p1, p2, p3 = os.pullEvent( sFilter )
|
||||
if sEvent == "rednet_message" then
|
||||
-- Return the first matching rednet_message
|
||||
local nSenderID, message, sProtocol = p1, p2, p3
|
||||
if sProtocolFilter == nil or sProtocol == sProtocolFilter then
|
||||
return nSenderID, message, sProtocol
|
||||
end
|
||||
elseif sEvent == "timer" then
|
||||
-- Return nil if we timeout
|
||||
if p1 == timer then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Wait for events
|
||||
while true do
|
||||
local sEvent, p1, p2, p3 = os.pullEvent( sFilter )
|
||||
if sEvent == "rednet_message" then
|
||||
-- Return the first matching rednet_message
|
||||
local nSenderID, message, sProtocol = p1, p2, p3
|
||||
if sProtocolFilter == nil or sProtocol == sProtocolFilter then
|
||||
return nSenderID, message, sProtocol
|
||||
end
|
||||
elseif sEvent == "timer" then
|
||||
-- Return nil if we timeout
|
||||
if p1 == timer then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function host( sProtocol, sHostname )
|
||||
@ -219,41 +219,41 @@ end
|
||||
|
||||
local bRunning = false
|
||||
function run()
|
||||
if bRunning then
|
||||
error( "rednet is already running", 2 )
|
||||
end
|
||||
bRunning = true
|
||||
|
||||
while bRunning do
|
||||
local sEvent, p1, p2, p3, p4 = os.pullEventRaw()
|
||||
if sEvent == "modem_message" then
|
||||
-- Got a modem message, process it and add it to the rednet event queue
|
||||
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
|
||||
if isOpen( sModem ) and ( nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST ) then
|
||||
if type( tMessage ) == "table" and tMessage.nMessageID then
|
||||
if not tReceivedMessages[ tMessage.nMessageID ] then
|
||||
tReceivedMessages[ tMessage.nMessageID ] = true
|
||||
if bRunning then
|
||||
error( "rednet is already running", 2 )
|
||||
end
|
||||
bRunning = true
|
||||
|
||||
while bRunning do
|
||||
local sEvent, p1, p2, p3, p4 = os.pullEventRaw()
|
||||
if sEvent == "modem_message" then
|
||||
-- Got a modem message, process it and add it to the rednet event queue
|
||||
local sModem, nChannel, nReplyChannel, tMessage = p1, p2, p3, p4
|
||||
if isOpen( sModem ) and ( nChannel == os.getComputerID() or nChannel == CHANNEL_BROADCAST ) then
|
||||
if type( tMessage ) == "table" and tMessage.nMessageID then
|
||||
if not tReceivedMessages[ tMessage.nMessageID ] then
|
||||
tReceivedMessages[ tMessage.nMessageID ] = true
|
||||
tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = tMessage.nMessageID
|
||||
os.queueEvent( "rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol )
|
||||
end
|
||||
end
|
||||
end
|
||||
os.queueEvent( "rednet_message", nReplyChannel, tMessage.message, tMessage.sProtocol )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif sEvent == "rednet_message" then
|
||||
-- Got a rednet message (queued from above), respond to dns lookup
|
||||
local nSenderID, tMessage, sProtocol = p1, p2, p3
|
||||
if sProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup" then
|
||||
local sHostname = tHostnames[ tMessage.sProtocol ]
|
||||
if sHostname ~= nil and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then
|
||||
rednet.send( nSenderID, {
|
||||
sType = "lookup response",
|
||||
sHostname = sHostname,
|
||||
sProtocol = tMessage.sProtocol,
|
||||
}, "dns" )
|
||||
end
|
||||
end
|
||||
elseif sEvent == "rednet_message" then
|
||||
-- Got a rednet message (queued from above), respond to dns lookup
|
||||
local nSenderID, tMessage, sProtocol = p1, p2, p3
|
||||
if sProtocol == "dns" and type(tMessage) == "table" and tMessage.sType == "lookup" then
|
||||
local sHostname = tHostnames[ tMessage.sProtocol ]
|
||||
if sHostname ~= nil and (tMessage.sHostname == nil or tMessage.sHostname == sHostname) then
|
||||
rednet.send( nSenderID, {
|
||||
sType = "lookup response",
|
||||
sHostname = sHostname,
|
||||
sProtocol = tMessage.sProtocol,
|
||||
}, "dns" )
|
||||
end
|
||||
end
|
||||
|
||||
elseif sEvent == "timer" then
|
||||
elseif sEvent == "timer" then
|
||||
-- Got a timer event, use it to clear the event queue
|
||||
local nTimer = p1
|
||||
local nMessage = tReceivedMessageTimeouts[ nTimer ]
|
||||
@ -261,6 +261,6 @@ function run()
|
||||
tReceivedMessageTimeouts[ nTimer ] = nil
|
||||
tReceivedMessages[ nMessage ] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,4 @@
|
||||
edit is a text editor for creating or modifying programs or text files. After creating a program with edit, type its filename in the shell to run it. You can open any of the builtin programs with edit to learn how to program.
|
||||
|
||||
ex:
|
||||
"edit hello" opens a file called "hello" for editing.
|
||||
|
||||
By changing setting "edit.advanced_functionality" to true you can unlock ability to jump to specific line in longer files.
|
||||
"edit hello" opens a file called "hello" for editing.
|
@ -59,9 +59,6 @@ end
|
||||
if peripheral.find( "printer" ) then
|
||||
table.insert( tMenuItems, "Print" )
|
||||
end
|
||||
if settings.get( "edit.advanced_functionality" ) then
|
||||
table.insert( tMenuItems, "Jump" )
|
||||
end
|
||||
table.insert( tMenuItems, "Exit" )
|
||||
|
||||
local sStatus = "Press Ctrl to access menu"
|
||||
@ -137,65 +134,39 @@ local tKeywords = {
|
||||
["while"] = true,
|
||||
}
|
||||
|
||||
local tHex = {
|
||||
[ colors.white ] = "0",
|
||||
[ colors.orange ] = "1",
|
||||
[ colors.magenta ] = "2",
|
||||
[ colors.lightBlue ] = "3",
|
||||
[ colors.yellow ] = "4",
|
||||
[ colors.lime ] = "5",
|
||||
[ colors.pink ] = "6",
|
||||
[ colors.gray ] = "7",
|
||||
[ colors.lightGray ] = "8",
|
||||
[ colors.cyan ] = "9",
|
||||
[ colors.purple ] = "a",
|
||||
[ colors.blue ] = "b",
|
||||
[ colors.brown ] = "c",
|
||||
[ colors.green ] = "d",
|
||||
[ colors.red ] = "e",
|
||||
[ colors.black ] = "f",
|
||||
}
|
||||
|
||||
local tPattern = {
|
||||
[ 1 ] = "^(%-%-%[%[.-%]%])()",
|
||||
[ 2 ] = "^(%-%-.*)()",
|
||||
[ 3 ] = "^(\"\")()",
|
||||
[ 4 ] = "^(\".-[^\\]\")()",
|
||||
[ 5 ] = "^(\'\')()",
|
||||
[ 6 ] = "^(\'.-[^\\]\')()",
|
||||
[ 7 ] = "^(%[%[.-%]%])()",
|
||||
[ 8 ] = "^([%w_]+)()",
|
||||
[ 9 ] = "^([^%w_])()",
|
||||
}
|
||||
|
||||
local tPatternColors = {
|
||||
[ 1 ] = commentColour,
|
||||
[ 2 ] = commentColour,
|
||||
[ 3 ] = stringColour,
|
||||
[ 4 ] = stringColour,
|
||||
[ 5 ] = stringColour,
|
||||
[ 6 ] = stringColour,
|
||||
[ 7 ] = stringColour,
|
||||
[ 8 ] = function( sMatch ) return tKeywords[ sMatch ] and keywordColour or textColour end,
|
||||
[ 9 ] = textColour,
|
||||
}
|
||||
local function tryWrite( sLine, regex, colour )
|
||||
local match = string.match( sLine, regex )
|
||||
if match then
|
||||
if type(colour) == "number" then
|
||||
term.setTextColour( colour )
|
||||
else
|
||||
term.setTextColour( colour(match) )
|
||||
end
|
||||
term.write( match )
|
||||
term.setTextColour( textColour )
|
||||
return string.sub( sLine, string.len(match) + 1 )
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function writeHighlighted( sLine )
|
||||
local tColor = {}
|
||||
local nPosition = 1
|
||||
local sMatch,nNextPosition
|
||||
local nColor
|
||||
while nPosition <= #sLine do
|
||||
local i = 0
|
||||
repeat
|
||||
i=i+1
|
||||
sMatch,nNextPosition = string.match( sLine, tPattern[i] , nPosition)
|
||||
until sMatch
|
||||
nColor = tPatternColors[i]
|
||||
tColor[#tColor+1] = string.rep( tHex[ type(nColor) == "number" and nColor or nColor(sMatch) ] , nNextPosition - nPosition)
|
||||
nPosition = nNextPosition
|
||||
while string.len(sLine) > 0 do
|
||||
sLine =
|
||||
tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or
|
||||
tryWrite( sLine, "^%-%-.*", commentColour ) or
|
||||
tryWrite( sLine, "^\"\"", stringColour ) or
|
||||
tryWrite( sLine, "^\".-[^\\]\"", stringColour ) or
|
||||
tryWrite( sLine, "^\'\'", stringColour ) or
|
||||
tryWrite( sLine, "^\'.-[^\\]\'", stringColour ) or
|
||||
tryWrite( sLine, "^%[%[.-%]%]", stringColour ) or
|
||||
tryWrite( sLine, "^[%w_]+", function( match )
|
||||
if tKeywords[ match ] then
|
||||
return keywordColour
|
||||
end
|
||||
return textColour
|
||||
end ) or
|
||||
tryWrite( sLine, "^[^%w_]", textColour )
|
||||
end
|
||||
term.blit( sLine, table.concat( tColor ), string.rep( tHex[bgColour], #sLine ) )
|
||||
end
|
||||
|
||||
local tCompletions
|
||||
@ -204,7 +175,7 @@ local nCompletion
|
||||
local tCompleteEnv = _ENV
|
||||
local function complete( sLine )
|
||||
if settings.get( "edit.autocomplete" ) then
|
||||
local nStartPos = string.find( sLine, "[a-zA-Z0-9_%.:]+$" )
|
||||
local nStartPos = string.find( sLine, "[a-zA-Z0-9_%.]+$" )
|
||||
if nStartPos then
|
||||
sLine = string.sub( sLine, nStartPos )
|
||||
end
|
||||
@ -311,47 +282,6 @@ local function redrawMenu()
|
||||
term.setCursorPos( x - scrollX, y - scrollY )
|
||||
end
|
||||
|
||||
local function setCursor( newX, newY )
|
||||
local oldX, oldY = x, y
|
||||
x, y = newX, newY
|
||||
local screenX = x - scrollX
|
||||
local screenY = y - scrollY
|
||||
|
||||
local bRedraw = false
|
||||
if screenX < 1 then
|
||||
scrollX = x - 1
|
||||
screenX = 1
|
||||
bRedraw = true
|
||||
elseif screenX > w then
|
||||
scrollX = x - w
|
||||
screenX = w
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
if screenY < 1 then
|
||||
scrollY = y - 1
|
||||
screenY = 1
|
||||
bRedraw = true
|
||||
elseif screenY > h-1 then
|
||||
scrollY = y - (h-1)
|
||||
screenY = h-1
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
recomplete()
|
||||
if bRedraw then
|
||||
redrawText()
|
||||
elseif y ~= oldY then
|
||||
redrawLine( oldY )
|
||||
redrawLine( y )
|
||||
else
|
||||
redrawLine( y )
|
||||
end
|
||||
term.setCursorPos( screenX, screenY )
|
||||
|
||||
redrawMenu()
|
||||
end
|
||||
|
||||
local tMenuFuncs = {
|
||||
Save = function()
|
||||
if bReadOnly then
|
||||
@ -465,26 +395,7 @@ local tMenuFuncs = {
|
||||
sStatus="Error saving to "..sTempPath
|
||||
end
|
||||
redrawMenu()
|
||||
end,
|
||||
Jump = function()
|
||||
term.setCursorPos( 1, h )
|
||||
term.clearLine()
|
||||
term.setTextColour( highlightColour )
|
||||
term.write( "Line : " )
|
||||
term.setTextColour( textColour )
|
||||
local nLine = tonumber(read())
|
||||
if type(nLine) == "number" then
|
||||
nLine = math.min(math.max( 1, nLine ), #tLines )
|
||||
setCursor( 1, nLine )
|
||||
sStatus="Jumped to line "..nLine
|
||||
redrawMenu()
|
||||
redrawText()
|
||||
else
|
||||
sStatus="Invalid line number"
|
||||
redrawMenu()
|
||||
redrawText()
|
||||
end
|
||||
end,
|
||||
end
|
||||
}
|
||||
|
||||
local function doMenuItem( _n )
|
||||
@ -496,6 +407,47 @@ local function doMenuItem( _n )
|
||||
redrawMenu()
|
||||
end
|
||||
|
||||
local function setCursor( newX, newY )
|
||||
local oldX, oldY = x, y
|
||||
x, y = newX, newY
|
||||
local screenX = x - scrollX
|
||||
local screenY = y - scrollY
|
||||
|
||||
local bRedraw = false
|
||||
if screenX < 1 then
|
||||
scrollX = x - 1
|
||||
screenX = 1
|
||||
bRedraw = true
|
||||
elseif screenX > w then
|
||||
scrollX = x - w
|
||||
screenX = w
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
if screenY < 1 then
|
||||
scrollY = y - 1
|
||||
screenY = 1
|
||||
bRedraw = true
|
||||
elseif screenY > h-1 then
|
||||
scrollY = y - (h-1)
|
||||
screenY = h-1
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
recomplete()
|
||||
if bRedraw then
|
||||
redrawText()
|
||||
elseif y ~= oldY then
|
||||
redrawLine( oldY )
|
||||
redrawLine( y )
|
||||
else
|
||||
redrawLine( y )
|
||||
end
|
||||
term.setCursorPos( screenX, screenY )
|
||||
|
||||
redrawMenu()
|
||||
end
|
||||
|
||||
-- Actual program functionality begins
|
||||
load(sPath)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
-- Paint created by nitrogenfingers (edited by dan200 & co)
|
||||
-- Paint created by nitrogenfingers (edited by dan200)
|
||||
-- http://www.youtube.com/user/NitrogenFingers
|
||||
|
||||
------------
|
||||
@ -21,15 +21,9 @@ local mChoices = { "Save","Exit" }
|
||||
-- The message displayed in the footer bar
|
||||
local fMessage = "Press Ctrl to access menu"
|
||||
|
||||
-- Colour to character conversions
|
||||
local tColourLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ 2^(n-1) ] = string.sub( "0123456789abcdef",n,n )
|
||||
end
|
||||
|
||||
-----------------------
|
||||
-- Pre-Flight Checks --
|
||||
-----------------------
|
||||
-------------------------
|
||||
-- Initialisation --
|
||||
-------------------------
|
||||
|
||||
-- Determine if we can even run this
|
||||
if not term.isColour() then
|
||||
@ -38,13 +32,14 @@ if not term.isColour() then
|
||||
end
|
||||
|
||||
-- Determines if the file exists, and can be edited on this computer
|
||||
local sPath = ...
|
||||
if not sPath then
|
||||
local tArgs = {...}
|
||||
if #tArgs == 0 then
|
||||
print("Usage: paint <path>")
|
||||
return
|
||||
end
|
||||
sPath = shell.resolve( sPath )
|
||||
if fs.isDir( sPath ) then
|
||||
local sPath = shell.resolve(tArgs[1])
|
||||
local bReadOnly = fs.isReadOnly(sPath)
|
||||
if fs.exists(sPath) and fs.isDir(sPath) then
|
||||
print("Cannot edit a directory.")
|
||||
return
|
||||
end
|
||||
@ -57,14 +52,117 @@ 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
|
||||
|
||||
--[[
|
||||
Draws colour picker sidebar, the palette and the footer
|
||||
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
|
||||
returns: nil
|
||||
]]
|
||||
local function drawInterface()
|
||||
@ -88,22 +186,24 @@ local function drawInterface()
|
||||
term.write("\127\127")
|
||||
|
||||
-- Left and Right Selected Colours
|
||||
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")
|
||||
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
|
||||
end
|
||||
|
||||
-- Padding
|
||||
@ -114,24 +214,41 @@ 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
|
||||
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 ) )
|
||||
drawCanvasLine( y )
|
||||
end
|
||||
end
|
||||
|
||||
@ -142,15 +259,22 @@ 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.blit( "["..v.."]", "4"..string.rep(" ",#v).."4", string.rep("f",#v+2) )
|
||||
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)
|
||||
else
|
||||
term.write(" "..v.." ")
|
||||
end
|
||||
@ -158,39 +282,51 @@ local function accessMenu()
|
||||
|
||||
-- Handle input in the menu
|
||||
local id,key = os.pullEvent("key")
|
||||
|
||||
-- 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
|
||||
end
|
||||
fMessage = (paintutils.saveImage( canvas, sPath ) and "Saved to " or "Error saving to ")..sPath
|
||||
return false
|
||||
elseif mChoices[selection]=="Exit" then
|
||||
return true
|
||||
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
|
||||
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
|
||||
elseif key == keys.leftCtrl or keys == keys.rightCtrl then
|
||||
-- Cancel the menu
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -201,10 +337,11 @@ end
|
||||
returns: nil
|
||||
]]
|
||||
local function handleEvents()
|
||||
while true do
|
||||
local programActive = true
|
||||
while programActive do
|
||||
local id,p1,p2,p3 = os.pullEvent()
|
||||
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_click" or id=="mouse_drag" then
|
||||
if p2 >= w-1 and p3 >= 1 and p3 <= 17 then
|
||||
if id ~= "mouse_drag" then
|
||||
-- Selecting an items in the colour picker
|
||||
if p3 <= 16 then
|
||||
@ -220,14 +357,15 @@ local function handleEvents()
|
||||
rightColour = nil
|
||||
end
|
||||
end
|
||||
--drawCanvas()
|
||||
drawInterface()
|
||||
end
|
||||
elseif p2 < w-1 then
|
||||
elseif p2 < w-1 and p3 <= h-1 then
|
||||
-- Clicking on the canvas
|
||||
local paintColour
|
||||
local paintColour = nil
|
||||
if p1==1 then
|
||||
paintColour = leftColour
|
||||
else
|
||||
elseif p1==2 then
|
||||
paintColour = rightColour
|
||||
end
|
||||
if not canvas[p3] then
|
||||
@ -235,16 +373,11 @@ local function handleEvents()
|
||||
end
|
||||
canvas[p3][p2] = paintColour
|
||||
|
||||
term.setCursorPos( p2, p3 )
|
||||
if paintColour then
|
||||
term.blit( " ", " ", tColourLookup[paintColour] )
|
||||
else
|
||||
term.blit( "\127", "7", tColourLookup[canvasColour] )
|
||||
end
|
||||
drawCanvasPixel( p2, p3 )
|
||||
end
|
||||
elseif id=="key" then
|
||||
if p1==keys.leftCtrl or p1==keys.rightCtrl then
|
||||
if accessMenu() then return end
|
||||
programActive = not accessMenu()
|
||||
drawInterface()
|
||||
end
|
||||
elseif id=="term_resize" then
|
||||
@ -255,24 +388,15 @@ local function handleEvents()
|
||||
end
|
||||
end
|
||||
|
||||
--------------------
|
||||
-- Initialisation --
|
||||
--------------------
|
||||
|
||||
if fs.exists( sPath ) then canvas = paintutils.loadImage( sPath ) end
|
||||
-- Init
|
||||
load(sPath)
|
||||
drawCanvas()
|
||||
drawInterface()
|
||||
|
||||
---------------
|
||||
-- Main Loop --
|
||||
---------------
|
||||
|
||||
-- Main loop
|
||||
handleEvents()
|
||||
|
||||
--------------
|
||||
-- Shutdown --
|
||||
--------------
|
||||
|
||||
-- Shutdown
|
||||
term.setBackgroundColour(colours.black)
|
||||
term.setTextColour(colours.white)
|
||||
term.clear()
|
||||
|
@ -208,9 +208,7 @@ shell.setCompletionFunction( "rom/programs/command/exec.lua", completeExec )
|
||||
if turtle then
|
||||
local tGoOptions = { "left", "right", "forward", "back", "down", "up" }
|
||||
local function completeGo( shell, nIndex, sText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice(sText,tGoOptions)
|
||||
end
|
||||
return completeMultipleChoice(sText,tGoOptions)
|
||||
end
|
||||
local tTurnOptions = { "left", "right" }
|
||||
local function completeTurn( shell, nIndex, sText )
|
||||
|
Loading…
x
Reference in New Issue
Block a user