Advertisement
Guest User

speadersheet

a guest
May 23rd, 2016
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.10 KB | None | 0 0
  1. --Included libs:
  2. --delegate (by me)
  3. local function delegate()
  4. return setmetatable({func = {},
  5. add = function(self,func)
  6. checkTypes({self,func},{"table","function"})
  7. self.func[#self.func+1] = func
  8. end,
  9. sub = function(self,func)
  10. checkTypes({self,func},{"table","function"})
  11. for i=1,#self.func do
  12. local v = self.func[i]
  13. if v == func then
  14. table.remove(self.func,i)
  15. end
  16. end
  17. end,
  18. },
  19. {__call = function(tbl,...)
  20. if type(tbl.func) == "table" then
  21. local c,r = 0,{}
  22. for k,v in pairs(tbl.func) do
  23. if type(v) == "function" then
  24. c = c+1
  25. r[c] = {pcall(v,...)}
  26. end
  27. end
  28. return c,r
  29. end
  30. end,
  31. __add = function(self,func)
  32. self:add(func)
  33. end,
  34. __sub = function(self,func)
  35. self:sub(func)
  36. end,
  37. })
  38. end
  39. --Setup vars:
  40. --general vars
  41. local filepath = ""
  42. --display vars
  43. local scroll = {0,0}
  44. local showncolumncount = 10
  45. local w,h = term.getSize()
  46. local gridw, gridh = w-2, h-2 --why not put this here :P
  47. local gridx, gridy = 4,2
  48. local defaultColumnWidth = 10
  49. --selection vars
  50. local selected = {1,1} --selected cell position
  51. local endselection = {}
  52. local multiselect = false
  53. --file content vars
  54. local grid = {}
  55. local columnWidths = {}
  56. --copy/paste vars
  57. local clipboard = {}
  58. --theme vars
  59. local theme = term.isColor() and {
  60. default = {colors.white, colors.black},
  61. selected = {colors.green, colors.white},
  62. multiselected = {colors.lime, colors.black},
  63. menu = {colors.green, colors.white},
  64. border = {colors.lightGray, colors.black}
  65. } or {
  66. default = {colors.black, colors.white},
  67. selected = {colors.white, colors.black},
  68. multiselected = {colors.gray, colors.black},
  69. menu = {colors.white, colors.black},
  70. border = {colors.lightGray, colors.black}
  71. }
  72. --Handle args:
  73. local tArgs = {...}
  74. if #tArgs < 1 then --not enough args
  75. print[[
  76. Usage:
  77. speadersheet <filename>
  78. ]]
  79. error("",0)
  80. end
  81. filepath = tArgs[1]
  82. --Local functions:
  83. local function selectColors(name) --selects colors, args: name of theme
  84. local cols = theme[name]
  85. term.setBackgroundColor(cols[1])
  86. term.setTextColor(cols[2])
  87. end
  88. local function redrawGrid() --redraws grid and bottom line
  89. --this is the function that will need lots of optimization probably
  90. local drawing = {scroll[1], scroll[2]} --which cell are we drawing (to get the content)
  91. for y=gridy, gridh + gridy - 1 do
  92. drawing[2] = drawing[2] + 1
  93. drawing[1] = scroll[1]
  94. term.setCursorPos(gridx, y)
  95. for i=1,showncolumncount do
  96. drawing[1] = drawing[1] + 1
  97. local cwidth = columnWidths[drawing[1]] or defaultColumnWidth
  98. selectColors((selected[1] == drawing[1] and selected[2] == drawing[2]) and "selected" or (multiselect and (selected[1] >= drawing[1] and selected[2] >= drawing[2]) and (endselection[1] <= drawing[1] and endselection[2] <= drawing[2])) and "multiselected" or "default")
  99. local text = grid[drawing[1]] and grid[drawing[1]][drawing[2]] and grid[drawing[1]][drawing[2]] or ""
  100. term.write(text .. (#text < cwidth - 1 and string.rep(" ",(cwidth - 1) - #text) or ""))
  101. if selected[1] == drawing[1] and selected[2] == drawing[2] then
  102. local oldx,oldy = term.getCursorPos()
  103. term.setCursorPos(1,h)
  104. selectColors("menu")
  105. --This is repeated because of functions later
  106. local realtext = grid[drawing[1]] and grid[drawing[1]][drawing[2]] and grid[drawing[1]][drawing[2]] or ""
  107. term.write(realtext .. (#realtext < w and string.rep(" ",w - #realtext) or ""))
  108. term.setCursorPos(oldx,oldy)
  109. end
  110. selectColors("border")
  111. term.write(" ")
  112. end
  113. end
  114. end
  115. local function redrawMenu() --redraws column and row numbers
  116. --redraw top column numbers
  117. do
  118. local drawing = scroll[1]
  119. term.setCursorPos(gridx, 1)
  120. selectColors("menu")
  121. term.clearLine()
  122. term.setCursorPos(gridx, 1)
  123. for i=1,showncolumncount do
  124. drawing = drawing + 1
  125. local cwidth = columnWidths[drawing] or defaultColumnWidth
  126. term.write(drawing)
  127. term.write(string.rep(" ",cwidth - #tostring(drawing)))
  128. end
  129. end
  130. --redraw line numbers
  131. local drawing = scroll[2]
  132. for y=gridy, gridh + gridy - 1 do
  133. drawing = drawing + 1
  134. term.setCursorPos(1, y)
  135. term.write(tostring(drawing) .. string.rep(" ",3 - #tostring(drawing)))
  136. end
  137. end
  138. local function checkScroll() --scrolls if needed
  139. local scrolled = false
  140. --horizontal:
  141. local cx = gridx
  142. local count = 0
  143. local drawing = scroll[1]
  144. for i=1,w do -- count how many columns are on screen
  145. drawing = drawing + 1
  146. local cwidth = columnWidths[drawing] or defaultColumnWidth
  147. cx = cx + cwidth
  148. count = count + 1
  149. if cx >= w then break end
  150. end
  151. showncolumncount = count
  152. while selected[1] - scroll[1] < 1 do
  153. scroll[1] = scroll[1] - 1
  154. scrolled = true
  155. end
  156. while selected[1] > scroll[1] + count do
  157. scroll[1] = scroll[1] + 1
  158. scrolled = true
  159. end
  160. --vertical:
  161. while selected[2] - scroll[2] < 1 do
  162. scroll[2] = scroll[2] - 1
  163. scrolled = true
  164. end
  165. while selected[2] > scroll[2] + gridh do
  166. scroll[2] = scroll[2] + 1
  167. scrolled = true
  168. end
  169. if scrolled then
  170. redrawGrid()
  171. redrawMenu()
  172. end
  173. end
  174. local function save() --saves persistant data
  175. local h = fs.open(filepath,"w")
  176. local cont = textutils.serialize{
  177. grid,
  178. selected,
  179. endselection,
  180. multiselect,
  181. columnWidths,
  182. showhelp,
  183. scroll
  184. }
  185. h.write(cont)
  186. h.close()
  187. end
  188. local function reload() --loads persistant data
  189. if fs.exists(filepath) then
  190. local h = fs.open(filepath,"r")
  191. local cont = textutils.unserialize(h.readAll())
  192. h.close()
  193. grid = cont[1] or {}
  194. selected = cont[2] or {1,1}
  195. endselection = cont[3] or {1,1}
  196. multiselect = cont[4]
  197. columnWidths = cont[5] or {}
  198. showhelp = cont[6] or true
  199. scroll = cont[7] or {0,0}
  200. end
  201. end
  202. local function cancel() --cancels multiselection
  203. if multiselect then
  204. multiselect = false
  205. end
  206. endselection = {selected[1], selected[2]}
  207. end
  208. local function initMultiselect() --inits multiselection if needed
  209. if not multiselect then
  210. multiselect = true
  211. endselection = {selected[1], selected[2]}
  212. end
  213. end
  214. local function convertSelection() -- converts multi/single selection to a smaller sub grid and returns it
  215. local subx, suby = 1,1
  216. local subgrid = {}
  217. for x = endselection[1], selected[1] do
  218. subgrid[subx] = {}
  219. for y = endselection[2], selected[2] do
  220. subgrid[subx][suby] = grid[x] and grid[x][y] and grid[x][y] or ""
  221. suby = suby + 1
  222. end
  223. suby = 1
  224. subx = subx + 1
  225. end
  226. return subgrid
  227. end
  228. local function pasteSubgrid(subgrid, x, y) --pastes subgrid in main grid
  229. for i=#subgrid, 1, -1 do
  230. local line = subgrid[i]
  231. for j = #line, 1, -1 do
  232. local cell = line[j]
  233. if not grid[x + i - 1] then
  234. grid[x + i - 1] = {}
  235. end
  236. grid[x + i - 1][y + j - 1] = cell
  237. end
  238. end
  239. end
  240. local function deleteSelection()
  241. for x = endselection[1], selected[1] do
  242. for y = endselection[2], selected[2] do
  243. if grid[x] then
  244. grid[x][y] = ""
  245. end
  246. end
  247. end
  248. end
  249. reload()
  250. --Key-event table:
  251. local handler = {
  252. --[[
  253. movement:
  254. arrow keys = move
  255. p/l = multiselect (move right bottom corner right/down)
  256. enter = edit
  257. home = first column
  258. end = first row
  259. page up = page up
  260. page down = page down
  261. general:
  262. s = save
  263. q = exit
  264. copy/paste:
  265. c = copy
  266. v = paste
  267. x = cut
  268. ]]
  269. key = {
  270. [keys.up] = function() cancel() selected[2] = selected[2] > 1 and selected[2] - 1 or 1 redrawGrid() end;
  271. [keys.down] = function() cancel() selected[2] = selected[2] + 1 redrawGrid() end;
  272. [keys.left] = function() cancel() selected[1] = selected[1] > 1 and selected[1] - 1 or 1 redrawGrid() end;
  273. [keys.right] = function() cancel() selected[1] = selected[1] + 1 redrawGrid() end;
  274. [keys.home] = function() cancel() selected[1] = 1 redrawGrid() end;
  275. [keys["end"]] = function() cancel() selected[2] = 1 redrawGrid() end;
  276. [keys.pageUp] = function() cancel() selected[2] = selected[2] > gridh-1 and selected[2] - (gridh-1) or 1 redrawGrid() end;
  277. [keys.pageDown] = function() cancel() selected[2] = selected[2] + gridh - 1 redrawGrid() end;
  278. [keys.p] = function() initMultiselect() selected[1] = selected[1] + 1 redrawGrid() end;
  279. [keys.l] = function() initMultiselect() selected[2] = selected[2] + 1 redrawGrid() end;
  280. [keys.enter] = function()
  281. term.setCursorPos(1,h)
  282. selectColors("menu")
  283. term.clearLine()
  284. term.setCursorPos(1,h)
  285. if not grid[selected[1]] then
  286. grid[selected[1]] = {}
  287. end
  288. grid[selected[1]][selected[2]] = read()
  289. redrawGrid()
  290. redrawMenu()
  291. end;
  292. [keys.s] = function()
  293. save()
  294. end;
  295. [keys.q] = function()
  296. term.setBackgroundColor(colors.black)
  297. term.setTextColor(colors.white)
  298. term.clear()
  299. term.setCursorPos(1,1)
  300. sleep(0)
  301. error("",0)
  302. end;
  303. [keys.c] = function()
  304. clipboard = convertSelection()
  305. end;
  306. [keys.v] = function()
  307. pasteSubgrid(clipboard, selected[1], selected[2])
  308. redrawGrid()
  309. end;
  310. [keys.x] = function()
  311. clipboard = convertSelection()
  312. deleteSelection()
  313. redrawGrid()
  314. end;
  315. }
  316. }
  317. --Main loop:
  318. term.clear()
  319. redrawGrid()
  320. redrawMenu()
  321. while true do
  322. local event,param = os.pullEvent()
  323. if handler[event] and handler[event][param] then
  324. handler[event][param]()
  325. checkScroll()
  326. end
  327. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement