Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function Button(
- width,
- height,
- label,
- backgroundColorNormal,
- backgroundColorPressed,
- textColorNormal,
- textColorPressed,
- hasBorder,
- borderColorNormal,
- borderColorPressed,
- startColumn,
- startRow,
- isPressed,
- defaultBackgroundColor,
- defaultTextColor
- )
- local button = {}
- button.height=height or 1
- button.width=width or 1
- button.label=label or ""
- button.backgroundColorNormal=backgroundColorNormal or colors.black
- button.backgroundColorPressed=backgroundColorPressed or colors.white
- button.textColorNormal=textColorNormal or colors.white
- button.textColorPressed=textColorPressed or colors.black
- button.hasBorder = hasBorder or false
- button.borderColorNormal = borderColorNormal or backGroundColorNormal
- button.borderColorPressed = borderColorPressed or backGroundColorPressed
- button.defaultBackgroundColor = defaultBackgroundColor or colors.black
- button.defaultTextColor = defaultTextColor or colors.white
- button.startColumn = startColumn or 1
- button.startRow = startRow or 1
- button.isPressed=isPressed or false
- function button.press()
- button.isPressed = not button.isPressed
- end
- function button.clicked(column,row)
- return (column >= button.startColumn and column < button.startColumn + button.width and row >= button.startRow and row < button.startRow + button.height)
- end
- function button.draw(display,isPressed,startColumn,startRow)
- button.startColumn = startColumn or button.startColumn
- button.startRow = startRow or button.startRow
- display = display or term
- if isPressed == false or isPressed then
- button.isPressed = isPressed
- else isPressed = button.isPressed
- end
- local width = button.width
- local height = button.height
- startRow = button.startRow
- startColumn = button.startColumn
- local label = button.label
- local labelPad = 2
- -- set border params and draw border if hasBorder
- if button.hasBorder == true then
- -- button must be at least 3x3, if not, make it so
- if width < 3 then
- width = 3
- end
- if height < 3 then
- height = 3
- end
- -- set border colors
- if not isPressed then
- if not display.isColor() then
- display.setBackgroundColor(colors.white)
- else
- display.setBackgroundColor(button.borderColorNormal)
- end
- else
- if not display.isColor() then
- display.setBackgroundColor(colors.white)
- else
- display.setBackgroundColor(button.borderColorPressed)
- end
- end
- -- draw button border (inset)
- display.setCursorPos(startColumn,startRow)
- display.write(string.rep(" ",width))
- for row = 2,height-1 do
- display.setCursorPos(startColumn,button.startRow+row -1)
- display.write(" ")
- display.setCursorPos(startColumn+width -1 ,startRow + row-1)
- display.write(" ")
- end
- display.setCursorPos(startColumn,startRow+height-1)
- display.write(string.rep(" ",width))
- -- reset startColumn,startRow,width,column to inset button and label
- startColumn=startColumn+1
- startRow = startRow +1
- width = width - 2
- height = height - 2
- end
- --set button background and text colors
- if not isPressed then
- if not display.isColor() then
- display.setBackgroundColor(colors.black)
- display.setTextColor(colors.white)
- else
- display.setBackgroundColor(button.backgroundColorNormal)
- display.setTextColor(button.textColorNormal)
- end
- else
- if not display.isColor() then
- display.setBackgroundColor(colors.white)
- display.setTextColor(colors.black)
- else
- display.setBackgroundColor(button.backgroundColorPressed)
- display.setTextColor(button.textColorPressed)
- end
- end
- -- draw button background (will be inside border if there is one)
- for row = 1,height do
- --print(tostring(startColumn)..","..tostring(startRow-row))
- display.setCursorPos(startColumn,startRow + row -1)
- display.write(string.rep(" ",width))
- end
- -- prepare label, truncate label if necessary
- -- prepare label, truncate label if necessary
- if width < 3 then
- labelPad = 0
- end
- if #label > width - labelPad then
- label = label:sub(1,width - labelPad)
- end
- -- draw label
- display.setCursorPos(startColumn + math.floor((width - #label)/2),startRow + math.floor((height-1)/2))
- display.write(label)
- display.setBackgroundColor(button.defaultBackgroundColor)
- display.setTextColor(button.defaultTextColor)
- end
- button.toggle = function ()
- button.isPressed = not button.isPressed
- return button.isPressed
- end
- return button
- end
- function tablelength(T)
- local count = 0
- for _ in pairs(T) do count = count + 1 end
- return count
- end
- function drawSongs()
- songNameButtons = {}
- for i,song in ipairs(songNames) do
- -- First check if its on our page
- 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
- if i > lowestSong and i <= lowestSong + songsPerPage then
- if currentSong == i then
- 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)
- else
- 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)
- end
- songNameButtons[i].draw(monitor1)
- end
- end
- end
- function drawScreen(monitor, screenIndex)
- monitor.clear()
- if screenIndex == 0 then
- drawSongs()
- left.draw(monitor)
- right.draw(monitor)
- bottom.draw(monitor)
- instrumentsButton.label = "Setup"
- instrumentsButton.draw(monitor)
- pageLabel.label = "Page " .. (currentPage+1) .. "/" .. maxPage
- pageLabel.draw(monitor)
- elseif screenIndex == 1 then
- left.draw(monitor)
- right.draw(monitor)
- bottom.draw(monitor)
- instrumentsButton.label = "Save"
- instrumentsButton.draw(monitor)
- -- Draw the current song title at the top
- monitor.setBackgroundColor(colors.white)
- monitor.setTextColor(colors.black)
- monitor.setCursorPos(1,1)
- monitor.write(songNames[currentSong])
- -- So we need to build a list of instruments
- -- And put the value beside each one
- -- And have < and > buttons beside each value to change it
- monitor.setBackgroundColor(colors.black)
- monitor.setTextColor(colors.white)
- for i,name in pairs(varNames) do
- monitor.setCursorPos(1,i+2)
- monitor.write(name)
- end
- instrumentLeftButtons = {}
- instrumentRightButtons = {}
- for i,name in pairs(varValues) do
- monitor.setCursorPos(30,i+2)
- monitor.write(name)
- instrumentLeftButtons[i] = Button(1,1,"<",colors.black,colors.white,colors.orange,colors.green,false,colors.black,colors.black,29,i+2,false,nil,nil)
- instrumentRightButtons[i] = Button(1,1,">",colors.black,colors.white,colors.orange,colors.green,false,colors.black,colors.black,38,i+2,false,nil,nil)
- instrumentLeftButtons[i].draw(monitor)
- instrumentRightButtons[i].draw(monitor)
- -- We should also set instrumentIndex; this represents what position in the instruments list the current variable is
- for j,k in pairs(instruments) do
- if string.lower(k) == string.lower(name) then
- instrumentIndex[i] = j
- break
- end
- end
- if instrumentIndex[i] == nil then
- write("Error: Could not find instrument " .. name)
- end
- end
- end
- end
- function saveData()
- -- Using songNames[currentSong], saves a file with that name
- -- Writes serialized varNames and varValues
- local writer = fs.open(songs[currentSong], "w")
- -- The data really should stay like this but too late now...
- -- I want to crunch it into one array
- -- ... But I can't do that because then I can't guarantee the order
- writer.writeLine(textutils.serialize(varNames))
- writer.close()
- writer = fs.open(songs[currentSong] .. "1", "w")
- writer.writeLine(textutils.serialize(varValues))
- writer.close()
- end
- function readData()
- -- Using songNames[currentSong], reads a file with that name
- -- Reads serialized varNames and varValues
- if(fs.exists(songs[currentSong]) and fs.exists(songs[currentSong] .. "1")) then
- varNames = {}
- varValues = {}
- local reader = fs.open(songs[currentSong], "r")
- varNames = textutils.unserialize(reader.readAll())
- reader.close()
- reader = fs.open(songs[currentSong] .. "1", "r")
- varValues = textutils.unserialize(reader.readAll())
- return true
- end
- return false
- end
- function changeToNewSong(toggleOnly)
- -- Using currentSong, sends a Stop request if playing, then Starts a new song
- if playing then
- playing = false
- rednet.send(targetid,"stop")
- if toggleOnly then
- return
- end
- end
- playing = true
- rednet.send(targetid,songs[currentSong])
- -- Directly wait for the responses, there should be two arrays sent back
- local id,msg = rednet.receive(1) -- Max out at 1 second tho, just in case
- local tempNames = textutils.unserialize(msg)
- local id,msg = rednet.receive(1)
- local tempValues = textutils.unserialize(msg)
- if readData() then -- Check if we have saved values
- if tempValues ~= varValues then
- for i,v in pairs(varValues) do
- if(v ~= tempValues[i]) then
- rednet.send(id,"changeinstrument:" .. tempNames[i] .. ":" .. v)
- end
- end
- end
- else
- -- We had no data, so store what they gave us
- varNames = tempNames
- varValues = tempValues
- end
- end
- -- Start of test Program
- instrumentIndex = {} -- Contains the index of the instruments list that is currently selected
- instrumentLeftButtons = {}
- instrumentRightButtons = {} -- Indexed by the variable it would adjust
- varNames = {}
- varValues = {}
- monitor1 = peripheral.wrap("back")
- screenNum = 0 -- Indicates what to display on screen
- left= Button(4,3,"<<",colors.green,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,1,30,false,nil,nil)
- right = Button(4,3,">>",colors.green,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,36,30,false,nil,nil)
- bottom = Button(29,3,"Play",colors.lime,colors.red,colors.black,colors.yellow,true,colors.gray,colors.pink,6,30,false,nil,nil)
- 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)
- instrumentsButton = Button(40,1,"Setup",colors.orange,colors.red,colors.black,colors.lime,false,colors.orange,colors.pink,1,33,false,nil,nil)
- songs = {"Megalovania"}
- songNames = {"Undertale - Megalovania"}
- instruments = {"Harp","Bass","Pling","Bell","Chime","Flute","Guitar","Xylophone","BaseDrum","Hat","Snare"}
- songNameButtons = {}
- currentSong = 1
- currentPage = 0
- songsPerPage = 27
- maxPage = math.ceil(tablelength(songNames)/songsPerPage)
- -- Display buttons on monitor1
- -- And text I guess
- drawScreen(monitor1,screenNum)
- rednet.open("right")
- targetid = 0
- playing = false
- -- this is our event loop
- while true do
- event ={os.pullEvent()}
- -- Check for signal to go to next song
- if playing and event[1] =="rednet_message" then
- if event[3] == "done" and playing then
- currentSong = currentSong + 1
- if currentSong > tablelength(songNames) then
- currentSong = 1
- end
- changeToNewSong()
- drawScreen(monitor1,screenNum)
- end
- end
- if event[1] =="monitor_touch" then
- if left.clicked(event[3],event[4]) then
- currentPage = currentPage - 1
- if currentPage < 0 then
- currentPage = maxPage-1
- end
- elseif right.clicked(event[3],event[4]) then
- currentPage = currentPage + 1
- if currentPage >= maxPage then
- currentPage = 0
- end
- elseif bottom.clicked(event[3],event[4]) then
- changeToNewSong(true) -- Plays or stops as appropriate
- elseif instrumentsButton.clicked(event[3],event[4]) then
- -- Swap screens...
- if screenNum == 0 then
- screenNum = 1
- elseif screenNum == 1 then
- screenNum = 0
- -- Save our song data
- saveData()
- end
- -- drawScreen(monitor1,screenNum)
- elseif screenNum == 1 then
- for i,v in pairs(instrumentLeftButtons) do
- if(v.clicked(event[3],event[4])) then
- -- Cycle 1 instrument left for this index and send rednet command to change it
- instrumentIndex[i] = instrumentIndex[i]-1
- if instrumentIndex[i] <= 0 then
- instrumentIndex[i] = tablelength(instruments)
- end
- varValues[i] = instruments[instrumentIndex[i]]
- rednet.send(targetid,"changeinstrument:" .. varNames[i] .. ":" .. varValues[i])
- break
- end
- end
- for i,v in pairs(instrumentRightButtons) do
- if(v.clicked(event[3],event[4])) then
- -- Cycle 1 instrument right for this index and send rednet command to change it
- instrumentIndex[i] = instrumentIndex[i]+1
- if instrumentIndex[i] > tablelength(instruments) then
- instrumentIndex[i] = 1
- end
- varValues[i] = instruments[instrumentIndex[i]]
- rednet.send(targetid,"changeinstrument:" .. varNames[i] .. ":" .. varValues[i])
- break
- end
- end
- else
- for i,v in pairs(songNameButtons) do
- if(v.clicked(event[3],event[4])) then
- -- Set the selected index to this index and do play things
- currentSong = i
- if playing then changeToNewSong() end
- break
- end
- end
- end
- -- Redraw songs
- drawScreen(monitor1,screenNum)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment