· 6 years ago · Jan 21, 2020, 02:26 AM
1--Title: Dark buttons
2Version = 1.231
3--Author: Darkrising (minecraft name djhannz)
4--Platform: ComputerCraft Lua Virtual Machine
5if not term.isColour() then
6 print("Requires an Advanced Computer and an Advanced monitor.")
7 return
8end
9if fs.exists("dark") == false then -- load darkAPI
10 print("Missing DarkAPI")
11 print("Attempting to download...")
12 if not http then
13 error("Enable the HTTP API to download DarkAPI")
14 end
15 getGit = http.get("https://raw.github.com/darkrising/darkprograms/darkprograms/api/dark.lua")
16 getGit = getGit.readAll()
17 file = fs.open("dark", "w")
18 file.write(getGit)
19 file.close()
20end
21os.loadAPI("dark")
22
23monSids = {} -- stores monitor sides
24buttons = {} -- stores buttons data
25c = colors.combine() -- Default var for wires
26AutoUpdate = true
27
28--General Functions
29function Header(text, lText, rText) -- builds a header using functions above from <text>
30 local x,y = term.getSize()
31 dark.printL("-", 1, nil, "blue", "blue")
32 dark.printC(string.rep(" ", x+1), 2, nil, "white", "blue")
33 dark.printC(text, 2, nil, "white", "blue")
34 dark.printL("-", 3, 5, "blue", "blue")
35end
36function saveState()
37 dark.db.save("state", buttons)
38end
39function LoadState()
40 if fs.exists("state") == true then
41 buttons = dark.db.load("state")
42 end
43 for name, data in pairs(buttons) do
44 if data["active"] == true then
45 c = colors.combine(c, data.wireCol)
46 print(data.wireCol)
47 rs.setBundledOutput(options.wireSide, c)
48 end
49 end
50end
51function getMonitors()
52 monSids = {}
53 if peripheral.getNames then
54 for i,v in pairs(peripheral.getNames()) do
55 if string.sub(v,1,7) == "monitor" then
56 table.insert(monSids, v)
57 end
58 end
59 end
60 for i,v in pairs(rs.getSides()) do
61 if peripheral.isPresent(v) and peripheral.getType(v) == "monitor" then
62 table.insert(monSids, v)
63 end
64 end
65end
66function clearMonitors()
67 for i=1,#monSids do
68 monitor = peripheral.wrap(monSids[i])
69 monitor.clear()
70 end
71end
72function createStaticbuttons(name,xmin,xmax,ymin,ymax,tCol,bgCol,actCol,bside,wireCol)
73 buttons[name] = {}
74 buttons[name].active = false
75 buttons[name].xmin = xmin
76 buttons[name].ymin = ymin
77 buttons[name].xmax = xmax
78 buttons[name].ymax = ymax
79 buttons[name].side = bside
80 buttons[name].wireCol = colors[wireCol] -- bundled cable wire colour
81 buttons[name].tCol = colors[tCol] --Text color
82 buttons[name].bgCol = colors[bgCol] --Background color (non-active)
83 buttons[name].actCol = colors[actCol] --Active color (background active)
84end
85function drawBox(xmin,xmax,ymin,ymax,bgCol)
86 mon.setBackgroundColor(bgCol)
87 for i = ymin, ymax do
88 for j = xmin, xmax do
89 mon.setCursorPos(j, i)
90 mon.write(" ")
91 end
92 end
93 mon.setBackgroundColor(colors.black)
94end
95function boxText(text,xmin,xmax,ymin,ymax,tCol,bgCol)
96 thex = (((xmax - xmin) / 2) + xmin) - (#text / 2)
97 they = (ymin + ymax) / 2
98 mon.setCursorPos(thex , they)
99 mon.setTextColor(tCol)
100 mon.setBackgroundColor(bgCol)
101 mon.write(text)
102 mon.setTextColor(colors.white)
103 mon.setBackgroundColor(colors.black)
104end
105function textBox(text,xmin,xmax,ymin,ymax,tCol,bgCol)
106 drawBox(xmin,xmax,ymin,ymax,bgCol)
107 boxText(text,xmin,xmax,ymin,ymax,tCol,bgCol)
108end
109function draw()
110 getMonitors()
111 for i,v in pairs(monSids) do
112 mon = peripheral.wrap(v)
113 mon.clear()
114 end
115 for name, data in pairs(buttons) do
116 if peripheral.wrap(data.side) then
117 mon = peripheral.wrap(data.side)
118 x,y = mon.getSize()
119 if data.active == true then
120 textBox(name,data.xmin,data.xmax,data.ymin,data.ymax,data.tCol,data.actCol)
121 else
122 textBox(name,data.xmin,data.xmax,data.ymin,data.ymax,data.tCol,data.bgCol)
123 end
124 end
125 end
126end
127function checkerboard()
128 getMonitors()
129 for i,v in pairs(monSids) do
130 mon = peripheral.wrap(v)
131 local mx, my = mon.getSize()
132 if mon.isColor() then mon.setTextColor(colors.gray) end
133 for i = 1, my do
134 mon.setCursorPos(1,i)
135 mon.write(string.rep("X", mx))
136 end
137 if mon.isColor() then mon.setTextColor(colors.white) end
138 end
139 for name, data in pairs(buttons) do
140 mon = peripheral.wrap(data.side)
141 x,y = mon.getSize()
142 if data.active == true then
143 textBox(name,data.xmin,data.xmax,data.ymin,data.ymax,data.tCol,data.actCol)
144 else
145 textBox(name,data.xmin,data.xmax,data.ymin,data.ymax,data.tCol,data.bgCol)
146 end
147 end
148end
149function check(hx,hy,Side)
150 for name, data in pairs(buttons) do
151 if Side == data.side then
152 if hy>=data.ymin and hy<=data.ymax then
153 if hx>=data.xmin and hx<=data.xmax then
154 data.active = not data.active
155 if data.active == true then
156 c = colors.combine(c, data.wireCol)
157 else
158 c = colors.subtract(c, data.wireCol)
159 end
160 rs.setBundledOutput(options.wireSide, c)
161 return true
162 end
163 end
164 end
165 end
166 return false
167end
168--looping functions
169function terminalMenu()
170 while true do
171 term.clear()
172 term.setCursorPos(1,1)
173 Header("Running DarkButtons V"..Version)
174 print("Please press a key to select an option.")
175 print("\n[1] Add a button")
176 print("[2] Remove a button")
177 _,char = os.pullEvent()
178 if char == "1" then
179 os.queueEvent("stop")
180 wizard("add")
181 os.queueEvent("start")
182 elseif char == "2" then
183 os.queueEvent("stop")
184 wizard("remove")
185 os.queueEvent("start")
186 end
187 end
188end
189function stealthUpdate()
190 if AutoUpdate == true then
191 if ((dark.gitUpdate("darkbuttons", shell.getRunningProgram(), Version) == true) or (dark.gitUpdate("dark", "dark", dark.DARKversion) == true)) then
192 os.reboot()
193 end
194 end
195 return
196end
197function breakListen()
198 while true do
199 os.pullEvent("monitor_resize")
200 draw()
201 end
202end
203function hitListen()
204 while true do
205 draw()
206 Event,Side,hx,hy = os.pullEvent()
207 if Event == "monitor_touch" then
208 getMonitors()
209 check(hx,hy,Side)
210 draw()
211 saveState()
212 elseif Event == "stop" then
213 os.pullEvent("start")
214 end
215 end
216end
217--Wizard
218function wizard(mode)
219 function monWrite(text,mx,my)
220 mon.setCursorPos(mx,my)
221 mon.write(text)
222 end
223 function rButton(side,txd,tyd,txu,tyu)
224 -- reverse incase they hit bottom first
225 if txd > txu then
226 temp = txd
227 txd = txu
228 txu = temp
229 end
230 if tyd > tyu then
231 temp = tyd
232 tyd = tyu
233 tyu = temp
234 end
235 textBox("?",txd,txu,tyd,tyu,colors.white,colors.red)
236 end
237 function checkTemp(hx,hy,xmin,xmax,ymin,ymax)
238 if hy>=ymin and hy<=ymax then
239 if hx>=xmin and hx<=xmax then
240 return true
241 end
242 end
243 end
244 function drawX(mx,my)
245 mon.setCursorPos(mx,my)
246 mon.setTextColor(colors.lime)
247 mon.write("X")
248 mon.setTextColor(colors.white)
249 end
250 function rainbow(line)
251 local order = {}
252 local function drawPixyel(pxy,py,color)
253 term.setCursorPos(xy,py)
254 term.setBackgroundColor(colors[color5])
255 term.write(" ")
256 term.setBackgroundColor(colors.black)
257 end
258 xy = 1
259 for name,v in pairs(colors) do
260 if name == "subtract" or name == "combine" or name == "test" then
261 else
262 drawPixyel(xy, line, name)
263 table.insert(order,name)
264 xy = xy + 1
265 end
266 end
267 return order
268 end
269 function addButton_terminalPart()
270 function waitForClick(bOrder)
271 repeat
272 _,_,lx,ly = os.pullEvent("mouse_click")
273 until lx>0 and lx<17 and ly==1
274 return bOrder[lx]
275 end
276 function waitForExitClick()
277 _,_,lx,ly = os.pullEvent("mouse_click")
278 if ly == y-1 then
279 return true
280 else
281 return false
282 end
283 end
284 function boxesColors()
285 dark.cs()
286 color2 = "white"
287 bOrder = rainbow(1)
288 print(" <- Click one to select!")
289
290 term.setCursorPos(1,3)
291 print("Inactive button background colour. ")
292 color = waitForClick(bOrder)
293
294 term.setCursorPos(1,3)
295 print("Text colour. ")
296 color2 = waitForClick(bOrder)
297
298 term.setCursorPos(1,5)
299 print("Inactive button")
300 textBox("Test Box",1,x,6,8,colors[color2],colors[color])
301
302 term.setCursorPos(1,3)
303 print("Button activate background colour. ")
304 color3 = waitForClick(bOrder)
305
306 term.setCursorPos(1,10)
307 print("Active button")
308 textBox("Test Box",1,x,11,13,colors[color2],colors[color3])
309
310 term.setCursorPos(1,3)
311 print(" ")
312
313 term.setCursorPos(1,y-1)
314 write("Click ")
315 term.setTextColor(colors.yellow)
316 write("here ")
317 term.setTextColor(colors.white)
318 write("to confirm colours")
319 term.setCursorPos(1,y)
320 write("Else click here to choose again")
321 end
322 mon = term
323 x,y = term.getSize()
324 repeat
325 boxesColors()
326 happy = waitForExitClick()
327 until happy == true
328 dark.cs()
329 happy = false
330 print("Text on the button: ")
331 print("\nNote: This is the text that appears on the button, type it in and then press enter.")
332 term.setCursorPos(20,1)
333 bText = read()
334 repeat
335 dark.cs()
336 bOrder = rainbow(1)
337 term.setCursorPos(1,2)
338 write("Wire color for this button: ")
339 wireCol = waitForClick(bOrder)
340
341 term.setCursorPos(28,2)
342 term.setTextColor(colors[wireCol])
343 write(wireCol)
344 term.setTextColor(colors.white)
345
346 term.setCursorPos(1,y-1)
347 write("Click ")
348 term.setTextColor(colors.yellow)
349 write("here ")
350 term.setTextColor(colors.white)
351 write("to confirm colours")
352 term.setCursorPos(1,y)
353 write("Else click here to choose again")
354 happy = waitForExitClick()
355 until happy == true
356 happy = false
357 return color2,color,color3,bText,wireCol
358 end
359 function addButton()
360 repeat --Button wizard
361 clearMonitors()
362 checkerboard()
363 mon = peripheral.wrap(selectedMon)
364 monWrite("Tap position 1 for your button",1,y)
365 _,side,txd,tyd = os.pullEvent("monitor_touch")
366 drawX(txd,tyd)
367 monWrite("Tap position 2 for your button",1,y)
368 _,_,txu,tyu = os.pullEvent("monitor_touch")
369 rButton(side,txd,tyd,txu,tyu)
370 monWrite("If you are happy Tap the button",1,y-1)
371 monWrite("Else, Tap any black space ",1,y)
372 _,Side,hx,hy = os.pullEvent("monitor_touch")
373 do --Reverse if hit from bottom first
374 if txd > txu then
375 temp = txd
376 txd = txu
377 txu = temp
378 end
379 if tyd > tyu then
380 temp = tyd
381 tyd = tyu
382 tyu = temp
383 end
384 end
385 happyness = checkTemp(hx,hy,txd,txu,tyd,tyu)
386 if happyness ~= true then
387 textBox(":'(",txd,txu,tyd,tyu,colors.white,colors.blue)
388 else
389 textBox(":)",txd,txu,tyd,tyu,colors.white,colors.green)
390 end
391 sleep(1)
392 until happyness == true
393 clearMonitors()
394 text = "Right click on the"
395 monWrite(text, x/2 - #text/2, y/2 - 1)
396 text = "terminal to continue."
397 monWrite(text, x/2 - #text/2, y/2)
398 return txd,txu,tyd,tyu
399 end
400 function removeButton()
401 while true do
402 clearMonitors()
403 draw()
404 mon = peripheral.wrap(selectedMon)
405 monWrite("Tap a button to remove it.",1,y-1)
406 monWrite("Tap ",1,y)
407 mon.setTextColor(colors.yellow)
408 mon.write("here")
409 mon.setTextColor(colors.white)
410 mon.write(" when you're finished.")
411 _,Side,hx,hy = os.pullEvent("monitor_touch")
412 if hy == y then
413 break
414 end
415 for name, data in pairs(buttons) do
416 if Side == data.side then
417 if checkTemp(hx,hy,data.xmin,data.xmax,data.ymin,data.ymax) == true then
418 c = colors.subtract(c, buttons[name].wireCol) -- if the button is on, we turn it off
419 rs.setBundledOutput(options.wireSide, c)
420 buttons[name] = nil
421 break
422 end
423 end
424 end
425 end
426 end
427 function selectMonitor()
428 print("Select a monitor by right clicking on it.")
429 for i=1,#monSids do
430 mon = peripheral.wrap(monSids[i])
431 x,y = mon.getSize()
432 mon.setCursorPos(x/2,y/2)
433 mon.write(tostring(i))
434 end
435 _,Side,hx,hy = os.pullEvent("monitor_touch")
436 mon = peripheral.wrap(Side)
437 selectedMon = Side
438 x,y = mon.getSize()
439 mon.setCursorPos(x/2 - 9/2,y/2)
440 mon.write("Selected!")
441 sleep(1)
442 return selectedMon
443 end
444 getMonitors()
445 clearMonitors()
446 term.clear()
447 term.setCursorPos(1,1)
448 selectedMon = selectMonitor()
449
450 if mode == "add" then
451 xmin,xmax,ymin,ymax = addButton()
452 tCol,bgCol,actCol,name,wireCol = addButton_terminalPart()
453 dark.cs()
454 createStaticbuttons(name,xmin,xmax,ymin,ymax,tCol,bgCol,actCol,selectedMon,wireCol)
455 elseif mode == "remove" then
456 dark.cs()
457 removeButton()
458 end
459 clearMonitors()
460 saveState()
461end
462
463options = {}
464options.wireSide = "bottom"
465LoadState()
466getMonitors()
467parallel.waitForAll(hitListen, breakListen, terminalMenu, stealthUpdate)