Advertisement
CodeCrafter

Paint (myedit)

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