· 6 years ago · Apr 05, 2020, 12:14 PM
1os.loadAPI("nbs") -- load the API
2
3local function endsWith(input, endPattern)
4 if input == nil or (not type(string) == string) then
5 return false
6 else
7 local length = string.len(input)
8 if endPattern == nil or (not type(endPattern) == string) then
9 return false
10 else
11 local patternLength = string.len(endPattern)
12 local inputEnd = string.sub(input, 0 - string.len(endPattern))
13
14 if inputEnd == endPattern then
15 return true
16 else
17 return false
18 end
19 end
20 end
21end
22
23local function getSongNames(dirPath)
24 if fs.isDir(dirPath) then
25 files = fs.list(dirPath)
26 songFiles = {}
27 local i = 1
28
29 for key, value in pairs(files) do
30 if endsWith(value, ".nbs") then
31 songFiles[i] = value
32 i = i + 1
33 end
34 end
35
36 return songFiles
37 else
38 return nil
39 end
40end
41
42local function printSongLabel(monitor, text, maxLength, x, y)
43 text = string.sub(text, 1, maxLength)
44
45 for j = 0, 2, 1 do
46 monitor.setCursorPos(x, y + j)
47 for i = 1, maxLength + 2, 1 do
48 monitor.write(" ")
49 end
50 end
51
52 local shiftX = math.floor((maxLength - string.len(text)) / 2)
53
54 monitor.setCursorPos(x + 1 + shiftX, y + 1)
55 monitor.write(text)
56end
57
58local function getSelectedIdx(monitor, maxFileNameLength, pageNumber, x, y)
59 if x == nil or y == nil then
60 return nil
61 end
62
63 local sizeX, sizeY = monitor.getSize()
64 local songsPerRow = math.floor(sizeX / (maxFileNameLength + 4))
65 local songsPerColumn = math.floor(sizeY / 5)
66 local songsPerPage = songsPerRow * songsPerColumn
67 local shiftX = math.floor((sizeX - songsPerRow * (maxFileNameLength + 4)) / 2)
68 local shiftY = math.floor((sizeY - songsPerColumn * 5) / 2)
69
70 local col = nil
71 local row = nil
72
73 local xStart = nil
74 for k = 1, songsPerRow, 1 do
75 xStart = 2 + shiftX + (k-1) * (maxFileNameLength + 4)
76 if x >= xStart and x <= xStart + maxFileNameLength + 2 then
77 col = k
78 end
79 end
80
81 local yStart = nil
82 for k = 1, songsPerColumn, 1 do
83 yStart = 2 + shiftY + (k - 1) * 5
84 if y >= yStart and y <= yStart + 2 then
85 row = k
86 end
87 end
88
89 if col and row then
90 local selectedIdx = (pageNumber - 1) * songsPerPage + (col - 1) * songsPerColumn + row
91 return selectedIdx
92 end
93 return nil
94end
95
96local function updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber, selectedIdx)
97 monitor.clear()
98 local sizeX, sizeY = monitor.getSize()
99 local songsPerRow = math.floor(sizeX / (maxFileNameLength + 4))
100 local songsPerColumn = math.floor(sizeY / 5)
101 local songsPerPage = songsPerRow * songsPerColumn
102 local firstSongIdx = 1
103
104 if selectedIdx then
105 firstSongIdx = math.floor(selectedIdx / songsPerPage) + 1
106 end
107
108 local x = 1
109 local y = 1
110 local shiftX = math.floor((sizeX - songsPerRow * (maxFileNameLength + 4)) / 2)
111 local shiftY = math.floor((sizeY - songsPerColumn * 5) / 2)
112
113 local defaultBgColor = colors.lightGray
114 local selectedBgColor = colors.lime
115
116 local k = 1
117 for i = firstSongIdx, firstSongIdx + songsPerPage - 1, 1 do
118 if i == selectedIdx then
119 monitor.setBackgroundColor(selectedBgColor)
120 else
121 monitor.setBackgroundColor(defaultBgColor)
122 end
123
124 x = 2 + shiftX + math.floor((k - 1) / songsPerColumn) * (maxFileNameLength + 4)
125 y = 2 + shiftY + ((k - 1) % songsPerColumn) * 5
126
127 if songFiles[i] then
128 printSongLabel(monitor, songFiles[i], maxFileNameLength, x, y)
129 end
130
131 k = k + 1
132 end
133
134 monitor.setBackgroundColor(colors.black)
135end
136
137local modemSide, monitorSide = ...
138
139rednet.open(modemSide)
140local monitor = peripheral.wrap(monitorSide)
141monitor.setTextScale(1)
142monitor.clear()
143
144local maxFileNameLength = 16
145local pageNumber = 1
146local selectedIdx = nil
147local selectedSong = nil
148
149local songFiles = getSongNames("music")
150
151updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber)
152
153while true do
154 event, par1, x, y = os.pullEvent("monitor_touch")
155 selectedIdx = getSelectedIdx(monitor, maxFileNameLength, pageNumber, x, y)
156
157 if selectedIdx then
158 selectedSong = songFiles[selectedIdx]
159 if selectedSong then
160 updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber, selectedIdx)
161 nbs.play("music/"..selectedSong, modemSide, 3, true)
162 updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber)
163 end
164 end
165end