Guest User

Untitled

a guest
Jul 1st, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.85 KB | None | 0 0
  1. -- Paint created by nitrogenfingers (edited by dan200)
  2. -- http://www.youtube.com/user/NitrogenFingers
  3.  
  4. ------------
  5. -- Fields --
  6. ------------
  7.  
  8. -- The width and height of the terminal
  9. local w,h = term.getSize()
  10.  
  11. -- The selected colours on the left and right mouse button, and the colour of the canvas
  12. local leftColour, rightColour = colours.white, nil
  13. local canvasColour = colours.black
  14.  
  15. -- The values stored in the canvas
  16. local canvas = {}
  17.  
  18. -- The menu options
  19. local mChoices = { "Save","Exit" }
  20.  
  21. -- The message displayed in the footer bar
  22. local fMessage = "Press Ctrl to access menu"
  23.  
  24. -------------------------
  25. -- Initialisation --
  26. -------------------------
  27.  
  28. -- Determine if we can even run this
  29. if not term.isColour() then
  30. print("Requires an Advanced Computer")
  31. return
  32. end
  33.  
  34. -- Determines if the file exists, and can be edited on this computer
  35. local tArgs = {...}
  36. if #tArgs == 0 then
  37. print("Usage: paint <path>")
  38. return
  39. end
  40. local sPath = shell.resolve(tArgs[1])
  41. local bReadOnly = fs.isReadOnly(sPath)
  42. if fs.exists(sPath) and fs.isDir(sPath) then
  43. print("Cannot edit a directory.")
  44. return
  45. end
  46.  
  47. ---------------
  48. -- Functions --
  49. ---------------
  50.  
  51. local function getCanvasPixel( x, y )
  52. if canvas[y] then
  53. return canvas[y][x]
  54. end
  55. return nil
  56. end
  57.  
  58. --[[
  59. Converts a colour value to a text character
  60. params: colour = the number to convert to a hex value
  61. returns: a string representing the chosen colour
  62. ]]
  63. local function getCharOf( colour )
  64. -- Incorrect values always convert to nil
  65. if type(colour) == "number" then
  66. local value = math.floor( math.log(colour) / math.log(2) ) + 1
  67. if value >= 1 and value <= 16 then
  68. return string.sub( "0123456789abcdef", value, value )
  69. end
  70. end
  71. return " "
  72. end
  73.  
  74. --[[
  75. Converts a text character to colour value
  76. params: char = the char (from string.byte) to convert to number
  77. returns: the colour number of the hex value
  78. ]]
  79. local tColourLookup = {}
  80. for n=1,16 do
  81. tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
  82. end
  83. local function getColourOf( char )
  84. -- Values not in the hex table are transparent (canvas coloured)
  85. return tColourLookup[char]
  86. end
  87.  
  88. --[[
  89. Loads the file into the canvas
  90. params: path = the path of the file to open
  91. returns: nil
  92. ]]
  93. local function load(path)
  94. -- Load the file
  95. if fs.exists(path) then
  96. local file = fs.open(sPath, "r")
  97. local sLine = file.readLine()
  98. while sLine do
  99. local line = {}
  100. for x=1,w-2 do
  101. line[x] = getColourOf( string.byte(sLine,x,x) )
  102. end
  103. table.insert( canvas, line )
  104. sLine = file.readLine()
  105. end
  106. file.close()
  107. end
  108. end
  109.  
  110. --[[
  111. Saves the current canvas to file
  112. params: path = the path of the file to save
  113. returns: true if save was successful, false otherwise
  114. ]]
  115. local function save(path)
  116. -- Open file
  117. local sDir = string.sub(sPath, 1, #sPath - #fs.getName(sPath))
  118. if not fs.exists(sDir) then
  119. fs.makeDir(sDir)
  120. end
  121.  
  122. local file = fs.open( path, "w" )
  123. if not file then
  124. return false
  125. end
  126.  
  127. -- Encode (and trim)
  128. local tLines = {}
  129. local nLastLine = 0
  130. for y=1,h-1 do
  131. local sLine = ""
  132. local nLastChar = 0
  133. for x=1,w-2 do
  134. local c = getCharOf( getCanvasPixel( x, y ) )
  135. sLine = sLine .. c
  136. if c ~= " " then
  137. nLastChar = x
  138. end
  139. end
  140. sLine = string.sub( sLine, 1, nLastChar )
  141. tLines[y] = sLine
  142. if string.len( sLine ) > 0 then
  143. nLastLine = y
  144. end
  145. end
  146.  
  147. -- Save out
  148. for n=1,nLastLine do
  149. file.writeLine( tLines[ n ] )
  150. end
  151. file.close()
  152. return true
  153. end
  154.  
  155. --[[
  156. Draws colour picker sidebar, the pallette and the footer
  157. returns: nil
  158. ]]
  159. local function drawInterface()
  160. -- Footer
  161. term.setCursorPos(1, h)
  162. term.setBackgroundColour(colours.black)
  163. term.setTextColour(colours.yellow)
  164. term.clearLine()
  165. term.write(fMessage)
  166.  
  167. -- Colour Picker
  168. for i=1,16 do
  169. term.setCursorPos(w-1, i)
  170. term.setBackgroundColour( 2^(i-1) )
  171. term.write(" ")
  172. end
  173.  
  174. term.setCursorPos(w-1, 17)
  175. term.setBackgroundColour( canvasColour )
  176. term.setTextColour( colours.grey )
  177. term.write("XX")
  178.  
  179. -- Left and Right Selected Colours
  180. for i=18,18 do
  181. term.setCursorPos(w-1, i)
  182. if leftColour ~= nil then
  183. term.setBackgroundColour( leftColour )
  184. term.write(" ")
  185. else
  186. term.setBackgroundColour( canvasColour )
  187. term.setTextColour( colours.grey )
  188. term.write("X")
  189. end
  190. if rightColour ~= nil then
  191. term.setBackgroundColour( rightColour )
  192. term.write(" ")
  193. else
  194. term.setBackgroundColour( canvasColour )
  195. term.setTextColour( colours.grey )
  196. term.write("X")
  197. end
  198. end
  199.  
  200. -- Padding
  201. term.setBackgroundColour( canvasColour )
  202. for i=20,h-1 do
  203. term.setCursorPos(w-1, i)
  204. term.write(" ")
  205. end
  206. end
  207.  
  208. --[[
  209. Converts a single pixel of a single line of the canvas and draws it
  210. returns: nil
  211. ]]
  212. local function drawCanvasPixel( x, y )
  213. local pixel = getCanvasPixel( x, y )
  214. if pixel then
  215. term.setBackgroundColour( pixel or canvasColour )
  216. term.setCursorPos(x, y)
  217. term.write(" ")
  218. else
  219. term.setBackgroundColour( canvasColour )
  220. term.setTextColour( colours.grey )
  221. term.setCursorPos(x, y)
  222. term.write("-")
  223. end
  224. end
  225.  
  226. --[[
  227. Converts each colour in a single line of the canvas and draws it
  228. returns: nil
  229. ]]
  230. local function drawCanvasLine( y )
  231. for x = 1, w-2 do
  232. drawCanvasPixel( x, y )
  233. end
  234. end
  235.  
  236. --[[
  237. Converts each colour in the canvas and draws it
  238. returns: nil
  239. ]]
  240. local function drawCanvas()
  241. for y = 1, h-1 do
  242. drawCanvasLine( y )
  243. end
  244. end
  245.  
  246. --[[
  247. Draws menu options and handles input from within the menu.
  248. returns: true if the program is to be exited; false otherwise
  249. ]]
  250. local function accessMenu()
  251. -- Selected menu option
  252. local selection = 1
  253.  
  254. term.setBackgroundColour(colours.black)
  255. while true do
  256. -- Draw the menu
  257. term.setCursorPos(1,h)
  258. term.clearLine()
  259. term.setTextColour(colours.white)
  260. for k,v in pairs(mChoices) do
  261. if selection==k then
  262. term.setTextColour(colours.yellow)
  263. local ox,_ = term.getCursorPos()
  264. term.write("["..string.rep(" ",#v).."]")
  265. term.setCursorPos(ox+1,h)
  266. term.setTextColour(colours.white)
  267. term.write(v)
  268. term.setCursorPos(term.getCursorPos()+1,h)
  269. else
  270. term.write(" "..v.." ")
  271. end
  272. end
  273.  
  274. -- Handle input in the menu
  275. local id,key = os.pullEvent("key")
  276. if id == "key" then
  277. -- S and E are shortcuts
  278. if key == keys.s then
  279. selection = 1
  280. key = keys.enter
  281. elseif key == keys.e then
  282. selection = 2
  283. key = keys.enter
  284. end
  285.  
  286. if key == keys.right then
  287. -- Move right
  288. selection = selection + 1
  289. if selection > #mChoices then
  290. selection = 1
  291. end
  292.  
  293. elseif key == keys.left and selection > 1 then
  294. -- Move left
  295. selection = selection - 1
  296. if selection < 1 then
  297. selection = #mChoices
  298. end
  299.  
  300. elseif key == keys.enter then
  301. -- Select an option
  302. if mChoices[selection]=="Save" then
  303. if bReadOnly then
  304. fMessage = "Access Denied"
  305. return false
  306. end
  307. local success = save(sPath)
  308. if success then
  309. fMessage = "Saved to "..sPath
  310. else
  311. fMessage = "Error saving to "..sPath
  312. end
  313. return false
  314. elseif mChoices[selection]=="Exit" then
  315. return true
  316. end
  317. elseif key == keys.leftCtrl or keys == keys.rightCtrl then
  318. -- Cancel the menu
  319. return false
  320. end
  321. end
  322. end
  323. end
  324.  
  325. --[[
  326. Runs the main thread of execution. Draws the canvas and interface, and handles
  327. mouse and key events.
  328. returns: nil
  329. ]]
  330. local function handleEvents()
  331. local programActive = true
  332. while programActive do
  333. local id,p1,p2,p3 = os.pullEvent()
  334. if id=="mouse_click" or id=="mouse_drag" then
  335. if p2 >= w-1 and p3 >= 1 and p3 <= 17 then
  336. if id ~= "mouse_drag" then
  337. -- Selecting an items in the colour picker
  338. if p3 <= 16 then
  339. if p1==1 then
  340. leftColour = 2^(p3-1)
  341. else
  342. rightColour = 2^(p3-1)
  343. end
  344. else
  345. if p1==1 then
  346. leftColour = nil
  347. else
  348. rightColour = nil
  349. end
  350. end
  351. --drawCanvas()
  352. drawInterface()
  353. end
  354. elseif p2 < w-1 and p3 <= h-1 then
  355. -- Clicking on the canvas
  356. local paintColour = nil
  357. if p1==1 then
  358. paintColour = leftColour
  359. elseif p1==2 then
  360. paintColour = rightColour
  361. end
  362. if not canvas[p3] then
  363. canvas[p3] = {}
  364. end
  365. canvas[p3][p2] = paintColour
  366.  
  367. drawCanvasPixel( p2, p3 )
  368. end
  369. elseif id=="key" then
  370. if p1==keys.leftCtrl or p1==keys.rightCtrl then
  371. programActive = not accessMenu()
  372. drawInterface()
  373. end
  374. elseif id=="term_resize" then
  375. w,h = term.getSize()
  376. drawCanvas()
  377. drawInterface()
  378. end
  379. end
  380. end
  381.  
  382. -- Init
  383. load(sPath)
  384. drawCanvas()
  385. drawInterface()
  386.  
  387. -- Main loop
  388. handleEvents()
  389.  
  390. -- Shutdown
  391. term.setBackgroundColour(colours.black)
  392. term.setTextColour(colours.white)
  393. term.clear()
  394. term.setCursorPos(1,1)
Add Comment
Please, Sign In to add comment