· 6 years ago · Apr 01, 2020, 07:18 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 endIndex = length - patternLength + 1
13 local inputEnd = string.sub(input, endIndex)
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 + 1)
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 print(x.." "..y)
74
75 local xStart = nil
76 for k = 1, songsPerRow, 1 do
77 xStart = 2 + shiftX + (k-1) * (maxFileNameLength + 4)
78 print(xStart)
79 if x >= xStart and x <= xStart + maxFileNameLength + 2 then
80 col = k
81 end
82 end
83
84 local yStart = nil
85 for k = 1, songsPerColumn, 1 do
86 yStart = 2 + shiftY + (k - 1) * 5
87 print(yStart)
88 if y >= yStart and y <= yStart + 2 then
89 row = k
90 end
91 end
92
93 if col and row then
94 local selectedIdx = (pageNumber - 1) * songsPerPage + (col - 1) * songsPerColumn + row
95 return selectedIdx
96 end
97 return nil
98end
99
100local function updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber, selectedIdx)
101 monitor.clear()
102 local sizeX, sizeY = monitor.getSize()
103 local songsPerRow = math.floor(sizeX / (maxFileNameLength + 4))
104 local songsPerColumn = math.floor(sizeY / 5)
105 local songsPerPage = songsPerRow * songsPerColumn
106 local firstSongIdx = 1
107
108 if selectedIdx then
109 firstSongIdx = math.floor(selectedIdx / songsPerPage) + 1
110 end
111
112 local x = 1
113 local y = 1
114 local shiftX = math.floor((sizeX - songsPerRow * (maxFileNameLength + 4)) / 2)
115 local shiftY = math.floor((sizeY - songsPerColumn * 5) / 2)
116
117 local defaultBgColor = colors.lightGray
118 local selectedBgColor = colors.lime
119
120 local k = 1
121 for i = firstSongIdx, firstSongIdx + songsPerPage - 1, 1 do
122 if i == selectedIdx then
123 monitor.setBackgroundColor(selectedBgColor)
124 else
125 monitor.setBackgroundColor(defaultBgColor)
126 end
127
128 x = 2 + shiftX + math.floor((k - 1) / songsPerColumn) * (maxFileNameLength + 4)
129 y = 2 + shiftY + ((k - 1) % songsPerColumn) * 5
130
131 if songFiles[i] then
132 printSongLabel(monitor, songFiles[i], maxFileNameLength, x, y)
133 end
134
135 k = k + 1
136 end
137
138 monitor.setBackgroundColor(colors.black)
139end
140
141local side = ...
142
143local monitor = peripheral.wrap(side)
144monitor.setTextScale(1)
145monitor.clear()
146
147local maxFileNameLength = 16
148local pageNumber = 1
149local selectedIdx = nil
150local selectedSong = nil
151
152local songFiles = getSongNames("music")
153
154updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber)
155
156while true do
157 event, par1, x, y = os.pullEvent("monitor_touch")
158 selectedIdx = getSelectedIdx(monitor, maxFileNameLength, pageNumber, x, y)
159
160 if selectedIdx then
161 selectedSong = songFiles[selectedIdx]
162 if selectedSong then
163 updateMonitor(monitor, songFiles, maxFileNameLength, pageNumber, selectedIdx)
164 nbs.play("music/"..selectedSong, side, 3, true)
165 end
166 end
167end