Dimencia

MonitorProgram

Nov 2nd, 2019
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.51 KB | None | 0 0
  1. local function Button(
  2. width,
  3. height,
  4. label,
  5. backgroundColorNormal,
  6. backgroundColorPressed,
  7. textColorNormal,
  8. textColorPressed,
  9. hasBorder,
  10. borderColorNormal,
  11. borderColorPressed,
  12. startColumn,
  13. startRow,
  14. isPressed,
  15. defaultBackgroundColor,
  16. defaultTextColor
  17. )
  18. local button = {}
  19. button.height=height or 1
  20. button.width=width or 1
  21. button.label=label or ""
  22. button.backgroundColorNormal=backgroundColorNormal or colors.black
  23. button.backgroundColorPressed=backgroundColorPressed or colors.white
  24. button.textColorNormal=textColorNormal or colors.white
  25. button.textColorPressed=textColorPressed or colors.black
  26. button.hasBorder = hasBorder or false
  27. button.borderColorNormal = borderColorNormal or backGroundColorNormal
  28. button.borderColorPressed = borderColorPressed or backGroundColorPressed
  29. button.defaultBackgroundColor = defaultBackgroundColor or colors.black
  30. button.defaultTextColor = defaultTextColor or colors.white
  31. button.startColumn = startColumn or 1
  32. button.startRow = startRow or 1
  33. button.isPressed=isPressed or false
  34. function button.press()
  35. button.isPressed = not button.isPressed
  36. end
  37. function button.clicked(column,row)
  38. return (column >= button.startColumn and column < button.startColumn + button.width and row >= button.startRow and row < button.startRow + button.height)
  39. end
  40. function button.draw(display,isPressed,startColumn,startRow)
  41.  
  42. button.startColumn = startColumn or button.startColumn
  43. button.startRow = startRow or button.startRow
  44. display = display or term
  45. if isPressed == false or isPressed then
  46. button.isPressed = isPressed
  47. else isPressed = button.isPressed
  48. end
  49. local width = button.width
  50. local height = button.height
  51. startRow = button.startRow
  52. startColumn = button.startColumn
  53.  
  54. local label = button.label
  55. local labelPad = 2
  56.  
  57. -- set border params and draw border if hasBorder
  58. if button.hasBorder == true then
  59. -- button must be at least 3x3, if not, make it so
  60. if width < 3 then
  61. width = 3
  62. end
  63. if height < 3 then
  64. height = 3
  65. end
  66.  
  67. -- set border colors
  68. if not isPressed then
  69. if not display.isColor() then
  70. display.setBackgroundColor(colors.white)
  71. else
  72. display.setBackgroundColor(button.borderColorNormal)
  73. end
  74. else
  75. if not display.isColor() then
  76. display.setBackgroundColor(colors.white)
  77. else
  78. display.setBackgroundColor(button.borderColorPressed)
  79. end
  80. end
  81.  
  82. -- draw button border (inset)
  83. display.setCursorPos(startColumn,startRow)
  84. display.write(string.rep(" ",width))
  85. for row = 2,height-1 do
  86. display.setCursorPos(startColumn,button.startRow+row -1)
  87. display.write(" ")
  88. display.setCursorPos(startColumn+width -1 ,startRow + row-1)
  89. display.write(" ")
  90. end
  91. display.setCursorPos(startColumn,startRow+height-1)
  92. display.write(string.rep(" ",width))
  93.  
  94. -- reset startColumn,startRow,width,column to inset button and label
  95. startColumn=startColumn+1
  96. startRow = startRow +1
  97. width = width - 2
  98. height = height - 2
  99. end
  100.  
  101. --set button background and text colors
  102. if not isPressed then
  103. if not display.isColor() then
  104. display.setBackgroundColor(colors.black)
  105. display.setTextColor(colors.white)
  106. else
  107. display.setBackgroundColor(button.backgroundColorNormal)
  108. display.setTextColor(button.textColorNormal)
  109. end
  110. else
  111. if not display.isColor() then
  112. display.setBackgroundColor(colors.white)
  113. display.setTextColor(colors.black)
  114. else
  115. display.setBackgroundColor(button.backgroundColorPressed)
  116. display.setTextColor(button.textColorPressed)
  117. end
  118. end
  119.  
  120. -- draw button background (will be inside border if there is one)
  121. for row = 1,height do
  122. --print(tostring(startColumn)..","..tostring(startRow-row))
  123. display.setCursorPos(startColumn,startRow + row -1)
  124. display.write(string.rep(" ",width))
  125. end
  126.  
  127. -- prepare label, truncate label if necessary
  128.  
  129. -- prepare label, truncate label if necessary
  130. if width < 3 then
  131. labelPad = 0
  132. end
  133. if #label > width - labelPad then
  134. label = label:sub(1,width - labelPad)
  135. end
  136.  
  137. -- draw label
  138. display.setCursorPos(startColumn + math.floor((width - #label)/2),startRow + math.floor((height-1)/2))
  139. display.write(label)
  140. display.setBackgroundColor(button.defaultBackgroundColor)
  141. display.setTextColor(button.defaultTextColor)
  142. end
  143. button.toggle = function ()
  144. button.isPressed = not button.isPressed
  145. return button.isPressed
  146. end
  147. return button
  148. end
  149.  
  150. function tablelength(T)
  151. local count = 0
  152. for _ in pairs(T) do count = count + 1 end
  153. return count
  154. end
  155.  
  156. function drawSongs()
  157. songNameButtons = {}
  158. for i,song in ipairs(songNames) do
  159. -- First check if its on our page
  160. local lowestSong = currentPage * songsPerPage -- So 0 on page 0, we can use hard > which means the lowestSong+songsPerPage is included on this page and not the next one
  161. if i > lowestSong and i <= lowestSong + songsPerPage then
  162.  
  163. if currentSong == i then
  164. songNameButtons[i] = Button(40,1,song,colors.white,colors.white,colors.black,colors.green,false,colors.white,colors.black,0,i%songsPerPage,false,nil,nil)
  165. else
  166. songNameButtons[i] = Button(40,1,song,colors.black,colors.white,colors.orange,colors.green,false,colors.black,colors.black,0,i%songsPerPage,false,nil,nil)
  167. end
  168. songNameButtons[i].draw(monitor1)
  169. end
  170. end
  171. end
  172.  
  173. function drawScreen(monitor, screenIndex)
  174. monitor.clear()
  175.  
  176. if screenIndex == 0 then
  177. drawSongs()
  178. left.draw(monitor)
  179. right.draw(monitor)
  180. bottom.draw(monitor)
  181. instrumentsButton.label = "Setup"
  182. instrumentsButton.draw(monitor)
  183. pageLabel.label = "Page " .. (currentPage+1) .. "/" .. maxPage
  184. pageLabel.draw(monitor)
  185. elseif screenIndex == 1 then
  186. left.draw(monitor)
  187. right.draw(monitor)
  188. bottom.draw(monitor)
  189. instrumentsButton.label = "Save"
  190. instrumentsButton.draw(monitor)
  191. -- Draw the current song title at the top
  192. monitor.setBackgroundColor(colors.white)
  193. monitor.setTextColor(colors.black)
  194. monitor.setCursorPos(1,1)
  195. monitor.write(songNames[currentSong])
  196.  
  197. -- So we need to build a list of instruments
  198. -- And put the value beside each one
  199. -- And have < and > buttons beside each value to change it
  200. monitor.setBackgroundColor(colors.black)
  201. monitor.setTextColor(colors.white)
  202. for i,name in pairs(varNames) do
  203. monitor.setCursorPos(1,i+2)
  204. monitor.write(name)
  205. end
  206. instrumentLeftButtons = {}
  207. instrumentRightButtons = {}
  208. for i,name in pairs(varValues) do
  209. monitor.setCursorPos(30,i+2)
  210. monitor.write(name)
  211. instrumentLeftButtons[i] = Button(1,1,"<",colors.black,colors.white,colors.orange,colors.green,false,colors.black,colors.black,29,i+2,false,nil,nil)
  212. instrumentRightButtons[i] = Button(1,1,">",colors.black,colors.white,colors.orange,colors.green,false,colors.black,colors.black,38,i+2,false,nil,nil)
  213. instrumentLeftButtons[i].draw(monitor)
  214. instrumentRightButtons[i].draw(monitor)
  215. -- We should also set instrumentIndex; this represents what position in the instruments list the current variable is
  216. for j,k in pairs(instruments) do
  217. if string.lower(k) == string.lower(name) then
  218. instrumentIndex[i] = j
  219. break
  220. end
  221. end
  222. if instrumentIndex[i] == nil then
  223. write("Error: Could not find instrument " .. name)
  224. end
  225. end
  226. end
  227. end
  228.  
  229. function saveData()
  230. -- Using songNames[currentSong], saves a file with that name
  231. -- Writes serialized varNames and varValues
  232. local writer = fs.open(songs[currentSong], "w")
  233. -- The data really should stay like this but too late now...
  234. -- I want to crunch it into one array
  235. -- ... But I can't do that because then I can't guarantee the order
  236. writer.writeLine(textutils.serialize(varNames))
  237. writer.close()
  238. writer = fs.open(songs[currentSong] .. "1", "w")
  239. writer.writeLine(textutils.serialize(varValues))
  240. writer.close()
  241. end
  242.  
  243. function readData()
  244. -- Using songNames[currentSong], reads a file with that name
  245. -- Reads serialized varNames and varValues
  246. if(fs.exists(songs[currentSong]) and fs.exists(songs[currentSong] .. "1")) then
  247. varNames = {}
  248. varValues = {}
  249. local reader = fs.open(songs[currentSong], "r")
  250. varNames = textutils.unserialize(reader.readAll())
  251. reader.close()
  252. reader = fs.open(songs[currentSong] .. "1", "r")
  253. varValues = textutils.unserialize(reader.readAll())
  254. return true
  255. end
  256. return false
  257. end
  258.  
  259. function changeToNewSong(toggleOnly)
  260. -- Using currentSong, sends a Stop request if playing, then Starts a new song
  261. if playing then
  262. playing = false
  263. rednet.send(targetid,"stop")
  264. if toggleOnly then
  265. return
  266. end
  267. end
  268. playing = true
  269. rednet.send(targetid,songs[currentSong])
  270. -- Directly wait for the responses, there should be two arrays sent back
  271. local id,msg = rednet.receive(1) -- Max out at 1 second tho, just in case
  272. local tempNames = textutils.unserialize(msg)
  273. local id,msg = rednet.receive(1)
  274. local tempValues = textutils.unserialize(msg)
  275. if readData() then -- Check if we have saved values
  276. if tempValues ~= varValues then
  277. for i,v in pairs(varValues) do
  278. if(v ~= tempValues[i]) then
  279. rednet.send(id,"changeinstrument:" .. tempNames[i] .. ":" .. v)
  280. end
  281. end
  282. end
  283. else
  284. -- We had no data, so store what they gave us
  285. varNames = tempNames
  286. varValues = tempValues
  287. end
  288. end
  289.  
  290. -- Start of test Program
  291.  
  292. instrumentIndex = {} -- Contains the index of the instruments list that is currently selected
  293.  
  294. instrumentLeftButtons = {}
  295. instrumentRightButtons = {} -- Indexed by the variable it would adjust
  296.  
  297. varNames = {}
  298. varValues = {}
  299.  
  300. monitor1 = peripheral.wrap("back")
  301. screenNum = 0 -- Indicates what to display on screen
  302.  
  303. left= Button(4,3,"<<",colors.green,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,1,30,false,nil,nil)
  304. right = Button(4,3,">>",colors.green,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,36,30,false,nil,nil)
  305. bottom = Button(29,3,"Play",colors.lime,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,6,30,false,nil,nil)
  306.  
  307. pageLabel = Button(40,1,"Page 1/1",colors.black,colors.black,colors.orange,colors.orange,false,colors.orange,colors.orange,1,29,false,nil,nil)
  308.  
  309. instrumentsButton = Button(40,1,"Setup",colors.orange,colors.red,colors.black,colors.lime,false,colors.orange,colors.pink,1,33,false,nil,nil)
  310.  
  311. songs = {"Megalovania"}
  312. songNames = {"Undertale - Megalovania"}
  313.  
  314. instruments = {"Harp","Bass","Pling","Bell","Chime","Flute","Guitar","Xylophone","BaseDrum","Hat","Snare"}
  315.  
  316. songNameButtons = {}
  317.  
  318. currentSong = 1
  319. currentPage = 0
  320. songsPerPage = 27
  321.  
  322. maxPage = math.ceil(tablelength(songNames)/songsPerPage)
  323.  
  324. -- Display buttons on monitor1
  325.  
  326. -- And text I guess
  327.  
  328. drawScreen(monitor1,screenNum)
  329.  
  330.  
  331. rednet.open("left")
  332. targetid = 0
  333.  
  334. playing = false
  335.  
  336. -- this is our event loop
  337. while true do
  338. event ={os.pullEvent()}
  339. -- Check for signal to go to next song
  340. if playing and event[1] =="rednet_message" then
  341. if event[3] == "done" and playing then
  342. currentSong = currentSong + 1
  343. if currentSong > tablelength(songNames) then
  344. currentSong = 1
  345. end
  346. changeToNewSong()
  347. drawScreen(monitor1,screenNum)
  348. end
  349. end
  350. if event[1] =="monitor_touch" then
  351. if left.clicked(event[3],event[4]) then
  352. currentPage = currentPage - 1
  353. if currentPage < 0 then
  354. currentPage = maxPage-1
  355. end
  356. elseif right.clicked(event[3],event[4]) then
  357. currentPage = currentPage + 1
  358. if currentPage >= maxPage then
  359. currentPage = 0
  360. end
  361. elseif bottom.clicked(event[3],event[4]) then
  362. changeToNewSong(true) -- Plays or stops as appropriate
  363. elseif instrumentsButton.clicked(event[3],event[4]) then
  364. -- Swap screens...
  365. if screenNum == 0 then
  366. screenNum = 1
  367. elseif screenNum == 1 then
  368. screenNum = 0
  369. -- Save our song data
  370. saveData()
  371. end
  372. -- drawScreen(monitor1,screenNum)
  373. elseif screenNum == 1 then
  374. for i,v in pairs(instrumentLeftButtons) do
  375. if(v.clicked(event[3],event[4])) then
  376. -- Cycle 1 instrument left for this index and send rednet command to change it
  377. instrumentIndex[i] = instrumentIndex[i]-1
  378. if instrumentIndex[i] <= 0 then
  379. instrumentIndex[i] = tablelength(instruments)
  380. end
  381. varValues[i] = instruments[instrumentIndex[i]]
  382. rednet.send(targetid,"changeinstrument:" .. varNames[i] .. ":" .. varValues[i])
  383. break
  384. end
  385. end
  386. for i,v in pairs(instrumentRightButtons) do
  387. if(v.clicked(event[3],event[4])) then
  388. -- Cycle 1 instrument right for this index and send rednet command to change it
  389. instrumentIndex[i] = instrumentIndex[i]+1
  390. if instrumentIndex[i] > tablelength(instruments) then
  391. instrumentIndex[i] = 1
  392. end
  393. varValues[i] = instruments[instrumentIndex[i]]
  394. rednet.send(targetid,"changeinstrument:" .. varNames[i] .. ":" .. varValues[i])
  395. break
  396. end
  397. end
  398. else
  399. for i,v in pairs(songNameButtons) do
  400. if(v.clicked(event[3],event[4])) then
  401. -- Set the selected index to this index and do play things
  402. currentSong = i
  403. if playing then changeToNewSong() end
  404. break
  405. end
  406. end
  407.  
  408. end
  409. -- Redraw songs
  410. drawScreen(monitor1,screenNum)
  411.  
  412. end
  413. end
Advertisement
Add Comment
Please, Sign In to add comment