· 6 years ago · Feb 25, 2020, 11:14 PM
1-- Hideously Smashed Together by Compilr, a Hideous Smash-Stuff-Togetherer, (c) 2014 oeed --
2
3-- This file REALLLLLLLY isn't suitable to be used for anything other than being executed --
4
5-- To extract all the files, run: "<filename> --extract" in the Shell --
6local files = {
7 owo = {},
8 ReactorControl = {
9 Views = {
10 [ "reactorDetailed.view" ] = "{\
11 Children={\
12 {\
13 X=0,\
14 Y=1,\
15 Name=\"topBar\",\
16 Type=\"ProgressBar\",\
17 Width=\"100%,+1\",\
18 Align=\"Center\",\
19 BackgroundColour='gray',\
20 },\
21 {\
22 X=0,\
23 Y=\"100%\",\
24 Name=\"BottomBar\",\
25 Type=\"ProgressBar\",\
26 Width=\"100%,+1\",\
27 Align=\"Center\",\
28 BackgroundColour='gray',\
29 },\
30 {\
31 X=1,\
32 Y=1,\
33 Name=\"reactorName_Label\",\
34 Type=\"Label\",\
35 Text=\"reactor_name\",\
36 Width=\"100%\",\
37 Align=\"Center\",\
38 BackgroundColour=0,\
39 TextColour='white',\
40 },\
41 {\
42 X=2,\
43 Y=3,\
44 Name=\"Status_Static_Label\",\
45 Type=\"Label\",\
46 Text=\"Status: \",\
47 Width=\"100%\",\
48 Align=\"left\",\
49 BackgroundColour=0,\
50 },\
51 {\
52 X=2,\
53 Y=5,\
54 Name=\"CoreTemp_Static_Label\",\
55 Type=\"Label\",\
56 Text=\"Core Temperature: \",\
57 Width=\"100%\",\
58 Align=\"left\",\
59 BackgroundColour=0,\
60 },\
61 {\
62 X=2,\
63 Y=7,\
64 Name=\"FuelRate_Static_Label\",\
65 Type=\"Label\",\
66 Text=\"Fuel Burnup Rate: \",\
67 Width=\"100%\",\
68 Align=\"left\",\
69 BackgroundColour=0,\
70 },\
71 {\
72 X=1,\
73 Y=8,\
74 Name=\"S1_Seperator\",\
75 Type=\"Separator\",\
76 Width=\"100%\",\
77 Align=\"left\",\
78 BackgroundColour=0,\
79 },\
80 {\
81 X=2,\
82 Y=9,\
83 Name=\"SteamTank_Static_Label\",\
84 Type=\"Label\",\
85 Text=\"Steam Tanklevel: \",\
86 Width=\"100%\",\
87 Align=\"left\",\
88 BackgroundColour=0,\
89 },\
90 {\
91 X=2,\
92 Y=11,\
93 Name=\"WaterTank_Static_Label\",\
94 Type=\"Label\",\
95 Text=\"Water Tanklevel: \",\
96 Width=\"100%\",\
97 Align=\"left\",\
98 BackgroundColour=0,\
99 },\
100 {\
101 X=1,\
102 Y=12,\
103 Name=\"S2_Seperator\",\
104 Type=\"Separator\",\
105 Width=\"100%\",\
106 Align=\"left\",\
107 BackgroundColour=0,\
108 },\
109 {\
110 X=2,\
111 Y=13,\
112 Name=\"ControlRods_Static_Label\",\
113 Type=\"Label\",\
114 Text=\"Control Rods: \",\
115 Width=\"100%\",\
116 Align=\"left\",\
117 BackgroundColour=0,\
118 },\
119 {\
120 X=2,\
121 Y=15,\
122 Name=\"FuelWaste_Static_Label\",\
123 Type=\"Label\",\
124 Text=\"Fuel/Waste: \",\
125 Width=\"100%\",\
126 Align=\"left\",\
127 BackgroundColour=0,\
128 },\
129 {\
130 X=2,\
131 Y=17,\
132 Name=\"SteamOut_Static_Label\",\
133 Type=\"Label\",\
134 Text=\"Steam Output: \",\
135 Width=\"100%\",\
136 Align=\"left\",\
137 BackgroundColour=0,\
138 },\
139 {\
140 X=\"50%,-5\",\
141 Y=3,\
142 Name=\"Reactor_Status_Button\",\
143 Type=\"Button\",\
144 Text=\" Inactive \",\
145 Width=12,\
146 Align=\"center\",\
147 BackgroundColour=\"red\",\
148 },\
149 {\
150 X=\"50%,-5\",\
151 Y=5,\
152 Name=\"Reactor_CoreTemp_Label\",\
153 Type=\"Label\",\
154 Text=\"1285 C\",\
155 Width=\"100%\",\
156 Align=\"left\",\
157 BackgroundColour=0,\
158 },\
159 {\
160 X=\"50%,-5\",\
161 Y=7,\
162 Name=\"Reactor_Burnup_Label\",\
163 Type=\"Label\",\
164 Text=\"1,04 mB/t\",\
165 Width=\"100%\",\
166 Align=\"left\",\
167 BackgroundColour=0,\
168 },\
169 {\
170 X=\"50%,-5\",\
171 Y=9,\
172 Name=\"Reactor_Steamtank_ProgressBar\",\
173 Type=\"ProgressBar\",\
174 Width=\"50%,+4\",\
175 Align=\"left\",\
176 BackgroundColour='gray',\
177 BarColour='lightGray',\
178 Value=1000,\
179 Maximum=45000,\
180 ShowText=true,\
181 },\
182 {\
183 X=\"50%,-5\",\
184 Y=11,\
185 Name=\"Reactor_Watertank_ProgressBar\",\
186 Type=\"ProgressBar\",\
187 Width=\"50%,+4\",\
188 Align=\"left\",\
189 BackgroundColour='gray',\
190 BarColour='blue',\
191 Value=3000,\
192 Maximum=45000,\
193 ShowText=true,\
194 },\
195 {\
196 X=\"50%,-5\",\
197 Y=13,\
198 Name=\"Reactor_ControlRod_Label\",\
199 Type=\"Label\",\
200 Text=\"26 Rods set to 90%\",\
201 Width=\"100%\",\
202 Align=\"left\",\
203 BackgroundColour=0,\
204 },\
205 {\
206 X=\"50%,-5\",\
207 Y=15,\
208 Name=\"Reactor_Fuel_ProgressBar\",\
209 Type=\"ProgressBar\",\
210 Width=\"50%,+4\",\
211 Align=\"left\",\
212 BackgroundColour='gray',\
213 BarColour='yellow',\
214 Value=3000,\
215 Maximum=4000,\
216 ShowText=false,\
217 },\
218 {\
219 X=\"50%,-5\",\
220 Y=15,\
221 Name=\"Reactor_Waste_ProgressBar\",\
222 Type=\"ProgressBar\",\
223 Width=\"50%,+4\",\
224 Align=\"left\",\
225 BackgroundColour=0,\
226 BarColour='lightBlue',\
227 Value=2000,\
228 Maximum=4000,\
229 ShowText=false,\
230 },\
231 {\
232 X=\"50%,-5\",\
233 Y=15,\
234 Width=\"50%,+4\",\
235 Name=\"Reactor_FuelWaste_Label\",\
236 Type=\"Label\",\
237 Text=\"10% Waste 50% Fuel\",\
238 Align=\"Center\",\
239 TextColour='white',\
240 BackgroundColour=0,\
241 },\
242 {\
243 X=\"50%,-5\",\
244 Y=17,\
245 Name=\"Reactor_SteamOut_Label\",\
246 Type=\"Label\",\
247 Text=\"5600 mB/t\",\
248 Width=\"100%\",\
249 Align=\"left\",\
250 BackgroundColour=0,\
251 },\
252 {\
253 X=0,\
254 Y=\"100%\",\
255 Name=\"Reactor_SetControlRod_Button\",\
256 Type=\"Button\",\
257 Text=\"|Set Control Rod Levels|\",\
258 Width=25,\
259 Align=\"left\",\
260 BackgroundColour=\"gray\",\
261 TextColour='white',\
262 Enabled=false,\
263 },\
264 {\
265 X=\"100%,-5\",\
266 Y=\"100%\",\
267 Name=\"Reactor_Back_Button\",\
268 Type=\"Button\",\
269 Text=\"|Back|\",\
270 Width=6,\
271 Align=\"Center\",\
272 BackgroundColour=\"gray\",\
273 TextColour='white',\
274 },\
275 {\
276 X=\"100%,-2\",\
277 Y=1,\
278 Name=\"Reactor_NextReactor_Button\",\
279 Type=\"Button\",\
280 Text=\" ->\",\
281 Width=3,\
282 Align=\"Center\",\
283 BackgroundColour=\"gray\",\
284 Enabled=false,\
285 TextColour='white',\
286 },\
287 {\
288 X=1,\
289 Y=1,\
290 Name=\"Reactor_LastReactor_Button\",\
291 Type=\"Button\",\
292 Text=\"<- \",\
293 Width=3,\
294 Align=\"Center\",\
295 BackgroundColour=\"gray\",\
296 Enabled=false,\
297 TextColour='white',\
298 },\
299 },\
300 BackgroundColour='white'\
301}",
302 [ "main.view" ] = "{\
303 Children={\
304 {\
305 X=\"50%, -4\",\
306 Y=\"50%, -2\",\
307 Name=\"Header_Static_Label\",\
308 Type=\"Label\",\
309 Text=\"Booting\",\
310 Align=\"Center\",\
311 BackgroundColour=0,\
312 TextColour='white',\
313 },\
314 {\
315 X=\"50%, -8\",\
316 Y=\"50%, +5\",\
317 Name=\"Status_Static_Label\",\
318 Type=\"Label\",\
319 Text=\"\",\
320 Align=\"Center\",\
321 BackgroundColour=0,\
322 TextColour='white',\
323 },\
324 },\
325 BackgroundColour='blue'\
326}",
327 [ "reactorDetailed_passive.view" ] = "{\
328 Children={\
329{\
330 X=0,\
331 Y=1,\
332 Name=\"topBar\",\
333 Type=\"ProgressBar\",\
334 Width=\"100%,+1\",\
335 Align=\"Center\",\
336 BackgroundColour='gray',\
337 },\
338 {\
339 X=0,\
340 Y=\"100%\",\
341 Name=\"BottomBar\",\
342 Type=\"ProgressBar\",\
343 Width=\"100%,+1\",\
344 Align=\"Center\",\
345 BackgroundColour='gray',\
346 },\
347 {\
348 X=1,\
349 Y=1,\
350 Name=\"reactorName_Label\",\
351 Type=\"Label\",\
352 Text=\"reactor_name\",\
353 Width=\"100%\",\
354 Align=\"Center\",\
355 BackgroundColour=0,\
356 TextColour='white',\
357 },\
358 {\
359 X=2,\
360 Y=3,\
361 Name=\"Status_Static_Label\",\
362 Type=\"Label\",\
363 Text=\"Status: \",\
364 Width=\"100%\",\
365 Align=\"left\",\
366 BackgroundColour=0,\
367 },\
368 {\
369 X=2,\
370 Y=5,\
371 Name=\"CoreTemp_Static_Label\",\
372 Type=\"Label\",\
373 Text=\"Core Temperature: \",\
374 Width=\"100%\",\
375 Align=\"left\",\
376 BackgroundColour=0,\
377 },\
378 {\
379 X=2,\
380 Y=7,\
381 Name=\"FuelRate_Static_Label\",\
382 Type=\"Label\",\
383 Text=\"Fuel Burnup Rate: \",\
384 Width=\"100%\",\
385 Align=\"left\",\
386 BackgroundColour=0,\
387 },\
388 {\
389 X=1,\
390 Y=8,\
391 Name=\"S1_Seperator\",\
392 Type=\"Separator\",\
393 Width=\"100%\",\
394 Align=\"left\",\
395 BackgroundColour=0,\
396 },\
397 {\
398 X=2,\
399 Y=9,\
400 Name=\"ControlRods_Static_Label\",\
401 Type=\"Label\",\
402 Text=\"Control Rods: \",\
403 Width=\"100%\",\
404 Align=\"left\",\
405 BackgroundColour=0,\
406 },\
407 {\
408 X=2,\
409 Y=11,\
410 Name=\"FuelWaste_Static_Label\",\
411 Type=\"Label\",\
412 Text=\"Fuel/Waste: \",\
413 Width=\"100%\",\
414 Align=\"left\",\
415 BackgroundColour=0,\
416 },\
417 {\
418 X=1,\
419 Y=12,\
420 Name=\"S2_Seperator\",\
421 Type=\"Separator\",\
422 Width=\"100%\",\
423 Align=\"left\",\
424 BackgroundColour=0,\
425 },\
426 {\
427 X=2,\
428 Y=13,\
429 Name=\"Reactivity_Static_Label\",\
430 Type=\"Label\",\
431 Text=\"Fuel Reactivity: \",\
432 Width=\"100%\",\
433 Align=\"left\",\
434 BackgroundColour=0,\
435 },\
436 {\
437 X=2,\
438 Y=15,\
439 Name=\"EnergyOut_Static_Label\",\
440 Type=\"Label\",\
441 Text=\"Energy Output: \",\
442 Width=\"100%\",\
443 Align=\"left\",\
444 BackgroundColour=0,\
445 },\
446 {\
447 X=2,\
448 Y=17,\
449 Name=\"EneryBuf_Static_Label\",\
450 Type=\"Label\",\
451 Text=\"Energy Buffer: \",\
452 Width=\"100%\",\
453 Align=\"left\",\
454 BackgroundColour=0,\
455 },\
456 {\
457 X=\"50%,-5\",\
458 Y=3,\
459 Name=\"Reactor_Status_Button\",\
460 Type=\"Button\",\
461 Text=\" Inactive \",\
462 Width=12,\
463 Align=\"center\",\
464 BackgroundColour=\"red\",\
465 },\
466 {\
467 X=\"50%,-5\",\
468 Y=5,\
469 Name=\"Reactor_CoreTemp_Label\",\
470 Type=\"Label\",\
471 Text=\"1285 C\",\
472 Width=\"100%\",\
473 Align=\"left\",\
474 BackgroundColour=0,\
475 },\
476 {\
477 X=\"50%,-5\",\
478 Y=7,\
479 Name=\"Reactor_Burnup_Label\",\
480 Type=\"Label\",\
481 Text=\"1,04 mB/t\",\
482 Width=\"100%\",\
483 Align=\"left\",\
484 BackgroundColour=0,\
485 },\
486 {\
487 X=\"50%,-5\",\
488 Y=9,\
489 Name=\"Reactor_ControlRod_Label\",\
490 Type=\"Label\",\
491 Text=\"26 Rods set to 90%\",\
492 Width=\"100%\",\
493 Align=\"left\",\
494 BackgroundColour=0,\
495 },\
496 {\
497 X=\"50%,-5\",\
498 Y=11,\
499 Name=\"Reactor_Fuel_ProgressBar\",\
500 Type=\"ProgressBar\",\
501 Width=\"50%,+4\",\
502 Align=\"left\",\
503 BackgroundColour='gray',\
504 BarColour='yellow',\
505 Value=3000,\
506 Maximum=4000,\
507 ShowText=false,\
508 },\
509 {\
510 X=\"50%,-5\",\
511 Y=11,\
512 Name=\"Reactor_Waste_ProgressBar\",\
513 Type=\"ProgressBar\",\
514 Width=\"50%,+4\",\
515 Align=\"left\",\
516 BackgroundColour=0,\
517 BarColour='lightBlue',\
518 Value=2000,\
519 Maximum=4000,\
520 ShowText=false,\
521 },\
522 {\
523 X=\"50%,-5\",\
524 Y=11,\
525 Width=\"50%,+4\",\
526 Name=\"Reactor_FuelWaste_Label\",\
527 Type=\"Label\",\
528 Text=\"10% Waste 50% Fuel\",\
529 Align=\"Center\",\
530 TextColour='white',\
531 BackgroundColour=0,\
532 },\
533 {\
534 X=\"50%,-5\",\
535 Y=13,\
536 Name=\"Reactor_Reactivity_Label\",\
537 Type=\"Label\",\
538 Text=\"150%\",\
539 Width=\"100%\",\
540 Align=\"left\",\
541 BackgroundColour=0,\
542 },\
543 {\
544 X=\"50%,-5\",\
545 Y=15,\
546 Name=\"Reactor_EnergyOut_Label\",\
547 Type=\"Label\",\
548 Text=\"50200 RF/t\",\
549 Width=\"100%\",\
550 Align=\"left\",\
551 BackgroundColour=0,\
552 },\
553 {\
554 X=\"50%,-5\",\
555 Y=17,\
556 Name=\"Reactor_EnergyBuf_ProgressBar\",\
557 Type=\"ProgressBar\",\
558 Width=\"50%,+4\",\
559 Align=\"left\",\
560 BackgroundColour='gray',\
561 BarColour='red',\
562 Value=200000,\
563 Maximum=10000000,\
564 ShowText=true,\
565 },\
566 {\
567 X=0,\
568 Y=\"100%\",\
569 Name=\"Reactor_SetControlRod_Button\",\
570 Type=\"Button\",\
571 Text=\"|Set Control Rod Levels|\",\
572 Width=25,\
573 Align=\"left\",\
574 BackgroundColour=\"gray\",\
575 TextColour='white',\
576 },\
577 {\
578 X=\"100%,-5\",\
579 Y=\"100%\",\
580 Name=\"Reactor_Back_Button\",\
581 Type=\"Button\",\
582 Text=\"|Back|\",\
583 Width=6,\
584 Align=\"Center\",\
585 BackgroundColour=\"gray\",\
586 TextColour='white',\
587 },\
588 {\
589 X=\"100%,-2\",\
590 Y=1,\
591 Name=\"Reactor_NextReactor_Button\",\
592 Type=\"Button\",\
593 Text=\" ->\",\
594 Width=3,\
595 Align=\"Center\",\
596 BackgroundColour=\"gray\",\
597 Enabled=false,\
598 TextColour='white',\
599 },\
600 {\
601 X=1,\
602 Y=1,\
603 Name=\"Reactor_LastReactor_Button\",\
604 Type=\"Button\",\
605 Text=\"<- \",\
606 Width=3,\
607 Align=\"Center\",\
608 BackgroundColour=\"gray\",\
609 Enabled=false,\
610 TextColour='white',\
611 },\
612 },\
613 BackgroundColour='white'\
614}",
615 [ "empty.view" ] = "{\
616 Children={\
617\
618 },\
619 BackgroundColour='black'\
620}",
621 [ "groupEditor.view" ] = "{\
622 Children={\
623 {\
624 X=0,\
625 Y=1,\
626 Name=\"topBar\",\
627 Type=\"ProgressBar\",\
628 Width=\"100%,+1\",\
629 Align=\"Center\",\
630 BackgroundColour='gray',\
631 },\
632 {\
633 X=0,\
634 Y=\"100%\",\
635 Name=\"BottomBar\",\
636 Type=\"ProgressBar\",\
637 Width=\"100%,+1\",\
638 Align=\"Center\",\
639 BackgroundColour='gray',\
640 },\
641 {\
642 X=1,\
643 Y=1,\
644 Name=\"Header_Static_Label\",\
645 Type=\"Label\",\
646 Text=\"Group Editor\",\
647 Width=\"100%\",\
648 Align=\"Center\",\
649 BackgroundColour=0,\
650 TextColour='white',\
651 },\
652 {\
653 X=\"50%,+2\",\
654 Y=3,\
655 Name=\"S1_Seperator\",\
656 Type=\"Separator\",\
657 Width=\"50%,-3\",\
658 Align=\"left\",\
659 BackgroundColour=0,\
660 },\
661 {\
662 X=\"50%,+2\",\
663 Y=3,\
664 Name=\"HeaderGroup_Static_Label\",\
665 Type=\"Label\",\
666 Text=\"[ Group ]\",\
667 Width=\"50%,-2\",\
668 Align=\"Center\",\
669 BackgroundColour=0,\
670 TextColour='black',\
671 },\
672 {\
673 X=\"50%,+2\",\
674 Y=9,\
675 Name=\"S2_Seperator\",\
676 Type=\"Separator\",\
677 Width=\"50%,-3\",\
678 Align=\"left\",\
679 BackgroundColour=0,\
680 },\
681 {\
682 X=\"50%,+2\",\
683 Y=5,\
684 Width=\"50%,-3\",\
685 Type=\"TextBox\",\
686 Name=\"GroupEditor_GroupName_TextBox\",\
687 Placeholder=\"Group name...\",\
688 },\
689 {\
690 X=\"50%,+2\",\
691 Y=7,\
692 Name=\"GroupEditor_AddGroup_Button\",\
693 Type=\"Button\",\
694 Text=\"Add\",\
695 BackgroundColour='gray',\
696 TextColour='white',\
697 Align=\"Center\",\
698 Enabled=false,\
699 },\
700 {\
701 X=\"75%,-5\",\
702 Y=7,\
703 Name=\"GroupEditor_RenameGroup_Button\",\
704 Type=\"Button\",\
705 Text=\"Rename\",\
706 BackgroundColour='gray',\
707 TextColour='white',\
708 Align=\"Center\",\
709 Enabled=false,\
710 },\
711 {\
712 X=\"100%,-8\",\
713 Y=7,\
714 Name=\"GroupEditor_DeleteGroup_Button\",\
715 Type=\"Button\",\
716 Text=\"Delete\",\
717 BackgroundColour='gray',\
718 TextColour='white',\
719 Align=\"Center\",\
720 Enabled=false,\
721 },\
722 {\
723 X=\"50%,+2\",\
724 Y=9,\
725 Name=\"HeaderPeripheral_Static_Label\",\
726 Type=\"Label\",\
727 Text=\"[ Peripheral ]\",\
728 Width=\"50%,-3\",\
729 Align=\"Center\",\
730 BackgroundColour=0,\
731 TextColour='black',\
732 },\
733 {\
734 X=\"50%,+2\",\
735 Y=11,\
736 Width=\"50%,-3\",\
737 Type=\"TextBox\",\
738 Name=\"GroupEditor_PeripheralSide_TextBox\",\
739 Placeholder=\"Peripheral side...\",\
740 },\
741 {\
742 X=\"50%,+2\",\
743 Y=13,\
744 Width=\"50%,-3\",\
745 Type=\"TextBox\",\
746 Name=\"GroupEditor_PeripheralName_TextBox\",\
747 Placeholder=\"Name...\",\
748 },\
749 {\
750 X=\"50%,+2\",\
751 Y=15,\
752 Name=\"GroupEditor_AddPeripheral_Button\",\
753 Type=\"Button\",\
754 Text=\"Add\",\
755 BackgroundColour='gray',\
756 TextColour='white',\
757 Align=\"Center\",\
758 Enabled=false,\
759 },\
760 {\
761 X=\"75%,-5\",\
762 Y=15,\
763 Name=\"GroupEditor_ChangePeripheral_Button\",\
764 Type=\"Button\",\
765 Text=\"Change\",\
766 BackgroundColour='gray',\
767 TextColour='white',\
768 Align=\"Center\",\
769 Enabled=false,\
770 },\
771 {\
772 X=\"100%,-8\",\
773 Y=15,\
774 Name=\"GroupEditor_DeletePeripheral_Button\",\
775 Type=\"Button\",\
776 Text=\"Delete\",\
777 BackgroundColour='gray',\
778 TextColour='white',\
779 Align=\"Center\",\
780 Enabled=false,\
781 },\
782 {\
783 X=\"50%,+2\",\
784 Y=16,\
785 Name=\"S3_Seperator\",\
786 Type=\"Separator\",\
787 Width=\"50%,-3\",\
788 Align=\"left\",\
789 BackgroundColour=0,\
790 },\
791 {\
792 X=\"50%,+5\",\
793 Y=17,\
794 Name=\"GroupEditor_MoveUp_Button\",\
795 Type=\"Button\",\
796 Text=\" Up \",\
797 BackgroundColour='gray',\
798 TextColour='white',\
799 Align=\"Center\",\
800 Enabled=false,\
801 },\
802 {\
803 X=\"100%,-11\",\
804 Y=17,\
805 Name=\"GroupEditor_MoveDown_Button\",\
806 Type=\"Button\",\
807 Text=\"Down\",\
808 BackgroundColour='gray',\
809 TextColour='white',\
810 Align=\"Center\",\
811 Enabled=false,\
812 },\
813 {\
814 X=2,\
815 Y=3,\
816 Name=\"GroupEditor_GroupList_ListView\",\
817 Type=\"ListView\",\
818 Width=\"50%, -1\",\
819 Height=\"100%, -4\",\
820 Align=\"Center\",\
821 BackgroundColour=\"lightGray\",\
822 TextColour='white',\
823 Initialised=false,\
824 CanSelect=true,\
825 },\
826 {\
827 X=\"100%,-5\",\
828 Y=\"100%\",\
829 Name=\"GroupEditor_Back_Button\",\
830 Type=\"Button\",\
831 Text=\"|Back|\",\
832 Width=6,\
833 Align=\"Center\",\
834 BackgroundColour=\"gray\",\
835 TextColour='white',\
836 },\
837 {\
838 X=1,\
839 Y=\"100%\",\
840 Name=\"GroupEditor_Apply_Button\",\
841 Type=\"Button\",\
842 Text=\"|Apply|\",\
843 Width=7,\
844 Align=\"Center\",\
845 BackgroundColour=\"gray\",\
846 TextColour='white',\
847 },\
848\
849 },\
850 BackgroundColour='white'\
851}",
852 [ "turbineDetailed.view" ] = "{\
853 Children={\
854 {\
855 X=0,\
856 Y=1,\
857 Name=\"topBar\",\
858 Type=\"ProgressBar\",\
859 Width=\"100%,+1\",\
860 Align=\"Center\",\
861 BackgroundColour=\"gray\",\
862 },\
863 {\
864 X=0,\
865 Y=\"100%\",\
866 Name=\"BottomBar\",\
867 Type=\"ProgressBar\",\
868 Width=\"100%,+1\",\
869 Align=\"Center\",\
870 BackgroundColour=\"gray\",\
871 },\
872 {\
873 X=1,\
874 Y=1,\
875 Name=\"turbineName_Label\",\
876 Type=\"Label\",\
877 Text=\"turbine_name\",\
878 TextColour='white',\
879 Width=\"100%\",\
880 Align=\"Center\",\
881 BackgroundColour=0,\
882 },\
883 {\
884 X=2,\
885 Y=3,\
886 Name=\"Status_Static_Label\",\
887 Type=\"Label\",\
888 Text=\"Status: \",\
889 Width=\"100%\",\
890 Align=\"left\",\
891 BackgroundColour=0,\
892 },\
893 {\
894 X=2,\
895 Y=5,\
896 Name=\"RPM_Static_Label\",\
897 Type=\"Label\",\
898 Text=\"Speed: \",\
899 Width=\"100%\",\
900 Align=\"left\",\
901 BackgroundColour=0,\
902 },\
903 {\
904 X=2,\
905 Y=7,\
906 Name=\"Flowrate_Static_Label\",\
907 Type=\"Label\",\
908 Text=\"Steam Flowrate: \",\
909 Width=\"100%\",\
910 Align=\"left\",\
911 BackgroundColour=0,\
912 },\
913 {\
914 X=1,\
915 Y=8,\
916 Name=\"S1_Seperator\",\
917 Type=\"Separator\",\
918 Width=\"100%\",\
919 Align=\"left\",\
920 BackgroundColour=0,\
921 },\
922 {\
923 X=2,\
924 Y=9,\
925 Name=\"SteamTank_Static_Label\",\
926 Type=\"Label\",\
927 Text=\"Steam Tanklevel: \",\
928 Width=\"100%\",\
929 Align=\"left\",\
930 BackgroundColour=0,\
931 },\
932 {\
933 X=2,\
934 Y=11,\
935 Name=\"WaterTank_Static_Label\",\
936 Type=\"Label\",\
937 Text=\"Water Tanklevel: \",\
938 Width=\"100%\",\
939 Align=\"left\",\
940 BackgroundColour=0,\
941 },\
942 {\
943 X=1,\
944 Y=12,\
945 Name=\"S2_Seperator\",\
946 Type=\"Separator\",\
947 Width=\"100%\",\
948 Align=\"left\",\
949 BackgroundColour=0,\
950 },\
951 {\
952 X=2,\
953 Y=13,\
954 Name=\"Coils_Static_Label\",\
955 Type=\"Label\",\
956 Text=\"Coils: \",\
957 Width=\"100%\",\
958 Align=\"left\",\
959 BackgroundColour=0,\
960 },\
961 {\
962 X=2,\
963 Y=15,\
964 Name=\"EnergyOut_Static_Label\",\
965 Type=\"Label\",\
966 Text=\"Energy Output: \",\
967 Width=\"100%\",\
968 Align=\"left\",\
969 BackgroundColour=0,\
970 },\
971 {\
972 X=2,\
973 Y=17,\
974 Name=\"EnergyBuf_Static_Label\",\
975 Type=\"Label\",\
976 Text=\"Energy Buffer: \",\
977 Width=\"100%\",\
978 Align=\"left\",\
979 BackgroundColour=0,\
980 },\
981 {\
982 X=\"50%,-5\",\
983 Y=3,\
984 Name=\"Turbine_Status_Button\",\
985 Type=\"Button\",\
986 Text=\" Inactive \",\
987 Width=12,\
988 Align=\"center\",\
989 BackgroundColour=\"red\",\
990 },\
991 {\
992 X=\"50%,-5\",\
993 Y=5,\
994 Name=\"Turbine_RPM_Label\",\
995 Type=\"Label\",\
996 Text=\"1800 RPM\",\
997 Width=\"100%\",\
998 Align=\"left\",\
999 BackgroundColour=0,\
1000 },\
1001 {\
1002 X=\"50%,-5\",\
1003 Y=7,\
1004 Name=\"Turbine_Flowrate_Label\",\
1005 Type=\"Label\",\
1006 Text=\"980 mB/t of 1250 mb/t\",\
1007 Width=\"100%\",\
1008 Align=\"left\",\
1009 BackgroundColour=0,\
1010 },\
1011 {\
1012 X=\"50%,-5\",\
1013 Y=9,\
1014 Name=\"Turbine_Steamtank_ProgressBar\",\
1015 Type=\"ProgressBar\",\
1016 Width=\"50%,+4\",\
1017 Align=\"left\",\
1018 BackgroundColour='gray',\
1019 BarColour='lightGray',\
1020 Value=1000,\
1021 Maximum=4000,\
1022 ShowText=true,\
1023 },\
1024 {\
1025 X=\"50%,-5\",\
1026 Y=11,\
1027 Name=\"Turbine_Watertank_ProgressBar\",\
1028 Type=\"ProgressBar\",\
1029 Width=\"50%,+4\",\
1030 Align=\"left\",\
1031 BackgroundColour='gray',\
1032 BarColour='blue',\
1033 Value=3000,\
1034 Maximum=4000,\
1035 ShowText=true,\
1036 },\
1037 {\
1038 X=\"50%,-5\",\
1039 Y=13,\
1040 Name=\"Turbine_Coils_Button\",\
1041 Type=\"Button\",\
1042 Text=\"Disengaged\",\
1043 Width=12,\
1044 Align=\"center\",\
1045 BackgroundColour=\"red\",\
1046 },\
1047 {\
1048 X=\"50%,-5\",\
1049 Y=15,\
1050 Name=\"Turbine_EnergyOut_Label\",\
1051 Type=\"Label\",\
1052 Text=\"13000 RF/t\",\
1053 Width=\"100%\",\
1054 Align=\"left\",\
1055 BackgroundColour=0,\
1056 },\
1057 {\
1058 X=\"50%,-5\",\
1059 Y=17,\
1060 Name=\"Turbine_EnergyBuf_ProgressBar\",\
1061 Type=\"ProgressBar\",\
1062 Width=\"50%,+4\",\
1063 Align=\"left\",\
1064 BackgroundColour='gray',\
1065 BarColour='red',\
1066 Value=200000,\
1067 Maximum=1000000,\
1068 ShowText=true,\
1069 },\
1070 {\
1071 X=0,\
1072 Y=\"100%\",\
1073 Name=\"Turbine_SetFlowrate_Button\",\
1074 Type=\"Button\",\
1075 Text=\"|Set Flowrate|\",\
1076 Width=15,\
1077 Align=\"left\",\
1078 BackgroundColour=\"gray\",\
1079 TextColour='white',\
1080 Enabled=false,\
1081 },\
1082 {\
1083 X=\"100%,-5\",\
1084 Y=\"100%\",\
1085 Name=\"Turbine_Back_Button\",\
1086 Type=\"Button\",\
1087 Text=\"|Back|\",\
1088 Width=6,\
1089 Align=\"Center\",\
1090 BackgroundColour=\"gray\",\
1091 TextColour='white',\
1092 },\
1093 {\
1094 X=\"100%,-2\",\
1095 Y=1,\
1096 Name=\"Turbine_NextTurbine_Button\",\
1097 Type=\"Button\",\
1098 Text=\" ->\",\
1099 Width=3,\
1100 Align=\"Center\",\
1101 BackgroundColour=\"gray\",\
1102 Enabled=false,\
1103 TextColour='white',\
1104 },\
1105 {\
1106 X=1,\
1107 Y=1,\
1108 Name=\"Turbine_LastTurbine_Button\",\
1109 Type=\"Button\",\
1110 Text=\"<- \",\
1111 Width=3,\
1112 Align=\"Center\",\
1113 BackgroundColour=\"gray\",\
1114 Enabled=false,\
1115 TextColour='white',\
1116 },\
1117\
1118 },\
1119 BackgroundColour='white'\
1120}",
1121 [ "groupSettings.view" ] = "{\
1122 Children={\
1123 {\
1124 X=0,\
1125 Y=1,\
1126 Name=\"topBar\",\
1127 Type=\"ProgressBar\",\
1128 Width=\"100%,+1\",\
1129 Align=\"Center\",\
1130 BackgroundColour='gray',\
1131 },\
1132 {\
1133 X=0,\
1134 Y=\"100%\",\
1135 Name=\"BottomBar\",\
1136 Type=\"ProgressBar\",\
1137 Width=\"100%,+1\",\
1138 Align=\"Center\",\
1139 BackgroundColour='gray',\
1140 },\
1141 {\
1142 X=1,\
1143 Y=1,\
1144 Name=\"groupName_Label\",\
1145 Type=\"Label\",\
1146 Text=\"group_name\",\
1147 Width=\"100%\",\
1148 Align=\"Center\",\
1149 BackgroundColour='gray',\
1150 TextColour='white',\
1151 },\
1152 {\
1153 X=2,\
1154 Y=3,\
1155 Name=\"EE_Static_Label\",\
1156 Type=\"Label\",\
1157 Text=\"Efficient Energy: \",\
1158 Width=\"100%\",\
1159 Align=\"left\",\
1160 BackgroundColour=0,\
1161 },\
1162 {\
1163 X=2,\
1164 Y=7,\
1165 Name=\"EE_OffTh_Static_Label\",\
1166 Type=\"Label\",\
1167 Text=\"L Deactivate on: \",\
1168 Width=\"100%\",\
1169 Align=\"left\",\
1170 BackgroundColour=0,\
1171 },\
1172 {\
1173 X=\"50%,+4\",\
1174 Y=5,\
1175 Name=\"EE_OffTh_Unit_Static_Label\",\
1176 Type=\"Label\",\
1177 Text=\"%\",\
1178 Width=\"100%\",\
1179 Align=\"left\",\
1180 BackgroundColour=0,\
1181 },\
1182 {\
1183 X=2,\
1184 Y=5,\
1185 Name=\"EE_OnTh_Static_Label\",\
1186 Type=\"Label\",\
1187 Text=\"L Activate on: \",\
1188 Width=\"100%\",\
1189 Align=\"left\",\
1190 BackgroundColour=0,\
1191 },\
1192 {\
1193 X=\"50%,+4\",\
1194 Y=7,\
1195 Name=\"EE_OnTh_Unit_Static_Label\",\
1196 Type=\"Label\",\
1197 Text=\"%\",\
1198 Width=\"100%\",\
1199 Align=\"left\",\
1200 BackgroundColour=0,\
1201 },\
1202 {\
1203 X=1,\
1204 Y=8,\
1205 Name=\"S1_Seperator\",\
1206 Type=\"Separator\",\
1207 Width=\"100%\",\
1208 Align=\"left\",\
1209 BackgroundColour=0,\
1210 },\
1211 {\
1212 X=2,\
1213 Y=13,\
1214 Name=\"OptimiseTurbine_Static_Label\",\
1215 Type=\"Label\",\
1216 Text=\"Optimise Turbine: \",\
1217 Width=\"100%\",\
1218 Align=\"left\",\
1219 BackgroundColour=0,\
1220 },\
1221 {\
1222 X=2,\
1223 Y=15,\
1224 Name=\"OptimiseTurbine_RPM_Static_Label\",\
1225 Type=\"Label\",\
1226 Text=\"L Wanted RPM: \",\
1227 Width=\"100%\",\
1228 Align=\"left\",\
1229 BackgroundColour=0,\
1230 },\
1231 {\
1232 X=\"50%,+4\",\
1233 Y=15,\
1234 Name=\"OptimiseTurbine_RPM_Unit_Static_Label\",\
1235 Type=\"Label\",\
1236 Text=\"RPM\",\
1237 Width=\"100%\",\
1238 Align=\"left\",\
1239 BackgroundColour=0,\
1240 },\
1241 {\
1242 X=2,\
1243 Y=17,\
1244 Name=\"Coils_Static_Label\",\
1245 Type=\"Label\",\
1246 Text=\"Disengage Coils: \",\
1247 Width=\"100%\",\
1248 Align=\"left\",\
1249 BackgroundColour=0,\
1250 },\
1251 {\
1252 X=1,\
1253 Y=12,\
1254 Name=\"S1_Seperator\",\
1255 Type=\"Separator\",\
1256 Width=\"100%\",\
1257 Align=\"left\",\
1258 BackgroundColour=0,\
1259 },\
1260 {\
1261 X=2,\
1262 Y=9,\
1263 Name=\"OptimiseReactor_Static_Label\",\
1264 Type=\"Label\",\
1265 Text=\"Optimise Reactor: \",\
1266 Width=\"100%\",\
1267 Align=\"left\",\
1268 BackgroundColour=0,\
1269 },\
1270 {\
1271 X=2,\
1272 Y=11,\
1273 Name=\"OptimiseReactor_MaxTemp_Static_Label\",\
1274 Type=\"Label\",\
1275 Text=\"L Max Temperatur: \",\
1276 Width=\"100%\",\
1277 Align=\"left\",\
1278 BackgroundColour=0,\
1279 },\
1280 {\
1281 X=\"50%,+4\",\
1282 Y=11,\
1283 Name=\"OptimiseReactor_MaxTemp_Unit_Static_Label\",\
1284 Type=\"Label\",\
1285 Text=\"C\",\
1286 Width=\"100%\",\
1287 Align=\"left\",\
1288 BackgroundColour=0,\
1289 },\
1290 {\
1291 X=\"50%,-5\",\
1292 Y=3,\
1293 Name=\"GroupSettings_EE_Button\",\
1294 Type=\"Button\",\
1295 Text=\" Inactive \",\
1296 Width=12,\
1297 Align=\"center\",\
1298 BackgroundColour=\"red\",\
1299 },\
1300 {\
1301 X=\"50%,-5\",\
1302 Y=7,\
1303 Name=\"GroupSettings_EE_OffTh_NumberBox\",\
1304 Type=\"NumberBox\",\
1305 Align=\"center\",\
1306 Width=8,\
1307 Minimum=1,\
1308 Maximum=100,\
1309 Value=-100,\
1310 },\
1311 {\
1312 X=\"50%,-5\",\
1313 Y=5,\
1314 Name=\"GroupSettings_EE_OnTh_NumberBox\",\
1315 Type=\"NumberBox\",\
1316 Align=\"center\",\
1317 Width=8,\
1318 Minimum=1,\
1319 Maximum=100,\
1320 },\
1321 {\
1322 X=\"50%,-5\",\
1323 Y=13,\
1324 Name=\"GroupSettings_OptimiseTurbine_Button\",\
1325 Type=\"Button\",\
1326 Text=\" Inactive \",\
1327 Width=12,\
1328 Align=\"center\",\
1329 BackgroundColour=\"red\",\
1330 },\
1331 {\
1332 X=\"50%,-5\",\
1333 Y=15,\
1334 Name=\"GroupSettings_OptimiseTurbine_RPM_NumberBox\",\
1335 Type=\"NumberBox\",\
1336 Align=\"center\",\
1337 Width=8,\
1338 Minimum=100,\
1339 Maximum=10000,\
1340 },\
1341 {\
1342 X=\"50%,-5\",\
1343 Y=17,\
1344 Name=\"GroupSettings_DisengageCoils_Button\",\
1345 Type=\"Button\",\
1346 Text=\" Inactive \",\
1347 Width=12,\
1348 Align=\"center\",\
1349 BackgroundColour=\"red\",\
1350 },\
1351 {\
1352 X=\"50%,-5\",\
1353 Y=9,\
1354 Name=\"GroupSettings_OptimiseReactor_Button\",\
1355 Type=\"Button\",\
1356 Text=\" Inactive \",\
1357 Width=12,\
1358 Align=\"center\",\
1359 BackgroundColour=\"red\",\
1360 },\
1361 {\
1362 X=\"50%,-5\",\
1363 Y=11,\
1364 Name=\"GroupSettings_OptimiseReactor_MaxTemp_NumberBox\",\
1365 Type=\"NumberBox\",\
1366 Align=\"center\",\
1367 Width=8,\
1368 Minimum=20,\
1369 Maximum=10000,\
1370 },\
1371 {\
1372 X=\"75%,+3\",\
1373 Y=3,\
1374 Name=\"GroupSettings_EE_Help_Button\",\
1375 Type=\"Button\",\
1376 Text=\"?\",\
1377 Width=3,\
1378 Align=\"center\",\
1379 BackgroundColour=\"gray\",\
1380 TextColour=\"white\",\
1381 },\
1382 {\
1383 X=\"75%,+3\",\
1384 Y=13,\
1385 Name=\"GroupSettings_OptimiseTurbine_Help_Button\",\
1386 Type=\"Button\",\
1387 Text=\"?\",\
1388 Width=3,\
1389 Align=\"center\",\
1390 BackgroundColour=\"gray\",\
1391 TextColour=\"white\",\
1392 },\
1393 {\
1394 X=\"75%,+3\",\
1395 Y=17,\
1396 Name=\"GroupSettings_DisengageCoils_Help_Button\",\
1397 Type=\"Button\",\
1398 Text=\"?\",\
1399 Width=3,\
1400 Align=\"center\",\
1401 BackgroundColour=\"gray\",\
1402 TextColour=\"white\",\
1403 },\
1404 {\
1405 X=\"75%,+3\",\
1406 Y=9,\
1407 Name=\"GroupSettings_OptimiseReactor_Help_Button\",\
1408 Type=\"Button\",\
1409 Text=\"?\",\
1410 Width=3,\
1411 Align=\"center\",\
1412 BackgroundColour=\"gray\",\
1413 TextColour=\"white\",\
1414 },\
1415 {\
1416 X=\"100%,-5\",\
1417 Y=\"100%\",\
1418 Name=\"GroupSettings_Back_Button\",\
1419 Type=\"Button\",\
1420 Text=\"|Back|\",\
1421 Width=6,\
1422 Align=\"Center\",\
1423 BackgroundColour=\"gray\",\
1424 TextColour='white',\
1425 },\
1426 {\
1427 X=1,\
1428 Y=\"100%\",\
1429 Name=\"GroupSettings_Apply_Button\",\
1430 Type=\"Button\",\
1431 Text=\"|Apply|\",\
1432 Width=7,\
1433 Align=\"Center\",\
1434 BackgroundColour=\"gray\",\
1435 TextColour='white',\
1436 },\
1437 },\
1438 BackgroundColour='white'\
1439}",
1440 [ "home.view" ] = "{\
1441 Children={\
1442 {\
1443 X=0,\
1444 Y=1,\
1445 Name=\"topBar\",\
1446 Type=\"ProgressBar\",\
1447 Width=\"100%,+1\",\
1448 Align=\"Center\",\
1449 BackgroundColour='gray',\
1450 },\
1451 {\
1452 X=0,\
1453 Y=\"100%\",\
1454 Name=\"BottomBar\",\
1455 Type=\"ProgressBar\",\
1456 Width=\"100%,+1\",\
1457 Align=\"Center\",\
1458 BackgroundColour='gray',\
1459 },\
1460 {\
1461 X=1,\
1462 Y=1,\
1463 Name=\"Header_Static_Label\",\
1464 Type=\"Label\",\
1465 Text=\"Home\",\
1466 Width=\"100%\",\
1467 Align=\"Center\",\
1468 BackgroundColour=0,\
1469 TextColour='white',\
1470 },\
1471 {\
1472 X=2,\
1473 Y=3,\
1474 Name=\"TotalReactors_Static_Label\",\
1475 Type=\"Label\",\
1476 Text=\"Reactors: \",\
1477 BackgroundColour=0,\
1478 },\
1479 {\
1480 X=2,\
1481 Y=5,\
1482 Name=\"TotalTurbines_Static_Label\",\
1483 Type=\"Label\",\
1484 Text=\"Turbines: \",\
1485 BackgroundColour=0,\
1486 },\
1487 {\
1488 X=2,\
1489 Y=7,\
1490 Name=\"TotalBatteries_Static_Label\",\
1491 Type=\"Label\",\
1492 Text=\"Batteries: \",\
1493 BackgroundColour=0,\
1494 },\
1495 {\
1496 X=1,\
1497 Y=8,\
1498 Name=\"S1_Seperator\",\
1499 Type=\"Separator\",\
1500 Width=\"100%\",\
1501 Align=\"left\",\
1502 BackgroundColour=0,\
1503 },\
1504 {\
1505 X=2,\
1506 Y=9,\
1507 Name=\"TotalEnergy_Static_Label\",\
1508 Type=\"Label\",\
1509 Text=\"Energy Producing: \",\
1510 BackgroundColour=0,\
1511 },\
1512 {\
1513 X=2,\
1514 Y=11,\
1515 Name=\"TotalStored_Static_Label\",\
1516 Type=\"Label\",\
1517 Text=\"Energy Stored: \",\
1518 BackgroundColour=0,\
1519 },\
1520 {\
1521 X=1,\
1522 Y=12,\
1523 Name=\"S1_Seperator\",\
1524 Type=\"Separator\",\
1525 Width=\"100%\",\
1526 Align=\"left\",\
1527 BackgroundColour=0,\
1528 },\
1529 {\
1530 X=\"50%,-5\",\
1531 Y=3,\
1532 Name=\"Home_Reactors_Label\",\
1533 Type=\"Label\",\
1534 Text=\"3 connected\",\
1535 Width=\"100%\",\
1536 Align=\"left\",\
1537 BackgroundColour=0,\
1538 },\
1539 {\
1540 X=\"50%,-5\",\
1541 Y=5,\
1542 Name=\"Home_Turbines_Label\",\
1543 Type=\"Label\",\
1544 Text=\"12 connected\",\
1545 Width=\"100%\",\
1546 Align=\"left\",\
1547 BackgroundColour=0,\
1548 },\
1549 {\
1550 X=\"50%,-5\",\
1551 Y=7,\
1552 Name=\"Home_Batteries_Label\",\
1553 Type=\"Label\",\
1554 Text=\"5 connected\",\
1555 Width=\"100%\",\
1556 Align=\"left\",\
1557 BackgroundColour=0,\
1558 },\
1559 {\
1560 X=\"50%,-5\",\
1561 Y=9,\
1562 Name=\"Home_EnergyProduce_Label\",\
1563 Type=\"Label\",\
1564 Text=\"5000000 RF/t\",\
1565 Width=\"100%\",\
1566 Align=\"left\",\
1567 BackgroundColour=0,\
1568 },\
1569 {\
1570 X=\"50%,-5\",\
1571 Y=11,\
1572 Name=\"Home_EnergyStorage_ProgressBar\",\
1573 Type=\"ProgressBar\",\
1574 Width=\"50%,+4\",\
1575 Align=\"left\",\
1576 BackgroundColour='gray',\
1577 BarColour='red',\
1578 Value=3000,\
1579 Maximum=45000,\
1580 ShowText=true,\
1581 },\
1582 {\
1583 X=4,\
1584 Y=\"75%, -1\",\
1585 Name=\"Home_RandomFact_Label\",\
1586 Type=\"Label\",\
1587 Text=\"\",\
1588 Width=\"100%, -7\",\
1589 Align=\"Center\",\
1590 BackgroundColour=0,\
1591 },\
1592 {\
1593 X=\"100%, -2\",\
1594 Y=1,\
1595 Name=\"Home_Refresh_Button\",\
1596 Type=\"Button\",\
1597 Text=\"Q\",\
1598 BackgroundColour='gray',\
1599 TextColour='white',\
1600 Align=\"Center\",\
1601 },\
1602 {\
1603 X=\"25%, -6\",\
1604 Y=\"100%,-2\",\
1605 Name=\"Home_GroupOverview_Button\",\
1606 Type=\"Button\",\
1607 Text=\"View Groups\",\
1608 BackgroundColour='gray',\
1609 TextColour='white',\
1610 Align=\"Center\",\
1611 },\
1612 {\
1613 X=\"75%, -6\",\
1614 Y=\"100%,-2\",\
1615 Name=\"Home_GroupEdit_Button\",\
1616 Type=\"Button\",\
1617 Text=\"Edit Groups\",\
1618 BackgroundColour='gray',\
1619 TextColour='white',\
1620 Align=\"Center\",\
1621 },\
1622 {\
1623 X=\"100%, -5\",\
1624 Y=\"100%\",\
1625 Name=\"Home_Quit_Button\",\
1626 Type=\"Button\",\
1627 Text=\"|Quit|\",\
1628 BackgroundColour='gray',\
1629 TextColour='white',\
1630 Width=6,\
1631 Align=\"Center\",\
1632 },\
1633 {\
1634 X=\"1\",\
1635 Y=\"100%\",\
1636 Name=\"Home_Settings_Button\",\
1637 Type=\"Button\",\
1638 Text=\"|Settings|\",\
1639 BackgroundColour='gray',\
1640 TextColour='white',\
1641 Width=10,\
1642 Align=\"Center\",\
1643 },\
1644 },\
1645 BackgroundColour='white'\
1646}",
1647 [ "groupOverview.view" ] = "{\
1648 Children={\
1649 {\
1650 X=0,\
1651 Y=1,\
1652 Name=\"topBar\",\
1653 Type=\"ProgressBar\",\
1654 Width=\"100%,+1\",\
1655 Align=\"Center\",\
1656 BackgroundColour='gray',\
1657 },\
1658 {\
1659 X=0,\
1660 Y=\"100%\",\
1661 Name=\"BottomBar\",\
1662 Type=\"ProgressBar\",\
1663 Width=\"100%,+1\",\
1664 Align=\"Center\",\
1665 BackgroundColour='gray',\
1666 },\
1667 {\
1668 X=1,\
1669 Y=1,\
1670 Name=\"groupName_Label\",\
1671 Type=\"Label\",\
1672 Text=\"group_name\",\
1673 Width=\"100%\",\
1674 Align=\"Center\",\
1675 BackgroundColour='gray',\
1676 TextColour='white',\
1677 },\
1678 {\
1679 X=2,\
1680 Y=3,\
1681 Name=\"numReactor_Static_Label\",\
1682 Type=\"Label\",\
1683 Text=\"Reactors: \",\
1684 Width=\"100%\",\
1685 Align=\"left\",\
1686 BackgroundColour=0,\
1687 },\
1688 {\
1689 X=2,\
1690 Y=5,\
1691 Name=\"numTurbine_Static_Label\",\
1692 Type=\"Label\",\
1693 Text=\"Turbines: \",\
1694 Width=\"100%\",\
1695 Align=\"left\",\
1696 BackgroundColour=0,\
1697 },\
1698 {\
1699 X=2,\
1700 Y=7,\
1701 Name=\"numBattery_Static_Label\",\
1702 Type=\"Label\",\
1703 Text=\"Batteries: \",\
1704 Width=\"100%\",\
1705 Align=\"left\",\
1706 BackgroundColour=0,\
1707 },\
1708 {\
1709 X=1,\
1710 Y=8,\
1711 Name=\"S1_Seperator\",\
1712 Type=\"Separator\",\
1713 Width=\"100%\",\
1714 Align=\"left\",\
1715 BackgroundColour=0,\
1716 },\
1717 {\
1718 X=2,\
1719 Y=9,\
1720 Name=\"SteamRequired_Static_Label\",\
1721 Type=\"Label\",\
1722 Text=\"Steam Requiring: \",\
1723 Width=\"100%\",\
1724 Align=\"left\",\
1725 BackgroundColour=0,\
1726 },\
1727 {\
1728 X=2,\
1729 Y=11,\
1730 Name=\"SteamProduced_Static_Label\",\
1731 Type=\"Label\",\
1732 Text=\"Steam Producing: \",\
1733 Width=\"100%\",\
1734 Align=\"left\",\
1735 BackgroundColour=0,\
1736 },\
1737 {\
1738 X=1,\
1739 Y=12,\
1740 Name=\"S2_Seperator\",\
1741 Type=\"Separator\",\
1742 Width=\"100%\",\
1743 Align=\"left\",\
1744 BackgroundColour=0,\
1745 },\
1746 {\
1747 X=2,\
1748 Y=13,\
1749 Name=\"Rf_Static_Label\",\
1750 Type=\"Label\",\
1751 Text=\"Energy Producing: \",\
1752 Width=\"100%\",\
1753 Align=\"left\",\
1754 BackgroundColour=0,\
1755 },\
1756 {\
1757 X=2,\
1758 Y=15,\
1759 Name=\"RfStored_Static_Label\",\
1760 Type=\"Label\",\
1761 Text=\"Energy Stored: \",\
1762 Width=\"100%\",\
1763 Align=\"left\",\
1764 BackgroundColour=0,\
1765 },\
1766 {\
1767 X=1,\
1768 Y=16,\
1769 Name=\"S3_Seperator\",\
1770 Type=\"Separator\",\
1771 Width=\"100%\",\
1772 Align=\"left\",\
1773 BackgroundColour=0,\
1774 },\
1775 {\
1776 X=\"50%,-5\",\
1777 Y=3,\
1778 Name=\"GroupOverview_Reactors_Label\",\
1779 Type=\"Label\",\
1780 Text=\"2 out of 2 connected\",\
1781 Width=\"100%\",\
1782 Align=\"left\",\
1783 BackgroundColour=0,\
1784 },\
1785 {\
1786 X=\"50%,-5\",\
1787 Y=5,\
1788 Name=\"GroupOverview_Turbines_Label\",\
1789 Type=\"Label\",\
1790 Text=\"1 out of 2 conencted\",\
1791 Width=\"100%\",\
1792 Align=\"left\",\
1793 BackgroundColour=0,\
1794 },\
1795 {\
1796 X=\"50%,-5\",\
1797 Y=7,\
1798 Name=\"GroupOverview_Batteries_Label\",\
1799 Type=\"Label\",\
1800 Text=\"2 out of 2 connected\",\
1801 Width=\"100%\",\
1802 Align=\"left\",\
1803 BackgroundColour=0,\
1804 },\
1805 {\
1806 X=\"50%,-5\",\
1807 Y=9,\
1808 Name=\"GroupOverview_SteamRequire_Label\",\
1809 Type=\"Label\",\
1810 Text=\"10870 mB/t\",\
1811 Width=\"100%\",\
1812 Align=\"left\",\
1813 BackgroundColour=0,\
1814 },\
1815 {\
1816 X=\"50%,-5\",\
1817 Y=11,\
1818 Name=\"GroupOverview_SteamProduce_ProgressBar\",\
1819 Type=\"ProgressBar\",\
1820 Width=\"50%,+4\",\
1821 Align=\"left\",\
1822 BackgroundColour='gray',\
1823 BarColour='lightBlue',\
1824 Value=120000,\
1825 Maximum=100000,\
1826 ShowText=true,\
1827 },\
1828 {\
1829 X=\"50%,-5\",\
1830 Y=13,\
1831 Name=\"GroupOverview_EnergyProduce_Label\",\
1832 Type=\"Label\",\
1833 Text=\"45675 RF/t\",\
1834 Width=\"100%\",\
1835 Align=\"left\",\
1836 BackgroundColour=0,\
1837 },\
1838 {\
1839 X=\"50%,-5\",\
1840 Y=15,\
1841 Name=\"GroupOverview_EnergyStorage_ProgressBar\",\
1842 Type=\"ProgressBar\",\
1843 Width=\"50%,-8\",\
1844 Align=\"left\",\
1845 BackgroundColour='gray',\
1846 BarColour='red',\
1847 Value=200000,\
1848 Maximum=1000000,\
1849 ShowText=true,\
1850 },\
1851 {\
1852 X=\"100%,-11\",\
1853 Y=15,\
1854 Name=\"GroupOverview_EnergyInOut_Label\",\
1855 Type=\"Label\",\
1856 Text=\"+999400 RF/t\",\
1857 Align=\"left\",\
1858 BackgroundColour=0,\
1859 },\
1860 {\
1861 X=\"0%, +5\",\
1862 Y=\"100%, -2\",\
1863 Name=\"GroupOverview_Reactor_Button\",\
1864 Type=\"Button\",\
1865 Text=\"Reactors\",\
1866 BackgroundColour='gray',\
1867 TextColour='white',\
1868 },\
1869 {\
1870 X=\"50%, -5\",\
1871 Y=\"100%, -2\",\
1872 Name=\"GroupOverview_Turbine_Button\",\
1873 Type=\"Button\",\
1874 Text=\"Turbines\",\
1875 BackgroundColour='gray',\
1876 TextColour='white',\
1877 },\
1878 {\
1879 X=\"100%, -14\",\
1880 Y=\"100%, -2\",\
1881 Name=\"GroupOverview_Battery_Button\",\
1882 Type=\"Button\",\
1883 Text=\"Batteries\",\
1884 BackgroundColour='gray',\
1885 TextColour='white',\
1886 }, \
1887 {\
1888 X=\"100%, -15\",\
1889 Y=\"100%\",\
1890 Name=\"GroupOverview_Home_Button\",\
1891 Type=\"Button\",\
1892 Text=\"|Return to Home|\",\
1893 BackgroundColour='gray',\
1894 TextColour='white',\
1895 Width=16,\
1896 Align=\"Center\",\
1897 },\
1898 {\
1899 X=\"1\",\
1900 Y=\"100%\",\
1901 Name=\"GroupOverview_Settings_Button\",\
1902 Type=\"Button\",\
1903 Text=\"|Settings|\",\
1904 BackgroundColour='gray',\
1905 TextColour='white',\
1906 Width=10,\
1907 Align=\"Center\",\
1908 },\
1909 {\
1910 X=\"100%,-2\",\
1911 Y=1,\
1912 Name=\"GroupOverview_NextGroup_Button\",\
1913 Type=\"Button\",\
1914 Text=\" =>\",\
1915 Width=3,\
1916 Align=\"Center\",\
1917 BackgroundColour=\"gray\",\
1918 TextColour='white',\
1919 Enabled=false,\
1920 },\
1921 {\
1922 X=1,\
1923 Y=1,\
1924 Name=\"GroupOverview_LastGroup_Button\",\
1925 Type=\"Button\",\
1926 Text=\"<= \",\
1927 Width=3,\
1928 Align=\"Center\",\
1929 BackgroundColour=\"gray\",\
1930 TextColour='white',\
1931 Enabled=false,\
1932 },\
1933 },\
1934 BackgroundColour='white'\
1935}",
1936 [ "globalSettings.view" ] = "{\
1937 Children={\
1938 {\
1939 X=0,\
1940 Y=1,\
1941 Name=\"topBar\",\
1942 Type=\"ProgressBar\",\
1943 Width=\"100%,+1\",\
1944 Align=\"Center\",\
1945 BackgroundColour='gray',\
1946 },\
1947 {\
1948 X=0,\
1949 Y=\"100%\",\
1950 Name=\"BottomBar\",\
1951 Type=\"ProgressBar\",\
1952 Width=\"100%,+1\",\
1953 Align=\"Center\",\
1954 BackgroundColour='gray',\
1955 },\
1956 {\
1957 X=1,\
1958 Y=1,\
1959 Name=\"Header_Static_Label\",\
1960 Type=\"Label\",\
1961 Text=\"Settings\",\
1962 Width=\"100%\",\
1963 Align=\"Center\",\
1964 BackgroundColour='gray',\
1965 TextColour='white',\
1966 },\
1967 {\
1968 X=2,\
1969 Y=3,\
1970 Name=\"RefreshSpeed_Static_Label\",\
1971 Type=\"Label\",\
1972 Text=\"Refresh Speed: \",\
1973 Width=\"100%\",\
1974 Align=\"left\",\
1975 BackgroundColour=0,\
1976 },\
1977 {\
1978 X=2,\
1979 Y=5,\
1980 Name=\"RefreshHomeManuel_Static_Label\",\
1981 Type=\"Label\",\
1982 Text=\"L Exclude Home: \",\
1983 Width=\"100%\",\
1984 Align=\"left\",\
1985 BackgroundColour=0,\
1986 },\
1987 {\
1988 X=2,\
1989 Y=7,\
1990 Name=\"AuotmaticControl_Static_Label\",\
1991 Type=\"Label\",\
1992 Text=\"Autmatic Control: \",\
1993 Width=\"100%\",\
1994 Align=\"left\",\
1995 BackgroundColour=0,\
1996 },\
1997 {\
1998 X=1,\
1999 Y=8,\
2000 Name=\"S1_Seperator\",\
2001 Type=\"Separator\",\
2002 Width=\"100%\",\
2003 Align=\"left\",\
2004 BackgroundColour=0,\
2005 },\
2006 {\
2007 X=2,\
2008 Y=9,\
2009 Name=\"TemperaturColor_Static_Label\",\
2010 Type=\"Label\",\
2011 Text=\"Temperatur Color: \",\
2012 Width=\"100%\",\
2013 Align=\"left\",\
2014 BackgroundColour=0,\
2015 },\
2016 {\
2017 X=2,\
2018 Y=11,\
2019 Name=\"RPMColor_Static_Label\",\
2020 Type=\"Label\",\
2021 Text=\"RPM Color: \",\
2022 Width=\"100%\",\
2023 Align=\"left\",\
2024 BackgroundColour=0,\
2025 },\
2026 {\
2027 X=1,\
2028 Y=12,\
2029 Name=\"S2_Seperator\",\
2030 Type=\"Separator\",\
2031 Width=\"100%\",\
2032 Align=\"left\",\
2033 BackgroundColour=0,\
2034 },\
2035\
2036 {\
2037 X=2,\
2038 Y=13,\
2039 Name=\"Darkmode_Static_Label\",\
2040 Type=\"Label\",\
2041 Text=\"Darkmode: \",\
2042 Width=\"100%\",\
2043 Align=\"left\",\
2044 BackgroundColour=0,\
2045 },\
2046 {\
2047 X=2,\
2048 Y=15,\
2049 Name=\"OSK_Static_Label\",\
2050 Type=\"Label\",\
2051 Text=\"On Screen Keyboard: \",\
2052 Width=\"100%\",\
2053 Align=\"left\",\
2054 BackgroundColour=0,\
2055 },\
2056 {\
2057 X=2,\
2058 Y=17,\
2059 Name=\"GroupPath_Static_Label\",\
2060 Type=\"Label\",\
2061 Text=\"Group file: \",\
2062 Width=\"100%\",\
2063 Align=\"left\",\
2064 BackgroundColour=0,\
2065 },\
2066\
2067 {\
2068 X=\"100%,-5\",\
2069 Y=\"100%\",\
2070 Name=\"GlobalSettings_Back_Button\",\
2071 Type=\"Button\",\
2072 Text=\"|Back|\",\
2073 Width=6,\
2074 Align=\"Center\",\
2075 BackgroundColour=\"gray\",\
2076 TextColour='white',\
2077 },\
2078 {\
2079 X=1,\
2080 Y=\"100%\",\
2081 Name=\"GlobalSettings_Apply_Button\",\
2082 Type=\"Button\",\
2083 Text=\"|Apply|\",\
2084 Width=7,\
2085 Align=\"Center\",\
2086 BackgroundColour=\"gray\",\
2087 TextColour='white',\
2088 },\
2089 },\
2090 BackgroundColour='white'\
2091}",
2092 [ "batteryDetailed.view" ] = "{\
2093 Children={\
2094 {\
2095 X=0,\
2096 Y=1,\
2097 Name=\"topBar\",\
2098 Type=\"ProgressBar\",\
2099 Width=\"100%,+1\",\
2100 Align=\"Center\",\
2101 BackgroundColour='gray',\
2102 },\
2103 {\
2104 X=0,\
2105 Y=\"100%\",\
2106 Name=\"BottomBar\",\
2107 Type=\"ProgressBar\",\
2108 Width=\"100%,+1\",\
2109 Align=\"Center\",\
2110 BackgroundColour='gray',\
2111 },\
2112 {\
2113 X=1,\
2114 Y=1,\
2115 Name=\"batteryName_Label\",\
2116 Type=\"Label\",\
2117 Text=\"battery_name\",\
2118 Width=\"100%\",\
2119 Align=\"Center\",\
2120 BackgroundColour=0,\
2121 TextColour='white',\
2122 },\
2123 {\
2124 X=2,\
2125 Y=5,\
2126 Name=\"Type_Static_Label\",\
2127 Type=\"Label\",\
2128 Text=\"Type: \",\
2129 Width=\"100%\",\
2130 Align=\"left\",\
2131 BackgroundColour=0,\
2132 },\
2133 {\
2134 X=2,\
2135 Y=7,\
2136 Name=\"IO_Static_Label\",\
2137 Type=\"Label\",\
2138 Text=\"Input/Output: \",\
2139 Width=\"100%\",\
2140 Align=\"left\",\
2141 BackgroundColour=0,\
2142 },\
2143 {\
2144 X=2,\
2145 Y=9,\
2146 Name=\"EnergyStored_Static_Label\",\
2147 Type=\"Label\",\
2148 Text=\"Energy Stored: \",\
2149 Width=\"100%\",\
2150 Align=\"left\",\
2151 BackgroundColour=0,\
2152 },\
2153 {\
2154 X=\"50%,-5\",\
2155 Y=5,\
2156 Name=\"Battery_Type_Label\",\
2157 Type=\"Label\",\
2158 Text=\"EnderIO Capacitor Bank\",\
2159 Width=\"100%\",\
2160 Align=\"left\",\
2161 BackgroundColour=0,\
2162 },\
2163 {\
2164 X=\"50%,-5\",\
2165 Y=7,\
2166 Name=\"Battery_EnergyInOut_Label\",\
2167 Type=\"Label\",\
2168 Text=\"+50000 RF/t\",\
2169 Width=\"100%\",\
2170 Align=\"left\",\
2171 BackgroundColour=0,\
2172 },\
2173 {\
2174 X=2,\
2175 Y=11,\
2176 Name=\"Battery_EnergyStored_ProgressBar\",\
2177 Type=\"ProgressBar\",\
2178 Width=\"100%,-2\",\
2179 Align=\"left\",\
2180 BackgroundColour='gray',\
2181 BarColour='red',\
2182 Value=1000,\
2183 Maximum=45000,\
2184 ShowText=true,\
2185 },\
2186 {\
2187 X=1,\
2188 Y=13,\
2189 Name=\"Battery_EnergyStored_Label\",\
2190 Type=\"Label\",\
2191 Text=\"200000 RF / 5000000 RF\",\
2192 Width=\"100%\",\
2193 Align=\"Center\",\
2194 BackgroundColour=0,\
2195 },\
2196 {\
2197 X=\"100%,-5\",\
2198 Y=\"100%\",\
2199 Name=\"Battery_Back_Button\",\
2200 Type=\"Button\",\
2201 Text=\"|Back|\",\
2202 Width=6,\
2203 Align=\"Center\",\
2204 BackgroundColour=\"gray\",\
2205 TextColour='white',\
2206 },\
2207 {\
2208 X=\"100%,-2\",\
2209 Y=1,\
2210 Name=\"Battery_NextBattery_Button\",\
2211 Type=\"Button\",\
2212 Text=\" ->\",\
2213 Width=3,\
2214 Align=\"Center\",\
2215 BackgroundColour=\"gray\",\
2216 Enabled=false,\
2217 TextColour='white',\
2218 },\
2219 {\
2220 X=1,\
2221 Y=1,\
2222 Name=\"Battery_LastBattery_Button\",\
2223 Type=\"Button\",\
2224 Text=\"<- \",\
2225 Width=3,\
2226 Align=\"Center\",\
2227 BackgroundColour=\"gray\",\
2228 Enabled=false,\
2229 TextColour='white',\
2230 },\
2231 },\
2232 BackgroundColour='white'\
2233}",
2234 },
2235 [ "start.lua" ] = "local function a()\
2236 return shell.openTab(\"monitor monitor_0 r_control.lua ui ireallyknowwhatiamdoingiswear\")\
2237end\
2238\
2239local function b()\
2240 return shell.openTab(\"monitor monitor_1 r_control.lua ui ireallyknowwhatiamdoingiswear\")\
2241end\
2242 \
2243parallel.waitForAll(a, b)",
2244 Bedrock = "--Bedrock Build: 483\
2245--This code is squished down in to one, rather hard to read file.\
2246--As such it is not much good for anything other than being loaded as an API.\
2247--If you want to look at the code to learn from it, copy parts or just take a look,\
2248--you should go to the GitHub repo. http://github.com/oeed/Bedrock/\
2249\
2250--\
2251-- Bedrock is the core program framework used by all OneOS and OneCode programs.\
2252-- Inspired by Apple's Cocoa framework.\
2253-- (c) oeed 2014\
2254--\
2255-- For documentation see the Bedrock wiki, github.com/oeed/Bedrock/wiki/\
2256--\
2257\
2258local apis = {\
2259[\"Drawing\"] = [[\
2260local round = function(num, idp)\
2261 local mult = 10^(idp or 0)\
2262 return math.floor(num * mult + 0.5) / mult\
2263end\
2264\
2265local _w, _h = term.getSize()\
2266local copyBuffer = nil\
2267\
2268Screen = {\
2269 Width = _w,\
2270 Height = _h\
2271}\
2272\
2273Constraints = {\
2274 \
2275}\
2276\
2277CurrentConstraint = {1,1,_w,_h}\
2278IgnoreConstraint = false\
2279\
2280function AddConstraint(x, y, width, height)\
2281 local x2 = x + width - 1\
2282 local y2 = y + height - 1\
2283 table.insert(Drawing.Constraints, {x, y, x2, y2})\
2284 Drawing.GetConstraint()\
2285end\
2286\
2287function RemoveConstraint()\
2288 --table.remove(Drawing.Constraints, #Drawing.Constraints)\
2289 Drawing.Constraints[#Drawing.Constraints] = nil\
2290 Drawing.GetConstraint()\
2291end\
2292\
2293function GetConstraint()\
2294 local x = 1\
2295 local y = 1\
2296 local x2 = Drawing.Screen.Width\
2297 local y2 = Drawing.Screen.Height\
2298 for i, c in ipairs(Drawing.Constraints) do\
2299 if x < c[1] then\
2300 x = c[1]\
2301 end\
2302 if y < c[2] then\
2303 y = c[2]\
2304 end\
2305 if x2 > c[3] then\
2306 x2 = c[3]\
2307 end\
2308 if y2 > c[4] then\
2309 y2 = c[4]\
2310 end\
2311 end\
2312 Drawing.CurrentConstraint = {x, y, x2, y2}\
2313end\
2314\
2315function WithinContraint(x, y)\
2316 return Drawing.IgnoreConstraint or\
2317 (x >= Drawing.CurrentConstraint[1] and\
2318 y >= Drawing.CurrentConstraint[2] and\
2319 x <= Drawing.CurrentConstraint[3] and\
2320 y <= Drawing.CurrentConstraint[4])\
2321end\
2322\
2323colours.transparent = 0\
2324colors.transparent = 0\
2325\
2326Filters = {\
2327 None = {\
2328 [colours.white] = colours.white,\
2329 [colours.orange] = colours.orange,\
2330 [colours.magenta] = colours.magenta,\
2331 [colours.lightBlue] = colours.lightBlue,\
2332 [colours.yellow] = colours.yellow,\
2333 [colours.lime] = colours.lime,\
2334 [colours.pink] = colours.pink,\
2335 [colours.grey] = colours.grey,\
2336 [colours.lightGrey] = colours.lightGrey,\
2337 [colours.cyan] = colours.cyan,\
2338 [colours.purple] = colours.purple,\
2339 [colours.blue] = colours.blue,\
2340 [colours.brown] = colours.brown,\
2341 [colours.green] = colours.green,\
2342 [colours.red] = colours.red,\
2343 [colours.black] = colours.black,\
2344 [colours.transparent] = colours.transparent,\
2345 },\
2346\
2347 Greyscale = {\
2348 [colours.white] = colours.white,\
2349 [colours.orange] = colours.lightGrey,\
2350 [colours.magenta] = colours.lightGrey,\
2351 [colours.lightBlue] = colours.lightGrey,\
2352 [colours.yellow] = colours.lightGrey,\
2353 [colours.lime] = colours.lightGrey,\
2354 [colours.pink] = colours.lightGrey,\
2355 [colours.grey] = colours.grey,\
2356 [colours.lightGrey] = colours.lightGrey,\
2357 [colours.cyan] = colours.grey,\
2358 [colours.purple] = colours.grey,\
2359 [colours.blue] = colours.grey,\
2360 [colours.brown] = colours.grey,\
2361 [colours.green] = colours.grey,\
2362 [colours.red] = colours.grey,\
2363 [colours.black] = colours.black,\
2364 [colours.transparent] = colours.transparent,\
2365 },\
2366\
2367 BlackWhite = {\
2368 [colours.white] = colours.white,\
2369 [colours.orange] = colours.white,\
2370 [colours.magenta] = colours.white,\
2371 [colours.lightBlue] = colours.white,\
2372 [colours.yellow] = colours.white,\
2373 [colours.lime] = colours.white,\
2374 [colours.pink] = colours.white,\
2375 [colours.grey] = colours.black,\
2376 [colours.lightGrey] = colours.white,\
2377 [colours.cyan] = colours.black,\
2378 [colours.purple] = colours.black,\
2379 [colours.blue] = colours.black,\
2380 [colours.brown] = colours.black,\
2381 [colours.green] = colours.black,\
2382 [colours.red] = colours.black,\
2383 [colours.black] = colours.black,\
2384 [colours.transparent] = colours.transparent,\
2385 },\
2386\
2387 Darker = {\
2388 [colours.white] = colours.lightGrey,\
2389 [colours.orange] = colours.red,\
2390 [colours.magenta] = colours.purple,\
2391 [colours.lightBlue] = colours.cyan,\
2392 [colours.yellow] = colours.orange,\
2393 [colours.lime] = colours.green,\
2394 [colours.pink] = colours.magenta,\
2395 [colours.grey] = colours.black,\
2396 [colours.lightGrey] = colours.grey,\
2397 [colours.cyan] = colours.blue,\
2398 [colours.purple] = colours.grey,\
2399 [colours.blue] = colours.grey,\
2400 [colours.brown] = colours.grey,\
2401 [colours.green] = colours.grey,\
2402 [colours.red] = colours.brown,\
2403 [colours.black] = colours.black,\
2404 [colours.transparent] = colours.transparent,\
2405 },\
2406\
2407 Lighter = {\
2408 [colours.white] = colours.lightGrey,\
2409 [colours.orange] = colours.yellow,\
2410 [colours.magenta] = colours.pink,\
2411 [colours.lightBlue] = colours.cyan,\
2412 [colours.yellow] = colours.orange,\
2413 [colours.lime] = colours.green,\
2414 [colours.pink] = colours.magenta,\
2415 [colours.grey] = colours.lightGrey,\
2416 [colours.lightGrey] = colours.grey,\
2417 [colours.cyan] = colours.lightBlue,\
2418 [colours.purple] = colours.magenta,\
2419 [colours.blue] = colours.lightBlue,\
2420 [colours.brown] = colours.red,\
2421 [colours.green] = colours.lime,\
2422 [colours.red] = colours.orange,\
2423 [colours.black] = colours.grey,\
2424 [colours.transparent] = colours.transparent,\
2425 },\
2426\
2427 Highlight = {\
2428 [colours.white] = colours.lightGrey,\
2429 [colours.orange] = colours.yellow,\
2430 [colours.magenta] = colours.pink,\
2431 [colours.lightBlue] = colours.cyan,\
2432 [colours.yellow] = colours.orange,\
2433 [colours.lime] = colours.green,\
2434 [colours.pink] = colours.magenta,\
2435 [colours.grey] = colours.lightGrey,\
2436 [colours.lightGrey] = colours.grey,\
2437 [colours.cyan] = colours.lightBlue,\
2438 [colours.purple] = colours.magenta,\
2439 [colours.blue] = colours.lightBlue,\
2440 [colours.brown] = colours.red,\
2441 [colours.green] = colours.lime,\
2442 [colours.red] = colours.orange,\
2443 [colours.black] = colours.grey,\
2444 [colours.transparent] = colours.transparent,\
2445 },\
2446\
2447 Invert = {\
2448 [colours.white] = colours.black,\
2449 [colours.orange] = colours.blue,\
2450 [colours.magenta] = colours.green,\
2451 [colours.lightBlue] = colours.brown,\
2452 [colours.yellow] = colours.blue,\
2453 [colours.lime] = colours.purple,\
2454 [colours.pink] = colours.green,\
2455 [colours.grey] = colours.lightGrey,\
2456 [colours.lightGrey] = colours.grey,\
2457 [colours.cyan] = colours.red,\
2458 [colours.purple] = colours.green,\
2459 [colours.blue] = colours.yellow,\
2460 [colours.brown] = colours.lightBlue,\
2461 [colours.green] = colours.purple,\
2462 [colours.red] = colours.cyan,\
2463 [colours.black] = colours.white,\
2464 [colours.transparent] = colours.transparent,\
2465 },\
2466}\
2467\
2468function FilterColour(colour, filter)\
2469 if filter[colour] then\
2470 return filter[colour]\
2471 else\
2472 return colour\
2473 end\
2474end\
2475\
2476DrawCharacters = function (x, y, characters, textColour, bgColour)\
2477 Drawing.WriteStringToBuffer(x, y, tostring(characters), textColour, bgColour)\
2478end\
2479\
2480DrawBlankArea = function (x, y, w, h, colour)\
2481 if colour ~= colours.transparent then\
2482 Drawing.DrawArea (x, y, w, h, \" \", 1, colour)\
2483 end\
2484end\
2485\
2486DrawArea = function (x, y, w, h, character, textColour, bgColour)\
2487 --width must be greater than 1, otherwise we get problems\
2488 if w < 0 then\
2489 w = w * -1\
2490 elseif w == 0 then\
2491 w = 1\
2492 end\
2493\
2494 for ix = 1, w do\
2495 local currX = x + ix - 1\
2496 for iy = 1, h do\
2497 local currY = y + iy - 1\
2498 Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour)\
2499 end\
2500 end\
2501end\
2502\
2503DrawImage = function(_x,_y,tImage, w, h)\
2504 if tImage then\
2505 for y = 1, h do\
2506 if not tImage[y] then\
2507 break\
2508 end\
2509 for x = 1, w do\
2510 if not tImage[y][x] then\
2511 break\
2512 end\
2513 local bgColour = tImage[y][x]\
2514 local textColour = tImage.textcol[y][x] or colours.white\
2515 local char = tImage.text[y][x]\
2516 Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour)\
2517 end\
2518 end\
2519 elseif w and h then\
2520 Drawing.DrawBlankArea(_x, _y, w, h, colours.lightGrey)\
2521 end\
2522end\
2523\
2524--using .nft\
2525LoadImage = function(path, global)\
2526 local image = {\
2527 text = {},\
2528 textcol = {}\
2529 }\
2530 if fs.exists(path) then\
2531 local _io = io\
2532 if OneOS and global then\
2533 _io = OneOS.IO\
2534 end\
2535 local file = _io.open(path, \"r\")\
2536 if not file then\
2537 error('Error Occured. _io:'..tostring(_io)..' OneOS: '..tostring(OneOS)..' OneOS.IO'..tostring(OneOS.IO)..' io: '..tostring(io))\
2538 end\
2539 local sLine = file:read()\
2540 local num = 1\
2541 while sLine do \
2542 table.insert(image, num, {})\
2543 table.insert(image.text, num, {})\
2544 table.insert(image.textcol, num, {})\
2545 \
2546 --As we're no longer 1-1, we keep track of what index to write to\
2547 local writeIndex = 1\
2548 --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour\
2549 local bgNext, fgNext = false, false\
2550 --The current background and foreground colours\
2551 local currBG, currFG = nil,nil\
2552 for i=1,#sLine do\
2553 local nextChar = string.sub(sLine, i, i)\
2554 if nextChar:byte() == 30 then\
2555 bgNext = true\
2556 elseif nextChar:byte() == 31 then\
2557 fgNext = true\
2558 elseif bgNext then\
2559 currBG = Drawing.GetColour(nextChar)\
2560 if currBG == nil then\
2561 currBG = colours.transparent\
2562 end\
2563 bgNext = false\
2564 elseif fgNext then\
2565 currFG = Drawing.GetColour(nextChar)\
2566 if currFG == nil or currFG == colours.transparent then\
2567 currFG = colours.white\
2568 end\
2569 fgNext = false\
2570 else\
2571 if nextChar ~= \" \" and currFG == nil then\
2572 currFG = colours.white\
2573 end\
2574 image[num][writeIndex] = currBG\
2575 image.textcol[num][writeIndex] = currFG\
2576 image.text[num][writeIndex] = nextChar\
2577 writeIndex = writeIndex + 1\
2578 end\
2579 end\
2580 num = num+1\
2581 sLine = file:read()\
2582 end\
2583 file:close()\
2584 else\
2585 return nil\
2586 end\
2587 return image\
2588end\
2589\
2590DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)\
2591 w = w or Drawing.Screen.Width\
2592 h = h or Drawing.Screen.Height\
2593 x = x or 0\
2594 y = y or 0\
2595 x = math.floor((w - #characters) / 2) + x\
2596 y = math.floor(h / 2) + y\
2597\
2598 Drawing.DrawCharacters(x, y, characters, textColour, bgColour)\
2599end\
2600\
2601GetColour = function(hex)\
2602 if hex == ' ' then\
2603 return colours.transparent\
2604 end\
2605 local value = tonumber(hex, 16)\
2606 if not value then return nil end\
2607 value = math.pow(2,value)\
2608 return value\
2609end\
2610\
2611Clear = function (_colour)\
2612 _colour = _colour or colours.black\
2613 Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour)\
2614end\
2615\
2616Buffer = {}\
2617BackBuffer = {}\
2618\
2619TryRestore = false\
2620\
2621\
2622--TODO: make this quicker\
2623-- maybe sort the pixels in order of colour so it doesn't have to set the colour each time\
2624DrawBuffer = function()\
2625 if TryRestore and Restore then\
2626 Restore()\
2627 end\
2628\
2629 for y,row in pairs(Drawing.Buffer) do\
2630 for x,pixel in pairs(row) do\
2631 local shouldDraw = true\
2632 local hasBackBuffer = true\
2633 if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then\
2634 hasBackBuffer = false\
2635 end\
2636 if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then\
2637 shouldDraw = false\
2638 end\
2639 if shouldDraw then\
2640 term.setBackgroundColour(pixel[3])\
2641 term.setTextColour(pixel[2])\
2642 term.setCursorPos(x, y)\
2643 term.write(pixel[1])\
2644 end\
2645 end\
2646 end\
2647 Drawing.BackBuffer = Drawing.Buffer\
2648 Drawing.Buffer = {}\
2649end\
2650\
2651ClearBuffer = function()\
2652 Drawing.Buffer = {}\
2653end\
2654\
2655WriteStringToBuffer = function (x, y, characters, textColour,bgColour)\
2656 for i = 1, #characters do\
2657 local character = characters:sub(i,i)\
2658 Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)\
2659 end\
2660end\
2661\
2662WriteToBuffer = function(x, y, character, textColour,bgColour, cached)\
2663 if not cached and not Drawing.WithinContraint(x, y) then\
2664 return\
2665 end\
2666 x = round(x)\
2667 y = round(y)\
2668\
2669 if textColour == colours.transparent then\
2670 character = ' '\
2671 end\
2672\
2673 if bgColour == colours.transparent then\
2674 Drawing.Buffer[y] = Drawing.Buffer[y] or {}\
2675 Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {\"\", colours.white, colours.black}\
2676 Drawing.Buffer[y][x][1] = character\
2677 Drawing.Buffer[y][x][2] = textColour\
2678 else\
2679 Drawing.Buffer[y] = Drawing.Buffer[y] or {}\
2680 Drawing.Buffer[y][x] = {character, textColour, bgColour}\
2681 end\
2682\
2683 if copyBuffer then\
2684 copyBuffer[y] = copyBuffer[y] or {}\
2685 copyBuffer[y][x] = {character, textColour, bgColour} \
2686 end\
2687end\
2688\
2689DrawCachedBuffer = function(buffer)\
2690 for y, row in pairs(buffer) do\
2691 for x, pixel in pairs(row) do\
2692 WriteToBuffer(x, y, pixel[1], pixel[2], pixel[3], true)\
2693 end\
2694 end\
2695end\
2696\
2697StartCopyBuffer = function()\
2698 copyBuffer = {}\
2699end\
2700\
2701EndCopyBuffer = function()\
2702 local tmpCopy = copyBuffer\
2703 copyBuffer = nil\
2704 return tmpCopy\
2705end\
2706]],\
2707[\"Helpers\"] = [[\
2708LongestString = function(input, key, isKey)\
2709 local length = 0\
2710 if isKey then\
2711 for k, v in pairs(input) do\
2712 local titleLength = string.len(k)\
2713 if titleLength > length then\
2714 length = titleLength\
2715 end\
2716 end\
2717 else\
2718 for i = 1, #input do\
2719 local value = input[i]\
2720 if key then\
2721 if value[key] then\
2722 value = value[key]\
2723 else\
2724 value = ''\
2725 end\
2726 end\
2727 local titleLength = string.len(value)\
2728 if titleLength > length then\
2729 length = titleLength\
2730 end\
2731 end\
2732 end\
2733 return length\
2734end\
2735\
2736Split = function(str,sep)\
2737 sep=sep or'/'\
2738 return str:match(\"(.*\"..sep..\")\")\
2739end\
2740\
2741Extension = function(path, addDot)\
2742 if not path then\
2743 return nil\
2744 elseif not string.find(fs.getName(path), '%.') then\
2745 return ''\
2746 else\
2747 local _path = path\
2748 if path:sub(#path) == '/' then\
2749 _path = path:sub(1,#path-1)\
2750 end\
2751 local extension = _path:gmatch('%.[0-9a-z]+$')()\
2752 if extension then\
2753 extension = extension:sub(2)\
2754 else\
2755 --extension = nil\
2756 return ''\
2757 end\
2758 if addDot then\
2759 extension = '.'..extension\
2760 end\
2761 return extension:lower()\
2762 end\
2763end\
2764\
2765RemoveExtension = function(path)\
2766--local name = string.match(fs.getName(path), '(%a+)%.?.-')\
2767 if not path:find('%.') then\
2768 return path\
2769 end\
2770 local extension = Helpers.Extension(path)\
2771 if extension == path then\
2772 return fs.getName(path)\
2773 end\
2774 return string.gsub(path, extension, ''):sub(1, -2)\
2775end\
2776\
2777RemoveFileName = function(path)\
2778 if string.sub(path, -1) == '/' then\
2779 path = string.sub(path, 1, -2)\
2780 end\
2781 local v = string.match(path, \"(.-)([^\\\\/]-%.?([^%.\\\\/]*))$\")\
2782 if type(v) == 'string' then\
2783 return v\
2784 end\
2785 return v[1]\
2786end\
2787\
2788TruncateString = function(sString, maxLength)\
2789 if #sString > maxLength then\
2790 sString = sString:sub(1,maxLength-3)\
2791 if sString:sub(-1) == ' ' then\
2792 sString = sString:sub(1,maxLength-4)\
2793 end\
2794 sString = sString .. '...'\
2795 end\
2796 return sString\
2797end\
2798\
2799TruncateStringStart = function(sString, maxLength)\
2800 local len = #sString\
2801 if #sString > maxLength then\
2802 sString = sString:sub(len - maxLength, len - 3)\
2803 if sString:sub(-1) == ' ' then\
2804 sString = sString:sub(len - maxLength, len - 4)\
2805 end\
2806 sString = '...' .. sString\
2807 end\
2808 return sString\
2809end\
2810\
2811WrapText = function(text, maxWidth)\
2812 local lines = {''}\
2813 for word, space in text:gmatch('(%S+)(%s*)') do\
2814 local temp = lines[#lines] .. word .. space:gsub('\\n','')\
2815 if #temp > maxWidth then\
2816 table.insert(lines, '')\
2817 end\
2818 if space:find('\\n') then\
2819 lines[#lines] = lines[#lines] .. word\
2820 \
2821 space = space:gsub('\\n', function()\
2822 table.insert(lines, '')\
2823 return ''\
2824 end)\
2825 else\
2826 lines[#lines] = lines[#lines] .. word .. space\
2827 end\
2828 end\
2829 if #lines[1] == 0 then\
2830 table.remove(lines,1)\
2831 end\
2832 return lines\
2833end\
2834\
2835TidyPath = function(path)\
2836 path = '/'..path\
2837 if fs.exists(path) and fs.isDir(path) then\
2838 path = path .. '/'\
2839 end\
2840\
2841 path, n = path:gsub(\"//\", \"/\")\
2842 while n > 0 do\
2843 path, n = path:gsub(\"//\", \"/\")\
2844 end\
2845 return path\
2846end\
2847\
2848Capitalise = function(str)\
2849 return str:sub(1, 1):upper() .. str:sub(2, -1)\
2850end\
2851\
2852Round = function(num, idp)\
2853 local mult = 10^(idp or 0)\
2854 return math.floor(num * mult + 0.5) / mult\
2855end\
2856]],\
2857[\"Object\"] = [[\
2858X = 1\
2859Y = 1\
2860Width = 1\
2861Height = 1\
2862Parent = nil\
2863OnClick = nil\
2864Visible = true\
2865IgnoreClick = false\
2866Name = nil \
2867ClipDrawing = true\
2868UpdateDrawBlacklist = {}\
2869Fixed = false\
2870Ready = false\
2871\
2872DrawCache = {}\
2873\
2874NeedsDraw = function(self)\
2875 if not self.Visible then\
2876 return false\
2877 end\
2878 \
2879 if not self.DrawCache.Buffer or self.DrawCache.AlwaysDraw or self.DrawCache.NeedsDraw then\
2880 return true\
2881 end\
2882\
2883 if self.OnNeedsUpdate then\
2884 if self.OnNeedsUpdate() then\
2885 return true\
2886 end\
2887 end\
2888\
2889 if self.Children then\
2890 for i, v in ipairs(self.Children) do\
2891 if v:NeedsDraw() then\
2892 return true\
2893 end\
2894 end\
2895 end\
2896end\
2897\
2898GetPosition = function(self)\
2899 return self.Bedrock:GetAbsolutePosition(self)\
2900end\
2901\
2902GetOffsetPosition = function(self)\
2903 if not self.Parent then\
2904 return {X = 1, Y = 1}\
2905 end\
2906\
2907 local offset = {X = 0, Y = 0}\
2908 if not self.Fixed and self.Parent.ChildOffset then\
2909 offset = self.Parent.ChildOffset\
2910 end\
2911\
2912 return {X = self.X + offset.X, Y = self.Y + offset.Y}\
2913end\
2914\
2915Draw = function(self)\
2916 if not self.Visible then\
2917 return\
2918 end\
2919\
2920 self.DrawCache.NeedsDraw = false\
2921 local pos = self:GetPosition()\
2922 Drawing.StartCopyBuffer()\
2923\
2924 if self.ClipDrawing then\
2925 Drawing.AddConstraint(pos.X, pos.Y, self.Width, self.Height)\
2926 end\
2927\
2928 if self.OnDraw then\
2929 self:OnDraw(pos.X, pos.Y)\
2930 end\
2931\
2932 self.DrawCache.Buffer = Drawing.EndCopyBuffer()\
2933 \
2934 if self.Children then\
2935 for i, child in ipairs(self.Children) do\
2936 local pos = child:GetOffsetPosition()\
2937 if pos.Y + self.Height > 1 and pos.Y <= self.Height and pos.X + self.Width > 1 and pos.X <= self.Width then\
2938 child:Draw()\
2939 end\
2940 end\
2941 end\
2942\
2943\
2944 if self.OnPostChildrenDraw then\
2945 self:OnPostChildrenDraw(pos.X, pos.Y)\
2946 end\
2947\
2948 if self.ClipDrawing then\
2949 Drawing.RemoveConstraint()\
2950 end \
2951end\
2952\
2953ForceDraw = function(self, ignoreChildren, ignoreParent, ignoreBedrock)\
2954 if not ignoreBedrock and self.Bedrock then\
2955 self.Bedrock:ForceDraw()\
2956 end\
2957 self.DrawCache.NeedsDraw = true\
2958 if not ignoreParent and self.Parent then\
2959 self.Parent:ForceDraw(true, nil, true)\
2960 end\
2961 if not ignoreChildren and self.Children then\
2962 for i, child in ipairs(self.Children) do\
2963 child:ForceDraw(nil, true, true)\
2964 end\
2965 end\
2966end\
2967\
2968OnRemove = function(self)\
2969 if self == self.Bedrock:GetActiveObject() then\
2970 self.Bedrock:SetActiveObject()\
2971 end\
2972end\
2973\
2974local function ParseColour(value)\
2975 if type(value) == 'string' then\
2976 if colours[value] and type(colours[value]) == 'number' then\
2977 return colours[value]\
2978 elseif colors[value] and type(colors[value]) == 'number' then\
2979 return colors[value]\
2980 end\
2981 elseif type(value) == 'number' and (value == colours.transparent or (value >= colours.white and value <= colours.black)) then\
2982 return value\
2983 end\
2984 error('Invalid colour: \"'..tostring(value)..'\"')\
2985end\
2986\
2987Initialise = function(self, values)\
2988 local _new = values -- the new instance\
2989 _new.DrawCache = {\
2990 NeedsDraw = true,\
2991 AlwaysDraw = false,\
2992 Buffer = nil\
2993 }\
2994 setmetatable(_new, {__index = self} )\
2995\
2996 local new = {} -- the proxy\
2997 setmetatable(new, {\
2998 __index = function(t, k)\
2999 if k:find('Color') then\
3000 k = k:gsub('Color', 'Colour')\
3001 end\
3002\
3003 if k:find('Colour') and type(_new[k]) ~= 'table' and type(_new[k]) ~= 'function' then\
3004 if _new[k] then\
3005 return ParseColour(_new[k])\
3006 end\
3007 elseif _new[k] ~= nil then\
3008 return _new[k]\
3009 end\
3010 end,\
3011\
3012 __newindex = function (t,k,v)\
3013 if k:find('Color') then\
3014 k = k:gsub('Color', 'Colour')\
3015 end\
3016\
3017 if k == 'Width' or k == 'X' or k == 'Height' or k == 'Y' then\
3018 v = new.Bedrock:ParseStringSize(new.Parent, k, v)\
3019 end\
3020\
3021 if v ~= _new[k] then\
3022 _new[k] = v\
3023 if t.OnUpdate then\
3024 t:OnUpdate(k)\
3025 end\
3026\
3027 if t.UpdateDrawBlacklist[k] == nil then\
3028 t:ForceDraw()\
3029 end\
3030 end\
3031 end\
3032 })\
3033 if new.OnInitialise then\
3034 new:OnInitialise()\
3035 end\
3036\
3037 return new\
3038end\
3039\
3040AnimateValue = function(self, valueName, from, to, duration, done, tbl)\
3041 tbl = tbl or self\
3042 if type(tbl[valueName]) ~= 'number' then\
3043 error('Animated value ('..valueName..') must be number.')\
3044 elseif not self.Bedrock.AnimationEnabled then\
3045 tbl[valueName] = to\
3046 if done then\
3047 done()\
3048 end\
3049 return\
3050 end\
3051 from = from or tbl[valueName]\
3052 duration = duration or 0.2\
3053 local delta = to - from\
3054\
3055 local startTime = os.clock()\
3056 local previousFrame = startTime\
3057 local frame\
3058 frame = function()\
3059 local time = os.clock()\
3060 local totalTime = time - startTime\
3061 local isLast = totalTime >= duration\
3062\
3063 if isLast then\
3064 tbl[valueName] = to\
3065 self:ForceDraw()\
3066 if done then\
3067 done()\
3068 end\
3069 else\
3070 tbl[valueName] = self.Bedrock.Helpers.Round(from + delta * (totalTime / duration))\
3071 self:ForceDraw()\
3072 self.Bedrock:StartTimer(function()\
3073 frame()\
3074 end, 0.05)\
3075 end\
3076 end\
3077 frame()\
3078end\
3079\
3080Click = function(self, event, side, x, y)\
3081 if self.Visible and not self.IgnoreClick then\
3082 if event == 'mouse_click' and self.OnClick and self:OnClick(event, side, x, y) ~= false then\
3083 return true\
3084 elseif event == 'mouse_drag' and self.OnDrag and self:OnDrag(event, side, x, y) ~= false then\
3085 return true\
3086 elseif event == 'mouse_scroll' and self.OnScroll and self:OnScroll(event, side, x, y) ~= false then\
3087 return true\
3088 else\
3089 return false\
3090 end\
3091 else\
3092 return false\
3093 end\
3094\
3095end\
3096\
3097ToggleMenu = function(self, name, x, y)\
3098 return self.Bedrock:ToggleMenu(name, self, x, y)\
3099end\
3100\
3101function OnUpdate(self, value)\
3102 if value == 'Z' then\
3103 self.Bedrock:ReorderObjects()\
3104 end\
3105end\
3106]],\
3107}\
3108local objects = {\
3109[\"Button\"] = [[\
3110BackgroundColour = colours.lightGrey\
3111ActiveBackgroundColour = colours.blue\
3112ActiveTextColour = colours.white\
3113TextColour = colours.black\
3114DisabledTextColour = colours.lightGrey\
3115Text = \"\"\
3116Toggle = nil\
3117Momentary = true\
3118AutoWidth = true\
3119Align = 'Center'\
3120Enabled = true\
3121\
3122OnUpdate = function(self, value)\
3123 if value == 'Text' and self.AutoWidth then\
3124 self.Width = #self.Text + 2\
3125 end\
3126end\
3127\
3128OnDraw = function(self, x, y)\
3129 local bg = self.BackgroundColour\
3130\
3131 if self.Toggle then\
3132 bg = self.ActiveBackgroundColour\
3133 end\
3134\
3135 local txt = self.TextColour\
3136 if self.Toggle then\
3137 txt = self.ActiveTextColour\
3138 end\
3139 if not self.Enabled then\
3140 txt = self.DisabledTextColour\
3141 end\
3142 Drawing.DrawBlankArea(x, y, self.Width, self.Height, bg)\
3143\
3144 local _x = 1\
3145 if self.Align == 'Right' then\
3146 _x = self.Width - #self.Text - 1\
3147 elseif self.Align == 'Center' then\
3148 _x = math.floor((self.Width - #self.Text) / 2)\
3149 end\
3150\
3151 Drawing.DrawCharacters(x + _x, y-1+math.ceil(self.Height/2), self.Text, txt, bg)\
3152end\
3153\
3154OnLoad = function(self)\
3155 if self.Toggle ~= nil then\
3156 self.Momentary = false\
3157 end\
3158end\
3159\
3160Click = function(self, event, side, x, y)\
3161 if self.Visible and not self.IgnoreClick and self.Enabled and event ~= 'mouse_scroll' then\
3162 if self.OnClick then\
3163 if self.Momentary then\
3164 self.Toggle = true\
3165 self.Bedrock:StartTimer(function()self.Toggle = false end,0.25)\
3166 elseif self.Toggle ~= nil then\
3167 self.Toggle = not self.Toggle\
3168 end\
3169\
3170 self:OnClick(event, side, x, y, self.Toggle)\
3171 else\
3172 self.Toggle = not self.Toggle\
3173 end\
3174 return true\
3175 else\
3176 return false\
3177 end\
3178end\
3179]],\
3180[\"CollectionView\"] = [[\
3181Inherit = 'ScrollView'\
3182UpdateDrawBlacklist = {['NeedsItemUpdate']=true}\
3183\
3184TextColour = colours.black\
3185BackgroundColour = colours.white\
3186Items = false\
3187NeedsItemUpdate = false\
3188SpacingX = 2\
3189SpacingY = 1\
3190\
3191OnDraw = function(self, x, y)\
3192 if self.NeedsItemUpdate then\
3193 self:UpdateItems()\
3194 self.NeedsItemUpdate = false\
3195 end\
3196 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3197end\
3198\
3199local function MaxIcons(self, obj)\
3200 local x, y = 2, 1\
3201 if not obj.Height or not obj.Width then\
3202 error('You must provide each object\\'s height when adding to a CollectionView.')\
3203 end\
3204 local slotHeight = obj.Height + self.SpacingY\
3205 local slotWidth = obj.Width + self.SpacingX\
3206 local maxX = math.floor((self.Width - 2) / slotWidth)\
3207 return x, y, maxX, slotWidth, slotHeight\
3208end\
3209\
3210local function IconLocation(self, obj, i)\
3211 local x, y, maxX, slotWidth, slotHeight = MaxIcons(self, obj)\
3212 local rowPos = ((i - 1) % maxX)\
3213 local colPos = math.ceil(i / maxX) - 1\
3214 x = x + (slotWidth * rowPos)\
3215 y = y + colPos * slotHeight\
3216 return x, y\
3217end\
3218\
3219local function AddItem(self, v, i)\
3220 local toggle = false\
3221 if not self.CanSelect then\
3222 toggle = nil\
3223 end\
3224 local x, y = IconLocation(self, v, i)\
3225 local item = {\
3226 [\"X\"]=x,\
3227 [\"Y\"]=y,\
3228 [\"Name\"]=\"CollectionViewItem\",\
3229 [\"Type\"]=\"View\",\
3230 [\"TextColour\"]=self.TextColour,\
3231 [\"BackgroundColour\"]=0,\
3232 OnClick = function(itm)\
3233 if self.CanSelect then\
3234 for i2, _v in ipairs(self.Children) do\
3235 _v.Toggle = false\
3236 end\
3237 self.Selected = itm\
3238 end\
3239 end\
3240 }\
3241 for k, _v in pairs(v) do\
3242 item[k] = _v\
3243 end\
3244 self:AddObject(item)\
3245end\
3246\
3247\
3248UpdateItems = function(self)\
3249 self:RemoveAllObjects()\
3250 local groupMode = false\
3251 for k, v in pairs(self.Items) do\
3252 if type(k) == 'string' then\
3253 groupMode = true\
3254 break\
3255 end\
3256 end\
3257\
3258 for i, v in ipairs(self.Items) do\
3259 AddItem(self, v, i)\
3260 end\
3261 self:UpdateScroll()\
3262end\
3263\
3264OnUpdate = function(self, value)\
3265 if value == 'Items' then\
3266 self.NeedsItemUpdate = true\
3267 end\
3268end\
3269]],\
3270[\"ImageView\"] = [[\
3271Image = false\
3272\
3273OnDraw = function(self, x, y)\
3274 Drawing.DrawImage(x, y, self.Image, self.Width, self.Height)\
3275end\
3276\
3277OnLoad = function(self)\
3278 if self.Path and fs.exists(self.Path) then\
3279 self.Image = Drawing.LoadImage(self.Path)\
3280 end\
3281end\
3282\
3283OnUpdate = function(self, value)\
3284 if value == 'Path' then\
3285 if self.Path and fs.exists(self.Path) then\
3286 self.Image = Drawing.LoadImage(self.Path)\
3287 end\
3288 end\
3289end\
3290]],\
3291[\"Label\"] = [[\
3292TextColour = colours.black\
3293BackgroundColour = colours.transparent\
3294Text = \"\"\
3295AutoWidth = false\
3296Align = 'Left'\
3297\
3298local wrapText = function(text, maxWidth)\
3299 local lines = {''}\
3300 for word, space in text:gmatch('(%S+)(%s*)') do\
3301 local temp = lines[#lines] .. word .. space:gsub('\\n','')\
3302 if #temp > maxWidth then\
3303 table.insert(lines, '')\
3304 end\
3305 if space:find('\\n') then\
3306 lines[#lines] = lines[#lines] .. word\
3307 \
3308 space = space:gsub('\\n', function()\
3309 table.insert(lines, '')\
3310 return ''\
3311 end)\
3312 else\
3313 lines[#lines] = lines[#lines] .. word .. space\
3314 end\
3315 end\
3316 if #lines[1] == 0 then\
3317 table.remove(lines,1)\
3318 end\
3319 return lines\
3320end\
3321\
3322OnUpdate = function(self, value)\
3323 if value == 'Text' then\
3324 if self.AutoWidth then\
3325 self.Width = #self.Text\
3326 else\
3327 self.Height = #wrapText(self.Text, self.Width)\
3328 end\
3329 end\
3330end\
3331\
3332OnDraw = function(self, x, y)\
3333 for i, v in ipairs(wrapText(self.Text, self.Width)) do\
3334 local _x = 0\
3335 if self.Align == 'Right' then\
3336 _x = self.Width - #v\
3337 elseif self.Align == 'Center' then\
3338 _x = math.floor((self.Width - #v) / 2)\
3339 end\
3340 Drawing.DrawCharacters(x + _x, y + i - 1, v, self.TextColour, self.BackgroundColour)\
3341 end\
3342end\
3343]],\
3344[\"ListView\"] = [[\
3345Inherit = 'ScrollView'\
3346UpdateDrawBlacklist = {['NeedsItemUpdate']=true}\
3347\
3348TextColour = colours.black\
3349BackgroundColour = colours.white\
3350HeadingColour = colours.lightGrey\
3351SelectionBackgroundColour = colours.blue\
3352SelectionTextColour = colours.white\
3353Items = false\
3354CanSelect = false\
3355Selected = nil\
3356NeedsItemUpdate = false\
3357ItemMargin = 1\
3358HeadingMargin = 0\
3359TopMargin = 0\
3360\
3361OnDraw = function(self, x, y)\
3362 if self.NeedsItemUpdate then\
3363 self:UpdateItems()\
3364 end\
3365 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3366end\
3367\
3368local function AddItem(self, v, x, y, group)\
3369 local toggle = false\
3370 if not self.CanSelect then\
3371 toggle = nil\
3372 elseif v.Selected then\
3373 toggle = true\
3374 end\
3375 local item = {\
3376 [\"Width\"]=self.Width,\
3377 [\"X\"]=x,\
3378 [\"Y\"]=y,\
3379 [\"Name\"]=\"ListViewItem\",\
3380 [\"Type\"]=\"Button\",\
3381 [\"TextColour\"]=self.TextColour,\
3382 [\"BackgroundColour\"]=0,\
3383 [\"ActiveTextColour\"]=self.SelectionTextColour,\
3384 [\"ActiveBackgroundColour\"]=self.SelectionBackgroundColour,\
3385 [\"Align\"]='Left',\
3386 [\"Toggle\"]=toggle,\
3387 [\"Group\"]=group,\
3388 OnClick = function(itm)\
3389 if self.CanSelect then\
3390 self:SelectItem(itm)\
3391 elseif self.OnSelect then\
3392 self:OnSelect(itm.Text)\
3393 end\
3394 end\
3395 }\
3396 if type(v) == 'table' then\
3397 for k, _v in pairs(v) do\
3398 item[k] = _v\
3399 end\
3400 else\
3401 item.Text = v\
3402 end\
3403 \
3404 local itm = self:AddObject(item)\
3405 if v.Selected then\
3406 self:SelectItem(itm)\
3407 end\
3408end\
3409\
3410UpdateItems = function(self)\
3411 if not self.Items or type(self.Items) ~= 'table' then\
3412 self.Items = {}\
3413 end\
3414 self.Selected = nil\
3415 self:RemoveAllObjects()\
3416 local groupMode = false\
3417 for k, v in pairs(self.Items) do\
3418 if type(k) == 'string' then\
3419 groupMode = true\
3420 break\
3421 end\
3422 end\
3423\
3424 if not groupMode then\
3425 for i, v in ipairs(self.Items) do\
3426 AddItem(self, v, self.ItemMargin, i)\
3427 end\
3428 else\
3429 local y = self.TopMargin\
3430 for k, v in pairs(self.Items) do\
3431 y = y + 1\
3432 AddItem(self, {Text = k, TextColour = self.HeadingColour, IgnoreClick = true}, self.HeadingMargin, y)\
3433 for i, _v in ipairs(v) do\
3434 y = y + 1\
3435 AddItem(self, _v, 1, y, k)\
3436 end\
3437 y = y + 1\
3438 end\
3439 end\
3440 self:UpdateScroll()\
3441 self.NeedsItemUpdate = false\
3442end\
3443\
3444OnKeyChar = function(self, event, keychar)\
3445 if keychar == keys.up or keychar == keys.down then\
3446 local n = self:GetIndex(self.Selected)\
3447 if keychar == keys.up then\
3448 n = n - 1\
3449 else\
3450 n = n + 1\
3451 end\
3452 local new = self:GetNth(n)\
3453 if new then\
3454 self:SelectItem(new)\
3455 end\
3456 elseif keychar == keys.enter and self.Selected then\
3457 self.Selected:Click('mouse_click', 1, 1, 1)\
3458 end\
3459end\
3460\
3461--returns the index/'n' of the given item\
3462GetIndex = function(self, obj)\
3463 local n = 1\
3464 for i, v in ipairs(self.Children) do\
3465 if not v.IgnoreClick then\
3466 if obj == v then\
3467 return n\
3468 end\
3469 n = n + 1\
3470 end\
3471 end\
3472end\
3473\
3474--gets the 'nth' list item (does not include headings)\
3475GetNth = function(self, n)\
3476 local _n = 1\
3477 for i, v in ipairs(self.Children) do\
3478 if not v.IgnoreClick then\
3479 if n == _n then\
3480 return v\
3481 end\
3482 _n = _n + 1\
3483 end\
3484 end\
3485end\
3486\
3487SelectItem = function(self, item)\
3488 for i, v in ipairs(self.Children) do\
3489 v.Toggle = false\
3490 end\
3491 self.Selected = item\
3492 item.Toggle = true\
3493 if self.OnSelect then\
3494 self:OnSelect(item.Text)\
3495 end\
3496end\
3497\
3498OnUpdate = function(self, value)\
3499 if value == 'Items' then\
3500 self.NeedsItemUpdate = true\
3501 end\
3502end\
3503]],\
3504[\"Menu\"] = [[\
3505Inherit = 'View'\
3506\
3507TextColour = colours.black\
3508BackgroundColour = colours.white\
3509HideTop = false\
3510Prepared = false\
3511\
3512OnDraw = function(self, x, y)\
3513 Drawing.IgnoreConstraint = true\
3514 Drawing.DrawBlankArea(x + 1, y + (self.HideTop and 0 or 1), self.Width, self.Height + (self.HideTop and 1 or 0), colours.grey)\
3515 Drawing.IgnoreConstraint = false\
3516 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3517end\
3518\
3519OnLoad = function(self)\
3520 local owner = self.Owner\
3521 if type(owner) == 'string' then\
3522 owner = self.Bedrock:GetObject(self.Owner)\
3523 end\
3524\
3525 if owner then\
3526 if self.X == 0 and self.Y == 0 then\
3527 local pos = owner:GetPosition()\
3528 self.X = pos.X\
3529 self.Y = pos.Y + owner.Height\
3530 end\
3531 self.Owner = owner\
3532 else\
3533 self.Owner = nil\
3534 end\
3535end\
3536\
3537OnUpdate = function(self, value)\
3538 if value == 'Children' then\
3539 self.Height = #self.Children + 1 + (self.HideTop and 0 or 1)\
3540 if not self.BaseY then\
3541 self.BaseY = self.Y\
3542 end\
3543 if #self.Children > 0 and self.Children[1].Type == 'Button' then\
3544 self.Width = self.Bedrock.Helpers.LongestString(self.Children, 'Text') + 2\
3545 for i, v in ipairs(self.Children) do\
3546 if v.TextColour then\
3547 v.TextColour = self.TextColour\
3548 end\
3549 if v.BackgroundColour then\
3550 v.BackgroundColour = colours.transparent\
3551 end\
3552 if v.Colour then\
3553 v.Colour = colours.lightGrey\
3554 end\
3555 v.Align = 'Left'\
3556 v.X = 1\
3557 v.Y = i + (self.HideTop and 0 or 1)\
3558 v.Width = self.Width\
3559 v.Height = 1\
3560 end\
3561 elseif #self.Children > 0 and self.Children[1].Type == 'MenuItem' then\
3562 local width = 1\
3563 for i, v in ipairs(self.Children) do\
3564 if v.Width > width then\
3565 width = v.Width\
3566 end\
3567 end\
3568 self.Width = width\
3569 for i, v in ipairs(self.Children) do\
3570 if v.TextColour then\
3571 v.TextColour = self.TextColour\
3572 end\
3573 if v.Colour then\
3574 v.Colour = colours.lightGrey\
3575 end\
3576 v.X = 1\
3577 v.Y = i + (self.HideTop and 0 or 1)\
3578 v.Width = width\
3579 v.Height = 1\
3580 end\
3581 end\
3582\
3583 self.Y = self.BaseY\
3584 local pos = self:GetPosition()\
3585 if pos.Y + self.Height + 1 > Drawing.Screen.Height then\
3586 self.Y = self.BaseY - ((self.Height + pos.Y) - Drawing.Screen.Height)\
3587 end\
3588 \
3589 if pos.X + self.Width > Drawing.Screen.Width then\
3590 self.X = Drawing.Screen.Width - self.Width\
3591 end\
3592 end\
3593end\
3594\
3595Close = function(self, isBedrockCall)\
3596 self.Bedrock.Menu = nil\
3597 if not self.Prepared then\
3598 self.Parent:RemoveObject(self)\
3599 else\
3600 self.Visible = false\
3601 end\
3602\
3603 if self.Owner and self.Owner.Toggle then\
3604 self.Owner.Toggle = false\
3605 end\
3606 self.Parent:ForceDraw()\
3607 self = nil\
3608end\
3609\
3610OnChildClick = function(self, child, event, side, x, y)\
3611 self:Close()\
3612end\
3613]],\
3614[\"MenuItem\"] = [[\
3615BackgroundColour = colours.white\
3616TextColour = colours.black\
3617DisabledTextColour = colours.lightGrey\
3618ShortcutTextColour = colours.grey\
3619Text = \"\"\
3620Enabled = true\
3621Shortcut = nil\
3622ShortcutPadding = 2\
3623ShortcutName = nil\
3624\
3625OnUpdate = function(self, value)\
3626 if value == 'Text' then\
3627 if self.Shortcut then\
3628 self.Width = #self.Text + 2 + self.ShortcutPadding + #self.Shortcut\
3629 else\
3630 self.Width = #self.Text + 2\
3631 end\
3632 elseif value == 'OnClick' then\
3633 self:RegisterShortcut()\
3634 end\
3635end\
3636\
3637OnDraw = function(self, x, y)\
3638 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3639\
3640 local txt = self.TextColour\
3641 if not self.Enabled then\
3642 txt = self.DisabledTextColour\
3643 end\
3644 Drawing.DrawCharacters(x + 1, y, self.Text, txt, colours.transparent)\
3645\
3646 if self.Shortcut then\
3647 local shrt = self.ShortcutTextColour\
3648 if not self.Enabled then\
3649 shrt = self.DisabledTextColour\
3650 end\
3651 Drawing.DrawCharacters(x + self.Width - #self.Shortcut - 1, y, self.Shortcut, shrt, colours.transparent)\
3652 end\
3653end\
3654\
3655ParseShortcut = function(self)\
3656 local special = {\
3657 ['^'] = keys.leftShift,\
3658 ['<'] = keys.delete,\
3659 ['>'] = keys.delete,\
3660 ['#'] = keys.leftCtrl,\
3661 ['~'] = keys.leftAlt,\
3662 }\
3663\
3664 local keys = {}\
3665 for i = 1, #self.Shortcut do\
3666 local c = self.Shortcut:sub(i,i)\
3667 table.insert(keys, special[c] or c:lower())\
3668 end\
3669 return keys\
3670end\
3671\
3672RegisterShortcut = function(self)\
3673 if self.Shortcut then\
3674 self.Shortcut = self.Shortcut:upper()\
3675 self.ShortcutName = self.Bedrock:RegisterKeyboardShortcut(self:ParseShortcut(), function()\
3676 if self.OnClick and self.Enabled then\
3677 if self.Parent.Owner then\
3678 self.Parent:Close()\
3679 self.Parent.Owner.Toggle = true\
3680 self.Bedrock:StartTimer(function()\
3681 self.Parent.Owner.Toggle = false\
3682 end, 0.3)\
3683 end\
3684 return self:OnClick('keyboard_shortcut', 1, 1, 1)\
3685 else\
3686 return false\
3687 end\
3688 end)\
3689 end\
3690end\
3691\
3692OnRemove = function(self)\
3693 if self.ShortcutName then\
3694 self.Bedrock:UnregisterKeyboardShortcut(self.ShortcutName)\
3695 end\
3696end\
3697\
3698OnLoad = function(self)\
3699 if self.OnClick ~= nil then\
3700 self:RegisterShortcut()\
3701 end\
3702 -- self:OnUpdate('Text')\
3703end\
3704]],\
3705[\"NumberBox\"] = [[\
3706Inherit = 'View'\
3707\
3708Value = 1\
3709Minimum = 1\
3710Maximum = 99\
3711BackgroundColour = colours.lightGrey\
3712TextBoxTimer = nil\
3713Width = 7\
3714\
3715OnLoad = function(self)\
3716 self:AddObject({\
3717 X = self.Width - 1,\
3718 Y = 1,\
3719 Width = 1,\
3720 AutoWidth = false,\
3721 Text = '-',\
3722 Type = 'Button',\
3723 Name = 'AddButton',\
3724 BackgroundColour = colours.transparent,\
3725 OnClick = function()\
3726 self:ShiftValue(-1)\
3727 end\
3728 })\
3729\
3730 self:AddObject({\
3731 X = self.Width,\
3732 Y = 1,\
3733 Width = 1,\
3734 AutoWidth = false,\
3735 Text = '+',\
3736 Type = 'Button',\
3737 Name = 'SubButton',\
3738 BackgroundColour = colours.transparent,\
3739 OnClick = function()\
3740 self:ShiftValue(1)\
3741 end\
3742 })\
3743\
3744 self:AddObject({\
3745 X = 1,\
3746 Y = 1,\
3747 Width = self.Width - 2,\
3748 Text = tostring(self.Value),\
3749 Align = 'Center',\
3750 Type = 'TextBox',\
3751 BackgroundColour = colours.transparent,\
3752 OnChange = function(_self, event, keychar)\
3753 if keychar == keys.enter then\
3754 self:SetValue(tonumber(_self.Text))\
3755 self.TextBoxTimer = nil\
3756 end\
3757 if self.TextBoxTimer then\
3758 self.Bedrock:StopTimer(self.TextBoxTimer)\
3759 end\
3760\
3761 self.TextBoxTimer = self.Bedrock:StartTimer(function(_, timer)\
3762 if timer and timer == self.TextBoxTimer then\
3763 self:SetValue(tonumber(_self.Text))\
3764 self.TextBoxTimer = nil\
3765 end\
3766 end, 2)\
3767 end\
3768 })\
3769end\
3770\
3771OnScroll = function(self, event, dir, x, y)\
3772 self:ShiftValue(-dir)\
3773end\
3774\
3775ShiftValue = function(self, delta)\
3776 local val = tonumber(self:GetObject('TextBox').Text) or self.Minimum\
3777 self:SetValue(val + delta)\
3778end\
3779\
3780SetValue = function(self, newValue)\
3781 newValue = newValue or 0\
3782 if self.Maximum and newValue > self.Maximum then\
3783 newValue = self.Maximum\
3784 elseif self.Minimum and newValue < self.Minimum then\
3785 newValue = self.Minimum\
3786 end\
3787 self.Value = newValue\
3788 if self.OnChange then\
3789 self:OnChange()\
3790 end\
3791end\
3792\
3793OnUpdate = function(self, value)\
3794 if value == 'Value' then\
3795 local textbox = self:GetObject('TextBox')\
3796 if textbox then\
3797 textbox.Text = tostring(self.Value)\
3798 end\
3799 end\
3800end\
3801]],\
3802[\"ProgressBar\"] = [[\
3803BackgroundColour = colours.lightGrey\
3804BarColour = colours.blue\
3805TextColour = colours.white\
3806ShowText = false\
3807Value = 0\
3808Maximum = 1\
3809Indeterminate = false\
3810AnimationStep = 0\
3811\
3812OnDraw = function(self, x, y)\
3813 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3814\
3815 -- if self.Indeterminate then\
3816 -- for i = 1, self.Width do\
3817 -- local s = x + i - 1 + self.AnimationStep\
3818 -- if s % 4 == 1 or s % 4 == 2 then\
3819 -- Drawing.DrawBlankArea(s, y, 1, self.Height, self.BarColour)\
3820 -- end\
3821 -- end\
3822 -- self.AnimationStep = self.AnimationStep + 1\
3823 -- if self.AnimationStep >= 4 then\
3824 -- self.AnimationStep = 0\
3825 -- end\
3826 -- self.Bedrock:StartTimer(function()\
3827 -- self:Draw()\
3828 -- end, 0.25)\
3829 -- else\
3830 local values = self.Value\
3831 local barColours = self.BarColour\
3832 if type(values) == 'number' then\
3833 values = {values}\
3834 end\
3835 if type(barColours) == 'number' then\
3836 barColours = {barColours}\
3837 end\
3838 local total = 0\
3839 local _x = x\
3840 for i, v in ipairs(values) do\
3841 local width = self.Bedrock.Helpers.Round((v / self.Maximum) * self.Width)\
3842 total = total + v\
3843 Drawing.DrawBlankArea(_x, y, width, self.Height, barColours[((i-1)%#barColours)+1])\
3844 _x = _x + width\
3845 end\
3846\
3847 if self.ShowText then\
3848 local text = self.Bedrock.Helpers.Round((total / self.Maximum) * 100) .. '%'\
3849 Drawing.DrawCharactersCenter(x, y, self.Width, self.Height, text, self.TextColour, colours.transparent)\
3850 end\
3851 -- end\
3852end\
3853]],\
3854[\"ScrollBar\"] = [[\
3855BackgroundColour = colours.lightGrey\
3856BarColour = colours.lightBlue\
3857Scroll = 0\
3858MaxScroll = 0\
3859ClickPoint = nil\
3860Fixed = true\
3861\
3862OnUpdate = function(self, value)\
3863 if value == 'Text' and self.AutoWidth then\
3864 self.Width = #self.Text + 2\
3865 end\
3866end\
3867\
3868OnDraw = function(self, x, y)\
3869 local barHeight = self.Height * (self.Height / (self.Height + self.MaxScroll))\
3870 if barHeight < 3 then\
3871 barHeight = 3\
3872 end\
3873 local percentage = (self.Scroll/self.MaxScroll)\
3874\
3875 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
3876 Drawing.DrawBlankArea(x, y + math.ceil(self.Height*percentage - barHeight*percentage), self.Width, barHeight, self.BarColour)\
3877end\
3878\
3879OnScroll = function(self, event, direction, x, y)\
3880 if event == 'mouse_scroll' then\
3881 direction = self.Bedrock.Helpers.Round(direction * 3)\
3882 end\
3883 if self.Scroll < 0 or self.Scroll > self.MaxScroll then\
3884 return false\
3885 end\
3886 local old = self.Scroll\
3887 self.Scroll = self.Bedrock.Helpers.Round(self.Scroll + direction)\
3888 if self.Scroll < 0 then\
3889 self.Scroll = 0\
3890 elseif self.Scroll > self.MaxScroll then\
3891 self.Scroll = self.MaxScroll\
3892 end\
3893\
3894 if self.Scroll ~= old and self.OnChange then\
3895 self:OnChange()\
3896 end\
3897end\
3898\
3899OnClick = function(self, event, side, x, y)\
3900 if event == 'mouse_click' then\
3901 self.ClickPoint = y\
3902 else\
3903 if self.ClickPoint then\
3904 local gapHeight = self.Height - (self.Height * (self.Height / (self.Height + self.MaxScroll)))\
3905 local barHeight = self.Height * (self.Height / (self.Height + self.MaxScroll))\
3906 --local delta = (self.Height + self.MaxScroll) * ((y - self.ClickPoint) / barHeight)\
3907 local delta = ((y - self.ClickPoint)/gapHeight)*self.MaxScroll\
3908 --l(((y - self.ClickPoint)/gapHeight))\
3909 --l(delta)\
3910 self.Scroll = self.Bedrock.Helpers.Round(delta)\
3911 --l(self.Scroll)\
3912 --l('----')\
3913 if self.Scroll < 0 then\
3914 self.Scroll = 0\
3915 elseif self.Scroll > self.MaxScroll then\
3916 self.Scroll = self.MaxScroll\
3917 end\
3918 if self.OnChange then\
3919 self:OnChange()\
3920 end\
3921 end\
3922 end\
3923\
3924 local relScroll = self.MaxScroll * ((y-1)/self.Height)\
3925 if y == self.Height then\
3926 relScroll = self.MaxScroll\
3927 end\
3928 self.Scroll = self.Bedrock.Helpers.Round(relScroll)\
3929\
3930\
3931end\
3932\
3933OnDrag = OnClick\
3934]],\
3935[\"ScrollView\"] = [[\
3936Inherit = 'View'\
3937ChildOffset = false\
3938ContentWidth = 0\
3939ContentHeight = 0\
3940ScrollBarBackgroundColour = colours.lightGrey\
3941ScrollBarColour = colours.lightBlue\
3942\
3943CalculateContentSize = function(self)\
3944 local function calculateObject(obj)\
3945 local pos = obj:GetPosition()\
3946 local x2 = pos.X + obj.Width - 1\
3947 local y2 = pos.Y + obj.Height - 1\
3948 if obj.Children then\
3949 for i, child in ipairs(obj.Children) do\
3950 local _x2, _y2 = calculateObject(child)\
3951 if _x2 > x2 then\
3952 x2 = _x2\
3953 end\
3954 if _y2 > y2 then\
3955 y2 = _y2\
3956 end\
3957 end\
3958 end\
3959 return x2, y2\
3960 end\
3961\
3962 local pos = self:GetPosition()\
3963 local x2, y2 = calculateObject(self)\
3964 self.ContentWidth = x2 - pos.X + 1\
3965 self.ContentHeight = y2 - pos.Y + 1\
3966end\
3967\
3968UpdateScroll = function(self)\
3969 self.ChildOffset.Y = 0\
3970 self:CalculateContentSize()\
3971 if self.ContentHeight > self.Height then\
3972 if not self:GetObject('ScrollViewScrollBar') then\
3973 local _scrollBar = self:AddObject({\
3974 [\"Name\"] = 'ScrollViewScrollBar',\
3975 [\"Type\"] = 'ScrollBar',\
3976 [\"X\"] = self.Width,\
3977 [\"Y\"] = 1,\
3978 [\"Width\"] = 1,\
3979 [\"Height\"] = self.Height,\
3980 [\"BackgroundColour\"] = self.ScrollBarBackgroundColour,\
3981 [\"BarColour\"] = self.ScrollBarColour,\
3982 [\"Z\"]=999\
3983 })\
3984\
3985 _scrollBar.OnChange = function(scrollBar)\
3986 self.ChildOffset.Y = -scrollBar.Scroll\
3987 for i, child in ipairs(self.Children) do\
3988 child:ForceDraw()\
3989 end\
3990 end\
3991 end\
3992\
3993 if self:GetObject('ScrollViewScrollBar') then\
3994 self:GetObject('ScrollViewScrollBar').MaxScroll = self.ContentHeight - self.Height\
3995 end\
3996 else\
3997 self:RemoveObject('ScrollViewScrollBar')\
3998 end\
3999end\
4000\
4001OnScroll = function(self, event, direction, x, y)\
4002 if self:GetObject('ScrollViewScrollBar') then\
4003 self:GetObject('ScrollViewScrollBar'):OnScroll(event, direction, x, y)\
4004 end\
4005end\
4006\
4007OnLoad = function(self)\
4008 if not self.ChildOffset or not self.ChildOffset.X or not self.ChildOffset.Y then\
4009 self.ChildOffset = {X = 0, Y = 0}\
4010 end\
4011 self:UpdateScroll()\
4012end\
4013]],\
4014[\"SecureTextBox\"] = [[\
4015Inherit = 'TextBox'\
4016MaskCharacter = '*'\
4017\
4018OnDraw = function(self, x, y)\
4019 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
4020 if self.CursorPos > #self.Text then\
4021 self.CursorPos = #self.Text\
4022 elseif self.CursorPos < 0 then\
4023 self.CursorPos = 0\
4024 end\
4025 local text = ''\
4026\
4027 for i = 1, #self.Text do\
4028 text = text .. self.MaskCharacter\
4029 end\
4030\
4031 if self.Bedrock:GetActiveObject() == self then\
4032 if #text > (self.Width - 2) then\
4033 text = text:sub(#text-(self.Width - 3))\
4034 self.Bedrock.CursorPos = {x + 1 + self.Width-2, y}\
4035 else\
4036 self.Bedrock.CursorPos = {x + 1 + self.CursorPos, y}\
4037 end\
4038 self.Bedrock.CursorColour = self.TextColour\
4039 end\
4040\
4041 if #tostring(text) == 0 then\
4042 Drawing.DrawCharacters(x + 1, y, self.Placeholder, self.PlaceholderTextColour, self.BackgroundColour)\
4043 else\
4044 if not self.Selected then\
4045 Drawing.DrawCharacters(x + 1, y, text, self.TextColour, self.BackgroundColour)\
4046 else\
4047 for i = 1, #text do\
4048 local char = text:sub(i, i)\
4049 local textColour = self.TextColour\
4050 local backgroundColour = self.BackgroundColour\
4051 if i > self.DragStart and i - 1 <= self.CursorPos then\
4052 textColour = self.SelectedTextColour\
4053 backgroundColour = self.SelectedBackgroundColour\
4054 end\
4055 Drawing.DrawCharacters(x + i, y, char, textColour, backgroundColour)\
4056 end\
4057 end\
4058 end\
4059end\
4060]],\
4061[\"Separator\"] = [[\
4062Colour = colours.grey\
4063\
4064OnDraw = function(self, x, y)\
4065 local char = \"|\"\
4066 if self.Width > self.Height then\
4067 char = '-'\
4068 end\
4069 Drawing.DrawArea(x, y, self.Width, self.Height, char, self.Colour, colours.transparent)\
4070end\
4071]],\
4072[\"TextBox\"] = [[\
4073BackgroundColour = colours.lightGrey\
4074SelectedBackgroundColour = colours.blue\
4075SelectedTextColour = colours.white\
4076TextColour = colours.black\
4077PlaceholderTextColour = colours.grey\
4078Placeholder = ''\
4079AutoWidth = false\
4080Text = \"\"\
4081CursorPos = nil\
4082Numerical = false\
4083DragStart = nil\
4084Selected = false\
4085SelectOnClick = false\
4086ActualDragStart = nil\
4087\
4088OnDraw = function(self, x, y)\
4089 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
4090 if self.CursorPos > #self.Text then\
4091 self.CursorPos = #self.Text\
4092 elseif self.CursorPos < 0 then\
4093 self.CursorPos = 0\
4094 end\
4095 local text = self.Text\
4096 local offset = self:TextOffset()\
4097 if #text > (self.Width - 2) then\
4098 text = text:sub(offset+1, offset + self.Width - 2)\
4099 -- self.Bedrock.CursorPos = {x + 1 + self.Width-2, y}\
4100 -- else\
4101 end\
4102 if self.Bedrock:GetActiveObject() == self then\
4103 self.Bedrock.CursorPos = {x + 1 + self.CursorPos - offset, y}\
4104 self.Bedrock.CursorColour = self.TextColour\
4105 else\
4106 self.Selected = false\
4107 end\
4108\
4109 if #tostring(text) == 0 then\
4110 Drawing.DrawCharacters(x + 1, y, self.Placeholder, self.PlaceholderTextColour, self.BackgroundColour)\
4111 else\
4112 if not self.Selected then\
4113 Drawing.DrawCharacters(x + 1, y, text, self.TextColour, self.BackgroundColour)\
4114 else\
4115 local startPos = self.DragStart - offset\
4116 local endPos = self.CursorPos - offset\
4117 if startPos > endPos then\
4118 startPos = self.CursorPos - offset\
4119 endPos = self.DragStart - offset\
4120 end\
4121 for i = 1, #text do\
4122 local char = text:sub(i, i)\
4123 local textColour = self.TextColour\
4124 local backgroundColour = self.BackgroundColour\
4125\
4126 if i > startPos and i - 1 <= endPos then\
4127 textColour = self.SelectedTextColour\
4128 backgroundColour = self.SelectedBackgroundColour\
4129 end\
4130 Drawing.DrawCharacters(x + i, y, char, textColour, backgroundColour)\
4131 end\
4132 end\
4133 end\
4134end\
4135\
4136TextOffset = function(self)\
4137 if #self.Text < (self.Width - 2) then\
4138 return 0\
4139 elseif self.Bedrock:GetActiveObject() ~= self then\
4140 return 0\
4141 else\
4142 local textWidth = (self.Width - 2)\
4143 local offset = self.CursorPos - textWidth\
4144 if offset < 0 then\
4145 offset = 0\
4146 end\
4147 return offset\
4148 end\
4149end\
4150\
4151OnLoad = function(self)\
4152 if not self.CursorPos then\
4153 self.CursorPos = #self.Text\
4154 end\
4155end\
4156\
4157OnClick = function(self, event, side, x, y)\
4158 if self.Bedrock:GetActiveObject() ~= self and self.SelectOnClick then\
4159 self.CursorPos = #self.Text - 1\
4160 self.DragStart = 0\
4161 self.ActualDragStart = x - 2 + self:TextOffset()\
4162 self.Selected = true\
4163 else\
4164 self.CursorPos = x - 2 + self:TextOffset()\
4165 self.DragStart = self.CursorPos\
4166 self.Selected = false\
4167 end\
4168 self.Bedrock:SetActiveObject(self)\
4169end\
4170\
4171OnDrag = function(self, event, side, x, y)\
4172 self.CursorPos = x - 2 + self:TextOffset()\
4173 if self.ActualDragStart then\
4174 self.DragStart = self.ActualDragStart\
4175 self.ActualDragStart = nil\
4176 end\
4177 if self.DragStart then\
4178 self.Selected = true\
4179 end\
4180end\
4181\
4182OnKeyChar = function(self, event, keychar)\
4183 local deleteSelected = function()\
4184 if self.Selected then\
4185 local startPos = self.DragStart\
4186 local endPos = self.CursorPos\
4187 if startPos > endPos then\
4188 startPos = self.CursorPos\
4189 endPos = self.DragStart\
4190 end\
4191 self.Text = self.Text:sub(1, startPos) .. self.Text:sub(endPos + 2)\
4192 self.CursorPos = startPos\
4193 self.DragStart = nil\
4194 self.Selected = false\
4195 return true\
4196 end\
4197 end\
4198\
4199 if event == 'char' then\
4200 deleteSelected()\
4201 if self.Numerical then\
4202 keychar = tostring(tonumber(keychar))\
4203 end\
4204 if keychar == 'nil' then\
4205 return\
4206 end\
4207 self.Text = string.sub(self.Text, 1, self.CursorPos ) .. keychar .. string.sub( self.Text, self.CursorPos + 1 )\
4208 if self.Numerical then\
4209 self.Text = tostring(tonumber(self.Text))\
4210 if self.Text == 'nil' then\
4211 self.Text = '1'\
4212 end\
4213 end\
4214 \
4215 self.CursorPos = self.CursorPos + 1\
4216 if self.OnChange then\
4217 self:OnChange(event, keychar)\
4218 end\
4219 return false\
4220 elseif event == 'key' then\
4221 if keychar == keys.enter then\
4222 if self.OnChange then\
4223 self:OnChange(event, keychar)\
4224 end\
4225 elseif keychar == keys.left then\
4226 -- Left\
4227 if self.CursorPos > 0 then\
4228 if self.Selected then\
4229 self.CursorPos = self.DragStart\
4230 self.DragStart = nil\
4231 self.Selected = false\
4232 else\
4233 self.CursorPos = self.CursorPos - 1\
4234 end\
4235 if self.OnChange then\
4236 self:OnChange(event, keychar)\
4237 end\
4238 end\
4239 \
4240 elseif keychar == keys.right then\
4241 -- Right \
4242 if self.CursorPos < string.len(self.Text) then\
4243 if self.Selected then\
4244 self.CursorPos = self.CursorPos\
4245 self.DragStart = nil\
4246 self.Selected = false\
4247 else\
4248 self.CursorPos = self.CursorPos + 1\
4249 end\
4250 if self.OnChange then\
4251 self:OnChange(event, keychar)\
4252 end\
4253 end\
4254 \
4255 elseif keychar == keys.backspace then\
4256 -- Backspace\
4257 if not deleteSelected() and self.CursorPos > 0 then\
4258 self.Text = string.sub( self.Text, 1, self.CursorPos - 1 ) .. string.sub( self.Text, self.CursorPos + 1 )\
4259 self.CursorPos = self.CursorPos - 1 \
4260 if self.Numerical then\
4261 self.Text = tostring(tonumber(self.Text))\
4262 if self.Text == 'nil' then\
4263 self.Text = '1'\
4264 end\
4265 end\
4266 if self.OnChange then\
4267 self:OnChange(event, keychar)\
4268 end\
4269 end\
4270 elseif keychar == keys.home then\
4271 -- Home\
4272 self.CursorPos = 0\
4273 if self.OnChange then\
4274 self:OnChange(event, keychar)\
4275 end\
4276 elseif keychar == keys.delete then\
4277 if not deleteSelected() and self.CursorPos < string.len(self.Text) then\
4278 self.Text = string.sub( self.Text, 1, self.CursorPos ) .. string.sub( self.Text, self.CursorPos + 2 ) \
4279 if self.Numerical then\
4280 self.Text = tostring(tonumber(self.Text))\
4281 if self.Text == 'nil' then\
4282 self.Text = '1'\
4283 end\
4284 end\
4285 if self.OnChange then\
4286 self:OnChange(keychar)\
4287 end\
4288 end\
4289 elseif keychar == keys[\"end\"] then\
4290 -- End\
4291 self.CursorPos = string.len(self.Text)\
4292 else\
4293 if self.OnChange then\
4294 self:OnChange(event, keychar)\
4295 end\
4296 return false\
4297 end\
4298 end\
4299end\
4300]],\
4301[\"View\"] = [[\
4302BackgroundColour = colours.transparent\
4303Children = {}\
4304\
4305OnDraw = function(self, x, y)\
4306 if self.BackgroundColour then\
4307 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
4308 end\
4309end\
4310\
4311OnInitialise = function(self)\
4312 self.Children = {}\
4313end\
4314\
4315InitialiseFile = function(self, bedrock, file, name)\
4316 local _new = {}\
4317 _new.X = 1\
4318 _new.Y = 1\
4319 _new.Width = Drawing.Screen.Width\
4320 _new.Height = Drawing.Screen.Height\
4321 _new.BackgroundColour = file.BackgroundColour\
4322 _new.Name = name\
4323 _new.Children = {}\
4324 _new.Bedrock = bedrock\
4325 local new = self:Initialise(_new)\
4326 for i, obj in ipairs(file.Children) do\
4327 local view = bedrock:ObjectFromFile(obj, new)\
4328 if not view.Z then\
4329 view.Z = i\
4330 end\
4331 view.Parent = new\
4332 table.insert(new.Children, view)\
4333 end\
4334 return new\
4335end\
4336\
4337function CheckClick(self, object, x, y)\
4338 local offset = {X = 0, Y = 0}\
4339 if not object.Fixed and self.ChildOffset then\
4340 offset = self.ChildOffset\
4341 end\
4342 if object.X + offset.X <= x and object.Y + offset.Y <= y and object.X + offset.X + object.Width > x and object.Y + offset.Y + object.Height > y then\
4343 return true\
4344 end\
4345end\
4346\
4347function DoClick(self, object, event, side, x, y)\
4348 if object then\
4349 if self:CheckClick(object, x, y) then\
4350 local offset = {X = 0, Y = 0}\
4351 if not object.Fixed and self.ChildOffset then\
4352 offset = self.ChildOffset\
4353 end\
4354 return object:Click(event, side, x - object.X - offset.X + 1, y - object.Y + 1 - offset.Y)\
4355 end\
4356 end \
4357end\
4358\
4359Click = function(self, event, side, x, y, z)\
4360 if self.Visible and not self.IgnoreClick then\
4361 for i = #self.Children, 1, -1 do --children are ordered from smallest Z to highest, so this is done in reverse\
4362 local child = self.Children[i]\
4363 if self:DoClick(child, event, side, x, y) then\
4364 if self.OnChildClick then\
4365 self:OnChildClick(child, event, side, x, y)\
4366 end\
4367 return true\
4368 end\
4369 end\
4370 if event == 'mouse_click' and self.OnClick and self:OnClick(event, side, x, y) ~= false then\
4371 return true\
4372 elseif event == 'mouse_drag' and self.OnDrag and self:OnDrag(event, side, x, y) ~= false then\
4373 return true\
4374 elseif event == 'mouse_scroll' and self.OnScroll and self:OnScroll(event, side, x, y) ~= false then\
4375 return true\
4376 else\
4377 return false\
4378 end\
4379 else\
4380 return false\
4381 end\
4382end\
4383\
4384OnRemove = function(self)\
4385 if self == self.Bedrock:GetActiveObject() then\
4386 self.Bedrock:SetActiveObject()\
4387 end\
4388 for i, child in ipairs(self.Children) do\
4389 child:OnRemove()\
4390 end\
4391end\
4392\
4393local function findObjectNamed(view, name, minI)\
4394 local minI = minI or 0\
4395 if view and view.Children then\
4396 for i, child in ipairs(view.Children) do\
4397 if child.Name == name or child == name then\
4398 return child, i, view\
4399 elseif child.Children then\
4400 local found, index, foundView = findObjectNamed(child, name)\
4401 if found and minI <= index then\
4402 return found, index, foundView\
4403 end\
4404 end\
4405 end\
4406 end\
4407end\
4408\
4409function ReorderObjects(self)\
4410 if self.Children then\
4411 table.sort(self.Children, function(a,b)\
4412 return a.Z < b.Z \
4413 end)\
4414 for i, v in ipairs(self.Children) do\
4415 if v.ReorderObjects then\
4416 v:ReorderObjects()\
4417 end\
4418 end\
4419 end\
4420end\
4421\
4422function AddObject(self, info, extra, first)\
4423 if type(info) == 'string' then\
4424 local h = fs.open(self.Bedrock.ViewPath..info..'.view', 'r')\
4425 if h then\
4426 info = textutils.unserialize(h.readAll())\
4427 h.close()\
4428 else\
4429 error('Error in opening object: '..info)\
4430 end\
4431 end\
4432\
4433 if extra then\
4434 for k, v in pairs(extra) do\
4435 if v then\
4436 info[k] = v\
4437 end\
4438 end\
4439 end\
4440\
4441 local view = self.Bedrock:ObjectFromFile(info, self)\
4442 if not view.Z then\
4443 if first then\
4444 view.Z = 1\
4445 else\
4446 view.Z = #self.Children + 1\
4447 end\
4448 end\
4449 \
4450 if first then\
4451 table.insert(self.Children, 1, view)\
4452 else\
4453 table.insert(self.Children, view)\
4454 end\
4455 if self.Bedrock.View then\
4456 self.Bedrock:ReorderObjects()\
4457 end\
4458 self:ForceDraw()\
4459 return view\
4460end\
4461\
4462function GetObject(self, name)\
4463 return findObjectNamed(self, name)\
4464end\
4465\
4466local function findObjects(view, name)\
4467 local objects = {}\
4468 if view and view.Children then\
4469 for i, child in ipairs(view.Children) do\
4470 if child.Name == name or child == name then\
4471 table.insert(objects, child)\
4472 elseif child.Children then\
4473 local objs = findObjects(child, name)\
4474 if objs then\
4475 for i2, v in ipairs(objs) do\
4476 table.insert(objects, v)\
4477 end\
4478 end\
4479 end\
4480 end\
4481 end\
4482 return objects\
4483end\
4484\
4485function GetObjects(self, name)\
4486 return findObjects(self, name)\
4487end\
4488\
4489function RemoveObject(self, name)\
4490 local obj, index, view = findObjectNamed(self, name, minI)\
4491 if index then\
4492 view.Children[index]:OnRemove()\
4493 table.remove(view.Children, index)\
4494 if view.OnUpdate then\
4495 view:OnUpdate('Children')\
4496 end\
4497 return true\
4498 end\
4499 return false\
4500end\
4501\
4502function RemoveObjects(self, name)\
4503 local i = 1\
4504 while self:RemoveObject(name) and i < 100 do\
4505 i = i + 1\
4506 end\
4507 \
4508end\
4509\
4510function RemoveAllObjects(self)\
4511 for i, child in ipairs(self.Children) do\
4512 child:OnRemove()\
4513 self.Children[i] = nil\
4514 end\
4515 self:ForceDraw()\
4516end\
4517]],\
4518[\"Window\"] = [[\
4519Inherit = 'View'\
4520\
4521ToolBarColour = colours.lightGrey\
4522ToolBarTextColour = colours.black\
4523ShadowColour = colours.grey\
4524Title = ''\
4525Flashing = false\
4526CanClose = true\
4527OnCloseButton = nil\
4528OldActiveObject = nil\
4529\
4530LoadView = function(self)\
4531 local view = self:GetObject('View')\
4532 if view.ToolBarColour then\
4533 window.ToolBarColour = view.ToolBarColour\
4534 end\
4535 if view.ToolBarTextColour then\
4536 window.ToolBarTextColour = view.ToolBarTextColour\
4537 end\
4538 view.X = 1\
4539 view.Y = 2\
4540\
4541 view:ForceDraw()\
4542 self:OnUpdate('View')\
4543 if self.OnViewLoad then\
4544 self.OnViewLoad(view)\
4545 end\
4546 self.OldActiveObject = self.Bedrock:GetActiveObject()\
4547 self.Bedrock:SetActiveObject(view)\
4548end\
4549\
4550SetView = function(self, view)\
4551 self:RemoveObject('View')\
4552 table.insert(self.Children, view)\
4553 view.Parent = self\
4554 self:LoadView()\
4555end\
4556\
4557Flash = function(self)\
4558 self.Flashing = true\
4559 self:ForceDraw()\
4560 self.Bedrock:StartTimer(function()self.Flashing = false end, 0.4)\
4561end\
4562\
4563OnDraw = function(self, x, y)\
4564 local toolBarColour = (self.Flashing and colours.grey or self.ToolBarColour)\
4565 local toolBarTextColour = (self.Flashing and colours.black or self.ToolBarTextColour)\
4566 if toolBarColour then\
4567 Drawing.DrawBlankArea(x, y, self.Width, 1, toolBarColour)\
4568 end\
4569 if toolBarTextColour then\
4570 local title = self.Bedrock.Helpers.TruncateString(self.Title, self.Width - 2)\
4571 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, title, toolBarTextColour, toolBarColour)\
4572 end\
4573 Drawing.IgnoreConstraint = true\
4574 Drawing.DrawBlankArea(x + 1, y + 1, self.Width, self.Height, self.ShadowColour)\
4575 Drawing.IgnoreConstraint = false\
4576end\
4577\
4578Close = function(self)\
4579 self.Bedrock:SetActiveObject(self.OldActiveObject)\
4580 self.Bedrock.Window = nil\
4581 self.Bedrock:RemoveObject(self)\
4582 if self.OnClose then\
4583 self:OnClose()\
4584 end\
4585 self = nil\
4586end\
4587\
4588OnUpdate = function(self, value)\
4589 if value == 'View' and self:GetObject('View') then\
4590 self.Width = self:GetObject('View').Width\
4591 self.Height = self:GetObject('View').Height + 1\
4592 self.X = math.ceil((Drawing.Screen.Width - self.Width) / 2)\
4593 self.Y = math.ceil((Drawing.Screen.Height - self.Height) / 2)\
4594 elseif value == 'CanClose' then\
4595 self:RemoveObject('CloseButton')\
4596 if self.CanClose then\
4597 local button = self:AddObject({X = 1, Y = 1, Width = 1, Height = 1, Type = 'Button', BackgroundColour = colours.red, TextColour = colours.white, Text = 'x', Name = 'CloseButton'})\
4598 button.OnClick = function(btn)\
4599 if self.OnCloseButton then\
4600 self:OnCloseButton()\
4601 end\
4602 self:Close()\
4603 end\
4604 end\
4605 end\
4606end\
4607]],\
4608}\
4609BasePath = ''\
4610ProgramPath = nil\
4611\
4612-- Program functions...\
4613\
4614local function main(...)\
4615 -- Code here...\
4616end\
4617\
4618-- Run\
4619local args = {...}\
4620local _, err = pcall(function() main(unpack(args)) end)\
4621if err then\
4622 -- Make a nice error handling screen here...\
4623 term.setBackgroundColor(colors.black)\
4624 term.setTextColor(colors.white)\
4625 term.clear()\
4626 term.setCursorPos(1, 3)\
4627 print(\" An Error Has Occured! D:\\n\\n\")\
4628 print(\" \" .. tostring(err) .. \"\\n\\n\")\
4629 print(\" Press any key to exit...\")\
4630 os.pullEvent(\"key\")\
4631end\
4632\
4633function LoadAPIs(self)\
4634 local function loadAPI(name, content)\
4635 local env = setmetatable({}, { __index = getfenv() })\
4636 local func, err = loadstring(content, name..' (Bedrock API)')\
4637 if not func then\
4638 return false, printError(err)\
4639 end\
4640 setfenv(func, env)\
4641 func()\
4642 local api = {}\
4643 for k,v in pairs(env) do\
4644 api[k] = v\
4645 end\
4646 _G[name] = api\
4647 return true\
4648 end\
4649\
4650 local env = getfenv()\
4651 local function loadObject(name, content)\
4652 loadAPI(name, content)\
4653 if env[name].Inherit then\
4654 if not getfenv()[env[name].Inherit] then \
4655 if objects[env[name].Inherit] then\
4656 loadObject(env[name].Inherit, objects[env[name].Inherit])\
4657 elseif fs.exists(self.ProgramPath..'/Objects/'..env[name].Inherit..'.lua') then\
4658 local h = fs.open(self.ProgramPath..'/Objects/'..env[name].Inherit..'.lua', 'r')\
4659 loadObject(env[name].Inherit, h.readAll())\
4660 h.close()\
4661 loadObject(name, content)\
4662 return\
4663 end\
4664 end\
4665 env[name].__index = getfenv()[env[name].Inherit]\
4666 else\
4667 env[name].__index = Object\
4668 end\
4669 setmetatable(env[name], env[name])\
4670 end\
4671\
4672 for k, v in pairs(apis) do\
4673 loadAPI(k, v)\
4674 if k == 'Helpers' then\
4675 self.Helpers = Helpers\
4676 end\
4677 end\
4678\
4679 for k, v in pairs(objects) do\
4680 loadObject(k, v)\
4681 end\
4682 \
4683 local privateObjPath = self.ProgramPath..'/Objects/'\
4684 if fs.exists(privateObjPath) and fs.isDir(privateObjPath) then\
4685 for i, v in ipairs(fs.list(privateObjPath)) do\
4686 if v ~= '.DS_Store' then\
4687 local name = string.match(v, '(%a+)%.?.-')\
4688 local h = fs.open(privateObjPath..v, 'r')\
4689 loadObject(name, h.readAll())\
4690 h.close()\
4691 end\
4692 end\
4693 end\
4694 \
4695 local privateAPIPath = self.ProgramPath..'/APIs/'\
4696 if fs.exists(privateAPIPath) and fs.isDir(privateAPIPath) then\
4697 for i, v in ipairs(fs.list(privateAPIPath)) do\
4698 if v ~= '.DS_Store' then\
4699 local name = string.match(v, '(%a+)%.?.-')\
4700 local h = fs.open(privateAPIPath..v, 'r')\
4701 loadAPI(name, h.readAll())\
4702 h.close()\
4703 end\
4704 end\
4705 end\
4706end\
4707\
4708AllowTerminate = true\
4709\
4710View = nil\
4711Menu = nil\
4712\
4713ActiveObject = nil\
4714\
4715DrawTimer = nil\
4716DrawTimerExpiry = 0\
4717\
4718IsDrawing = false\
4719\
4720Running = true\
4721\
4722DefaultView = 'main'\
4723\
4724AnimationEnabled = true\
4725\
4726EventHandlers = {\
4727 \
4728}\
4729\
4730ObjectClickHandlers = {\
4731 \
4732}\
4733\
4734ObjectUpdateHandlers = {\
4735 \
4736}\
4737\
4738Timers = {\
4739 \
4740}\
4741\
4742ModifierKeys = {}\
4743KeyboardShortcuts = {}\
4744\
4745keys.leftCommand = 219\
4746keys.rightCommand = 220\
4747\
4748function Initialise(self, programPath)\
4749 self.ProgramPath = programPath or self.ProgramPath\
4750 if not programPath then\
4751 if self.ProgramPath then\
4752 local prgPath = self.ProgramPath\
4753 local prgName = fs.getName(prgPath)\
4754 if prgPath:find('/') then \
4755 self.ProgramPath = prgPath:sub(1, #prgPath-#prgName-1)\
4756 self.ProgramPath = prgPath:sub(1, #prgPath-#prgName-1) \
4757 else \
4758 self.ProgramPath = '' \
4759 end\
4760 else\
4761 self.ProgramPath = ''\
4762 end\
4763 end\
4764 self:LoadAPIs()\
4765 self.ViewPath = self.ProgramPath .. '/Views/'\
4766 --first, check that the barebones APIs are available\
4767 local requiredApis = {\
4768 'Drawing',\
4769 'View'\
4770 }\
4771 local env = getfenv()\
4772 for i,v in ipairs(requiredApis) do\
4773 if not env[v] then\
4774 error('The API: '..v..' is not loaded. Please make sure you load it to use Bedrock.')\
4775 end\
4776 end\
4777\
4778 local copy = { }\
4779 for k, v in pairs(self) do\
4780 if k ~= 'Initialise' then\
4781 copy[k] = v\
4782 end\
4783 end\
4784 return setmetatable(copy, getmetatable(self))\
4785end\
4786\
4787function HandleClick(self, event, side, x, y)\
4788 if self.Menu then\
4789 if not self.View:DoClick(self.Menu, event, side, x, y) then\
4790 self.Menu:Close()\
4791 end\
4792 elseif self.Window then\
4793 if not self.View:CheckClick(self.Window, x, y) then\
4794 self.Window:Flash()\
4795 else\
4796 self.View:DoClick(self.Window, event, side, x, y)\
4797 end\
4798 elseif self.View then\
4799 if self.View:Click(event, side, x, y) ~= false then\
4800 end \
4801 end\
4802end\
4803\
4804function UnregisterKeyboardShortcut(self, name)\
4805 if name then\
4806 self.KeyboardShortcuts[name] = nil\
4807 end\
4808end\
4809\
4810function RegisterKeyboardShortcut(self, keys, func, name)\
4811 name = name or tostring(math.random(1, 10000))\
4812 if type(keys[1]) == 'table' then\
4813 for i, v in ipairs(keys) do\
4814 self.KeyboardShortcuts[name] = {Keys = v, Function = func}\
4815 end\
4816 else\
4817 self.KeyboardShortcuts[name] = {Keys = keys, Function = func}\
4818 end\
4819 return name\
4820end\
4821\
4822function TryKeyboardShortcuts(self, keychar)\
4823 if keychar == keys.backspace then\
4824 keychar = keys.delete\
4825 end\
4826\
4827 local len = 1 -- + keychar\
4828 for k, v in pairs(self.ModifierKeys) do\
4829 len = len + 1\
4830 end\
4831\
4832 for _, shortcut in pairs(self.KeyboardShortcuts) do\
4833 local match = true\
4834 for i2, key in ipairs(shortcut.Keys) do\
4835 if self.ModifierKeys[key] == nil and key ~= keychar then\
4836 match = false\
4837 end\
4838 end\
4839\
4840 if match and #shortcut.Keys == len then\
4841 return shortcut.Function() ~= false\
4842 end\
4843 end\
4844end\
4845\
4846function HandleKeyChar(self, event, keychar)\
4847 if keychar == keys.leftCtrl or keychar == keys.leftShift or keychar == keys.leftAlt or keychar == keys.leftCommand or keychar == keys.rightCommand or keychar == keys.rightCtrl or keychar == keys.rightShift or keychar == keys.rightAlt then\
4848 if keychar == keys.leftCommand or keychar == keys.rightCommand or keychar == keys.rightCtrl then\
4849 keychar = keys.leftCtrl\
4850 elseif keychar == keys.rightAlt then\
4851 keychar = keys.leftAlt\
4852 elseif keychar == keys.rightShift then\
4853 keychar = keys.leftShift\
4854 end\
4855 self.ModifierKeys[keychar] = self:StartTimer(function(_, timer)\
4856 if timer == self.ModifierKeys[keychar] then\
4857 self.ModifierKeys[keychar] = nil\
4858 end\
4859 end, 1)\
4860 elseif self:TryKeyboardShortcuts(keychar) then\
4861 return\
4862 end\
4863\
4864 if self:GetActiveObject() then\
4865 local activeObject = self:GetActiveObject()\
4866 if activeObject.OnKeyChar then\
4867 if activeObject:OnKeyChar(event, keychar) ~= false then\
4868 --self:Draw()\
4869 end\
4870 end\
4871 end\
4872end\
4873\
4874PreparedMenus = {}\
4875\
4876function PrepareMenu(self, name)\
4877 local menu = self:AddObject(name, {Type = 'Menu', X = 1, Y = 1, Prepared = true})\
4878 menu.Visible = false\
4879 self.PreparedMenus[name] = menu\
4880 return menu\
4881end\
4882\
4883function ToggleMenu(self, name, owner, x, y)\
4884 if self.Menu then\
4885 self.Menu:Close()\
4886 return false\
4887 else\
4888 self:SetMenu(name, owner, x, y)\
4889 return true\
4890 end\
4891end\
4892\
4893function SetMenu(self, menu, owner, x, y)\
4894 x = x or 1\
4895 y = y or 1\
4896 if self.Menu then\
4897 self.Menu:Close()\
4898 end \
4899 if menu then\
4900 local pos = owner:GetPosition()\
4901 if self.PreparedMenus[menu] then\
4902 self.Menu = self.PreparedMenus[menu]\
4903 self.Menu.Visible = true\
4904 self.Menu.Owner = owner\
4905 self.Menu.X = pos.X + x - 1\
4906 self.Menu.Y = pos.Y + y\
4907 self.Menu.Z = self.View.Children[#self.View.Children].Z + 1\
4908 self:ReorderObjects()\
4909 else\
4910 self.Menu = self:AddObject(menu, {Type = 'Menu', Owner = owner, X = pos.X + x - 1, Y = pos.Y + y, Z = self.View.Children[#self.View.Children].Z + 1})\
4911 end\
4912 end\
4913end\
4914\
4915function ObjectClick(self, name, func)\
4916 self.ObjectClickHandlers[name] = func\
4917end\
4918\
4919function ClickObject(self, object, event, side, x, y)\
4920 if self.ObjectClickHandlers[object.Name] then\
4921 return self.ObjectClickHandlers[object.Name](object, event, side, x, y)\
4922 end\
4923 return false\
4924end\
4925\
4926function ObjectUpdate(self, name, func)\
4927 self.ObjectUpdateHandlers[name] = func\
4928end\
4929\
4930function UpdateObject(self, object, ...)\
4931 if self.ObjectUpdateHandlers[object.Name] then\
4932 self.ObjectUpdateHandlers[object.Name](object, ...)\
4933 --self:Draw()\
4934 end\
4935end\
4936\
4937function GetAbsolutePosition(self, obj)\
4938 if not obj.Parent then\
4939 return {X = obj.X, Y = obj.Y}\
4940 else\
4941 local pos = self:GetAbsolutePosition(obj.Parent)\
4942 local x = pos.X + obj.X - 1\
4943 local y = pos.Y + obj.Y - 1\
4944 if not obj.Fixed and obj.Parent.ChildOffset then\
4945 x = x + obj.Parent.ChildOffset.X\
4946 y = y + obj.Parent.ChildOffset.Y\
4947 end\
4948 return {X = x, Y = y}\
4949 end\
4950end\
4951\
4952function LoadView(self, name, draw)\
4953 if self.View and self.OnViewClose then\
4954 self.OnViewClose(self.View.Name)\
4955 end\
4956 if self.View then\
4957 self.View:OnRemove()\
4958 end\
4959 local success = false\
4960\
4961 if Drawing.Screen.Width <= 26 and fs.exists(self.ViewPath..name..'-pocket.view') then\
4962 name = name..'-pocket'\
4963 elseif Drawing.Screen.Width <= 39 and fs.exists(self.ViewPath..name..'-turtle.view') then\
4964 name = name..'-turtle'\
4965 end\
4966\
4967 if not fs.exists(self.ViewPath..name..'.view') then\
4968 error('The view: '..name..'.view does not exist.')\
4969 end\
4970\
4971 local h = fs.open(self.ViewPath..name..'.view', 'r')\
4972 if h then\
4973 local view = textutils.unserialize(h.readAll())\
4974 h.close()\
4975 if view then\
4976 self.View = View:InitialiseFile(self, view, name)\
4977 self:ReorderObjects()\
4978\
4979 if OneOS and view.ToolBarColour then\
4980 OneOS.ToolBarColour = view.ToolBarColour\
4981 end\
4982 if OneOS and view.ToolBarTextColour then\
4983 OneOS.ToolBarTextColour = view.ToolBarTextColour\
4984 end\
4985 if not self:GetActiveObject() then\
4986 self:SetActiveObject()\
4987 end\
4988 success = true\
4989 end\
4990 end\
4991\
4992 if success and self.OnViewLoad then\
4993 self.OnViewLoad(name)\
4994 end\
4995\
4996 if draw ~= false then\
4997 self:Draw()\
4998 end\
4999\
5000 if not success then\
5001 error('Failed to load view: '..name..'. It probably isn\\'t formatted correctly. Did you forget a } or ,?')\
5002 end\
5003\
5004 return success\
5005end\
5006\
5007function InheritFile(self, file, name)\
5008 local h = fs.open(self.ViewPath..name..'.view', 'r')\
5009 if h then\
5010 local super = textutils.unserialize(h.readAll())\
5011 if super then\
5012 if type(super) ~= 'table' then\
5013 error('View: \"'..name..'.view\" is not formatted correctly.')\
5014 end\
5015\
5016 for k, v in pairs(super) do\
5017 if not file[k] then\
5018 file[k] = v\
5019 end\
5020 end\
5021 return file\
5022 end\
5023 end\
5024 return file\
5025end\
5026\
5027function ParseStringSize(self, parent, k, v)\
5028 local parentSize = parent.Width\
5029 if k == 'Height' or k == 'Y' then\
5030 parentSize = parent.Height\
5031 end\
5032 local parts = {v}\
5033 if type(v) == 'string' and string.find(v, ',') then\
5034 parts = {}\
5035 for word in string.gmatch(v, '([^,]+)') do\
5036 table.insert(parts, word)\
5037 end\
5038 end\
5039\
5040 v = 0\
5041 for i2, part in ipairs(parts) do\
5042 if type(part) == 'string' and part:sub(#part) == '%' then\
5043 v = v + math.ceil(parentSize * (tonumber(part:sub(1, #part-1)) / 100))\
5044 else\
5045 v = v + tonumber(part)\
5046 end\
5047 end\
5048 return v\
5049end\
5050\
5051function ObjectFromFile(self, file, view)\
5052 local env = getfenv()\
5053 if env[file.Type] then\
5054 if not env[file.Type].Initialise then\
5055 error('Malformed Object: '..file.Type)\
5056 end\
5057 local object = {}\
5058\
5059 if file.InheritView then\
5060 file = self:InheritFile(file, file.InheritView)\
5061 end\
5062 \
5063 object.AutoWidth = true\
5064 for k, v in pairs(file) do\
5065 if k == 'Width' or k == 'X' or k == 'Height' or k == 'Y' then\
5066 v = self:ParseStringSize(view, k, v)\
5067 end\
5068\
5069 if k == 'Width' then\
5070 object.AutoWidth = false\
5071 end\
5072 if k ~= 'Children' then\
5073 object[k] = v\
5074 else\
5075 object[k] = {}\
5076 end\
5077 end\
5078\
5079 object.Parent = view\
5080 object.Bedrock = self\
5081 if not object.Name then\
5082 object.Name = file.Type\
5083 end\
5084\
5085 object = env[file.Type]:Initialise(object)\
5086\
5087 if file.Children then\
5088 for i, obj in ipairs(file.Children) do\
5089 local _view = self:ObjectFromFile(obj, object)\
5090 if not _view.Z then\
5091 _view.Z = i\
5092 end\
5093 _view.Parent = object\
5094 table.insert(object.Children, _view)\
5095 end\
5096 end\
5097\
5098 if not object.OnClick then\
5099 object.OnClick = function(...) return self:ClickObject(...) end\
5100 end\
5101 --object.OnUpdate = function(...) self:UpdateObject(...) end\
5102\
5103 if object.OnUpdate then\
5104 for k, v in pairs(env[file.Type]) do\
5105 object:OnUpdate(k)\
5106 end\
5107\
5108 for k, v in pairs(object.__index) do\
5109 object:OnUpdate(k)\
5110 end\
5111 end\
5112\
5113 if object.Active then\
5114 object.Bedrock:SetActiveObject(object)\
5115 end\
5116 if object.OnLoad then\
5117 object:OnLoad()\
5118 end\
5119 object.Ready = true\
5120 return object\
5121 elseif not file.Type then\
5122 error('No object type specified. (e.g. Type = \"Button\")')\
5123 else\
5124 error('No Object: '..file.Type..'. The API probably isn\\'t loaded')\
5125 end\
5126end\
5127\
5128function ReorderObjects(self)\
5129 if self.View and self.View.Children then\
5130 self.View:ReorderObjects()\
5131 end\
5132end\
5133\
5134function AddObject(self, info, extra, first)\
5135 return self.View:AddObject(info, extra, first)\
5136end\
5137\
5138function GetObject(self, name)\
5139 return self.View:GetObject(name)\
5140end\
5141\
5142function GetObjects(self, name)\
5143 return self.View:GetObjects(name)\
5144end\
5145\
5146function RemoveObject(self, name)\
5147 return self.View:RemoveObject(name)\
5148end\
5149\
5150function RemoveObjects(self, name)\
5151 return self.View:RemoveObjects(name)\
5152end\
5153\
5154DrawEvent = nil\
5155\
5156function HandleDraw(self, event, id)\
5157 if id == self.DrawEvent then\
5158 self.DrawEvent = nil\
5159 self:Draw()\
5160 end\
5161end\
5162\
5163function ForceDraw(self)\
5164 if not self.DrawEvent then--or self.DrawTimerExpiry <= os.clock() then\
5165 self.DrawEvent = math.random()\
5166 os.queueEvent('bedrock_draw', self.DrawEvent)\
5167 -- self:StartTimer(function()\
5168 -- self.DrawTimer = nil\
5169 -- self:Draw()\
5170 -- end, 0.05)\
5171 -- self.DrawTimerExpiry = os.clock() + 0.1\
5172 end\
5173end\
5174\
5175function DisplayWindow(self, _view, title, canClose)\
5176 if canClose == nil then\
5177 canClose = true\
5178 end\
5179 if type(_view) == 'string' then\
5180 local h = fs.open(self.ViewPath.._view..'.view', 'r')\
5181 if h then\
5182 _view = textutils.unserialize(h.readAll())\
5183 h.close()\
5184 end\
5185 end\
5186\
5187 self.Window = self:AddObject({Type = 'Window', Z = 999, Title = title, CanClose = canClose})\
5188 _view.Type = 'View'\
5189 _view.Name = 'View'\
5190 _view.BackgroundColour = _view.BackgroundColour or colours.white\
5191 self.Window:SetView(self:ObjectFromFile(_view, self.Window))\
5192end\
5193\
5194function DisplayAlertWindow(self, title, text, buttons, callback)\
5195 local func = function(btn)\
5196 self.Window:Close()\
5197 if callback then\
5198 callback(btn.Text)\
5199 end\
5200 end\
5201 local children = {}\
5202 local usedX = -1\
5203 if buttons then\
5204 for i, text in ipairs(buttons) do\
5205 usedX = usedX + 3 + #text\
5206 table.insert(children, {\
5207 [\"Y\"]=\"100%,-1\",\
5208 [\"X\"]=\"100%,-\"..usedX,\
5209 [\"Name\"]=text..\"Button\",\
5210 [\"Type\"]=\"Button\",\
5211 [\"Text\"]=text,\
5212 OnClick = func\
5213 })\
5214 end\
5215 end\
5216\
5217 local width = usedX + 2\
5218 if width < 28 then\
5219 width = 28\
5220 end\
5221\
5222 local canClose = true\
5223 if buttons and #buttons~=0 then\
5224 canClose = false\
5225 end\
5226\
5227 local height = 0\
5228 if text then\
5229 height = #Helpers.WrapText(text, width - 2)\
5230 table.insert(children, {\
5231 [\"Y\"]=2,\
5232 [\"X\"]=2,\
5233 [\"Width\"]=\"100%,-2\",\
5234 [\"Height\"]=height,\
5235 [\"Name\"]=\"Label\",\
5236 [\"Type\"]=\"Label\",\
5237 [\"Text\"]=text\
5238 })\
5239 end\
5240 local view = {\
5241 Children = children,\
5242 Width=width,\
5243 Height=3+height+(canClose and 0 or 1),\
5244 OnKeyChar = function(_view, keychar)\
5245 func({Text=buttons[1]})\
5246 end\
5247 }\
5248 self:DisplayWindow(view, title, canClose)\
5249end\
5250\
5251function DisplayTextBoxWindow(self, title, text, callback, textboxText, cursorAtEnd)\
5252 textboxText = textboxText or ''\
5253 local children = {\
5254 {\
5255 [\"Y\"]=\"100%,-1\",\
5256 [\"X\"]=\"100%,-4\",\
5257 [\"Name\"]=\"OkButton\",\
5258 [\"Type\"]=\"Button\",\
5259 [\"Text\"]=\"Ok\",\
5260 OnClick = function()\
5261 local text = self.Window:GetObject('TextBox').Text\
5262 self.Window:Close()\
5263 callback(true, text)\
5264 end\
5265 },\
5266 {\
5267 [\"Y\"]=\"100%,-1\",\
5268 [\"X\"]=\"100%,-13\",\
5269 [\"Name\"]=\"CancelButton\",\
5270 [\"Type\"]=\"Button\",\
5271 [\"Text\"]=\"Cancel\",\
5272 OnClick = function()\
5273 self.Window:Close()\
5274 callback(false)\
5275 end\
5276 }\
5277 }\
5278\
5279 local height = -1\
5280 if text and #text ~= 0 then\
5281 height = #Helpers.WrapText(text, 26)\
5282 table.insert(children, {\
5283 [\"Y\"]=2,\
5284 [\"X\"]=2,\
5285 [\"Width\"]=\"100%,-2\",\
5286 [\"Height\"]=height,\
5287 [\"Name\"]=\"Label\",\
5288 [\"Type\"]=\"Label\",\
5289 [\"Text\"]=text\
5290 })\
5291 end\
5292 table.insert(children,\
5293 {\
5294 [\"Y\"]=3+height,\
5295 [\"X\"]=2,\
5296 [\"Width\"]=\"100%,-2\",\
5297 [\"Name\"]=\"TextBox\",\
5298 [\"Type\"]=\"TextBox\",\
5299 [\"Text\"]=textboxText,\
5300 [\"CursorPos\"]=(cursorAtEnd or 0)\
5301 })\
5302 local view = {\
5303 Children = children,\
5304 Width=28,\
5305 Height=5+height+(canClose and 0 or 1),\
5306 }\
5307 self:DisplayWindow(view, title)\
5308 self.Window:GetObject('TextBox').OnChange = function(txtbox, event, keychar)\
5309 if keychar == keys.enter then\
5310 self.Window:Close()\
5311 callback(true, txtbox.Text)\
5312 end\
5313 end\
5314 self:SetActiveObject(self.Window:GetObject('TextBox'))\
5315 self.Window.OnCloseButton = function()callback(false)end\
5316end\
5317\
5318function DisplayOpenFileWindow(self, title, callback)\
5319 title = title or 'Open File'\
5320 local func = function(btn)\
5321 self.Window:Close()\
5322 if callback then\
5323 callback(btn.Text)\
5324 end\
5325 end\
5326\
5327 local sidebarItems = {}\
5328\
5329 --this is a really, really super bad way of doing it\
5330 local separator = ' !'\
5331\
5332 local function addFolder(path, level)\
5333 for i, v in ipairs(_fs.list(path)) do\
5334 local fPath = path .. '/' .. v\
5335 if fPath ~= '/rom' and _fs.isDir(fPath) then\
5336 table.insert(sidebarItems, level .. v..separator..fPath)\
5337 addFolder(fPath, level .. ' ')\
5338 end\
5339 end\
5340 end\
5341 \
5342 if OneOS then\
5343 _fs = OneOS.FS\
5344 end\
5345\
5346 addFolder('','')\
5347\
5348 local currentFolder = ''\
5349 local selectedPath = nil\
5350\
5351 local goToFolder = nil\
5352\
5353 local children = {\
5354 {\
5355 [\"Y\"]=\"100%,-2\",\
5356 [\"X\"]=1,\
5357 [\"Height\"]=3,\
5358 [\"Width\"]=\"100%\",\
5359 [\"BackgroundColour\"]=colours.lightGrey,\
5360 [\"Name\"]=\"SidebarListView\",\
5361 [\"Type\"]=\"View\"\
5362 },\
5363 {\
5364 [\"Y\"]=\"100%,-1\",\
5365 [\"X\"]=\"100%,-4\",\
5366 [\"Name\"]=\"OkButton\",\
5367 [\"Type\"]=\"Button\",\
5368 [\"Text\"]=\"Ok\",\
5369 [\"BackgroundColour\"]=colours.white,\
5370 [\"Enabled\"]=false,\
5371 OnClick = function()\
5372 if selectedPath then\
5373 self.Window:Close()\
5374 callback(true, Helpers.TidyPath(selectedPath))\
5375 end\
5376 end\
5377 },\
5378 {\
5379 [\"Y\"]=\"100%,-1\",\
5380 [\"X\"]=\"100%,-13\",\
5381 [\"Name\"]=\"CancelButton\",\
5382 [\"Type\"]=\"Button\",\
5383 [\"Text\"]=\"Cancel\",\
5384 [\"BackgroundColour\"]=colours.white,\
5385 OnClick = function()\
5386 self.Window:Close()\
5387 callback(false)\
5388 end\
5389 },\
5390 {\
5391 [\"Y\"]=1,\
5392 [\"X\"]=1,\
5393 [\"Height\"]=\"100%,-3\",\
5394 [\"Width\"]=\"40%,-1\",\
5395 [\"Name\"]=\"SidebarListView\",\
5396 [\"Type\"]=\"ListView\",\
5397 [\"CanSelect\"]=true,\
5398 [\"Items\"]={\
5399 [\"Computer\"] = sidebarItems\
5400 },\
5401 OnSelect = function(listView, text)\
5402 local _,s = text:find(separator)\
5403 if s then\
5404 local path = text:sub(s + 1)\
5405 goToFolder(path)\
5406 end\
5407 end,\
5408 OnClick = function(listView, event, side, x, y)\
5409 if y == 1 then\
5410 goToFolder('/')\
5411 end\
5412 end\
5413 },\
5414 {\
5415 [\"Y\"]=1,\
5416 [\"X\"]=\"40%\",\
5417 [\"Height\"]=\"100%,-3\",\
5418 [\"Width\"]=1,\
5419 [\"Type\"]=\"Separator\"\
5420 },\
5421 {\
5422 [\"Y\"]=1,\
5423 [\"X\"]=\"40%,2\",\
5424 [\"Width\"]=\"65%,-3\",\
5425 [\"Height\"]=1,\
5426 [\"Type\"]=\"Label\",\
5427 [\"Name\"]=\"PathLabel\",\
5428 [\"TextColour\"]=colours.lightGrey,\
5429 [\"Text\"]='/'\
5430 },\
5431 {\
5432 [\"Y\"]=2,\
5433 [\"X\"]=\"40%,1\",\
5434 [\"Height\"]=\"100%,-4\",\
5435 [\"Width\"]=\"65%,-1\",\
5436 [\"Name\"]=\"FilesListView\",\
5437 [\"Type\"]=\"ListView\",\
5438 [\"CanSelect\"]=true,\
5439 [\"Items\"]={},\
5440 OnSelect = function(listView, text)\
5441 selectedPath = Helpers.TidyPath(currentFolder .. '/' .. text)\
5442 self.Window:GetObject('OkButton').Enabled = true\
5443 end,\
5444 OnClick = function(listView, event, side, x, y)\
5445 if y == 1 then\
5446 goToFolder('/')\
5447 end\
5448 end\
5449 },\
5450 }\
5451 local view = {\
5452 Children = children,\
5453 Width=40,\
5454 Height= Drawing.Screen.Height - 4,\
5455 OnCloseButton=function()\
5456 callback(false)\
5457 end\
5458 }\
5459 self:DisplayWindow(view, title)\
5460\
5461 goToFolder = function(path)\
5462 path = Helpers.TidyPath(path)\
5463 self.Window:GetObject('PathLabel').Text = path\
5464 currentFolder = path\
5465\
5466 local filesListItems = {}\
5467 for i, v in ipairs(_fs.list(path)) do\
5468 if not _fs.isDir(currentFolder .. v) then\
5469 table.insert(filesListItems, v)\
5470 end\
5471 end\
5472 self.Window:GetObject('OkButton').Enabled = false\
5473 selectedPath = nil\
5474 self.Window:GetObject('FilesListView').Items = filesListItems\
5475\
5476 end\
5477\
5478 if startPath then\
5479 goToFolder(startPath)\
5480 elseif OneOS then\
5481 goToFolder('/Desktop/Documents/')\
5482 else\
5483 goToFolder('')\
5484 end\
5485\
5486 self.Window.OnCloseButton = function()callback(false)end\
5487end\
5488\
5489function DisplaySaveFileWindow(self, title, callback, extension, startPath)\
5490 local _fs = fs\
5491 if extension and extension:sub(1,1) ~= '.' then\
5492 extension = '.' .. extension\
5493 end\
5494 extension = extension or ''\
5495\
5496 title = title or 'Save File'\
5497 local func = function(btn)\
5498 self.Window:Close()\
5499 if callback then\
5500 callback(btn.Text)\
5501 end\
5502 end\
5503\
5504 local sidebarItems = {}\
5505\
5506 --this is a really, really super bad way of doing it\
5507 local separator = ' !'\
5508\
5509 local function addFolder(path, level)\
5510 for i, v in ipairs(_fs.list(path)) do\
5511 local fPath = path .. '/' .. v\
5512 if fPath ~= '/rom' and _fs.isDir(fPath) then\
5513 table.insert(sidebarItems, level .. v..separator..fPath)\
5514 addFolder(fPath, level .. ' ')\
5515 end\
5516 end\
5517 end\
5518 \
5519 if OneOS then\
5520 _fs = OneOS.FS\
5521 end\
5522 addFolder('','')\
5523\
5524 local currentFolder = ''\
5525 local selectedPath = nil\
5526\
5527 local goToFolder = nil\
5528\
5529 local function updatePath()\
5530 local text = self:GetObject('FileNameTextBox').Text\
5531 if #text == 0 then\
5532 self.Window:GetObject('OkButton').Enabled = false\
5533 selectedPath = Helpers.TidyPath(currentFolder)\
5534 else\
5535 self.Window:GetObject('OkButton').Enabled = true\
5536 selectedPath = Helpers.TidyPath(currentFolder .. '/' .. text .. extension)\
5537 end\
5538 self:GetObject('PathLabel').Text = selectedPath\
5539 end\
5540\
5541 local children = {\
5542 {\
5543 [\"Y\"]=\"100%,-2\",\
5544 [\"X\"]=1,\
5545 [\"Height\"]=3,\
5546 [\"Width\"]=\"100%\",\
5547 [\"BackgroundColour\"]=colours.lightGrey,\
5548 [\"Type\"]=\"View\"\
5549 },\
5550 {\
5551 [\"Y\"]=\"100%,-1\",\
5552 [\"X\"]=\"100%,-4\",\
5553 [\"Name\"]=\"OkButton\",\
5554 [\"Type\"]=\"Button\",\
5555 [\"Text\"]=\"Ok\",\
5556 [\"BackgroundColour\"]=colours.white,\
5557 [\"Enabled\"]=false,\
5558 OnClick = function()\
5559 if selectedPath then\
5560 local text = self:GetObject('FileNameTextBox').Text\
5561 self.Window:Close()\
5562 callback(true, selectedPath, text)\
5563 end\
5564 end\
5565 },\
5566 {\
5567 [\"Y\"]=\"100%,-1\",\
5568 [\"X\"]=\"100%,-13\",\
5569 [\"Name\"]=\"CancelButton\",\
5570 [\"Type\"]=\"Button\",\
5571 [\"Text\"]=\"Cancel\",\
5572 [\"BackgroundColour\"]=colours.white,\
5573 OnClick = function()\
5574 self.Window:Close()\
5575 callback(false)\
5576 end\
5577 },\
5578 {\
5579 [\"Y\"]=\"100%,-2\",\
5580 [\"X\"]=3,\
5581 [\"Width\"]=\"100%,-4\",\
5582 [\"Name\"]=\"PathLabel\",\
5583 [\"Type\"]=\"Label\",\
5584 [\"Text\"]=\"/\",\
5585 [\"TextColour\"]=colours.grey\
5586 },\
5587 {\
5588 [\"Y\"]=\"100%,-1\",\
5589 [\"X\"]=3,\
5590 [\"Width\"]=\"100%,-17\",\
5591 [\"Name\"]=\"FileNameTextBox\",\
5592 [\"Type\"]=\"TextBox\",\
5593 [\"Placeholder\"]=\"File Name\",\
5594 [\"Active\"]=true,\
5595 [\"BackgroundColour\"]=colours.white,\
5596 OnChange = function(_self, event, keychar)\
5597 if keychar == keys.enter then\
5598 self:GetObject('OkButton'):OnClick()\
5599 else\
5600 updatePath()\
5601 end\
5602 end\
5603 },\
5604 {\
5605 [\"Y\"]=1,\
5606 [\"X\"]=2,\
5607 [\"Height\"]=\"100%,-3\",\
5608 [\"Width\"]=\"100%,-1\",\
5609 [\"Name\"]=\"SidebarListView\",\
5610 [\"Type\"]=\"ListView\",\
5611 [\"CanSelect\"]=true,\
5612 [\"Items\"]={\
5613 [\"Computer\"] = sidebarItems\
5614 },\
5615 OnSelect = function(listView, text)\
5616 local _,s = text:find(separator)\
5617 if s then\
5618 local path = text:sub(s + 1)\
5619 goToFolder(path)\
5620 end\
5621 end,\
5622 OnClick = function(listView, event, side, x, y)\
5623 if y == 1 then\
5624 goToFolder('/')\
5625 end\
5626 end\
5627 },\
5628 }\
5629 local view = {\
5630 Children = children,\
5631 Width=35,\
5632 Height= Drawing.Screen.Height - 4,\
5633 OnCloseButton=function()\
5634 callback(false)\
5635 end\
5636 }\
5637 self:DisplayWindow(view, title)\
5638\
5639 self:SetActiveObject(self.Window:GetObject('FileNameTextBox'))\
5640\
5641 goToFolder = function(path)\
5642 path = Helpers.TidyPath(path)\
5643 currentFolder = path\
5644 selectedPath = nil\
5645 updatePath()\
5646 end\
5647\
5648 if startPath then\
5649 goToFolder(startPath)\
5650 elseif OneOS then\
5651 goToFolder('/Desktop/Documents/')\
5652 else\
5653 goToFolder('')\
5654 end\
5655\
5656 self.Window.OnCloseButton = function()callback(false)end\
5657end\
5658\
5659function RegisterEvent(self, event, func)\
5660 if not self.EventHandlers[event] then\
5661 self.EventHandlers[event] = {}\
5662 end\
5663 table.insert(self.EventHandlers[event], func)\
5664end\
5665\
5666function StartRepeatingTimer(self, func, interval)\
5667 local int = interval\
5668 if type(int) == 'function' then\
5669 int = int()\
5670 end\
5671 if not int or int <= 0 then\
5672 return\
5673 end\
5674 local timer = os.startTimer(int)\
5675\
5676 self.Timers[timer] = {func, true, interval}\
5677 return timer\
5678end\
5679\
5680function StartTimer(self, func, delay)\
5681 local timer = os.startTimer(delay)\
5682 self.Timers[timer] = {func, false}\
5683 return timer\
5684end\
5685\
5686function StopTimer(self, timer)\
5687 if self.Timers[timer] then\
5688 self.Timers[timer] = nil\
5689 end\
5690end\
5691\
5692function HandleTimer(self, event, timer)\
5693 if self.Timers[timer] then\
5694 local oldTimer = self.Timers[timer]\
5695 self.Timers[timer] = nil\
5696 local new = nil\
5697 if oldTimer[2] then\
5698 new = self:StartRepeatingTimer(oldTimer[1], oldTimer[3])\
5699 end\
5700 if oldTimer and oldTimer[1] then\
5701 oldTimer[1](new, timer)\
5702 end\
5703 elseif self.OnTimer then\
5704 self.OnTimer(self, event, timer)\
5705 end\
5706end\
5707\
5708function SetActiveObject(self, object)\
5709 if object then\
5710 if object ~= self.ActiveObject then\
5711 self.ActiveObject = object\
5712 object:ForceDraw()\
5713 end\
5714 elseif self.ActiveObject ~= nil then\
5715 self.ActiveObject = nil\
5716 self.CursorPos = nil\
5717 self.View:ForceDraw()\
5718 end\
5719end\
5720\
5721function GetActiveObject(self)\
5722 return self.ActiveObject\
5723end\
5724\
5725OnTimer = nil\
5726OnClick = nil\
5727OnKeyChar = nil\
5728OnDrag = nil\
5729OnScroll = nil\
5730OnViewLoad = nil\
5731OnViewClose = nil\
5732OnDraw = nil\
5733OnQuit = nil\
5734\
5735local eventFuncs = {\
5736 OnClick = {'mouse_click', 'monitor_touch'},\
5737 OnKeyChar = {'key', 'char'},\
5738 OnDrag = {'mouse_drag'},\
5739 OnScroll = {'mouse_scroll'},\
5740 HandleClick = {'mouse_click', 'mouse_drag', 'mouse_scroll', 'monitor_touch'},\
5741 HandleKeyChar = {'key', 'char'},\
5742 HandleTimer = {'timer'},\
5743 HandleDraw = {'bedrock_draw'}\
5744}\
5745\
5746local drawCalls = 0\
5747local ignored = 0\
5748function Draw(self)\
5749 self.IsDrawing = true\
5750 if self.OnDraw then\
5751 self:OnDraw()\
5752 end\
5753\
5754 if self.View and self.View:NeedsDraw() then\
5755 self.View:Draw()\
5756 Drawing.DrawBuffer()\
5757 if isDebug then\
5758 drawCalls = drawCalls + 1\
5759 end\
5760 elseif not self.View then\
5761 print('No loaded view. You need to do program:LoadView first.')\
5762 end \
5763\
5764 if self:GetActiveObject() and self.CursorPos and type(self.CursorPos[1]) == 'number' and type(self.CursorPos[2]) == 'number' then\
5765 term.setCursorPos(self.CursorPos[1], self.CursorPos[2])\
5766 term.setTextColour(self.CursorColour)\
5767 term.setCursorBlink(true)\
5768 else\
5769 term.setCursorBlink(false)\
5770 end\
5771\
5772 self.IsDrawing = false\
5773end\
5774\
5775function EventHandler(self)\
5776 local event = { os.pullEventRaw() }\
5777 \
5778 if self.EventHandlers[event[1]] then\
5779 for i, e in ipairs(self.EventHandlers[event[1]]) do\
5780 e(self, unpack(event))\
5781 end\
5782 end\
5783end\
5784\
5785function Quit(self)\
5786 self.Running = false\
5787 if self.OnQuit then\
5788 self:OnQuit()\
5789 end\
5790 if OneOS then\
5791 OneOS.Close()\
5792 end\
5793end\
5794\
5795function Run(self, ready)\
5796 if not term.isColour or not term.isColour() then\
5797 print('This program requires an advanced (golden) comptuer to run, sorry.')\
5798 error('', 0)\
5799 end\
5800\
5801 for name, events in pairs(eventFuncs) do\
5802 if self[name] then\
5803 for i, event in ipairs(events) do\
5804 self:RegisterEvent(event, self[name])\
5805 end\
5806 end\
5807 end\
5808\
5809 if self.AllowTerminate then\
5810 self:RegisterEvent('terminate', function()error('Terminated', 0) end)\
5811 end\
5812\
5813 if self.DefaultView and self.DefaultView ~= '' and fs.exists(self.ViewPath..self.DefaultView..'.view') then\
5814 self:LoadView(self.DefaultView)\
5815 end\
5816\
5817 if ready then\
5818 ready()\
5819 end\
5820 \
5821 self:Draw()\
5822\
5823 while self.Running do\
5824 self:EventHandler()\
5825 end\
5826end",
5827 Other = {
5828 settings = "{\
5829 terms = {\
5830 \"native\",\
5831 },\
5832 changeTempColor = true,\
5833 onScreenKeyboard = false,\
5834 defaultTurbineName = \"Turbine §n\",\
5835 darkmode = false,\
5836 changeRpmColor = true,\
5837 defaultReactorName = \"Reactor §n\",\
5838 defaultBatteryName = \"Battery §n\",\
5839 refreshSpeed = 0.25,\
5840 automaticControl = true,\
5841 groupPath = \"/ReactorControl/Other/\",\
5842 manualRefreshHome = true,\
5843}",
5844 groups = "{\
5845 {\
5846 reactor = {\
5847 {\
5848 device = \"BigReactors-Reactor_0\",\
5849 variables = {\
5850 lastTemp = 176.50163,\
5851 },\
5852 settings = {\
5853 overrideGroup = false,\
5854 maxTemp = 1500,\
5855 optimiseReactor = false,\
5856 allowEE = true,\
5857 },\
5858 name = \"Reactor $n\",\
5859 },\
5860 {\
5861 device = \"BigReactors-Reactor_1\",\
5862 variables = {\
5863 lastTemp = 1498.7506,\
5864 },\
5865 settings = {\
5866 overrideGroup = false,\
5867 maxTemp = 1500,\
5868 optimiseReactor = false,\
5869 allowEE = true,\
5870 },\
5871 name = \"Reactor $n\",\
5872 },\
5873 },\
5874 settings = {\
5875 energyOffTreshold = 95,\
5876 energyOnTreshold = 70,\
5877 disengageCoils = true,\
5878 efficentEnergy = false,\
5879 maxTemp = 1500,\
5880 optimiseRPM = 1840,\
5881 optimiseReactor = true,\
5882 optimiseTurbine = true,\
5883 },\
5884 Name = \"Main\",\
5885 turbine = {\
5886 {\
5887 device = \"BigReactors-Turbine_0\",\
5888 variables = {\
5889 startingDone = true,\
5890 lastRPM = 1844.2401,\
5891 },\
5892 settings = {\
5893 disengageCoils = false,\
5894 optimiseRPM = 1864,\
5895 optimiseTurbine = false,\
5896 allowEE = true,\
5897 overrideGroup = false,\
5898 },\
5899 name = \"Turbine $n\",\
5900 },\
5901 {\
5902 device = \"BigReactors-Turbine_1\",\
5903 variables = {\
5904 startingDone = true,\
5905 lastRPM = 1842.5106,\
5906 },\
5907 settings = {\
5908 disengageCoils = false,\
5909 optimiseRPM = 1864,\
5910 optimiseTurbine = false,\
5911 allowEE = true,\
5912 overrideGroup = false,\
5913 },\
5914 name = \"Turbine $n\",\
5915 },\
5916 {\
5917 device = \"BigReactors-Turbine_2\",\
5918 variables = {\
5919 startingDone = true,\
5920 lastRPM = 1848.813,\
5921 },\
5922 settings = {\
5923 disengageCoils = false,\
5924 optimiseRPM = 1864,\
5925 optimiseTurbine = false,\
5926 allowEE = true,\
5927 overrideGroup = false,\
5928 },\
5929 name = \"Turbine $n\",\
5930 },\
5931 {\
5932 device = \"BigReactors-Turbine_3\",\
5933 variables = {\
5934 startingDone = true,\
5935 lastRPM = 1849.1644,\
5936 },\
5937 settings = {\
5938 disengageCoils = false,\
5939 optimiseRPM = 1864,\
5940 optimiseTurbine = false,\
5941 allowEE = true,\
5942 overrideGroup = false,\
5943 },\
5944 name = \"Turbine $n\",\
5945 },\
5946 {\
5947 device = \"BigReactors-Turbine_4\",\
5948 variables = {\
5949 startingDone = true,\
5950 lastRPM = 1847.0411,\
5951 },\
5952 settings = {\
5953 disengageCoils = false,\
5954 optimiseRPM = 1864,\
5955 optimiseTurbine = false,\
5956 allowEE = true,\
5957 overrideGroup = false,\
5958 },\
5959 name = \"Turbine $n\",\
5960 },\
5961 },\
5962 battery = {\
5963 {\
5964 device = \"powered_tile_0\",\
5965 name = \"Battery $n\",\
5966 },\
5967 {\
5968 device = \"powered_tile_1\",\
5969 name = \"Battery $n\",\
5970 },\
5971 {\
5972 device = \"capacitor_bank_0\",\
5973 name = \"Battery $n\",\
5974 },\
5975 },\
5976 },\
5977}",
5978 groupsawa = "{\
5979 {\
5980 reactor = {\
5981 {\
5982 device = \"BigReactors-Reactor_0\",\
5983 variables = {\
5984 lastTemp = 3469.5186,\
5985 },\
5986 settings = {\
5987 overrideGroup = false,\
5988 maxTemp = 1500,\
5989 optimiseReactor = false,\
5990 allowEE = true,\
5991 },\
5992 name = \"Reactor $n\",\
5993 },\
5994 {\
5995 device = \"BigReactors-Reactor_1\",\
5996 variables = {\
5997 lastTemp = 1512.6394,\
5998 },\
5999 settings = {\
6000 overrideGroup = false,\
6001 maxTemp = 1500,\
6002 optimiseReactor = false,\
6003 allowEE = true,\
6004 },\
6005 name = \"Reactor $n\",\
6006 },\
6007 {\
6008 device = \"BigReactors-Reactor_0\",\
6009 variables = {\
6010 lastTemp = 3469.5186,\
6011 },\
6012 settings = {\
6013 overrideGroup = false,\
6014 maxTemp = 1500,\
6015 optimiseReactor = false,\
6016 allowEE = true,\
6017 },\
6018 name = \"Reactor $n\",\
6019 },\
6020 {\
6021 device = \"BigReactors-Reactor_1\",\
6022 variables = {\
6023 lastTemp = 1512.6394,\
6024 },\
6025 settings = {\
6026 overrideGroup = false,\
6027 maxTemp = 1500,\
6028 optimiseReactor = false,\
6029 allowEE = true,\
6030 },\
6031 name = \"Reactor $n\",\
6032 },\
6033 {\
6034 device = \"BigReactors-Reactor_0\",\
6035 variables = {\
6036 lastTemp = 3469.5186,\
6037 },\
6038 settings = {\
6039 overrideGroup = false,\
6040 maxTemp = 1500,\
6041 optimiseReactor = false,\
6042 allowEE = true,\
6043 },\
6044 name = \"Reactor $n\",\
6045 },\
6046 {\
6047 device = \"BigReactors-Reactor_1\",\
6048 variables = {\
6049 lastTemp = 1512.6394,\
6050 },\
6051 settings = {\
6052 overrideGroup = false,\
6053 maxTemp = 1500,\
6054 optimiseReactor = false,\
6055 allowEE = true,\
6056 },\
6057 name = \"Reactor $n\",\
6058 },\
6059 {\
6060 device = \"BigReactors-Reactor_0\",\
6061 variables = {\
6062 lastTemp = 0,\
6063 },\
6064 settings = {\
6065 overrideGroup = false,\
6066 maxTemp = 1500,\
6067 optimiseReactor = false,\
6068 allowEE = true,\
6069 },\
6070 name = \"Reactor $n\",\
6071 },\
6072 {\
6073 device = \"BigReactors-Reactor_1\",\
6074 variables = {\
6075 lastTemp = 0,\
6076 },\
6077 settings = {\
6078 overrideGroup = false,\
6079 maxTemp = 1500,\
6080 optimiseReactor = false,\
6081 allowEE = true,\
6082 },\
6083 name = \"Reactor $n\",\
6084 },\
6085 },\
6086 settings = {\
6087 energyOffTreshold = 95,\
6088 disengageCoils = false,\
6089 energyOnTreshold = 70,\
6090 efficentEnergy = false,\
6091 optimiseReactor = false,\
6092 optimiseRPM = 1864,\
6093 maxTemp = 1500,\
6094 optimiseTurbine = false,\
6095 },\
6096 Name = \"Ungrouped\",\
6097 turbine = {\
6098 {\
6099 device = \"BigReactors-Turbine_2\",\
6100 variables = {\
6101 startingDone = true,\
6102 lastRPM = 1791.0087,\
6103 },\
6104 settings = {\
6105 disengageCoils = false,\
6106 optimiseRPM = 1864,\
6107 optimiseTurbine = false,\
6108 allowEE = true,\
6109 overrideGroup = false,\
6110 },\
6111 name = \"Turbine $n\",\
6112 },\
6113 {\
6114 device = \"BigReactors-Turbine_3\",\
6115 variables = {\
6116 startingDone = true,\
6117 lastRPM = 1872.3533,\
6118 },\
6119 settings = {\
6120 disengageCoils = false,\
6121 optimiseRPM = 1864,\
6122 optimiseTurbine = false,\
6123 allowEE = true,\
6124 overrideGroup = false,\
6125 },\
6126 name = \"Turbine $n\",\
6127 },\
6128 {\
6129 device = \"BigReactors-Turbine_0\",\
6130 variables = {\
6131 startingDone = true,\
6132 lastRPM = 1801.6665,\
6133 },\
6134 settings = {\
6135 disengageCoils = false,\
6136 optimiseRPM = 1864,\
6137 optimiseTurbine = false,\
6138 allowEE = true,\
6139 overrideGroup = false,\
6140 },\
6141 name = \"Turbine $n\",\
6142 },\
6143 {\
6144 device = \"BigReactors-Turbine_1\",\
6145 variables = {\
6146 startingDone = true,\
6147 lastRPM = 1860.0282,\
6148 },\
6149 settings = {\
6150 disengageCoils = false,\
6151 optimiseRPM = 1864,\
6152 optimiseTurbine = false,\
6153 allowEE = true,\
6154 overrideGroup = false,\
6155 },\
6156 name = \"Turbine $n\",\
6157 },\
6158 {\
6159 device = \"BigReactors-Turbine_4\",\
6160 variables = {\
6161 startingDone = true,\
6162 lastRPM = 1847.7028,\
6163 },\
6164 settings = {\
6165 disengageCoils = false,\
6166 optimiseRPM = 1864,\
6167 optimiseTurbine = false,\
6168 allowEE = true,\
6169 overrideGroup = false,\
6170 },\
6171 name = \"Turbine $n\",\
6172 },\
6173 {\
6174 device = \"BigReactors-Turbine_2\",\
6175 variables = {\
6176 startingDone = true,\
6177 lastRPM = 1791.0087,\
6178 },\
6179 settings = {\
6180 disengageCoils = false,\
6181 optimiseRPM = 1864,\
6182 optimiseTurbine = false,\
6183 allowEE = true,\
6184 overrideGroup = false,\
6185 },\
6186 name = \"Turbine $n\",\
6187 },\
6188 {\
6189 device = \"BigReactors-Turbine_3\",\
6190 variables = {\
6191 startingDone = true,\
6192 lastRPM = 1872.3533,\
6193 },\
6194 settings = {\
6195 disengageCoils = false,\
6196 optimiseRPM = 1864,\
6197 optimiseTurbine = false,\
6198 allowEE = true,\
6199 overrideGroup = false,\
6200 },\
6201 name = \"Turbine $n\",\
6202 },\
6203 {\
6204 device = \"BigReactors-Turbine_0\",\
6205 variables = {\
6206 startingDone = true,\
6207 lastRPM = 1801.6665,\
6208 },\
6209 settings = {\
6210 disengageCoils = false,\
6211 optimiseRPM = 1864,\
6212 optimiseTurbine = false,\
6213 allowEE = true,\
6214 overrideGroup = false,\
6215 },\
6216 name = \"Turbine $n\",\
6217 },\
6218 {\
6219 device = \"BigReactors-Turbine_1\",\
6220 variables = {\
6221 startingDone = true,\
6222 lastRPM = 1860.0282,\
6223 },\
6224 settings = {\
6225 disengageCoils = false,\
6226 optimiseRPM = 1864,\
6227 optimiseTurbine = false,\
6228 allowEE = true,\
6229 overrideGroup = false,\
6230 },\
6231 name = \"Turbine $n\",\
6232 },\
6233 {\
6234 device = \"BigReactors-Turbine_4\",\
6235 variables = {\
6236 startingDone = true,\
6237 lastRPM = 1847.7028,\
6238 },\
6239 settings = {\
6240 disengageCoils = false,\
6241 optimiseRPM = 1864,\
6242 optimiseTurbine = false,\
6243 allowEE = true,\
6244 overrideGroup = false,\
6245 },\
6246 name = \"Turbine $n\",\
6247 },\
6248 {\
6249 device = \"BigReactors-Turbine_2\",\
6250 variables = {\
6251 startingDone = true,\
6252 lastRPM = 1791.0087,\
6253 },\
6254 settings = {\
6255 disengageCoils = false,\
6256 optimiseRPM = 1864,\
6257 optimiseTurbine = false,\
6258 allowEE = true,\
6259 overrideGroup = false,\
6260 },\
6261 name = \"Turbine $n\",\
6262 },\
6263 {\
6264 device = \"BigReactors-Turbine_3\",\
6265 variables = {\
6266 startingDone = true,\
6267 lastRPM = 1872.3533,\
6268 },\
6269 settings = {\
6270 disengageCoils = false,\
6271 optimiseRPM = 1864,\
6272 optimiseTurbine = false,\
6273 allowEE = true,\
6274 overrideGroup = false,\
6275 },\
6276 name = \"Turbine $n\",\
6277 },\
6278 {\
6279 device = \"BigReactors-Turbine_0\",\
6280 variables = {\
6281 startingDone = true,\
6282 lastRPM = 1801.6665,\
6283 },\
6284 settings = {\
6285 disengageCoils = false,\
6286 optimiseRPM = 1864,\
6287 optimiseTurbine = false,\
6288 allowEE = true,\
6289 overrideGroup = false,\
6290 },\
6291 name = \"Turbine $n\",\
6292 },\
6293 {\
6294 device = \"BigReactors-Turbine_1\",\
6295 variables = {\
6296 startingDone = true,\
6297 lastRPM = 1860.0282,\
6298 },\
6299 settings = {\
6300 disengageCoils = false,\
6301 optimiseRPM = 1864,\
6302 optimiseTurbine = false,\
6303 allowEE = true,\
6304 overrideGroup = false,\
6305 },\
6306 name = \"Turbine $n\",\
6307 },\
6308 {\
6309 device = \"BigReactors-Turbine_4\",\
6310 variables = {\
6311 startingDone = true,\
6312 lastRPM = 1847.7028,\
6313 },\
6314 settings = {\
6315 disengageCoils = false,\
6316 optimiseRPM = 1864,\
6317 optimiseTurbine = false,\
6318 allowEE = true,\
6319 overrideGroup = false,\
6320 },\
6321 name = \"Turbine $n\",\
6322 },\
6323 {\
6324 device = \"BigReactors-Turbine_2\",\
6325 variables = {\
6326 startingDone = false,\
6327 lastRPM = 0,\
6328 },\
6329 settings = {\
6330 disengageCoils = false,\
6331 optimiseRPM = 1864,\
6332 optimiseTurbine = false,\
6333 allowEE = true,\
6334 overrideGroup = false,\
6335 },\
6336 name = \"Turbine $n\",\
6337 },\
6338 {\
6339 device = \"BigReactors-Turbine_3\",\
6340 variables = {\
6341 startingDone = false,\
6342 lastRPM = 0,\
6343 },\
6344 settings = {\
6345 disengageCoils = false,\
6346 optimiseRPM = 1864,\
6347 optimiseTurbine = false,\
6348 allowEE = true,\
6349 overrideGroup = false,\
6350 },\
6351 name = \"Turbine $n\",\
6352 },\
6353 {\
6354 device = \"BigReactors-Turbine_0\",\
6355 variables = {\
6356 startingDone = false,\
6357 lastRPM = 0,\
6358 },\
6359 settings = {\
6360 disengageCoils = false,\
6361 optimiseRPM = 1864,\
6362 optimiseTurbine = false,\
6363 allowEE = true,\
6364 overrideGroup = false,\
6365 },\
6366 name = \"Turbine $n\",\
6367 },\
6368 {\
6369 device = \"BigReactors-Turbine_1\",\
6370 variables = {\
6371 startingDone = false,\
6372 lastRPM = 0,\
6373 },\
6374 settings = {\
6375 disengageCoils = false,\
6376 optimiseRPM = 1864,\
6377 optimiseTurbine = false,\
6378 allowEE = true,\
6379 overrideGroup = false,\
6380 },\
6381 name = \"Turbine $n\",\
6382 },\
6383 {\
6384 device = \"BigReactors-Turbine_4\",\
6385 variables = {\
6386 startingDone = false,\
6387 lastRPM = 0,\
6388 },\
6389 settings = {\
6390 disengageCoils = false,\
6391 optimiseRPM = 1864,\
6392 optimiseTurbine = false,\
6393 allowEE = true,\
6394 overrideGroup = false,\
6395 },\
6396 name = \"Turbine $n\",\
6397 },\
6398 },\
6399 battery = {\
6400 {\
6401 device = \"capacitor_bank_0\",\
6402 name = \"Battery $n\",\
6403 },\
6404 {\
6405 device = \"powered_tile_0\",\
6406 name = \"Battery $n\",\
6407 },\
6408 {\
6409 device = \"powered_tile_1\",\
6410 name = \"Battery $n\",\
6411 },\
6412 {\
6413 device = \"capacitor_bank_0\",\
6414 name = \"Battery $n\",\
6415 },\
6416 {\
6417 device = \"powered_tile_0\",\
6418 name = \"Battery $n\",\
6419 },\
6420 {\
6421 device = \"powered_tile_1\",\
6422 name = \"Battery $n\",\
6423 },\
6424 {\
6425 device = \"capacitor_bank_0\",\
6426 name = \"Battery $n\",\
6427 },\
6428 {\
6429 device = \"powered_tile_0\",\
6430 name = \"Battery $n\",\
6431 },\
6432 {\
6433 device = \"powered_tile_1\",\
6434 name = \"Battery $n\",\
6435 },\
6436 {\
6437 device = \"capacitor_bank_0\",\
6438 name = \"Battery $n\",\
6439 },\
6440 {\
6441 device = \"powered_tile_0\",\
6442 name = \"Battery $n\",\
6443 },\
6444 {\
6445 device = \"powered_tile_1\",\
6446 name = \"Battery $n\",\
6447 },\
6448 },\
6449 },\
6450}",
6451 },
6452 tbm = "-- Terminal Benchmark 1.0 by CrazedProgrammer\
6453\
6454local t, ft, fc, ftc, st, sc, stc, native = term, \" \", \"f\", \"0\", \" \", \"ffffffffffffffffffffffffffffffffffffffffffffffffff\", \"00000000000000000000000000000000000000000000000000\"\
6455if ({...})[1] == \"n\" then\
6456 t = term.native()\
6457 native = true\
6458end\
6459t.setBackgroundColor(colors.black)\
6460t.setTextColor(colors.white)\
6461t.setCursorPos(1, 2)\
6462t.setCursorBlink(false)\
6463t.clear()\
6464t.write((native and \"Native \" or \"\")..\"Terminal Benchmark 1.0 by CrazedProgrammer\")\
6465t.setCursorPos(1, 3)\
6466t.write(\"This will take around 1 minute.\")\
6467os.sleep(2)\
6468local clock = os.clock()\
6469local cclock = clock\
6470local count = 0\
6471while cclock < clock + 5 do\
6472 for i=1,1000 do\
6473 t.clear()\
6474 end\
6475 count = count + 1000\
6476 cclock = os.clock()\
6477end\
6478local dtime = cclock - clock\
6479local time = dtime / count\
6480t.setCursorPos(1, 2)\
6481t.write((native and \"Native \" or \"\")..\"Terminal Benchmark 1.0 by CrazedProgrammer\")\
6482t.setCursorPos(1, 3)\
6483t.write(\"term.clear: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6484t.setCursorPos(1, 1)\
6485os.sleep(0)\
6486clock = os.clock()\
6487cclock = clock\
6488count = 0\
6489while cclock < clock + 5 do\
6490 for i=1,1000 do\
6491 t.clearLine()\
6492 end\
6493 count = count + 1000\
6494 cclock = os.clock()\
6495end\
6496dtime = cclock - clock\
6497time = dtime / count\
6498t.setCursorPos(1, 4)\
6499t.write(\"term.clearLine: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6500os.sleep(0)\
6501clock = os.clock()\
6502cclock = clock\
6503count = 0\
6504while cclock < clock + 5 do\
6505 for i=1,1000 do\
6506 t.setCursorPos(1, 1)\
6507 end\
6508 count = count + 1000\
6509 cclock = os.clock()\
6510end\
6511dtime = cclock - clock\
6512time = dtime / count\
6513t.setCursorPos(1, 5)\
6514t.write(\"term.setCursorPos: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6515t.setCursorPos(1, 1)\
6516os.sleep(0)\
6517clock = os.clock()\
6518cclock = clock\
6519count = 0\
6520while cclock < clock + 5 do\
6521 for i=1,1000 do\
6522 t.setTextColor(1)\
6523 end\
6524 count = count + 1000\
6525 cclock = os.clock()\
6526end\
6527dtime = cclock - clock\
6528time = dtime / count\
6529t.setCursorPos(1, 6)\
6530t.write(\"term.setTextColor: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6531t.setCursorPos(1, 1)\
6532os.sleep(0)\
6533clock = os.clock()\
6534cclock = clock\
6535count = 0\
6536while cclock < clock + 5 do\
6537 for i=1,1000 do\
6538 t.setBackgroundColor(32768)\
6539 end\
6540 count = count + 1000\
6541 cclock = os.clock()\
6542end\
6543dtime = cclock - clock\
6544time = dtime / count\
6545t.setCursorPos(1, 7)\
6546t.write(\"term.setBackgroundColor: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6547t.setCursorPos(1, 1)\
6548os.sleep(0)\
6549clock = os.clock()\
6550cclock = clock\
6551count = 0\
6552while cclock < clock + 5 do\
6553 for i=1,1000 do\
6554 t.write(ft)\
6555 end\
6556 count = count + 1000\
6557 cclock = os.clock()\
6558end\
6559dtime = cclock - clock\
6560time = dtime / count\
6561t.setCursorPos(1, 8)\
6562t.write(\"term.write 1: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6563t.setCursorPos(1, 1)\
6564os.sleep(0)\
6565clock = os.clock()\
6566cclock = clock\
6567count = 0\
6568while cclock < clock + 5 do\
6569 for i=1,1000 do\
6570 t.write(st)\
6571 end\
6572 count = count + 1000\
6573 cclock = os.clock()\
6574end\
6575dtime = cclock - clock\
6576time = dtime / count\
6577t.setCursorPos(1, 9)\
6578t.write(\"term.write 50: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6579t.setCursorPos(1, 1)\
6580os.sleep(0)\
6581clock = os.clock()\
6582cclock = clock\
6583count = 0\
6584while cclock < clock + 5 do\
6585 for i=1,1000 do\
6586 t.blit(ft, ftc, fc)\
6587 end\
6588 count = count + 1000\
6589 cclock = os.clock()\
6590end\
6591dtime = cclock - clock\
6592time = dtime / count\
6593t.setCursorPos(1, 10)\
6594t.write(\"term.blit 1: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6595t.setCursorPos(1, 1)\
6596os.sleep(0)\
6597clock = os.clock()\
6598cclock = clock\
6599count = 0\
6600while cclock < clock + 5 do\
6601 for i=1,1000 do\
6602 t.blit(st, stc, sc)\
6603 end\
6604 count = count + 1000\
6605 cclock = os.clock()\
6606end\
6607dtime = cclock - clock\
6608time = dtime / count\
6609t.setCursorPos(1, 11)\
6610t.write(\"term.blit 50: \" .. tostring(time * 1000000) .. \" us (\"..tostring(count / 1000)..\"k in \"..tostring(dtime)..\" s)\")\
6611t.setCursorPos(1, 12)\
6612os.sleep(2)",
6613 test = "parallel.waitForAll(\
6614function() return shell.run(\"monitor monitor_0 ReactorCtrl.lua\") end,\
6615function() return shell.run(\"monitor monitor_1 ReactorCtrl.lua\") end\
6616)",
6617 [ "r_control.lua" ] = "local args = {...}\
6618local lastArgument = nil\
6619local firstStart = true\
6620local startTerm = term.current()\
6621\
6622if args[1] == \"native\" then\
6623 startTerm = term.native()\
6624end\
6625\
6626local function main(args)\
6627 --Main Start\
6628 local returnValue = nil\
6629\
6630 local bedrockPath='/ReactorControl' if OneOS then OneOS.LoadAPI('/System/API/Bedrock.lua', false)elseif fs.exists(bedrockPath..'/Bedrock')then os.loadAPI(bedrockPath..'/Bedrock')else if http then print('Downloading Bedrock...')local h=http.get('http://pastebin.com/raw.php?i=0MgKNqpN')if h then local f=fs.open(bedrockPath..'/Bedrock','w')f.write(h.readAll())f.close()h.close()os.loadAPI(bedrockPath..'/Bedrock')else error('Failed to download Bedrock. Is your internet working?') end else error('This program needs to download Bedrock to work. Please enable HTTP.') end end if Bedrock then Bedrock.BasePath = bedrockPath Bedrock.ProgramPath = shell.getRunningProgram() end\
6631 Bedrock.DefaultView = \"empty\"\
6632 --local args = {...}\
6633 local program = Bedrock:Initialise()\
6634\
6635 program:Run(function()\
6636 --[[Temp start\
6637 local groups = {\
6638 {\
6639 Name = \"owo\", \
6640 turbine = {\
6641 { device = \"BigReactors-Turbine_0\", name = \"Turbine $n\", settings = {overrideGroup = false, optimiseTurbine = true, optimiseRPM = 1840, disengageCoils = true, allowEE = true}, variables = {startingDone = false, lastRPM = 0}, },\
6642 { device = \"BigReactors-Turbine_1\", name = \"Turbine $n\", settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, variables = {startingDone = false, lastRPM = 0}, },\
6643 { device = \"BigReactors-Turbine_2\", name = \"Turbine $n\", settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, variables = {startingDone = false, lastRPM = 0}, },\
6644 { device = \"BigReactors-Turbine_3\", name = \"Turbine $n\", settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, variables = {startingDone = false, lastRPM = 0}, },\
6645 { device = \"BigReactors-Turbine_4\", name = \"Turbine $n\", settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, variables = {startingDone = false, lastRPM = 0}, },\
6646 },\
6647 reactor = {\
6648 { device = \"BigReactors-Reactor_0\", name = \"Reactor $n\", settings = {overrideGroup = false, optimiseReactor = true, maxTemp = 1500, allowEE = true}, variables = {lastTemp = 0}, },\
6649 { device = \"BigReactors-Reactor_1\", name = \"Reactor $n\", settings = {overrideGroup = false, optimiseReactor = false, maxTemp = 1500, allowEE = true}, variables = {lastTemp = 0}, },\
6650 },\
6651 battery = {\
6652 { device = \"powered_tile_0\", name = \"Battery $n\", },\
6653 { device = \"powered_tile_1\", name = \"Battery $n\", },\
6654 { device = \"capacitor_bank_0\", name = \"Battery $n\", },\
6655 },\
6656 settings = {optimiseReactor = true, efficentEnergy = false, energyOffTreshold = 95, energyOnTreshold = 70, optimiseTurbine = true, optimiseRPM = 1840, disengageCoils = true, maxTemp = 1500},\
6657 },\
6658 }\
6659 --Temp end]]\
6660\
6661 local defaultSettings = {\
6662 refreshSpeed = 0.15, \
6663 onScreenKeyboard = false, \
6664 changeTempColor = true, \
6665 changeRpmColor = true,\
6666 defaultTurbineName = \"Turbine $n\",\
6667 defaultReactorName = \"Reactor $n\",\
6668 defaultBatteryName = \"Battery $n\",\
6669 darkmode = false,\
6670 terms={\"native\"},\
6671 automaticControl = true,\
6672 groupPath=\"/ReactorControl/Other/\",\
6673 manualRefreshHome = true,\
6674 }\
6675\
6676 local defaultGroup = {\
6677 Name = \"Default Group\",\
6678 turbine = {},\
6679 reactor = {},\
6680 battery = {},\
6681 settings = {optimiseReactor = false, efficentEnergy = false, energyOffTreshold = 95, energyOnTreshold = 70, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, maxTemp = 1500},\
6682 }\
6683\
6684 local batteryTypes = {\
6685 capacitor_bank = \"EnderIO Capacitor Bank\",\
6686 powered_tile = \"Energy Cell\",\
6687 draconic_rf_storage = \"Draconic Energy Core\",\
6688 energyCellTypes = {\"Leadstone\", \"Hardened\", \"Redstone\", \"Resonant\"},\
6689 draconicTiers = {\"Tier 1\",\"Tier 2\", \"Tier 3\", \"Tier 4\", \"Tier 5\", \"Tier 6\", \"Tier 7\", \"Tier 8\"},\
6690 }\
6691\
6692 local currentGroupID = 1\
6693 local currentTurbineID = 1\
6694 local currentReactorID = 1\
6695 local currentBatteryID = 1\
6696 local currentTermID = 1\
6697 local currentView = \"main\"\
6698 local actualView = \"main\"\
6699\
6700 local storedEnergyLast = 0\
6701 local value = 0\
6702 local lastSelected = false\
6703 local refreshHome = true\
6704 local randomFact = \"Did you know? A carrot can also be a stick.\"\
6705 local factList = {\
6706 \"Turbines are working best when hold on 900 RPM or 1840 RPM.\",\
6707 \"Reactors with a teperatur higher than 1000 C have a high loss rate.\",\
6708 \"'Destabilized Redstone' is a good and cheap fluid to cool your reactor.\",\
6709 \"Turbines will output water which can be recycled to produce more steam.\",\
6710 \"The square root of 2 is 1.414\",\
6711 \"Ludicrite is the best coil material, but it comes with its price.\",\
6712 \"The refresh button is at the top right corner.\",\
6713 \"Wireless modems with a higher altitude have a higher range.\",\
6714 \"A tick is 1/20 second.\",\
6715 fs.getName( shell.getRunningProgram() ) ..\":1859: attempt to index ? (a nil value)\",\
6716 }\
6717\
6718 local settings = {}\
6719 local groups = {}\
6720 local version = 1.0 \
6721\
6722 local function redirectTerm(destTerm)\
6723 if destTerm == \"native\" and term.current() ~= startTerm then\
6724 term.redirect(startTerm)\
6725 program:LoadAPIs()\
6726 elseif peripheral.isPresent(destTerm) == true and term.current() ~= peripheral.wrap(destTerm) then\
6727 local mon = peripheral.wrap(destTerm)\
6728 mon.setTextScale(0.5)\
6729 term.redirect(mon)\
6730 program:LoadAPIs()\
6731 else\
6732 return\
6733 end\
6734 end\
6735\
6736 local function stop(restart, argument)\
6737 program:Quit()\
6738 if restart == true then\
6739 returnValue = argument\
6740 else\
6741 returnValue = \"stop\"\
6742 end\
6743 end\
6744\
6745 local function loadSettings()\
6746 local file = fs.open(\"/ReactorControl/Other/settings\", \"r\")\
6747 if file ~= nil then \
6748 settings = textutils.unserialise(file.readAll())\
6749 file.close()\
6750 else\
6751 local file = fs.open(\"/ReactorControl/Other/settings\", \"w\")\
6752 file.write(textutils.serialise(defaultSettings))\
6753 file.close()\
6754 --settings = defaultSettings\
6755 end\
6756 end\
6757\
6758 local function saveSettings()\
6759 local file = fs.open(\"/ReactorControl/Other/settings\", \"w\")\
6760 file.write(textutils.serialise(settings))\
6761 file.close()\
6762 end\
6763\
6764 --[[\
6765 local function loadGroup()\
6766 local file = fs.open(settings[\"groupPath\"] ..\"/groups\", \"r\")\
6767 local fileError = false\
6768 local allPeri = nil\
6769 groups = nil\
6770\
6771 if file ~= nil then\
6772 groups = textutils.unserialise(file.readAll())\
6773 file.close()\
6774 end\
6775\
6776 if groups == nil then\
6777 fileError = true\
6778 groups = {}\
6779 end\
6780\
6781 allPeri = peripheral.getNames()\
6782 term.setCursorPos(1,1)\
6783 if #groups > 0 then\
6784 for periID = 1, #allPeri do\
6785 for groupID = 1, #groups do\
6786 for turbineID = 1, #(groups[#groups][\"turbine\"]) do\
6787 print(\"turbine\")\
6788 print(#(groups[#groups][\"turbine\"]))\
6789 print(turbineID)\
6790 if allPeri[periID] == groups[groupID][\"turbine\"][turbineID][\"device\"] then\
6791 \
6792 table.remove(allPeri, periID)\
6793 end\
6794 end\
6795\
6796 for reactorID = 1, #(groups[#groups][\"reactor\"]) do\
6797 print(\"reactor\")\
6798 print(#(groups[#groups][\"reactor\"]))\
6799 print(reactorID)\
6800 if allPeri[periID] == groups[groupID][\"reactor\"][reactorID][\"device\"] then\
6801 table.remove(allPeri, periID)\
6802 end\
6803 end\
6804\
6805 for batteryID = 1, #(groups[#groups][\"battery\"]) do\
6806 if allPeri[periID] == groups[groupID][\"battery\"][batteryID][\"device\"] then\
6807 table.remove(allPeri, periID)\
6808 end\
6809 end\
6810\
6811 end\
6812 end\
6813 end\
6814\
6815 table.insert(groups, defaultGroup)\
6816 groups[#groups][\"Name\"] = \"Ungrouped\"\
6817 \
6818 for periID = 1, #allPeri do\
6819 if peripheral.getType(allPeri[periID]) == \"BigReactors-Turbine\" then\
6820 defaultTurbine[\"device\"] = allPeri[periID]\
6821 table.insert(groups[#groups][\"turbine\"], {\
6822 device = allPeri[periID], \
6823 name = \"Turbine $n\", \
6824 settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, \
6825 variables = {startingDone = false, lastRPM = 0}, \
6826 })\
6827 elseif peripheral.getType(allPeri[periID]) == \"BigReactors-Reactor\" then\
6828 defaultReactor[\"device\"] = allPeri[periID]\
6829 table.insert(groups[#groups][\"reactor\"], {\
6830 device = allPeri[periID], \
6831 name = \"Reactor $n\", \
6832 settings = {overrideGroup = false, optimiseReactor = false, maxTemp = 1500, allowEE = true}, \
6833 variables = {lastTemp = 0}, \
6834 })\
6835 elseif peripheral.getType(allPeri[periID]) == \"powered_tile\" then\
6836 defaultBattery[\"device\"] = allPeri[periID]\
6837 table.insert(groups[#groups][\"battery\"], {\
6838 device = allPeri[periID], \
6839 name = \"Battery $n\", \
6840 })\
6841 elseif peripheral.getType(allPeri[periID]) == \"capacitor_bank\" then\
6842 defaultBattery[\"device\"] = allPeri[periID]\
6843 table.insert(groups[#groups][\"battery\"], {\
6844 device = allPeri[periID], \
6845 name = \"Battery $n\", \
6846 })\
6847 end\
6848 end\
6849\
6850 local file = fs.open(settings[\"groupPath\"] ..\"/groupsawa\", \"w\")\
6851 file.write(textutils.serialize(groups))\
6852 file.close()\
6853 \
6854 return fileError\
6855 end\
6856 ]]--\
6857\
6858 local function saveGroup()\
6859 --table.remove(groups, #groups)\
6860\
6861 local file = fs.open(settings[\"groupPath\"] ..\"/groups\", \"w\")\
6862 file.write(textutils.serialize(groups))\
6863 file.close()\
6864 end\
6865 \
6866 local function loadGroup()\
6867 local file = fs.open(settings[\"groupPath\"] ..\"/groups\", \"r\")\
6868 local fileError = false\
6869 groups = {}\
6870\
6871 if file ~= nil then\
6872 groups = textutils.unserialise(file.readAll())\
6873 file.close()\
6874 end\
6875\
6876 if groups == nil or #groups < 1 then\
6877 fileError = true\
6878 groups = {}\
6879 table.insert(groups, defaultGroup)\
6880 saveGroup()\
6881 end\
6882 return fileError\
6883 end\
6884\
6885 local function loadColoredView(view)\
6886 if settings[\"darkmode\"] == true then\
6887 if actualView ~= view..\"-dark.view\" then\
6888 program:LoadView(view..\"-dark\")\
6889 end\
6890 else\
6891 if actualView ~= view then\
6892 program:LoadView(view)\
6893 end\
6894 end\
6895 refreshHome = true\
6896 actualView = view\
6897 currentView = view\
6898 end\
6899\
6900 local function refreshView()\
6901 if settings[\"darkmode\"] == true then\
6902 program:LoadView(actualView..\"-dark\")\
6903 --program:LoadAPIs()\
6904 else\
6905 program:LoadView(actualView)\
6906 --program:LoadAPIs()\
6907 end\
6908 end\
6909\
6910 local function flowrateWindow(turbine)\
6911 program:DisplayAlertWindow(\"Set Flowratelevel\", \"Change the flowratelevel of the Turbine.\\nLower values can decrease Speed.\\nValue: \".. value, {'+100', '+10', 'Abort', 'Apply', '-10', '-100'}, function(pressedButton)\
6912\
6913 if pressedButton == \"+100\" then\
6914 value = value + 100\
6915 flowrateWindow(turbine)\
6916 \
6917 elseif pressedButton == \"+10\" then\
6918 value = value + 10\
6919 flowrateWindow(turbine)\
6920 \
6921 elseif pressedButton == \"-10\" then\
6922 value = value - 10\
6923 if value < 0 then\
6924 value = 0\
6925 end\
6926 flowrateWindow(turbine)\
6927 \
6928 elseif pressedButton == \"-100\" then\
6929 value = value - 100\
6930 if value < 0 then\
6931 value = 0\
6932 end\
6933 flowrateWindow(turbine)\
6934 \
6935 elseif pressedButton == \"Abort\" then\
6936 value = 0\
6937 \
6938 elseif pressedButton == \"Apply\" then\
6939 turbine.setFluidFlowRateMax(value)\
6940\
6941 end\
6942\
6943 end)\
6944\
6945 end\
6946\
6947 local function controlRodWindow(reactor)\
6948 program:DisplayAlertWindow(\"Set Control Rod Levels\", \"Change the levels of the control rods.\\nHiger values can reduce fuel burnup rate.\\nValue: \".. value, {'+10%', '+1%', 'Abort', 'Apply', '-1%', '-10%'}, function(pressedButton)\
6949\
6950 if pressedButton == \"+10%\" then\
6951 value = value + 10\
6952 if value > 100 then\
6953 value = 100\
6954 end\
6955 controlRodWindow(reactor)\
6956 \
6957 elseif pressedButton == \"+1%\" then\
6958 value = value + 1\
6959 if value > 100 then\
6960 value = 100\
6961 end\
6962 controlRodWindow(reactor)\
6963 \
6964 elseif pressedButton == \"-1%\" then\
6965 value = value - 1\
6966 if value < 0 then\
6967 value = 0\
6968 end\
6969 controlRodWindow(reactor)\
6970 \
6971 elseif pressedButton == \"-10%\" then\
6972 value = value - 10\
6973 if value < 0 then\
6974 value = 0\
6975 end\
6976 controlRodWindow(reactor)\
6977 \
6978 elseif pressedButton == \"Abort\" then\
6979 value = 0\
6980 \
6981 elseif pressedButton == \"Apply\" then\
6982 reactor.setAllControlRodLevels(value)\
6983\
6984 end\
6985\
6986 end)\
6987\
6988 end\
6989\
6990 local function refreshScreen()\
6991 if currentView == \"home\" then\
6992\
6993 if refreshHome == true or settings[\"manualRefreshHome\"] == false then\
6994 refreshHome = false\
6995\
6996 local reactors = {peripheral.find(\"BigReactors-Reactor\")} or {}\
6997 local turbines = {peripheral.find(\"BigReactors-Turbine\")} or {}\
6998 local b_cell = {peripheral.find(\"powered_tile\")} or {}\
6999 local b_capacitor = {peripheral.find(\"capacitor_bank\")} or {}\
7000 local b_EnergyCore = {peripheral.find(\"draconic_rf_storage\")} or {}\
7001\
7002 local storedEnergy = 0\
7003 local maxEnergy = 0\
7004 local energyProduce = 0\
7005\
7006 for rID = 1, #reactors do\
7007 if reactors[rID].isActivelyCooled() == false then\
7008 energyProduce = energyProduce + reactors[rID].getEnergyProducedLastTick()\
7009 end\
7010 end\
7011\
7012 for tID = 1, #turbines do\
7013 energyProduce = energyProduce + turbines[tID].getEnergyProducedLastTick()\
7014 end\
7015\
7016 for bID = 1, #b_cell do\
7017 storedEnergy = storedEnergy + b_cell[bID].getEnergyStored()\
7018 maxEnergy = maxEnergy + b_cell[bID].getMaxEnergyStored()\
7019 end\
7020\
7021 for bID = 1, #b_capacitor do\
7022 storedEnergy = storedEnergy + b_capacitor[bID].getEnergyStored()\
7023 maxEnergy = maxEnergy + b_capacitor[bID].getMaxEnergyStored()\
7024 end\
7025\
7026 for bID = 1, #b_EnergyCore do\
7027 storedEnergy = storedEnergy + b_EnergyCore[bID].getEnergyStored()\
7028 maxEnergy = maxEnergy + b_EnergyCore[bID].getMaxEnergyStored()\
7029 end\
7030\
7031 -- Labels\
7032 program:GetObject(\"Home_Reactors_Label\").Text = #reactors ..\" connected\"\
7033 program:GetObject(\"Home_Turbines_Label\").Text = #turbines ..\" connected\"\
7034 program:GetObject(\"Home_Batteries_Label\").Text = #b_cell + #b_capacitor + #b_EnergyCore ..\" connected\"\
7035 program:GetObject(\"Home_EnergyProduce_Label\").Text = math.floor(energyProduce) ..\" RF/t\"\
7036 program:GetObject(\"Home_RandomFact_Label\").Text = randomFact\
7037\
7038 --Progress Bars\
7039 program:GetObject(\"Home_EnergyStorage_ProgressBar\").Value = storedEnergy\
7040 program:GetObject(\"Home_EnergyStorage_ProgressBar\").Maximum = maxEnergy\
7041\
7042 end\
7043\
7044 -- Buttons\
7045\
7046 program:GetObject(\"Home_Refresh_Button\").OnClick = function(self, event, side, x, y)\
7047 refreshHome = true \
7048 end\
7049\
7050 program:GetObject(\"Home_Quit_Button\").OnClick = function(self, event, side, x, y)\
7051 program:DisplayAlertWindow(\"Warning!\", \"Are you sure you want to close the program?\\nAutomatic Control wont run as long as the program is closed! \", {\"Abort\",\"Start in Silent mode\", \"Close\"}, function(pressedButton)\
7052 if pressedButton == \"Start in Silent mode\" then\
7053 stop(true, \"silent\")\
7054\
7055 elseif pressedButton == \"Close\" then\
7056 stop(false)\
7057 else\
7058 end\
7059 end)\
7060 end\
7061\
7062 program:GetObject(\"Home_GroupOverview_Button\").OnClick = function(self, event, side, x, y)\
7063 program:StartTimer(function()\
7064 loadColoredView(\"groupOverview\")\
7065 refreshScreen()\
7066 end, 0.15)\
7067 end\
7068\
7069 program:GetObject(\"Home_GroupEdit_Button\").OnClick = function(self, event, side, x, y)\
7070 program:StartTimer(function()\
7071 loadColoredView(\"groupEditor\")\
7072 refreshScreen()\
7073 end, 0.15)\
7074 end\
7075\
7076 program:GetObject(\"Home_Settings_Button\").OnClick = function(self, event, side, x, y)\
7077 program:StartTimer(function()\
7078 loadColoredView(\"globalSettings\")\
7079 refreshScreen()\
7080 end, 0.15)\
7081 end\
7082\
7083 elseif currentView == \"globalSettings\" then\
7084\
7085 elseif currentView == \"groupSettings\" then\
7086\
7087 if program:GetObject(\"GroupSettings_EE_OffTh_NumberBox\").Value == -100 then\
7088 program:GetObject(\"GroupSettings_EE_OffTh_NumberBox\").Value = groups[currentGroupID][\"settings\"][\"energyOffTreshold\"]\
7089 program:GetObject(\"GroupSettings_EE_OnTh_NumberBox\").Value = groups[currentGroupID][\"settings\"][\"energyOnTreshold\"]\
7090 program:GetObject(\"GroupSettings_OptimiseTurbine_RPM_NumberBox\").Value = groups[currentGroupID][\"settings\"][\"optimiseRPM\"]\
7091 program:GetObject(\"GroupSettings_OptimiseReactor_MaxTemp_NumberBox\").Value = groups[currentGroupID][\"settings\"][\"maxTemp\"]\
7092 end\
7093 --Labels\
7094 program:GetObject(\"groupName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] Settings\"\
7095\
7096 --Buttons\
7097\
7098 program:GetObject(\"GroupSettings_EE_Help_Button\").OnClick = function(self, event, side, x, y)\
7099 program:DisplayAlertWindow(\"Help: Efficient Energy\", \"Deactivates all Turbines and Reactors, if 'Deactivate Value' of 'Energy Stored' is met. Will be activated again if 'Activate Value' is met.\", {\"Ok\"}, function(pressedButton)\
7100 end)\
7101 end\
7102\
7103 program:GetObject(\"GroupSettings_OptimiseTurbine_Help_Button\").OnClick = function(self, event, side, x, y)\
7104\
7105 program:DisplayAlertWindow(\"Help: Optimise Turbine\", \"Optimise turbine flowrate to met the specified RPM.\", {\"Ok\"}, function(pressedButton)\
7106 end)\
7107 end\
7108\
7109 program:GetObject(\"GroupSettings_DisengageCoils_Help_Button\").OnClick = function(self, event, side, x, y)\
7110 program:DisplayAlertWindow(\"Help: Disengage Coils\", \"Disengage Coils on starting sequence.\", {\"Ok\"}, function(pressedButton)\
7111 end)\
7112 end\
7113\
7114 program:GetObject(\"GroupSettings_OptimiseReactor_Help_Button\").OnClick = function(self, event, side, x, y)\
7115 program:DisplayAlertWindow(\"Help: Optimise Reactor\", \"Optimise controlrodlevels to met the required steam consumption or to met the specified temperature.\", {\"Ok\"}, function(pressedButton)\
7116 end)\
7117 end\
7118\
7119 program:GetObject(\"GroupSettings_EE_Button\").OnClick = function(self, event, side, x, y)\
7120 groups[currentGroupID][\"settings\"][\"efficentEnergy\"] = (not groups[currentGroupID][\"settings\"][\"efficentEnergy\"])\
7121 refreshScreen()\
7122 end\
7123\
7124 program:GetObject(\"GroupSettings_OptimiseTurbine_Button\").OnClick = function(self, event, side, x, y)\
7125 groups[currentGroupID][\"settings\"][\"optimiseTurbine\"] = (not groups[currentGroupID][\"settings\"][\"optimiseTurbine\"])\
7126 refreshScreen()\
7127 end\
7128\
7129 program:GetObject(\"GroupSettings_DisengageCoils_Button\").OnClick = function(self, event, side, x, y)\
7130 groups[currentGroupID][\"settings\"][\"disengageCoils\"] = (not groups[currentGroupID][\"settings\"][\"disengageCoils\"])\
7131 refreshScreen()\
7132 end\
7133\
7134 program:GetObject(\"GroupSettings_OptimiseReactor_Button\").OnClick = function(self, event, side, x, y)\
7135 groups[currentGroupID][\"settings\"][\"optimiseReactor\"] = (not groups[currentGroupID][\"settings\"][\"optimiseReactor\"])\
7136 refreshScreen()\
7137 end\
7138\
7139 groups[currentGroupID][\"settings\"][\"energyOffTreshold\"] = program:GetObject(\"GroupSettings_EE_OffTh_NumberBox\").Value \
7140 groups[currentGroupID][\"settings\"][\"energyOnTreshold\"] = program:GetObject(\"GroupSettings_EE_OnTh_NumberBox\").Value \
7141 groups[currentGroupID][\"settings\"][\"optimiseRPM\"] = program:GetObject(\"GroupSettings_OptimiseTurbine_RPM_NumberBox\").Value \
7142 groups[currentGroupID][\"settings\"][\"maxTemp\"] = program:GetObject(\"GroupSettings_OptimiseReactor_MaxTemp_NumberBox\").Value \
7143\
7144 if groups[currentGroupID][\"settings\"][\"efficentEnergy\"] == true then\
7145 program:GetObject(\"GroupSettings_EE_Button\").Text = \" Active \"\
7146 program:GetObject(\"GroupSettings_EE_Button\").BackgroundColour = \"green\"\
7147 else\
7148 program:GetObject(\"GroupSettings_EE_Button\").Text = \" Inactive \"\
7149 program:GetObject(\"GroupSettings_EE_Button\").BackgroundColour = \"red\"\
7150 end\
7151\
7152 if groups[currentGroupID][\"settings\"][\"optimiseTurbine\"] == true then\
7153 program:GetObject(\"GroupSettings_OptimiseTurbine_Button\").Text = \" Active \"\
7154 program:GetObject(\"GroupSettings_OptimiseTurbine_Button\").BackgroundColour = \"green\"\
7155 else\
7156 program:GetObject(\"GroupSettings_OptimiseTurbine_Button\").Text = \" Inactive \"\
7157 program:GetObject(\"GroupSettings_OptimiseTurbine_Button\").BackgroundColour = \"red\"\
7158 end\
7159\
7160 if groups[currentGroupID][\"settings\"][\"disengageCoils\"] == true then\
7161 program:GetObject(\"GroupSettings_DisengageCoils_Button\").Text = \" Active \"\
7162 program:GetObject(\"GroupSettings_DisengageCoils_Button\").BackgroundColour = \"green\"\
7163 else\
7164 program:GetObject(\"GroupSettings_DisengageCoils_Button\").Text = \" Inactive \"\
7165 program:GetObject(\"GroupSettings_DisengageCoils_Button\").BackgroundColour = \"red\"\
7166 end\
7167\
7168 if groups[currentGroupID][\"settings\"][\"optimiseReactor\"] == true then\
7169 program:GetObject(\"GroupSettings_OptimiseReactor_Button\").Text = \" Active \"\
7170 program:GetObject(\"GroupSettings_OptimiseReactor_Button\").BackgroundColour = \"green\"\
7171 else\
7172 program:GetObject(\"GroupSettings_OptimiseReactor_Button\").Text = \" Inactive \"\
7173 program:GetObject(\"GroupSettings_OptimiseReactor_Button\").BackgroundColour = \"red\"\
7174 end\
7175\
7176 program:GetObject(\"GroupSettings_Back_Button\").OnClick = function(self, event, side, x, y)\
7177 loadGroup()\
7178 program:StartTimer(function()\
7179 loadColoredView(\"groupOverview\")\
7180 refreshScreen()\
7181 end, 0.15)\
7182 end\
7183 \
7184 program:GetObject(\"GroupSettings_Apply_Button\").OnClick = function(self, event, side, x, y)\
7185 saveGroup()\
7186 loadGroup()\
7187 end\
7188\
7189 elseif currentView == \"groupEditor\" then\
7190\
7191 local function refreshList(selectBool)\
7192 local listItems = {}\
7193 local selectIndex = nil\
7194 local gID = nil\
7195 local rID = nil\
7196 local tID = nil\
7197 local bID = nil\
7198 lastSelected = nil\
7199\
7200 if selectBool == true then\
7201 local object = program:GetObject(\"GroupEditor_GroupList_ListView\").Selected\
7202 if object ~= nil then\
7203 gID = object.groupID\
7204 rID = object.reactorID\
7205 tID = object.turbineID\
7206 bID = object.batteryID\
7207 end\
7208 \
7209 end\
7210\
7211 for groupID = 1, #groups do\
7212 table.insert(listItems, \
7213 {\
7214 Name=\"ListView_Item_Button\",\
7215 Type=\"Button\",\
7216 Text=\"[\".. groups[groupID][\"Name\"] ..\"]\",\
7217 BackgroundColour=\"gray\",\
7218 TextColour='white',\
7219 groupID=groupID,\
7220 })\
7221\
7222 if gID == groupID and rID == nil and tID == nil and bID == nil then\
7223 selectIndex = #listItems\
7224 end\
7225\
7226 table.insert(listItems, \
7227 {\
7228 Name=\"ListView_Item_Button\",\
7229 Type=\"Button\",\
7230 Text=\"L [Reactor]\",\
7231 BackgroundColour=\"lightGray\",\
7232 DisabledTextColour ='gray',\
7233 groupID=groupID,\
7234 cosmetic=true,\
7235 Enabled=false,\
7236 })\
7237\
7238 for reactorID = 1, #groups[groupID][\"reactor\"] do\
7239 table.insert(listItems, \
7240 {\
7241 Name=\"ListView_Item_Button\",\
7242 Type=\"Button\",\
7243 Text=\" L \".. string.gsub( groups[groupID][\"reactor\"][reactorID][\"device\"], \"BigReactors\",\"BR\" ),\
7244 BackgroundColour=\"lightGray\",\
7245 TextColour='black',\
7246 reactorID=reactorID,\
7247 groupID=groupID,\
7248 })\
7249\
7250 if gID == groupID and rID == reactorID then\
7251 selectIndex = #listItems\
7252 end\
7253 end\
7254\
7255 table.insert(listItems, \
7256 {\
7257 Name=\"ListView_Item_Button\",\
7258 Type=\"Button\",\
7259 Text=\"L [Turbine]\",\
7260 BackgroundColour=\"lightGray\",\
7261 DisabledTextColour='gray',\
7262 groupID=groupID,\
7263 cosmetic=true,\
7264 Enabled=false,\
7265 })\
7266\
7267 for turbineID = 1, #groups[groupID][\"turbine\"] do\
7268 table.insert(listItems, \
7269 {\
7270 Name=\"ListView_Item_Button\",\
7271 Type=\"Button\",\
7272 Text=\" L \".. string.gsub( groups[groupID][\"turbine\"][turbineID][\"device\"], \"BigReactors\",\"BR\" ),\
7273 BackgroundColour=\"lightGray\",\
7274 TextColour='black',\
7275 turbineID=turbineID,\
7276 groupID=groupID,\
7277 })\
7278\
7279 if gID == groupID and tID == turbineID then\
7280 selectIndex = #listItems\
7281 end\
7282 end\
7283\
7284 table.insert(listItems, \
7285 {\
7286 Name=\"ListView_Item_Button\",\
7287 Type=\"Button\",\
7288 Text=\"L [Battery] \",\
7289 BackgroundColour=\"lightGray\",\
7290 DisabledTextColour='gray',\
7291 groupID=groupID,\
7292 cosmetic=true,\
7293 Enabled=false,\
7294 })\
7295\
7296 for batteryID = 1, #groups[groupID][\"battery\"] do\
7297 table.insert(listItems, \
7298 {\
7299 Name=\"ListView_Item_Button\",\
7300 Type=\"Button\",\
7301 Text=\" L \".. string.gsub( groups[groupID][\"battery\"][batteryID][\"device\"], \"BigReactors\",\"BR\" ),\
7302 BackgroundColour=\"lightGray\",\
7303 TextColour='black',\
7304 batteryID=batteryID,\
7305 groupID=groupID,\
7306 })\
7307\
7308 if gID == groupID and bID == batteryID then\
7309 selectIndex = #listItems\
7310 end\
7311 end\
7312 end\
7313\
7314 program:GetObject(\"GroupEditor_GroupList_ListView\").Items = listItems\
7315 if selectIndex ~= nil then\
7316 program:StartTimer(function()\
7317 program:GetObject(\"GroupEditor_GroupList_ListView\").Selected = program:GetObject(\"GroupEditor_GroupList_ListView\").Items[selectIndex]\
7318 program:GetObject(\"GroupEditor_GroupList_ListView\"):SelectItem( listItems[selectIndex], listItems[selectIndex] )\
7319 program:GetObject(\"GroupEditor_GroupList_ListView\"):GetNth( selectIndex ).Toggle = true\
7320 end, 0.05)\
7321 end\
7322 \
7323 program:GetObject(\"GroupEditor_ChangePeripheral_Button\").Enabled = false\
7324 program:GetObject(\"GroupEditor_DeletePeripheral_Button\").Enabled = false\
7325 program:GetObject(\"GroupEditor_AddPeripheral_Button\").Enabled = false\
7326\
7327 program:GetObject(\"GroupEditor_RenameGroup_Button\").Enabled = false\
7328 program:GetObject(\"GroupEditor_DeleteGroup_Button\").Enabled = false\
7329 program:GetObject(\"GroupEditor_AddGroup_Button\").Enabled = true\
7330\
7331 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = false\
7332 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = false\
7333\
7334 end\
7335\
7336 -- List View\
7337 if program:GetObject(\"GroupEditor_GroupList_ListView\").Initialised == false then\
7338 program:GetObject(\"GroupEditor_GroupList_ListView\").Initialised = true\
7339 lastSelected = nil\
7340 refreshList()\
7341 end\
7342 -- Buttons\
7343\
7344 local focusedObject = program:GetObject(\"GroupEditor_GroupList_ListView\").Selected\
7345\
7346 term.setCursorPos(1,1)\
7347\
7348 if program:GetObject(\"GroupEditor_GroupList_ListView\").Selected ~= nil and program:GetObject(\"GroupEditor_GroupList_ListView\").Selected ~= lastSelected then\
7349 lastSelected = program:GetObject(\"GroupEditor_GroupList_ListView\").Selected\
7350 program:GetObject(\"GroupEditor_GroupName_TextBox\").Text = groups[focusedObject.groupID][\"Name\"]\
7351\
7352 program:GetObject(\"GroupEditor_ChangePeripheral_Button\").Enabled = true\
7353 program:GetObject(\"GroupEditor_DeletePeripheral_Button\").Enabled = true\
7354 program:GetObject(\"GroupEditor_AddPeripheral_Button\").Enabled = false\
7355\
7356 program:GetObject(\"GroupEditor_RenameGroup_Button\").Enabled = false\
7357 program:GetObject(\"GroupEditor_DeleteGroup_Button\").Enabled = false\
7358 program:GetObject(\"GroupEditor_AddGroup_Button\").Enabled = false\
7359\
7360 if focusedObject.Enabled == false then\
7361 program:GetObject(\"GroupEditor_ChangePeripheral_Button\").Enabled = false\
7362 program:GetObject(\"GroupEditor_DeletePeripheral_Button\").Enabled = false\
7363 program:GetObject(\"GroupEditor_AddPeripheral_Button\").Enabled = false\
7364 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = false\
7365 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = false\
7366 else\
7367 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = true\
7368 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = true\
7369\
7370 if focusedObject.reactorID ~= nil then\
7371 program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text = groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID][\"device\"]\
7372 program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text = groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID][\"name\"]\
7373 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = not (focusedObject.reactorID == 1)\
7374 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = not (focusedObject.reactorID == #groups[focusedObject.groupID][\"reactor\"])\
7375\
7376 elseif focusedObject.turbineID ~= nil then\
7377 program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text = groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID][\"device\"]\
7378 program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text = groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID][\"name\"]\
7379 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = not (focusedObject.turbineID == 1)\
7380 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = not (focusedObject.turbineID == #groups[focusedObject.groupID][\"turbine\"])\
7381 elseif focusedObject.batteryID ~= nil then\
7382 program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text = groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID][\"device\"]\
7383 program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text = groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID][\"name\"]\
7384 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = not (focusedObject.batteryID == 1)\
7385 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = not (focusedObject.batteryID == #groups[focusedObject.groupID][\"battery\"])\
7386 else\
7387 program:GetObject(\"GroupEditor_ChangePeripheral_Button\").Enabled = false\
7388 program:GetObject(\"GroupEditor_DeletePeripheral_Button\").Enabled = false\
7389 program:GetObject(\"GroupEditor_AddPeripheral_Button\").Enabled = true\
7390\
7391 program:GetObject(\"GroupEditor_RenameGroup_Button\").Enabled = true\
7392 program:GetObject(\"GroupEditor_DeleteGroup_Button\").Enabled = true\
7393 program:GetObject(\"GroupEditor_AddGroup_Button\").Enabled = true\
7394\
7395 --program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text = \"\"\
7396 --program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text = \"\"\
7397\
7398 program:GetObject(\"GroupEditor_MoveUp_Button\").Enabled = not (focusedObject.groupID == 1)\
7399 program:GetObject(\"GroupEditor_MoveDown_Button\").Enabled = not (focusedObject.groupID == #groups)\
7400 end\
7401 end\
7402\
7403 end\
7404\
7405 program:GetObject(\"GroupEditor_AddGroup_Button\").OnClick = function(self, event, side, x, y)\
7406 table.insert(groups,{\
7407 Name = program:GetObject(\"GroupEditor_GroupName_TextBox\").Text,\
7408 turbine = {},\
7409 reactor = {},\
7410 battery = {},\
7411 settings = {optimiseReactor = false, efficentEnergy = false, energyOffTreshold = 95, energyOnTreshold = 70, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, maxTemp = 1500},\
7412 } )\
7413 refreshList()\
7414 end\
7415\
7416 program:GetObject(\"GroupEditor_RenameGroup_Button\").OnClick = function(self, event, side, x, y)\
7417 groups[focusedObject.groupID][\"Name\"] = program:GetObject(\"GroupEditor_GroupName_TextBox\").Text\
7418 refreshList(true)\
7419 end\
7420\
7421 program:GetObject(\"GroupEditor_DeleteGroup_Button\").OnClick = function(self, event, side, x, y)\
7422 table.remove(groups, focusedObject.groupID)\
7423 refreshList()\
7424 end\
7425\
7426 program:GetObject(\"GroupEditor_AddPeripheral_Button\").OnClick = function(self, event, side, x, y)\
7427 local deviceString = program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text\
7428 deviceString = string.gsub( deviceString, \"BR\", \"BigReactors\" )\
7429 if program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text == \"\" then\
7430 program:DisplayAlertWindow(\"Error\", \"Name cannot be empty!\", {\"Ok\"}, function(pressedButton)\
7431 end)\
7432 return false\
7433 end\
7434\
7435 if string.match(deviceString, \"BigReactors%-Reactor\") then\
7436\
7437 table.insert(groups[focusedObject.groupID][\"reactor\"], {\
7438 device = deviceString, \
7439 name = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text, \
7440 settings = {overrideGroup = false, optimiseReactor = false, maxTemp = 1500, allowEE = true}, \
7441 variables = {lastTemp = 0},\
7442 })\
7443 refreshList()\
7444\
7445 elseif string.match(deviceString, \"BigReactors%-Turbine\") then\
7446\
7447 table.insert(groups[focusedObject.groupID][\"turbine\"], {\
7448 device = deviceString, \
7449 name = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text, \
7450 settings = {overrideGroup = false, optimiseTurbine = false, optimiseRPM = 1840, disengageCoils = false, allowEE = true}, \
7451 variables = {startingDone = false, lastRPM = 0}, \
7452 })\
7453 refreshList()\
7454\
7455 elseif string.match(deviceString, \"capacitor%_bank\") or string.match(deviceString, \"powered%_tile\") or string.match(deviceString, \"draconic%_rf%_storage\") then\
7456 \
7457 table.insert(groups[focusedObject.groupID][\"battery\"], {\
7458 device = deviceString, \
7459 name = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text, \
7460 })\
7461 refreshList()\
7462 \
7463 else\
7464 program:DisplayAlertWindow(\"Error\", \"Wasn't able to identify peripheral type.\", {\"Ok\"}, function(pressedButton)\
7465 end)\
7466 end\
7467 \
7468 end\
7469\
7470 program:GetObject(\"GroupEditor_ChangePeripheral_Button\").OnClick = function(self, event, side, x, y)\
7471 if focusedObject.reactorID ~= nil then\
7472 groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID][\"device\"] = program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text\
7473 groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID][\"name\"] = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text\
7474 elseif focusedObject.turbineID ~= nil then\
7475 groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID][\"device\"] = program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text\
7476 groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID][\"name\"] = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text\
7477 elseif focusedObject.batteryID ~= nil then\
7478 groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID][\"device\"] = program:GetObject(\"GroupEditor_PeripheralSide_TextBox\").Text\
7479 groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID][\"name\"] = program:GetObject(\"GroupEditor_PeripheralName_TextBox\").Text\
7480 end\
7481 refreshList(true)\
7482 end\
7483\
7484 program:GetObject(\"GroupEditor_DeletePeripheral_Button\").OnClick = function(self, event, side, x, y)\
7485 if focusedObject.reactorID ~= nil then\
7486 table.remove( groups[focusedObject.groupID][\"reactor\"], focusedObject.reactorID )\
7487 elseif focusedObject.turbineID ~= nil then\
7488 table.remove( groups[focusedObject.groupID][\"turbine\"], focusedObject.turbineID )\
7489 elseif focusedObject.batteryID ~= nil then\
7490 table.remove( groups[focusedObject.groupID][\"battery\"], focusedObject.batteryID )\
7491 end\
7492 refreshList(true)\
7493 end\
7494\
7495 program:GetObject(\"GroupEditor_MoveUp_Button\").OnClick = function(self, event, side, x, y)\
7496 if focusedObject.reactorID ~= nil then\
7497 groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID], groups[focusedObject.groupID][\"reactor\"][(focusedObject.reactorID - 1)] = groups[focusedObject.groupID][\"reactor\"][(focusedObject.reactorID - 1)], groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID]\
7498 focusedObject.reactorID = focusedObject.reactorID - 1\
7499 elseif focusedObject.turbineID ~= nil then\
7500 groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID], groups[focusedObject.groupID][\"turbine\"][(focusedObject.turbineID - 1)] = groups[focusedObject.groupID][\"turbine\"][(focusedObject.turbineID - 1)], groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID]\
7501 focusedObject.turbineID = focusedObject.turbineID - 1\
7502 elseif focusedObject.batteryID ~= nil then\
7503 groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID], groups[focusedObject.groupID][\"battery\"][(focusedObject.batteryID - 1)] = groups[focusedObject.groupID][\"battery\"][(focusedObject.batteryID - 1)], groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID]\
7504 focusedObject.batteryID = focusedObject.batteryID - 1\
7505 else\
7506 groups[focusedObject.groupID], groups[(focusedObject.groupID - 1)] = groups[(focusedObject.groupID - 1)], groups[focusedObject.groupID]\
7507 focusedObject.groupID = focusedObject.groupID - 1\
7508 end\
7509 refreshList(true)\
7510 end\
7511\
7512 program:GetObject(\"GroupEditor_MoveDown_Button\").OnClick = function(self, event, side, x, y)\
7513 if focusedObject.reactorID ~= nil then\
7514 groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID], groups[focusedObject.groupID][\"reactor\"][(focusedObject.reactorID + 1)] = groups[focusedObject.groupID][\"reactor\"][(focusedObject.reactorID + 1)], groups[focusedObject.groupID][\"reactor\"][focusedObject.reactorID]\
7515 focusedObject.reactorID = focusedObject.reactorID + 1\
7516 elseif focusedObject.turbineID ~= nil then\
7517 groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID], groups[focusedObject.groupID][\"turbine\"][(focusedObject.turbineID + 1)] = groups[focusedObject.groupID][\"turbine\"][(focusedObject.turbineID + 1)], groups[focusedObject.groupID][\"turbine\"][focusedObject.turbineID]\
7518 focusedObject.turbineID = focusedObject.turbineID + 1\
7519 elseif focusedObject.batteryID ~= nil then\
7520 groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID], groups[focusedObject.groupID][\"battery\"][(focusedObject.batteryID + 1)] = groups[focusedObject.groupID][\"battery\"][(focusedObject.batteryID + 1)], groups[focusedObject.groupID][\"battery\"][focusedObject.batteryID]\
7521 focusedObject.batteryID = focusedObject.batteryID + 1\
7522 else\
7523 groups[focusedObject.groupID], groups[(focusedObject.groupID + 1)] = groups[(focusedObject.groupID + 1)], groups[focusedObject.groupID]\
7524 focusedObject.groupID = focusedObject.groupID + 1\
7525 end\
7526 \
7527 refreshList(true)\
7528 end\
7529\
7530 program:GetObject(\"GroupEditor_Apply_Button\").OnClick = function(self, event, side, x, y)\
7531 saveGroup()\
7532 loadGroup()\
7533 refreshList()\
7534 end\
7535\
7536 program:GetObject(\"GroupEditor_Back_Button\").OnClick = function(self, event, side, x, y)\
7537 program:StartTimer(function()\
7538 loadGroup()\
7539 loadColoredView(\"home\")\
7540 refreshScreen()\
7541 end, 0.15)\
7542 end\
7543\
7544 elseif currentView == \"tutorial\" then\
7545\
7546 elseif currentView == \"groupOverview\" then\
7547\
7548 local availableReactors = 0\
7549 local availableTurbines = 0\
7550 local availableBatteries = 0\
7551 local requiredSteam = 0\
7552 local producedSteam = 0\
7553 local producedEnergy = 0\
7554 local storedEnergy = 0\
7555 local storedEnergyMax = 0\
7556 local ioEnergy = 0\
7557\
7558 \
7559 for i = 1, #groups[currentGroupID][\"reactor\"] do\
7560 if peripheral.isPresent( groups[currentGroupID][\"reactor\"][i][\"device\"] ) == true then\
7561 if peripheral.call( groups[currentGroupID][\"reactor\"][i][\"device\"], \"getConnected\" ) == true then\
7562\
7563 producedSteam = producedSteam + tonumber( peripheral.call( groups[currentGroupID][\"reactor\"][i][\"device\"], \"getHotFluidProducedLastTick\" ) )\
7564\
7565 if peripheral.call( groups[currentGroupID][\"reactor\"][i][\"device\"], \"isActivelyCooled\" ) == false then\
7566 producedEnergy = producedEnergy + tonumber( peripheral.call( groups[currentGroupID][\"reactor\"][i][\"device\"], \"getEnergyProducedLastTick\" ) )\
7567 end\
7568\
7569 availableReactors = availableReactors + 1\
7570 end\
7571 end\
7572 end\
7573\
7574 for i = 1, #groups[currentGroupID][\"turbine\"] do\
7575 if peripheral.isPresent( groups[currentGroupID][\"turbine\"][i][\"device\"] ) == true then\
7576 if peripheral.call( groups[currentGroupID][\"turbine\"][i][\"device\"], \"getConnected\" ) == true then\
7577\
7578 requiredSteam = requiredSteam + tonumber( peripheral.call( groups[currentGroupID][\"turbine\"][i][\"device\"], \"getFluidFlowRateMax\" ) )\
7579 producedEnergy = producedEnergy + tonumber( peripheral.call( groups[currentGroupID][\"turbine\"][i][\"device\"], \"getEnergyProducedLastTick\" ) )\
7580 availableTurbines = availableTurbines + 1\
7581 end\
7582 end\
7583 end\
7584\
7585 for i = 1, #groups[currentGroupID][\"battery\"] do\
7586 if peripheral.isPresent( groups[currentGroupID][\"battery\"][i][\"device\"] ) == true then\
7587\
7588 storedEnergy = storedEnergy + tonumber( peripheral.call( groups[currentGroupID][\"battery\"][i][\"device\"], \"getEnergyStored\" ) )\
7589 storedEnergyMax = storedEnergyMax + tonumber( peripheral.call( groups[currentGroupID][\"battery\"][i][\"device\"], \"getMaxEnergyStored\" ) )\
7590 availableBatteries = availableBatteries + 1\
7591 end\
7592 end\
7593\
7594 program:GetObject(\"GroupOverview_LastGroup_Button\").Enabled = not (currentGroupID == 1)\
7595 program:GetObject(\"GroupOverview_NextGroup_Button\").Enabled = not (currentGroupID >= #groups)\
7596\
7597 ioEnergy = (storedEnergy - storedEnergyLast) / (20 * settings[\"refreshSpeed\"]) \
7598 storedEnergyLast = storedEnergy\
7599\
7600 --Labels\
7601 program:GetObject(\"groupName_Label\").Text = groups[currentGroupID][\"Name\"]\
7602 program:GetObject(\"GroupOverview_Reactors_Label\").Text = availableReactors ..\" out of \".. #groups[currentGroupID][\"reactor\"] ..\" connected.\"\
7603 program:GetObject(\"GroupOverview_Turbines_Label\").Text = availableTurbines ..\" out of \".. #groups[currentGroupID][\"turbine\"] ..\" connected.\"\
7604 program:GetObject(\"GroupOverview_Batteries_Label\").Text = availableBatteries ..\" out of \".. #groups[currentGroupID][\"battery\"] ..\" connected.\"\
7605 program:GetObject(\"GroupOverview_SteamRequire_Label\").Text = requiredSteam ..\" mB/t\"\
7606 program:GetObject(\"GroupOverview_EnergyProduce_Label\").Text = math.floor( producedEnergy ) ..\" RF/t\"\
7607 \
7608 if math.floor( ioEnergy ) >= 1000000 or math.floor( ioEnergy ) <= -1000000 then\
7609 program:GetObject(\"GroupOverview_EnergyInOut_Label\").Text = math.floor( ioEnergy / 1000000 ) ..\" MRF/t\"\
7610 else\
7611 program:GetObject(\"GroupOverview_EnergyInOut_Label\").Text = math.floor( ioEnergy ) ..\" RF/t\"\
7612 end\
7613\
7614 if math.floor( ioEnergy ) >= 1 then\
7615 program:GetObject(\"GroupOverview_EnergyInOut_Label\").Text = \"+\".. program:GetObject(\"GroupOverview_EnergyInOut_Label\").Text\
7616 program:GetObject(\"GroupOverview_EnergyInOut_Label\").TextColour = 'green'\
7617 elseif math.floor( ioEnergy ) == 0 then\
7618 if settings[\"darkmode\"] == true then\
7619 program:GetObject(\"GroupOverview_EnergyInOut_Label\").TextColour = 'lightGray'\
7620 else\
7621 program:GetObject(\"GroupOverview_EnergyInOut_Label\").TextColour = 'black'\
7622 end\
7623 else\
7624 program:GetObject(\"GroupOverview_EnergyInOut_Label\").TextColour = 'red'\
7625 end\
7626\
7627 -- Progress Bars\
7628 program:GetObject(\"GroupOverview_SteamProduce_ProgressBar\").Maximum = math.floor( requiredSteam )\
7629 program:GetObject(\"GroupOverview_EnergyStorage_ProgressBar\").Maximum = math.floor( storedEnergyMax )\
7630 program:GetObject(\"GroupOverview_SteamProduce_ProgressBar\").Value = math.floor( producedSteam )\
7631 program:GetObject(\"GroupOverview_EnergyStorage_ProgressBar\").Value = math.floor( storedEnergy )\
7632\
7633 --Buttons\
7634 program:GetObject(\"GroupOverview_Reactor_Button\").OnClick = function(self, event, side, x, y)\
7635 program:StartTimer(function()\
7636 loadColoredView(\"reactorDetailed\")\
7637 refreshScreen()\
7638 end, 0.15)\
7639 end\
7640\
7641 program:GetObject(\"GroupOverview_Turbine_Button\").OnClick = function(self, event, side, x, y)\
7642 program:StartTimer(function()\
7643 loadColoredView(\"turbineDetailed\")\
7644 refreshScreen()\
7645 end, 0.15)\
7646 end\
7647\
7648 program:GetObject(\"GroupOverview_Battery_Button\").OnClick = function(self, event, side, x, y)\
7649 program:StartTimer(function()\
7650 loadColoredView(\"batteryDetailed\")\
7651 refreshScreen()\
7652 end, 0.15)\
7653 end\
7654\
7655 program:GetObject(\"GroupOverview_Home_Button\").OnClick = function(self, event, side, x, y)\
7656 program:StartTimer(function()\
7657 loadColoredView(\"home\")\
7658 refreshScreen()\
7659 end, 0.15)\
7660 end\
7661\
7662 program:GetObject(\"GroupOverview_Settings_Button\").OnClick = function(self, event, side, x, y)\
7663 program:StartTimer(function()\
7664 loadColoredView(\"groupSettings\")\
7665 refreshScreen()\
7666 end, 0.15)\
7667 end\
7668\
7669 program:GetObject(\"GroupOverview_NextGroup_Button\").OnClick = function(self, event, side, x, y)\
7670 program:StartTimer(function()\
7671 if currentGroupID < #groups then\
7672 currentGroupID = currentGroupID + 1\
7673 refreshScreen()\
7674 end\
7675 end, 0.15)\
7676 end\
7677\
7678 program:GetObject(\"GroupOverview_LastGroup_Button\").OnClick = function(self, event, side, x, y)\
7679 program:StartTimer(function()\
7680 if currentGroupID > 1 then\
7681 currentGroupID = currentGroupID - 1\
7682 refreshScreen()\
7683 end\
7684 end, 0.15)\
7685 end\
7686\
7687\
7688 elseif currentView == \"turbineDetailed\" then\
7689 local selectedTurbine = nil\
7690\
7691 if groups[currentGroupID][\"turbine\"][currentTurbineID] ~= nil then\
7692 selectedTurbine = peripheral.wrap(groups[currentGroupID][\"turbine\"][currentTurbineID][\"device\"])\
7693 end\
7694\
7695 program:GetObject(\"Turbine_LastTurbine_Button\").Enabled = not (currentTurbineID == 1)\
7696 program:GetObject(\"Turbine_NextTurbine_Button\").Enabled = not (currentTurbineID >= #groups[currentGroupID][\"turbine\"])\
7697\
7698 \
7699 if selectedTurbine and selectedTurbine.getConnected() == true then\
7700 program:RemoveObject(\"Turbine_NotFound\")\
7701 program:GetObject(\"Turbine_SetFlowrate_Button\").Enabled = true\
7702\
7703 -- Labels\
7704 program:GetObject(\"turbineName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"turbine\"][currentTurbineID][\"name\"]:gsub( \"$n\", tostring(currentTurbineID) )\
7705 program:GetObject(\"Turbine_RPM_Label\").Text = math.floor(selectedTurbine.getRotorSpeed()) ..\" RPM\"\
7706 program:GetObject(\"Turbine_Flowrate_Label\").Text = math.floor(selectedTurbine.getFluidFlowRate()) ..\" mB/t of \".. math.floor(selectedTurbine.getFluidFlowRateMax()) ..\" mB/t\" \
7707 program:GetObject(\"Turbine_EnergyOut_Label\").Text = math.floor(selectedTurbine.getEnergyProducedLastTick()) ..\" RF/t\"\
7708\
7709 -- Progress Bars\
7710 program:GetObject(\"Turbine_Steamtank_ProgressBar\").Maximum = math.floor(selectedTurbine.getFluidAmountMax())\
7711 program:GetObject(\"Turbine_Watertank_ProgressBar\").Maximum = math.floor(selectedTurbine.getFluidAmountMax())\
7712 program:GetObject(\"Turbine_Steamtank_ProgressBar\").Value = math.floor(selectedTurbine.getInputAmount())\
7713 program:GetObject(\"Turbine_Watertank_ProgressBar\").Value = math.floor(selectedTurbine.getOutputAmount()) \
7714 program:GetObject(\"Turbine_EnergyBuf_ProgressBar\").Value = math.floor(selectedTurbine.getEnergyStored())\
7715\
7716 --Buttons\
7717 if selectedTurbine.getActive() then\
7718 program:GetObject(\"Turbine_Status_Button\").Text = \" Active \"\
7719 program:GetObject(\"Turbine_Status_Button\").BackgroundColour= \"green\"\
7720 else\
7721 program:GetObject(\"Turbine_Status_Button\").Text = \" Inactive \"\
7722 program:GetObject(\"Turbine_Status_Button\").BackgroundColour= \"red\"\
7723 end\
7724\
7725 if selectedTurbine.getInductorEngaged() then\
7726 program:GetObject(\"Turbine_Coils_Button\").Text = \" Engaged \"\
7727 program:GetObject(\"Turbine_Coils_Button\").BackgroundColour= \"green\"\
7728 else\
7729 program:GetObject(\"Turbine_Coils_Button\").Text = \"Disengaged\"\
7730 program:GetObject(\"Turbine_Coils_Button\").BackgroundColour= \"red\"\
7731 end\
7732\
7733 program:GetObject(\"Turbine_Status_Button\").OnClick = function(self, event, side, x, y)\
7734 selectedTurbine.setActive(not selectedTurbine.getActive())\
7735 refreshScreen()\
7736 end\
7737\
7738 program:GetObject(\"Turbine_Coils_Button\").OnClick = function(self, event, side, x, y)\
7739 selectedTurbine.setInductorEngaged(not selectedTurbine.getInductorEngaged())\
7740 refreshScreen()\
7741 end\
7742 \
7743 program:GetObject(\"Turbine_SetFlowrate_Button\").OnClick = function(self, event, side, x, y)\
7744 value = selectedTurbine.getFluidFlowRateMax()\
7745 flowrateWindow(selectedTurbine)\
7746 end\
7747\
7748 if groups[currentGroupID][\"turbine\"][currentTurbineID][\"settings\"][\"overrideGroup\"] == true then\
7749 program:GetObject(\"Turbine_Coils_Button\").Enabled = ( not groups[currentGroupID][\"turbine\"][currentTurbineID][\"settings\"][\"disengageCoils\"] )\
7750 program:GetObject(\"Turbine_SetFlowrate_Button\").Enabled = ( not groups[currentGroupID][\"turbine\"][currentTurbineID][\"settings\"][\"optimiseTurbine\"] )\
7751 program:GetObject(\"Turbine_Status_Button\").Enabled = ( not ( groups[currentGroupID][\"settings\"][\"efficentEnergy\"] and groups[currentGroupID][\"turbine\"][currentTurbineID][\"settings\"][\"allowEE\"] ) )\
7752 else\
7753 program:GetObject(\"Turbine_Coils_Button\").Enabled = ( not groups[currentGroupID][\"settings\"][\"disengageCoils\"] )\
7754 program:GetObject(\"Turbine_SetFlowrate_Button\").Enabled = ( not groups[currentGroupID][\"settings\"][\"optimiseTurbine\"] )\
7755 program:GetObject(\"Turbine_Status_Button\").Enabled = ( not groups[currentGroupID][\"settings\"][\"efficentEnergy\"] )\
7756 end\
7757\
7758 \
7759\
7760 if program:GetObject(\"Turbine_Status_Button\").Enabled == false then\
7761 program:GetObject(\"Turbine_Status_Button\").BackgroundColour= \"gray\"\
7762 end\
7763\
7764 if program:GetObject(\"Turbine_Coils_Button\").Enabled == false then\
7765 program:GetObject(\"Turbine_Coils_Button\").BackgroundColour= \"gray\"\
7766 end\
7767\
7768 else\
7769 -- Turbine Error\
7770 if currentTurbineID <= #groups[currentGroupID][\"turbine\"] then\
7771 program:GetObject(\"turbineName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"turbine\"][currentTurbineID][\"name\"]:gsub( \"$n\", tostring(currentTurbineID) )\
7772 else\
7773 program:GetObject(\"turbineName_Label\").Text = \"\"\
7774 end\
7775\
7776 if program:GetObject('Turbine_NotFound') == nil then\
7777 local bgColour = \"white\"\
7778 local buttonColour = \"gray\"\
7779 program:GetObject(\"Turbine_SetFlowrate_Button\").Enabled = false\
7780\
7781 if settings[\"darkmode\"] == true then\
7782 bgColour = \"black\"\
7783 end\
7784\
7785 program:AddObject({\
7786 Y=2,\
7787 X=0,\
7788 Width=\"100%, +1\",\
7789 Height=\"100%, -2\",\
7790 BackgroundColour=bgColour,\
7791 Name=\"Turbine_NotFound\",\
7792 Type=\"ProgressBar\",\
7793 Value=0,\
7794 Maximum=1,\
7795 })\
7796 program:AddObject({\
7797 Y=\"50%\",\
7798 X=\"50%, -17\",\
7799 Name=\"Turbine_NotFound\",\
7800 Type=\"Label\",\
7801 TextColour=\"red\",\
7802 Text=\"Turbine not ready or not connected!\",\
7803 })\
7804 end\
7805 end\
7806\
7807 program:GetObject(\"Turbine_NextTurbine_Button\").OnClick = function(self, event, side, x, y)\
7808 program:StartTimer(function()\
7809 if currentTurbineID < # groups[currentGroupID][\"turbine\"] then\
7810 currentTurbineID = currentTurbineID + 1\
7811 refreshScreen()\
7812 end\
7813 end, 0.15)\
7814 end\
7815\
7816 program:GetObject(\"Turbine_LastTurbine_Button\").OnClick = function(self, event, side, x, y)\
7817 program:StartTimer(function()\
7818 if currentTurbineID > 1 then\
7819 currentTurbineID = currentTurbineID - 1\
7820 refreshScreen()\
7821 end\
7822 end, 0.15)\
7823 end\
7824\
7825 program:GetObject(\"Turbine_Back_Button\").OnClick = function(self, event, side, x, y)\
7826 program:StartTimer(function()\
7827 loadColoredView(\"groupOverview\")\
7828 refreshScreen()\
7829 currentTurbineID = 1\
7830 currentReactorID = 1\
7831 currentBatteryID = 1\
7832 end, 0.15)\
7833 end\
7834\
7835 elseif currentView == \"reactorDetailed\" then\
7836\
7837 local selectedReactor = nil\
7838 if groups[currentGroupID][\"reactor\"][currentReactorID] ~= nil then\
7839 selectedReactor = peripheral.wrap(groups[currentGroupID][\"reactor\"][currentReactorID][\"device\"])\
7840 end\
7841\
7842 if currentReactorID == 1 then\
7843 program:GetObject(\"Reactor_LastReactor_Button\").Enabled = false\
7844 else\
7845 program:GetObject(\"Reactor_LastReactor_Button\").Enabled = true\
7846 end\
7847\
7848 if currentReactorID >= #groups[currentGroupID][\"reactor\"] then\
7849 program:GetObject(\"Reactor_NextReactor_Button\").Enabled = false\
7850 else\
7851 program:GetObject(\"Reactor_NextReactor_Button\").Enabled = true\
7852 end\
7853\
7854 program:GetObject(\"Reactor_LastReactor_Button\").Enabled = not (currentReactorID == 1)\
7855 program:GetObject(\"Reactor_NextReactor_Button\").Enabled = not (currentReactorID >= #groups[currentGroupID][\"reactor\"])\
7856\
7857 if selectedReactor and selectedReactor.getConnected() == true then\
7858 program:RemoveObject(\"Reactor_NotFound\")\
7859 program:GetObject(\"Reactor_SetControlRod_Button\").Enabled = true\
7860\
7861 if selectedReactor.isActivelyCooled() == false then\
7862 loadColoredView(\"reactorDetailed_passive\")\
7863 currentView = \"reactorDetailed\"\
7864 else\
7865 loadColoredView(\"reactorDetailed\")\
7866 end\
7867\
7868 --Labels\
7869 program:GetObject(\"reactorName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"reactor\"][currentReactorID][\"name\"]:gsub( \"$n\", tostring(currentReactorID) )\
7870 program:GetObject(\"Reactor_CoreTemp_Label\").Text = math.floor( selectedReactor.getFuelTemperature() ) ..\" C\"\
7871 program:GetObject(\"Reactor_Burnup_Label\").Text = math.floor( selectedReactor.getFuelConsumedLastTick() * 100) / 100 ..\" mB/t\"\
7872 program:GetObject(\"Reactor_ControlRod_Label\").Text = selectedReactor.getNumberOfControlRods() ..\" Rods set to \".. selectedReactor.getControlRodLevel(0) ..\"%\"\
7873 program:GetObject(\"Reactor_FuelWaste_Label\").Text = math.ceil( (selectedReactor.getWasteAmount() / selectedReactor.getFuelAmountMax()) * 100 ) ..\"% Waste \".. math.floor( (selectedReactor.getFuelAmount() / selectedReactor.getFuelAmountMax()) * 100 ) ..\"% Fuel\"\
7874\
7875 if actualView == \"reactorDetailed\" then\
7876 program:GetObject(\"Reactor_SteamOut_Label\").Text = math.floor( selectedReactor.getHotFluidProducedLastTick() ) ..\" mB/t\"\
7877 else\
7878 program:GetObject(\"Reactor_Reactivity_Label\").Text = math.floor( selectedReactor.getFuelReactivity() ) ..\"%\"\
7879 program:GetObject(\"Reactor_EnergyOut_Label\").Text = math.floor( selectedReactor.getEnergyProducedLastTick() ) ..\" RF/t\"\
7880 end\
7881\
7882 if settings[\"changeTempColor\"] == true then\
7883 if selectedReactor.getFuelTemperature() < 1000 then\
7884 program:GetObject(\"Reactor_CoreTemp_Label\").TextColour=\"blue\"\
7885 elseif selectedReactor.getFuelTemperature() < 1400 then\
7886 program:GetObject(\"Reactor_CoreTemp_Label\").TextColour=\"purple\"\
7887 else\
7888 program:GetObject(\"Reactor_CoreTemp_Label\").TextColour=\"red\"\
7889 end\
7890 else\
7891 if settings[\"darkmode\"] == true then\
7892 program:GetObject(\"Reactor_CoreTemp_Label\").TextColour=\"lightGray\"\
7893 else\
7894 program:GetObject(\"Reactor_CoreTemp_Label\").TextColour=\"black\"\
7895 end\
7896 end\
7897\
7898 --Progress Bars\
7899 if actualView == \"reactorDetailed\" then\
7900 program:GetObject(\"Reactor_Steamtank_ProgressBar\").Value = math.floor(selectedReactor.getCoolantAmount())\
7901 program:GetObject(\"Reactor_Watertank_ProgressBar\").Value = math.floor(selectedReactor.getHotFluidAmount())\
7902 else\
7903 program:GetObject(\"Reactor_EnergyBuf_ProgressBar\").Value = math.floor(selectedReactor.getEnergyStored())\
7904 end\
7905\
7906 program:GetObject(\"Reactor_Fuel_ProgressBar\").Maximum = math.floor(selectedReactor.getFuelAmountMax())\
7907 program:GetObject(\"Reactor_Waste_ProgressBar\").Maximum = math.floor(selectedReactor.getFuelAmountMax())\
7908 program:GetObject(\"Reactor_Fuel_ProgressBar\").Value = math.floor(selectedReactor.getWasteAmount() + selectedReactor.getFuelAmount())\
7909 program:GetObject(\"Reactor_Waste_ProgressBar\").Value = math.floor(selectedReactor.getWasteAmount())\
7910\
7911\
7912 --Buttons\
7913 if selectedReactor.getActive() then\
7914 program:GetObject(\"Reactor_Status_Button\").Text = \" Active \"\
7915 program:GetObject(\"Reactor_Status_Button\").BackgroundColour= \"green\"\
7916 else\
7917 program:GetObject(\"Reactor_Status_Button\").Text = \" Inactive \"\
7918 program:GetObject(\"Reactor_Status_Button\").BackgroundColour= \"red\"\
7919 end\
7920\
7921 program:GetObject(\"Reactor_Status_Button\").OnClick = function(self, event, side, x, y)\
7922 selectedReactor.setActive(not selectedReactor.getActive())\
7923 refreshScreen()\
7924 end\
7925\
7926 program:GetObject(\"Reactor_SetControlRod_Button\").OnClick = function(self, event, side, x, y)\
7927 value = selectedReactor.getControlRodLevel(0)\
7928 controlRodWindow(selectedReactor)\
7929 end\
7930\
7931 \
7932 if groups[currentGroupID][\"reactor\"][currentReactorID][\"settings\"][\"overrideGroup\"] == true then\
7933 program:GetObject(\"Reactor_SetControlRod_Button\").Enabled = ( not groups[currentGroupID][\"reactor\"][currentReactorID][\"settings\"][\"optimiseReactor\"] )\
7934 program:GetObject(\"Reactor_Status_Button\").Enabled = ( not ( groups[currentGroupID][\"settings\"][\"allowEE\"] and groups[currentGroupID][\"settings\"][\"efficentEnergy\"] ) )\
7935 else\
7936 program:GetObject(\"Reactor_SetControlRod_Button\").Enabled = ( not groups[currentGroupID][\"settings\"][\"optimiseReactor\"] )\
7937 program:GetObject(\"Reactor_Status_Button\").Enabled = ( not groups[currentGroupID][\"settings\"][\"efficentEnergy\"] )\
7938 end\
7939\
7940 if program:GetObject(\"Reactor_Status_Button\").Enabled == false then\
7941 program:GetObject(\"Reactor_Status_Button\").BackgroundColour= \"gray\"\
7942 end\
7943\
7944 else\
7945 -- Reactor Error\
7946 if currentReactorID <= #groups[currentGroupID][\"reactor\"] then\
7947 program:GetObject(\"reactorName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"reactor\"][currentReactorID][\"name\"]:gsub( \"$n\", tostring(currentReactorID) )\
7948 else\
7949 program:GetObject(\"reactorName_Label\").Text = \"\"\
7950 end\
7951\
7952 program:GetObject(\"Reactor_SetControlRod_Button\").Enabled = false\
7953\
7954 if program:GetObject('Reactor_NotFound') == nil then\
7955 local bgColour = \"white\"\
7956 local buttonColour = \"gray\"\
7957\
7958 if settings[\"darkmode\"] == true then\
7959 bgColour = \"black\"\
7960 end\
7961\
7962 program:AddObject({\
7963 Y=2,\
7964 X=0,\
7965 Width=\"100%, +1\",\
7966 Height=\"100%, -2\",\
7967 BackgroundColour=bgColour,\
7968 Name=\"Reactor_NotFound\",\
7969 Type=\"ProgressBar\",\
7970 Value=0,\
7971 Maximum=1,\
7972 })\
7973 program:AddObject({\
7974 Y=\"50%\",\
7975 X=\"50%, -17\",\
7976 Name=\"Reactor_NotFound\",\
7977 Type=\"Label\",\
7978 TextColour=\"red\",\
7979 Text=\"Reactor not ready or not connected!\",\
7980 })\
7981 end\
7982\
7983 end\
7984\
7985 program:GetObject(\"Reactor_NextReactor_Button\").OnClick = function(self, event, side, x, y)\
7986 program:StartTimer(function()\
7987 if currentReactorID < #groups[currentGroupID][\"reactor\"] then\
7988 currentReactorID = currentReactorID + 1\
7989 refreshScreen()\
7990 end\
7991 end, 0.15)\
7992 end\
7993\
7994 program:GetObject(\"Reactor_LastReactor_Button\").OnClick = function(self, event, side, x, y)\
7995 program:StartTimer(function()\
7996 if currentReactorID > 1 then\
7997 currentReactorID = currentReactorID - 1\
7998 refreshScreen()\
7999 end\
8000 end, 0.15)\
8001 end\
8002\
8003 program:GetObject(\"Reactor_Back_Button\").OnClick = function(self, event, side, x, y)\
8004 program:StartTimer(function()\
8005 loadColoredView(\"groupOverview\")\
8006 refreshScreen()\
8007 currentTurbineID = 1\
8008 currentReactorID = 1\
8009 currentBatteryID = 1\
8010 end, 0.15)\
8011 end\
8012\
8013 elseif currentView == \"batteryDetailed\" then\
8014\
8015 local ioEnergy = 0\
8016 local storedEnergy = 0\
8017 local cellPrefix = \"Unknown\"\
8018\
8019 local selectedBattery = nil\
8020\
8021 if groups[currentGroupID][\"battery\"][currentBatteryID] ~= nil then\
8022 selectedBattery = peripheral.wrap(groups[currentGroupID][\"battery\"][currentBatteryID][\"device\"])\
8023 end\
8024\
8025 program:GetObject(\"Battery_NextBattery_Button\").Enabled = not (currentBatteryID >= #groups[currentGroupID][\"battery\"])\
8026 program:GetObject(\"Battery_LastBattery_Button\").Enabled = not (currentBatteryID == 1)\
8027\
8028 if selectedBattery then\
8029 program:RemoveObject(\"Battery_NotFound\")\
8030 program:RemoveObject(\"Battery_NotFound_Button\")\
8031\
8032 --Labels\
8033 program:GetObject(\"batteryName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"battery\"][currentBatteryID][\"name\"]:gsub( \"$n\", tostring(currentBatteryID) )\
8034\
8035 local storedEnergy = selectedBattery.getEnergyStored()\
8036 local ioEnergy = (storedEnergy - storedEnergyLast) / (20 * settings[\"refreshSpeed\"]) \
8037 storedEnergyLast = storedEnergy\
8038\
8039 if peripheral.getType(groups[currentGroupID][\"battery\"][currentBatteryID][\"device\"]) == \"powered_tile\" then\
8040 if selectedBattery.getMaxEnergyStored() == 400000 then\
8041 cellPrefix = batteryTypes[\"energyCellTypes\"][1]\
8042 elseif selectedBattery.getMaxEnergyStored() == 2000000 then\
8043 cellPrefix = batteryTypes[\"energyCellTypes\"][2]\
8044 elseif selectedBattery.getMaxEnergyStored() == 20000000 then\
8045 cellPrefix = batteryTypes[\"energyCellTypes\"][3]\
8046 elseif selectedBattery.getMaxEnergyStored() == 80000000 then\
8047 cellPrefix = batteryTypes[\"energyCellTypes\"][4]\
8048 else\
8049 cellPrefix = \"Unknown\"\
8050 end\
8051\
8052 elseif peripheral.getType(groups[currentGroupID][\"battery\"][currentBatteryID][\"device\"]) == \"draconic_rf_storage\" then\
8053 if selectedBattery.getMaxEnergyStored() == 45500000 then\
8054 cellPrefix = batteryTypes[\"draconicTiers\"][1]\
8055 elseif selectedBattery.getMaxEnergyStored() == 273000000 then\
8056 cellPrefix = batteryTypes[\"draconicTiers\"][2]\
8057 elseif selectedBattery.getMaxEnergyStored() == 1640000000 then\
8058 cellPrefix = batteryTypes[\"draconicTiers\"][3]\
8059 elseif selectedBattery.getMaxEnergyStored() == 9880000000 then\
8060 cellPrefix = batteryTypes[\"draconicTiers\"][4]\
8061 elseif selectedBattery.getMaxEnergyStored() == 59300000000 then\
8062 cellPrefix = batteryTypes[\"draconicTiers\"][5]\
8063 elseif selectedBattery.getMaxEnergyStored() == 356000000000 then\
8064 cellPrefix = batteryTypes[\"draconicTiers\"][6]\
8065 elseif selectedBattery.getMaxEnergyStored() == 2140000000000 then\
8066 cellPrefix = batteryTypes[\"draconicTiers\"][7]\
8067 elseif selectedBattery.getMaxEnergyStored() == 9223372036854775807 then\
8068 cellPrefix = batteryTypes[\"draconicTiers\"][8]\
8069 else\
8070 cellPrefix = \"Unknown\"\
8071 end\
8072 else\
8073 cellPrefix = \"\"\
8074 end\
8075\
8076 if batteryTypes[peripheral.getType(groups[currentGroupID][\"battery\"][currentBatteryID][\"device\"])] ~= nil then \
8077 program:GetObject(\"Battery_Type_Label\").Text = cellPrefix ..\" \".. batteryTypes[peripheral.getType(groups[currentGroupID][\"battery\"][currentBatteryID][\"device\"])]\
8078 else\
8079 program:GetObject(\"Battery_Type_Label\").Text = \"Unknown\"\
8080 end\
8081\
8082 program:GetObject(\"Battery_EnergyInOut_Label\").Text = math.floor(ioEnergy) ..\" RF/t\"\
8083\
8084 if selectedBattery.getMaxEnergyStored() >= 1000000 and selectedBattery.getEnergyStored() >= 1000000 then\
8085 program:GetObject(\"Battery_EnergyStored_Label\").Text = math.floor(selectedBattery.getEnergyStored() / 10000) / 100 ..\" MRF / \".. math.floor(selectedBattery.getMaxEnergyStored() / 10000 ) / 100 ..\" MRF\"\
8086 elseif selectedBattery.getMaxEnergyStored() >= 1000000 then\
8087 program:GetObject(\"Battery_EnergyStored_Label\").Text = math.floor(selectedBattery.getEnergyStored()) ..\" RF / \".. math.floor(selectedBattery.getMaxEnergyStored() / 10000 ) / 100 ..\" MRF\"\
8088 else\
8089 program:GetObject(\"Battery_EnergyStored_Label\").Text = math.floor(selectedBattery.getEnergyStored()) ..\" RF / \".. selectedBattery.getMaxEnergyStored() ..\" RF\"\
8090 end\
8091\
8092 if math.floor( ioEnergy ) >= 1 then\
8093 program:GetObject(\"Battery_EnergyInOut_Label\").Text = \"+\".. program:GetObject(\"Battery_EnergyInOut_Label\").Text\
8094 program:GetObject(\"Battery_EnergyInOut_Label\").TextColour = 'green'\
8095 elseif math.floor( ioEnergy ) == 0 then\
8096 if settings[\"darkmode\"] == true then\
8097 program:GetObject(\"Battery_EnergyInOut_Label\").TextColour = 'lightGray'\
8098 else\
8099 program:GetObject(\"Battery_EnergyInOut_Label\").TextColour = 'black'\
8100 end\
8101 else\
8102 program:GetObject(\"Battery_EnergyInOut_Label\").TextColour = 'red'\
8103 end\
8104\
8105 --Progress Bars\
8106 program:GetObject(\"Battery_EnergyStored_ProgressBar\").Maximum = selectedBattery.getMaxEnergyStored()\
8107 program:GetObject(\"Battery_EnergyStored_ProgressBar\").Value = selectedBattery.getEnergyStored()\
8108\
8109\
8110 else\
8111 -- Battery Error\
8112 if currentBatteryID <= #groups[currentGroupID][\"battery\"] then\
8113 program:GetObject(\"batteryName_Label\").Text = \"[\".. groups[currentGroupID][\"Name\"] ..\"] \".. groups[currentGroupID][\"battery\"][currentBatteryID][\"name\"]:gsub( \"$n\", tostring(currentBatteryID) )\
8114 else\
8115 program:GetObject(\"batteryName_Label\").Text = \"\"\
8116 end\
8117\
8118 if program:GetObject('Battery_NotFound') == nil then\
8119 local bgColour = \"white\"\
8120 local buttonColour = \"gray\"\
8121\
8122 if settings[\"darkmode\"] == true then\
8123 bgColour = \"black\"\
8124 end\
8125\
8126 program:AddObject({\
8127 Y=2,\
8128 X=0,\
8129 Width=\"100%, +1\",\
8130 Height=\"100%, -2\",\
8131 BackgroundColour=bgColour,\
8132 Name=\"Battery_NotFound\",\
8133 Type=\"ProgressBar\",\
8134 Value=0,\
8135 Maximum=1,\
8136 })\
8137 program:AddObject({\
8138 Y=\"50%\",\
8139 X=\"50%, -11\",\
8140 Name=\"Battery_NotFound\",\
8141 Type=\"Label\",\
8142 TextColour=\"red\",\
8143 Text=\"Battery not connected!\",\
8144 })\
8145 end\
8146\
8147 end\
8148\
8149 program:GetObject(\"Battery_NextBattery_Button\").OnClick = function(self, event, side, x, y)\
8150 program:StartTimer(function()\
8151 if currentBatteryID < #groups[currentGroupID][\"battery\"] then\
8152 currentBatteryID = currentBatteryID + 1\
8153 refreshScreen()\
8154 end\
8155 end, 0.15)\
8156 end\
8157\
8158 program:GetObject(\"Battery_LastBattery_Button\").OnClick = function(self, event, side, x, y)\
8159 program:StartTimer(function()\
8160 if currentBatteryID > 1 then\
8161 currentBatteryID = currentBatteryID - 1\
8162 refreshScreen()\
8163 end\
8164 end, 0.15)\
8165 end\
8166\
8167 program:GetObject(\"Battery_Back_Button\").OnClick = function(self, event, side, x, y)\
8168 program:StartTimer(function()\
8169 loadColoredView(\"groupOverview\")\
8170 refreshScreen()\
8171 currentTurbineID = 1\
8172 currentReactorID = 1\
8173 currentBatteryID = 1\
8174 end, 0.15)\
8175\
8176 end\
8177\
8178 end\
8179 end\
8180\
8181 local function automaticControl()\
8182 for groupID = 1, #groups do\
8183\
8184 local energyStored = 0\
8185 local energyStoredMax = 0\
8186\
8187 for turbineID = 1, #groups[groupID][\"turbine\"] do\
8188\
8189 local turbineDevice = peripheral.wrap(groups[groupID][\"turbine\"][turbineID][\"device\"])\
8190\
8191 if turbineDevice ~= nil then\
8192\
8193 if turbineDevice.getActive() == true then\
8194\
8195 if turbineDevice.getRotorSpeed() >= groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] + 5 and turbineDevice.getRotorSpeed() <= ( turbineDevice.getFluidFlowRateMax() * 0.6 ) then\
8196 groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] = false\
8197 else\
8198 groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] = true\
8199 end\
8200\
8201 if groups[groupID][\"turbine\"][turbineID][\"settings\"][\"overrideGroup\"] == true then\
8202\
8203 if groups[groupID][\"turbine\"][turbineID][\"settings\"][\"optimiseTurbine\"] == true and groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] == true then\
8204\
8205 if turbineDevice.getRotorSpeed() > ( groups[groupID][\"turbine\"][turbineID][\"settings\"][\"optimiseRPM\"] + 20) and turbineDevice.getRotorSpeed() + 2 >= groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] then\
8206\
8207 if turbineDevice.getFluidFlowRate() >= ( turbineDevice.getFluidFlowRateMax() - 10 ) then\
8208\
8209 if turbineDevice.getRotorSpeed() > ( groups[groupID][\"turbine\"][turbineID][\"settings\"][\"optimiseRPM\"] + 200 ) then\
8210 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() - 100 )\
8211 else\
8212 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() - 10 )\
8213 end\
8214\
8215 end\
8216\
8217 elseif turbineDevice.getRotorSpeed() < ( groups[groupID][\"turbine\"][turbineID][\"settings\"][\"optimiseRPM\"] - 20) and turbineDevice.getRotorSpeed() - 2 <= groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] then\
8218\
8219 if turbineDevice.getFluidFlowRate() >= ( turbineDevice.getFluidFlowRateMax() - 10 ) then\
8220\
8221 if turbineDevice.getRotorSpeed() < ( groups[groupID][\"turbine\"][turbineID][\"settings\"][\"optimiseRPM\"] - 200 ) then\
8222 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() + 100 )\
8223 else\
8224 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() + 10 )\
8225 end\
8226\
8227 end\
8228\
8229 end\
8230\
8231 end\
8232\
8233 if groups[groupID][\"turbine\"][turbineID][\"settings\"][\"disengageCoils\"] == true then\
8234\
8235 if groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] == true then\
8236 turbineDevice.setInductorEngaged(true)\
8237 else\
8238 turbineDevice.setInductorEngaged(false)\
8239 end\
8240\
8241 end\
8242\
8243 else\
8244\
8245 if groups[groupID][\"settings\"][\"optimiseTurbine\"] == true and groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] == true then\
8246\
8247 if turbineDevice.getRotorSpeed() > ( groups[groupID][\"settings\"][\"optimiseRPM\"] + 20) and turbineDevice.getRotorSpeed() + 2 >= groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] then\
8248\
8249 if turbineDevice.getFluidFlowRate() >= ( turbineDevice.getFluidFlowRateMax() - 10 ) then\
8250\
8251 if turbineDevice.getRotorSpeed() > ( groups[groupID][\"settings\"][\"optimiseRPM\"] + 200 ) then\
8252 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() - 100 )\
8253 else\
8254 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() - 10 )\
8255 end\
8256\
8257 end\
8258\
8259 elseif turbineDevice.getRotorSpeed() < ( groups[groupID][\"settings\"][\"optimiseRPM\"] - 20) and turbineDevice.getRotorSpeed() - 2 <= groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] then\
8260\
8261 if turbineDevice.getFluidFlowRate() >= ( turbineDevice.getFluidFlowRateMax() - 10 ) then\
8262 \
8263 if turbineDevice.getRotorSpeed() < ( groups[groupID][\"settings\"][\"optimiseRPM\"] - 200 ) then\
8264 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() + 100 )\
8265 else\
8266 turbineDevice.setFluidFlowRateMax( turbineDevice.getFluidFlowRateMax() + 10 )\
8267 end\
8268\
8269 end\
8270\
8271 end\
8272\
8273 end\
8274\
8275 if groups[groupID][\"settings\"][\"disengageCoils\"] == true then\
8276\
8277 if groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] == true then\
8278 turbineDevice.setInductorEngaged(true)\
8279 else\
8280 turbineDevice.setInductorEngaged(false)\
8281 end\
8282\
8283 end\
8284 \
8285 end\
8286\
8287 groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] = turbineDevice.getRotorSpeed()\
8288\
8289 else\
8290 groups[groupID][\"turbine\"][turbineID][\"variables\"][\"lastRPM\"] = 0\
8291 groups[groupID][\"turbine\"][turbineID][\"variables\"][\"startingDone\"] = false\
8292 end\
8293\
8294\
8295\
8296 end\
8297\
8298 end\
8299\
8300 for reactorID = 1, #groups[groupID][\"reactor\"] do\
8301\
8302 local reactorDevice = peripheral.wrap(groups[groupID][\"reactor\"][reactorID][\"device\"])\
8303 local requiredOutput = 0\
8304\
8305 if reactorDevice ~= nil then\
8306\
8307 if reactorDevice.getActive() == true then\
8308\
8309 groups[groupID][\"reactor\"][reactorID][\"variables\"][\"lastTemp\"] = reactorDevice.getFuelTemperature()\
8310\
8311 for turbineID = 1, #groups[groupID][\"turbine\"] do\
8312 pcall(function()\
8313 if peripheral.isPresent( groups[groupID][\"turbine\"][turbineID][\"device\"] ) == true then\
8314 requiredOutput = requiredOutput + peripheral.call(groups[groupID][\"turbine\"][turbineID][\"device\"], \"getFluidFlowRateMax\")\
8315 end\
8316 end)\
8317 end\
8318\
8319 if groups[groupID][\"reactor\"][reactorID][\"settings\"][\"overrideGroup\"] == true then\
8320\
8321 if groups[groupID][\"reactor\"][reactorID][\"settings\"][\"optimiseReactor\"] == true and reactorDevice.isActivelyCooled() == true and ( ( groups[groupID][\"reactor\"][reactorID][\"variables\"][\"lastTemp\"] + 30 > reactorDevice.getFuelTemperature() ) and ( groups[groupID][\"reactor\"][reactorID][\"variables\"][\"lastTemp\"] - 30 < reactorDevice.getFuelTemperature() ) )then\
8322\
8323 local requiredOutput_Div = 0\
8324\
8325 for rID = 1, #groups[groupID][\"reactor\"] do\
8326 local rDevice = peripheral.wrap(groups[groupID][\"reactor\"][rID][\"device\"])\
8327 if rDevice ~= nil and ( rDevice.isActivelyCooled() ) == true then\
8328 requiredOutput_Div = requiredOutput_Div + 1\
8329 end\
8330 end\
8331 \
8332 if reactorDevice.getHotFluidProducedLastTick() < ( ( requiredOutput / requiredOutput_Div ) - 1 ) then\
8333 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8334 elseif reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) + 10 then\
8335 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) + 1)\
8336 end\
8337\
8338 program:StartTimer(function()\
8339 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8340 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8341 end\
8342 end, 2)\
8343\
8344 program:StartTimer(function()\
8345 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8346 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8347 end\
8348 end, 4)\
8349\
8350 program:StartTimer(function()\
8351 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8352 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8353 end\
8354 end, 6)\
8355\
8356 program:StartTimer(function()\
8357 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8358 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8359 end\
8360 end, 8)\
8361\
8362 elseif groups[groupID][\"reactor\"][reactorID][\"settings\"][\"optimiseReactor\"] == true and reactorDevice.isActivelyCooled() == false and ( ( groups[groupID][\"reactor\"][reactorID][\"variables\"][\"lastTemp\"] + 30 > reactorDevice.getFuelTemperature() ) and ( groups[groupID][\"reactor\"][reactorID][\"variables\"][\"lastTemp\"] - 30 < reactorDevice.getFuelTemperature() ) ) then\
8363\
8364 if reactorDevice.getFuelTemperature() < ( groups[groupID][\"reactor\"][reactorID][\"settings\"][\"maxTemp\"] ) then\
8365 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8366 else\
8367 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) + 1)\
8368 end\
8369\
8370 end\
8371\
8372 else\
8373\
8374 if groups[groupID][\"settings\"][\"optimiseReactor\"] == true and reactorDevice.isActivelyCooled() == true then\
8375\
8376 local requiredOutput_Div = 0\
8377\
8378 for rID = 1, #groups[groupID][\"reactor\"] do\
8379 local rDevice = peripheral.wrap(groups[groupID][\"reactor\"][rID][\"device\"])\
8380 if rDevice ~= nil and ( rDevice.isActivelyCooled() ) == true then\
8381 requiredOutput_Div = requiredOutput_Div + 1\
8382 end\
8383 end\
8384\
8385 if reactorDevice.getHotFluidProducedLastTick() < ( ( requiredOutput / requiredOutput_Div ) - 1 ) then\
8386 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8387 elseif reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) + 10 then\
8388 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) + 1)\
8389 end\
8390\
8391 program:StartTimer(function()\
8392 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8393 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8394 end\
8395 end, 2)\
8396\
8397 program:StartTimer(function()\
8398 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8399 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8400 end\
8401 end, 4)\
8402\
8403 program:StartTimer(function()\
8404 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8405 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8406 end\
8407 end, 6)\
8408\
8409 program:StartTimer(function()\
8410 if reactorDevice.getHotFluidProducedLastTick() < ( requiredOutput / requiredOutput_Div ) then\
8411 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8412 end\
8413 end, 8)\
8414\
8415 elseif groups[groupID][\"settings\"][\"optimiseReactor\"] == true and reactorDevice.isActivelyCooled() == false then\
8416\
8417 if reactorDevice.getFuelTemperature() < ( groups[groupID][\"settings\"][\"maxTemp\"] ) then\
8418 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) - 1)\
8419 else\
8420 reactorDevice.setAllControlRodLevels( reactorDevice.getControlRodLevel(0) + 1)\
8421 end\
8422\
8423 end\
8424\
8425 end\
8426\
8427 end\
8428\
8429 end\
8430\
8431 end\
8432\
8433 for batteryID = 1, #groups[groupID][\"battery\"] do\
8434\
8435 if peripheral.isPresent( groups[groupID][\"battery\"][batteryID][\"device\"] ) == true then\
8436 pcall(function()\
8437 energyStored = energyStored + peripheral.call(groups[groupID][\"battery\"][batteryID][\"device\"], \"getEnergyStored\")\
8438 energyStoredMax = energyStoredMax + peripheral.call(groups[groupID][\"battery\"][batteryID][\"device\"], \"getMaxEnergyStored\")\
8439 end)\
8440 end\
8441\
8442 end\
8443\
8444 if energyStored / energyStoredMax * 100 >= groups[groupID][\"settings\"][\"energyOffTreshold\"] and groups[groupID][\"settings\"][\"efficentEnergy\"] == true then\
8445\
8446 for turbineID = 1, #groups[groupID][\"turbine\"] do\
8447 if groups[groupID][\"turbine\"][turbineID][\"settings\"][\"overrideGroup\"] == false or groups[groupID][\"turbine\"][turbineID][\"settings\"][\"allowEE\"] == true then\
8448 local t = peripheral.wrap(groups[groupID][\"turbine\"][turbineID][\"device\"])\
8449 if t ~= nil then\
8450 t.setActive(false)\
8451 end\
8452 end\
8453 end\
8454\
8455 for reactorID = 1, #groups[groupID][\"reactor\"] do\
8456 if groups[groupID][\"reactor\"][reactorID][\"settings\"][\"overrideGroup\"] == false or groups[groupID][\"reactor\"][reactorID][\"settings\"][\"allowEE\"] == true then\
8457 local r = peripheral.wrap(groups[groupID][\"reactor\"][reactorID][\"device\"])\
8458 if r ~= nil then\
8459 r.setActive(false)\
8460 end\
8461 end\
8462 end\
8463\
8464 elseif energyStored / energyStoredMax * 100 <= groups[groupID][\"settings\"][\"energyOnTreshold\"] and groups[groupID][\"settings\"][\"efficentEnergy\"] == true then\
8465\
8466 for turbineID = 1, #groups[groupID][\"turbine\"] do\
8467 if groups[groupID][\"turbine\"][turbineID][\"settings\"][\"overrideGroup\"] == false or groups[groupID][\"turbine\"][turbineID][\"settings\"][\"allowEE\"] == true then\
8468 local t = peripheral.wrap(groups[groupID][\"turbine\"][turbineID][\"device\"])\
8469 if t ~= nil then\
8470 t.setActive(true)\
8471 end\
8472 end\
8473 end\
8474\
8475 for reactorID = 1, #groups[groupID][\"reactor\"] do\
8476 if groups[groupID][\"reactor\"][reactorID][\"settings\"][\"overrideGroup\"] == false or groups[groupID][\"reactor\"][reactorID][\"settings\"][\"allowEE\"] == true then\
8477 local r = peripheral.wrap(groups[groupID][\"reactor\"][reactorID][\"device\"])\
8478 if r ~= nil then\
8479 r.setActive(true)\
8480 end\
8481 end\
8482 end\
8483\
8484 end\
8485\
8486 end\
8487\
8488 end\
8489\
8490 -- Actual program start\
8491\
8492 loadSettings()\
8493 randomFact = factList[math.random(1, #factList)]\
8494\
8495 if loadGroup() == true then\
8496 program:DisplayAlertWindow(\"Oh no!\", \"Your Group file is corrupted. :c\\nCreating new one.\", {\"Ok\"}, function(pressedButton)\
8497 if pressedButton == \"Ok\" then\
8498 end\
8499 end)\
8500 end\
8501\
8502 program:StartRepeatingTimer(function()\
8503 randomFact = factList[math.random(1, #factList)]\
8504 end, 60)\
8505\
8506 if args[1] ~= \"silent\" then\
8507 program:StartRepeatingTimer(function()\
8508 redirectTerm(settings[\"terms\"][currentTermID])\
8509 if currentTermID == #settings[\"terms\"] then\
8510 currentTermID = 1\
8511 else\
8512 currentTermID = currentTermID + 1\
8513 end\
8514 refreshScreen()\
8515 end, settings[\"refreshSpeed\"] / #settings[\"terms\"])\
8516\
8517 program:StartTimer(function()\
8518 loadColoredView(\"home\")\
8519 end, settings[\"refreshSpeed\"] * 2)\
8520 else\
8521 term.setBackgroundColor(colors.black)\
8522 term.setTextColor(colors.white)\
8523 term.setCursorPos(1,1)\
8524 term.clear()\
8525 print(\"Running in silent mode...\")\
8526 print(\"Automatic Control is set to \".. tostring(settings[\"automaticControl\"]) ..\"!\")\
8527 print()\
8528 print(\"Press O to open the full view.\")\
8529 print(\"Press X to close the program.\")\
8530 print()\
8531\
8532 program:RegisterEvent('key', function(self, event, key)\
8533\
8534 if key == keys.o then\
8535 stop(true)\
8536 elseif key == keys.x then\
8537 stop(false)\
8538 end\
8539\
8540 end)\
8541\
8542 if multishell ~= nil then\
8543 if multishell.getCount() < 2 then\
8544 print(\"Opend a new shell tab!\")\
8545 shell.openTab(\"shell\")\
8546 else\
8547 print(\"Another tab is already open, no new tab created.\")\
8548 end\
8549 else\
8550 print(\"Mutlishell is disabled, a new tab cannot be opend.\")\
8551 end\
8552\
8553 end\
8554\
8555 if settings[\"automaticControl\"] == true then\
8556 program:StartRepeatingTimer(function()\
8557 automaticControl()\
8558 end, 10)\
8559 end\
8560\
8561 end)\
8562\
8563 return returnValue\
8564\
8565--Main End\
8566end\
8567\
8568while true do\
8569 local ok, status = nil\
8570\
8571 if firstStart == true then\
8572 firstStart = false\
8573 ok, status = pcall( main, args )\
8574 else\
8575 ok, status = pcall( main, ({lastArgument}) )\
8576 end\
8577 lastArgument = status\
8578\
8579 if ok == false then\
8580 --BSOD\
8581 local file = fs.open(\"/ReactorControl/Other/settings\", \"r\")\
8582 if file ~= nil then \
8583 settings = textutils.unserialise(file.readAll()) or {terms = {\"native\",},}\
8584 file.close()\
8585 end\
8586\
8587 for i = 1, #settings[\"terms\"] do\
8588 if settings[\"terms\"][i] == \"natvie\" then\
8589 term.redirect(startTerm)\
8590 else\
8591 if peripheral.isPresent(settings[\"terms\"][i]) then\
8592 term.redirect( peripheral.wrap(settings[\"terms\"][i]) )\
8593 end\
8594 end\
8595\
8596 term.setBackgroundColor(colors.black)\
8597 term.setTextColor(colors.white)\
8598 term.clear()\
8599 end\
8600\
8601 term.redirect(startTerm)\
8602 local w, h = term.getSize()\
8603 term.setBackgroundColor(colors.blue)\
8604 term.clear()\
8605 term.setTextColor(colors.white)\
8606 term.setCursorPos((w / 2) -9, (h * 0.2))\
8607 print(\"The program crashed!\")\
8608 term.setCursorPos((w / 2) -3, (h * 0.5))\
8609 print(\"Error:\")\
8610 term.setCursorPos((w / 2)-(string.len(status) / 2), (h * 0.5) +1 )\
8611 print(status)\
8612 print()\
8613 print()\
8614 term.setCursorPos((w / 2)-12, (h * 0.9) )\
8615 print(\"Press any key to continue.\")\
8616\
8617 local a, b = os.pullEvent(\"key\")\
8618 term.setBackgroundColor(colors.black)\
8619 term.setTextColor(colors.white)\
8620 term.clear()\
8621 term.setCursorPos(1,1)\
8622 sleep(0.2)\
8623 break\
8624\
8625 else\
8626 \
8627 if status ~= \"stop\" then\
8628 term.clear()\
8629 sleep(0.2)\
8630 else\
8631 term.clear()\
8632 sleep(0.2)\
8633\
8634 local file = fs.open(\"/ReactorControl/Other/settings\", \"r\")\
8635 if file ~= nil then \
8636 settings = textutils.unserialise(file.readAll()) or {terms = {\"native\",},}\
8637 file.close()\
8638 end\
8639\
8640 for i = 1, #settings[\"terms\"] do\
8641 if settings[\"terms\"][i] == \"natvie\" then\
8642 term.redirect(startTerm)\
8643 else\
8644 if peripheral.isPresent(settings[\"terms\"][i]) then\
8645 term.redirect( peripheral.wrap(settings[\"terms\"][i]) )\
8646 end\
8647 end\
8648 term.setBackgroundColor(colors.black)\
8649 term.setTextColor(colors.white)\
8650 term.clear()\
8651 term.setCursorPos(1,1)\
8652 print(\"Program closed...\")\
8653 end\
8654\
8655 break\
8656 \
8657 end\
8658 end\
8659end",
8660 },
8661 openp = {
8662 twitter = "-- Code written by Cruor, after request by Mikee\
8663-- Demonstration video can be found at http://www.youtube.com/watch?v=ElFNEgElPdo also by Cruor\
8664-- Help page can be found at http://pastebin.com/2wKZWR0u\
8665\
8666local function printUsage()\
8667 local scriptName = shell.getRunningProgram()\
8668 return 'Usage: ' .. scriptName .. ' <side>'\
8669end\
8670\
8671local args = {...}\
8672local side = args[1]\
8673\
8674assert(http, 'HTTP is required for this program.')\
8675assert(side, printUsage())\
8676\
8677local glass = assert(peripheral.wrap(side), printUsage())\
8678glass.clear()\
8679\
8680local settings = {\
8681 displayTime = 10,\
8682 autoDisplay = false,\
8683 toastCount = 2,\
8684 display = true,\
8685 timerRate = 2.5\
8686}\
8687\
8688local lastID\
8689local watching = {\
8690 ftb_team = true\
8691}\
8692\
8693local tweets = {}\
8694\
8695local function StatusBar(x, y)\
8696 local t = {\
8697 update = function(self)\
8698 local str = 'You have: ' .. #tweets .. ' unread tweet(s).'\
8699 if self.text.getText() ~= str and settings.display then\
8700 self.text.setText(str)\
8701 end\
8702 end,\
8703 hide = function(self)\
8704 self.text.setText('')\
8705\
8706 self.background.setAlpha(0)\
8707 self.background.setAlpha2(0)\
8708\
8709 self.background.setWidth(0)\
8710 self.background.setHeight(0)\
8711\
8712 end,\
8713 show = function(self)\
8714 if settings.display then\
8715 self.background.setAlpha(0.7)\
8716 self.background.setAlpha2(0.7)\
8717\
8718 self.background.setWidth(200)\
8719 self.background.setHeight(16)\
8720\
8721 self:update()\
8722 end\
8723 end,\
8724 delete = function(self)\
8725 self.background.delete()\
8726 self.text.delete()\
8727 end,\
8728 background = glass.addBox(x, y, 200, 16, 0x262626, 0),\
8729 text = glass.addText(x + 4, y + 4, '', 0xFFFFFF)\
8730 }\
8731 t.background.setZIndex(0)\
8732 t.text.setZIndex(1)\
8733\
8734 return t\
8735end\
8736\
8737local function TweetToast(x, y)\
8738 local t = {\
8739 lines = {},\
8740 hidden = true,\
8741 show = function(self, title, text)\
8742 self.hidden = false\
8743\
8744 local i = 1\
8745 local str = ''\
8746\
8747 for w in string.gmatch(text, '%S+') do\
8748 local currentWidth = glass.getStringWidth(str)\
8749 local wordWidth = glass.getStringWidth(w)\
8750\
8751 if currentWidth + wordWidth > 257 then\
8752 if self.lines[i] and settings.display then\
8753 self.lines[i].setText(str)\
8754 end\
8755 str = ''\
8756 i = i + 1\
8757 end\
8758 str = str .. w .. ' '\
8759 end\
8760 \
8761 if settings.display then\
8762 if self.lines[i] then\
8763 self.lines[i].setText(str)\
8764 end\
8765\
8766 self.title.setText(title)\
8767\
8768 self.background.setAlpha(0.7)\
8769 self.background.setAlpha2(0.7)\
8770\
8771 self.background.setWidth(265)\
8772 self.background.setHeight(112)\
8773\
8774 self.displayTimeAcc = 0\
8775 end\
8776 end,\
8777 update = function(self, dt)\
8778 self.displayTimeAcc = self.displayTimeAcc + dt\
8779 if not self.hidden and self.displayTimeAcc >= settings.displayTime then\
8780 self:hide()\
8781 self.hidden = true\
8782 end\
8783 end,\
8784 hide = function(self)\
8785 for i = 1, #self.lines do\
8786 self.lines[i].setText('')\
8787 end\
8788\
8789 self.background.setWidth(0)\
8790 self.background.setHeight(0)\
8791\
8792 self.background.setAlpha(0)\
8793 self.background.setAlpha2(0)\
8794\
8795 self.title.setText('')\
8796\
8797 self.hidden = true\
8798 end,\
8799 delete = function(self)\
8800 self.background.delete()\
8801 self.title.delete()\
8802\
8803 for i = 1, #self.lines do\
8804 self.lines[i].delete()\
8805 end\
8806 end,\
8807 displayTimeAcc = settings.displayTime,\
8808 background = glass.addBox(x, y, 265, 112, 0x262626, 0),\
8809 title = glass.addText(x + 4, y + 4, '', 0xFFFFFF)\
8810 }\
8811\
8812 for i = 1, 7 do\
8813 t.lines[i] = glass.addText(x + 4, y + 4 + i * 10, '', 0xFFFFFF)\
8814 t.lines[i].setZIndex(1)\
8815 end\
8816\
8817 t.title.setZIndex(1)\
8818 t.background.setZIndex(0)\
8819\
8820 return t\
8821end\
8822\
8823local function parseTweet(msg)\
8824 local unescapePattern = '&#(%x+);'\
8825 local userPattern = '<a href=\"/(.-)\" class=\"twitter%-atreply.-</a>'\
8826 local linkPattern = '<a href=\"(.-)\".-</a>'\
8827 local searchPattern = '<a href=\"/search.-%%23(.-)&.-</a>'\
8828\
8829 local msg = string.gsub(msg, unescapePattern, function(s)\
8830 return string.char(s)\
8831 end)\
8832\
8833 msg = string.gsub(msg, userPattern, function(s)\
8834 return '@' .. s\
8835 end)\
8836\
8837 msg = string.gsub(msg, searchPattern, function(s)\
8838 return '#' .. s\
8839 end)\
8840\
8841 msg = string.gsub(msg, linkPattern, function(s)\
8842 return s\
8843 end)\
8844\
8845 return msg\
8846end\
8847\
8848local function pullTweet(name)\
8849 local data\
8850\
8851 local fh = http.get('https://twitter.com/' .. name)\
8852 if fh then\
8853 data = fh.readAll()\
8854 fh.close()\
8855 end\
8856\
8857 if data then\
8858 local pattern = 'data%-tweet%-id=\"(.-)\".-data%-screen%-name=\"(.-)\".-\"(.-)\".-title=\"(.-)\".-<p class=\"js%-tweet%-text tweet%-text\">(.-)</p>'\
8859\
8860 local id, screenName, name, timestamp, text = string.match(data, pattern)\
8861 local text = parseTweet(text)\
8862\
8863 return id, text, name, screenName, timestamp\
8864 end\
8865\
8866 return\
8867end\
8868\
8869local function displayToasts(toasts, statusBar)\
8870 for i = 1, #toasts do\
8871 if toasts[i].displayTimeAcc >= settings.displayTime and settings.display then\
8872 if tweets[1] then\
8873 local tweet = tweets[1]\
8874 local title = tweet['name'] .. ' (@' .. tweet['screenName'] .. ')'\
8875 local text = tweet['text']\
8876\
8877 toasts[i]:show(title, text)\
8878\
8879 table.remove(tweets, 1)\
8880\
8881 statusBar:update()\
8882 end\
8883 end\
8884 end\
8885end\
8886\
8887local function loadConfig(filename)\
8888 local fh = io.open(filename)\
8889 local data = fh:read('*a')\
8890 fh:close()\
8891\
8892 local config = {}\
8893\
8894 for line in string.gmatch(data, '[^\\n]+') do\
8895 local k, v = string.match(line, '([^ =]+)%s+=%s+(.*)')\
8896\
8897 if v == 'true' then\
8898 v = true\
8899\
8900 elseif v == 'false' then\
8901 v = false\
8902 end\
8903\
8904 if tonumber(v) then\
8905 v = tonumber(v)\
8906 end\
8907\
8908 if k and v then\
8909 config[k] = v\
8910 end\
8911 end\
8912\
8913 return config\
8914end\
8915\
8916local function saveConfig(filename, t)\
8917 local fh = io.open(filename, 'w')\
8918\
8919 local data = ''\
8920\
8921 for k, v in pairs(t) do\
8922 data = data .. tostring(k) .. ' = ' .. tostring(v) .. '\\n'\
8923 end\
8924\
8925 fh:write(data)\
8926 fh:close()\
8927end\
8928\
8929local function loadWatchingList(filename)\
8930 local fh = io.open(filename)\
8931 local data = fh:read('*a')\
8932 fh:close()\
8933\
8934 local list = {}\
8935\
8936 for line in string.gmatch(data, '[^\\n]+') do\
8937 list[line] = true\
8938 end\
8939\
8940 return list\
8941end\
8942\
8943local function saveWatchingList(filename, t)\
8944 local fh = io.open(filename, 'w')\
8945\
8946 local data = ''\
8947\
8948 for k, v in pairs(t) do\
8949 if v then\
8950 data = data .. k .. '\\n'\
8951 end\
8952 end\
8953\
8954 fh:write(data)\
8955 fh:close()\
8956end\
8957\
8958local function watchingNum(watching)\
8959 local i = 0\
8960 for k, v in pairs(watching) do\
8961 if v then\
8962 i = i + 1\
8963 end\
8964 end\
8965 return i\
8966end\
8967\
8968local folder = '.twitter'\
8969local settingsFilename = '.twitter/config'\
8970local lastIDFilename = '.twitter/lastID'\
8971local watchingFilename = '.twitter/watching'\
8972\
8973if fs.exists(folder) and not fs.isDir(folder) then\
8974 print('File with name .twitter allready exists.')\
8975 print('Please delete this file and re run this program.')\
8976end\
8977\
8978if not fs.exists(folder) then\
8979 fs.makeDir(folder)\
8980end\
8981\
8982if fs.exists(settingsFilename) then\
8983 print('Loaded config')\
8984 settings = loadConfig(settingsFilename)\
8985else\
8986 print('Saved config to: ' .. settingsFilename)\
8987 saveConfig(settingsFilename, settings)\
8988end\
8989\
8990if fs.exists(lastIDFilename) then\
8991 lastID = loadConfig(lastIDFilename)\
8992else\
8993 lastID = {}\
8994end\
8995\
8996if fs.exists(watchingFilename) then\
8997 watching = loadWatchingList(watchingFilename)\
8998else\
8999 watching = {}\
9000end\
9001\
9002\
9003local statusBar = StatusBar(10, 10)\
9004statusBar:show()\
9005\
9006local toasts = {}\
9007\
9008for i = 1, settings.toastCount do\
9009 toasts[i] = TweetToast(10, 50 + 132 * (i - 1))\
9010 toasts[i]:hide()\
9011end\
9012\
9013-- This is to make twitter not hate us!\
9014local sleepLength = 24 * watchingNum(watching) + 1\
9015local updateAcc = sleepLength\
9016\
9017local timerID = os.startTimer(settings.timerRate)\
9018\
9019while true do\
9020 local event, par1, par2 = os.pullEvent()\
9021 if event == 'timer' then\
9022 timerID = os.startTimer(settings.timerRate)\
9023\
9024 if #tweets > 0 and settings.autoDisplay then\
9025 displayToasts(toasts, statusBar)\
9026 end\
9027\
9028 for i = 1, #toasts do\
9029 toasts[i]:update(settings.timerRate)\
9030 end\
9031\
9032 if updateAcc >= sleepLength then\
9033 updateAcc = updateAcc - sleepLength\
9034\
9035 for k, v in pairs(watching) do\
9036 if v then\
9037 local id, text, name, screenName, timestamp = pullTweet(k)\
9038 id = tonumber(id)\
9039 if id then\
9040 if not lastID[k] or id ~= lastID[k] then\
9041 lastID[k] = id\
9042\
9043 table.insert(tweets, {\
9044 text = text,\
9045 name = name,\
9046 screenName = screenName,\
9047 timestamp = timestamp\
9048 })\
9049 end\
9050 end\
9051 end\
9052 end\
9053 statusBar:update()\
9054\
9055 saveConfig(lastIDFilename, lastID)\
9056 end\
9057\
9058 updateAcc = updateAcc + settings.timerRate\
9059\
9060 elseif event == 'chat_command' then\
9061 local command = par1\
9062 local user = par2\
9063 local splitted = {}\
9064\
9065 if user then\
9066 print(user .. ' used command: ' .. command)\
9067 else\
9068 print('Command: ' .. command)\
9069 end\
9070\
9071 for w in string.gmatch(command, '[^ ]+') do\
9072 table.insert(splitted, w)\
9073 end\
9074\
9075 if command == 'hide' then\
9076 settings.display = false\
9077 statusBar:hide()\
9078 \
9079 for i = 1, #toasts do\
9080 toasts[i]:hide()\
9081 end\
9082\
9083 saveConfig(settingsFilename, settings)\
9084\
9085 elseif command == 'show' then\
9086 settings.display = true\
9087 statusBar:show()\
9088\
9089 saveConfig(settingsFilename, settings)\
9090\
9091 elseif command == 'display' then\
9092 if not settings.autoDisplay then\
9093 displayToasts(toasts, statusBar)\
9094 end\
9095\
9096 elseif command == 'clear' then\
9097 lastID = {}\
9098 saveConfig(lastIDFilename, lastID)\
9099\
9100 elseif splitted[1] == 'watch' then\
9101 watching[splitted[2]] = true\
9102 saveWatchingList(watchingFilename, watching)\
9103\
9104 sleepLength = math.floor(3600 / 150 * watchingNum(watching)) + 1\
9105\
9106 -- Maybe show on the HUD?\
9107 print('Added \"' .. splitted[2] .. '\" to watching list.')\
9108\
9109 elseif splitted[1] == 'unwatch' then\
9110 watching[splitted[2]] = false\
9111 saveWatchingList(watchingFilename, watching)\
9112\
9113 sleepLength = 24 * watchingNum(watching) + 1\
9114\
9115 print('Removed \"' .. splitted[2] .. '\" from watching list.')\
9116\
9117 elseif splitted[1] == 'set' then\
9118 if splitted[2] == 'displayTime' then\
9119 settings.displaytime = tonumber(splitted[3])\
9120\
9121 elseif splitted[2] == 'autoDisplay' then\
9122 if splitted[3] == 'true' then\
9123 settings.autoDisplay = true\
9124\
9125 elseif splitted[3] == 'false' then\
9126 settings.autoDisplay = false\
9127 end\
9128\
9129 elseif splitted[2] == 'toastCount' then\
9130 settings.toastCount = tonumber(splitted[3])\
9131\
9132 elseif splitted[2] == 'timerRate' then\
9133 settings.timerRate = tonumber(splitted[3])\
9134 end\
9135 saveConfig(settingsFilename, settings)\
9136 end\
9137 end\
9138end",
9139 docs = "--[[\
9140 Made by SinZ and boq\
9141--]]\
9142local args = {...}\
9143if #args == 0 then\
9144 print(\"usage: docs <side> (function)\")\
9145 return\
9146end\
9147\
9148local side = args[1]\
9149local p = peripheral.wrap(side)\
9150\
9151if not p then\
9152 print(\"No peripheral on '\" .. side .. \"'\")\
9153 return\
9154end\
9155\
9156if not p.getAdvancedMethodsData then\
9157 print(\"Peripheral '\" .. peripheral.getType(side) .. \"' is not OpenPeripheral(TM)\")\
9158 return\
9159end\
9160\
9161local info = p.getAdvancedMethodsData()\
9162\
9163function argName(arg)\
9164 if arg.vararg then\
9165 return arg.name..\"...\"\
9166 elseif arg.optional then\
9167 return arg.name..\"?\"\
9168 else\
9169 return arg.name\
9170 end\
9171end\
9172\
9173if #args == 1 then\
9174 for name,data in pairs(info) do\
9175 args = {}\
9176 for _,arg in pairs(data.args) do\
9177 table.insert(args, argName(arg))\
9178 end\
9179 print(name..\"(\"..table.concat(args,\",\")..\")\")\
9180 end\
9181else --must be 2 or more\
9182 for name,data in pairs(info) do\
9183 if args[2]:lower() == name:lower() then\
9184 print(name..\": \"..data.description)\
9185 print(\"source: \" .. data.source) \
9186 print(\"returns: \"..string.lower(data.returnTypes))\
9187 if #data.args > 0 then\
9188 print(\"args: \")\
9189 for _,arg in ipairs(data.args) do\
9190 print(\" - (\"..arg.type:lower() .. \")\"..argName(arg)..\": \"..arg.description)\
9191 end\
9192 end\
9193 end\
9194 end\
9195end",
9196 github = "--edit of the pastebin program to get stuff from Github, edited by Vexatos\
9197local function printUsage()\
9198 print( \"Usages:\" )\
9199 print( \"github get username/reponame/branch/path <filename>\" )\
9200 print( \"github run username/reponame/branch/path <arguments>\" )\
9201 print( \"'github help' for more information\" )\
9202end\
9203\
9204local tArgs = { ... }\
9205 \
9206if not http then\
9207 printError( \"Github requires http API\" )\
9208 printError( \"Set enableAPI_http to true in ComputerCraft.cfg\" )\
9209 return\
9210end\
9211 \
9212local function get(name,reponame,branch,path)\
9213 write( \"Connecting to github.com... \" )\
9214 local response = http.get(\
9215 \"https://raw.github.com/\"..name..\"/\"..reponame..\"/\"..branch..\"/\"..path\
9216 )\
9217 \
9218 if response then\
9219 print( \"Success.\" )\
9220 \
9221 local sResponse = response.readAll()\
9222 response.close()\
9223 return sResponse\
9224 else\
9225 printError( \"Failed.\" )\
9226 end\
9227end\
9228\
9229local function getFull(path)\
9230 write( \"Connecting to github.com... \" )\
9231 local response = http.get(\
9232 \"https://raw.github.com/\"..path\
9233 )\
9234 \
9235 if response then\
9236 print( \"Success.\" )\
9237 \
9238 local sResponse = response.readAll()\
9239 response.close()\
9240 return sResponse\
9241 else\
9242 printError( \"Failed.\" )\
9243 end\
9244end\
9245\
9246local sCommand = tArgs[1]\
9247if sCommand == \"get\" then\
9248 -- Download a file from github.com\
9249 if #tArgs < 6 then\
9250 if #tArgs == 3 then\
9251\
9252 -- Determine file to download\
9253 local sPath = tArgs[2]\
9254 local sFile = tArgs[3]\
9255 local sPathN = shell.resolve( sFile )\
9256 if fs.exists( sPathN ) then\
9257 print( \"File already exists\" )\
9258 return\
9259 end\
9260 \
9261 -- GET the contents from github\
9262 local res = getFull(sPath)\
9263 if res then \
9264 local file = fs.open( sPathN, \"w\" )\
9265 file.write( res )\
9266 file.close()\
9267\
9268 print( \"Downloaded as \"..sFile )\
9269 end\
9270 else\
9271 printUsage()\
9272 return\
9273 end\
9274 elseif #tArgs == 6 then\
9275 -- Determine file to download\
9276 local sName = tArgs[2]\
9277 local sRepo = tArgs[3]\
9278 local sBranch = tArgs[4]\
9279 local sPath = tArgs[5]\
9280 local sFile = tArgs[6]\
9281 local sPathN = shell.resolve( sFile )\
9282 if fs.exists( sPathN ) then\
9283 print( \"File already exists\" )\
9284 return\
9285 end\
9286\
9287 -- GET the contents from github\
9288 local res = get(sName,sRepo,sBranch,sPath)\
9289 if res then \
9290 local file = fs.open( sPathN, \"w\" )\
9291 file.write( res )\
9292 file.close()\
9293\
9294 print( \"Downloaded as \"..sFile )\
9295 end \
9296 else\
9297 printUsage()\
9298 return\
9299 end\
9300\
9301elseif sCommand == \"run\" then\
9302 if string.find(tArgs[2],\"/\") then\
9303 if #tArgs >= 2 then\
9304 local sPath = tArgs[2]\
9305\
9306 local res = getFull(sPath)\
9307 if res then\
9308 local func, err = loadstring(res)\
9309 if not func then\
9310 printError( err )\
9311 return\
9312 end\
9313 setfenv(func, getfenv())\
9314 local success, msg = pcall(func, unpack(tArgs, 3))\
9315 if not success then\
9316 printError( msg )\
9317 end\
9318 end\
9319 else\
9320 printUsage()\
9321 return\
9322 end\
9323 else\
9324 if #tArgs >= 5 then\
9325 local sName = tArgs[2]\
9326 local sRepo = tArgs[3]\
9327 local sBranch = tArgs[4]\
9328 local sPath = tArgs[5]\
9329\
9330 local res = get(sName,sRepo,sBranch,sPath)\
9331 if res then\
9332 local func, err = loadstring(res)\
9333 if not func then\
9334 printError( err )\
9335 return\
9336 end\
9337 setfenv(func, getfenv())\
9338 local success, msg = pcall(func, unpack(tArgs, 6))\
9339 if not success then\
9340 printError( msg )\
9341 end\
9342 end\
9343 else\
9344 printUsage()\
9345 return\
9346 end\
9347 end\
9348elseif sCommand == \"help\" then\
9349 term.clear()\
9350 print( \"github is a program that allows you to get files\" )\
9351 print( \"from a Github repository and store or run them in your Computer.\" )\
9352 print (\"\")\
9353 printUsage()\
9354 print (\"\")\
9355 print(\"There is also another spelling:\")\
9356 print(\"github get <username> <reponame> <branch> <path> <filename>\")\
9357 print(\"github run <username> <reponame> <branch> <path> [arguments]\")\
9358 print(\"Note: Do not use the '/' (slash) character with this spelling, except in <path>!\")\
9359else\
9360 printUsage()\
9361 return\
9362end",
9363 multiperipheral = "local sideNames = rs.getSides()\
9364\
9365table.reduce = function (list, fn) \
9366 local acc\
9367 for k, v in ipairs(list) do\
9368 if 1 == k then\
9369 acc = v\
9370 else\
9371 acc = fn(acc, v)\
9372 end \
9373 end \
9374 return acc \
9375end\
9376\
9377local multiperipheral = {\
9378\
9379 -- wrap multiple targets at once\
9380 wrap = function (self, ...)\
9381 local meta = getmetatable(self)\
9382 for k, name in pairs({...}) do\
9383 table.insert(self.names, name)\
9384 for k2, methodName in pairs(peripheral.getMethods(name)) do\
9385 meta.__index[methodName] = function (a, ...)\
9386 local returnVal = {}\
9387 for k3, pName in pairs(a.names) do\
9388 for k4, mName in pairs(peripheral.getMethods(pName)) do\
9389 if mName == methodName then\
9390 table.insert(returnVal, peripheral.call(pName, methodName, ...))\
9391 end\
9392 end\
9393 end\
9394 return returnVal\
9395 end\
9396 end\
9397 end\
9398 return self\
9399 end,\
9400 \
9401 -- wrap multiple targets by their type\
9402 types = function(self, ...)\
9403 local checkTypes = {}\
9404 local addNames = {}\
9405\
9406 for _,v in ipairs({...}) do\
9407 checkTypes[v] = true\
9408 end\
9409\
9410 for _,name in pairs(peripheral.getNames()) do\
9411 if checkTypes[peripheral.getType(name)] then\
9412 addNames[#addNames+1] = name\
9413 end\
9414 end\
9415\
9416 return self:wrap(unpack(addNames))\
9417 end,\
9418 \
9419 getNames = function(self)\
9420 return self.names\
9421 end\
9422\
9423}\
9424\
9425local gmetatable = {\
9426 __index = multiperipheral,\
9427 __tostring = function(g) return g:tostring() end,\
9428}\
9429\
9430function new()\
9431 local g = {\
9432 names = {}\
9433 }\
9434 setmetatable(g, gmetatable)\
9435 return g\
9436end",
9437 },
9438 startup = "shell.run(\"bg ReactorControl/r_control.lua silent\")",
9439 Bedrock = "--Bedrock Build: 483\
9440--This code is squished down in to one, rather hard to read file.\
9441--As such it is not much good for anything other than being loaded as an API.\
9442--If you want to look at the code to learn from it, copy parts or just take a look,\
9443--you should go to the GitHub repo. http://github.com/oeed/Bedrock/\
9444\
9445--\
9446-- Bedrock is the core program framework used by all OneOS and OneCode programs.\
9447-- Inspired by Apple's Cocoa framework.\
9448-- (c) oeed 2014\
9449--\
9450-- For documentation see the Bedrock wiki, github.com/oeed/Bedrock/wiki/\
9451--\
9452\
9453local apis = {\
9454[\"Drawing\"] = [[\
9455local round = function(num, idp)\
9456 local mult = 10^(idp or 0)\
9457 return math.floor(num * mult + 0.5) / mult\
9458end\
9459\
9460local _w, _h = term.getSize()\
9461local copyBuffer = nil\
9462\
9463Screen = {\
9464 Width = _w,\
9465 Height = _h\
9466}\
9467\
9468Constraints = {\
9469 \
9470}\
9471\
9472CurrentConstraint = {1,1,_w,_h}\
9473IgnoreConstraint = false\
9474\
9475function AddConstraint(x, y, width, height)\
9476 local x2 = x + width - 1\
9477 local y2 = y + height - 1\
9478 table.insert(Drawing.Constraints, {x, y, x2, y2})\
9479 Drawing.GetConstraint()\
9480end\
9481\
9482function RemoveConstraint()\
9483 --table.remove(Drawing.Constraints, #Drawing.Constraints)\
9484 Drawing.Constraints[#Drawing.Constraints] = nil\
9485 Drawing.GetConstraint()\
9486end\
9487\
9488function GetConstraint()\
9489 local x = 1\
9490 local y = 1\
9491 local x2 = Drawing.Screen.Width\
9492 local y2 = Drawing.Screen.Height\
9493 for i, c in ipairs(Drawing.Constraints) do\
9494 if x < c[1] then\
9495 x = c[1]\
9496 end\
9497 if y < c[2] then\
9498 y = c[2]\
9499 end\
9500 if x2 > c[3] then\
9501 x2 = c[3]\
9502 end\
9503 if y2 > c[4] then\
9504 y2 = c[4]\
9505 end\
9506 end\
9507 Drawing.CurrentConstraint = {x, y, x2, y2}\
9508end\
9509\
9510function WithinContraint(x, y)\
9511 return Drawing.IgnoreConstraint or\
9512 (x >= Drawing.CurrentConstraint[1] and\
9513 y >= Drawing.CurrentConstraint[2] and\
9514 x <= Drawing.CurrentConstraint[3] and\
9515 y <= Drawing.CurrentConstraint[4])\
9516end\
9517\
9518colours.transparent = 0\
9519colors.transparent = 0\
9520\
9521Filters = {\
9522 None = {\
9523 [colours.white] = colours.white,\
9524 [colours.orange] = colours.orange,\
9525 [colours.magenta] = colours.magenta,\
9526 [colours.lightBlue] = colours.lightBlue,\
9527 [colours.yellow] = colours.yellow,\
9528 [colours.lime] = colours.lime,\
9529 [colours.pink] = colours.pink,\
9530 [colours.grey] = colours.grey,\
9531 [colours.lightGrey] = colours.lightGrey,\
9532 [colours.cyan] = colours.cyan,\
9533 [colours.purple] = colours.purple,\
9534 [colours.blue] = colours.blue,\
9535 [colours.brown] = colours.brown,\
9536 [colours.green] = colours.green,\
9537 [colours.red] = colours.red,\
9538 [colours.black] = colours.black,\
9539 [colours.transparent] = colours.transparent,\
9540 },\
9541\
9542 Greyscale = {\
9543 [colours.white] = colours.white,\
9544 [colours.orange] = colours.lightGrey,\
9545 [colours.magenta] = colours.lightGrey,\
9546 [colours.lightBlue] = colours.lightGrey,\
9547 [colours.yellow] = colours.lightGrey,\
9548 [colours.lime] = colours.lightGrey,\
9549 [colours.pink] = colours.lightGrey,\
9550 [colours.grey] = colours.grey,\
9551 [colours.lightGrey] = colours.lightGrey,\
9552 [colours.cyan] = colours.grey,\
9553 [colours.purple] = colours.grey,\
9554 [colours.blue] = colours.grey,\
9555 [colours.brown] = colours.grey,\
9556 [colours.green] = colours.grey,\
9557 [colours.red] = colours.grey,\
9558 [colours.black] = colours.black,\
9559 [colours.transparent] = colours.transparent,\
9560 },\
9561\
9562 BlackWhite = {\
9563 [colours.white] = colours.white,\
9564 [colours.orange] = colours.white,\
9565 [colours.magenta] = colours.white,\
9566 [colours.lightBlue] = colours.white,\
9567 [colours.yellow] = colours.white,\
9568 [colours.lime] = colours.white,\
9569 [colours.pink] = colours.white,\
9570 [colours.grey] = colours.black,\
9571 [colours.lightGrey] = colours.white,\
9572 [colours.cyan] = colours.black,\
9573 [colours.purple] = colours.black,\
9574 [colours.blue] = colours.black,\
9575 [colours.brown] = colours.black,\
9576 [colours.green] = colours.black,\
9577 [colours.red] = colours.black,\
9578 [colours.black] = colours.black,\
9579 [colours.transparent] = colours.transparent,\
9580 },\
9581\
9582 Darker = {\
9583 [colours.white] = colours.lightGrey,\
9584 [colours.orange] = colours.red,\
9585 [colours.magenta] = colours.purple,\
9586 [colours.lightBlue] = colours.cyan,\
9587 [colours.yellow] = colours.orange,\
9588 [colours.lime] = colours.green,\
9589 [colours.pink] = colours.magenta,\
9590 [colours.grey] = colours.black,\
9591 [colours.lightGrey] = colours.grey,\
9592 [colours.cyan] = colours.blue,\
9593 [colours.purple] = colours.grey,\
9594 [colours.blue] = colours.grey,\
9595 [colours.brown] = colours.grey,\
9596 [colours.green] = colours.grey,\
9597 [colours.red] = colours.brown,\
9598 [colours.black] = colours.black,\
9599 [colours.transparent] = colours.transparent,\
9600 },\
9601\
9602 Lighter = {\
9603 [colours.white] = colours.lightGrey,\
9604 [colours.orange] = colours.yellow,\
9605 [colours.magenta] = colours.pink,\
9606 [colours.lightBlue] = colours.cyan,\
9607 [colours.yellow] = colours.orange,\
9608 [colours.lime] = colours.green,\
9609 [colours.pink] = colours.magenta,\
9610 [colours.grey] = colours.lightGrey,\
9611 [colours.lightGrey] = colours.grey,\
9612 [colours.cyan] = colours.lightBlue,\
9613 [colours.purple] = colours.magenta,\
9614 [colours.blue] = colours.lightBlue,\
9615 [colours.brown] = colours.red,\
9616 [colours.green] = colours.lime,\
9617 [colours.red] = colours.orange,\
9618 [colours.black] = colours.grey,\
9619 [colours.transparent] = colours.transparent,\
9620 },\
9621\
9622 Highlight = {\
9623 [colours.white] = colours.lightGrey,\
9624 [colours.orange] = colours.yellow,\
9625 [colours.magenta] = colours.pink,\
9626 [colours.lightBlue] = colours.cyan,\
9627 [colours.yellow] = colours.orange,\
9628 [colours.lime] = colours.green,\
9629 [colours.pink] = colours.magenta,\
9630 [colours.grey] = colours.lightGrey,\
9631 [colours.lightGrey] = colours.grey,\
9632 [colours.cyan] = colours.lightBlue,\
9633 [colours.purple] = colours.magenta,\
9634 [colours.blue] = colours.lightBlue,\
9635 [colours.brown] = colours.red,\
9636 [colours.green] = colours.lime,\
9637 [colours.red] = colours.orange,\
9638 [colours.black] = colours.grey,\
9639 [colours.transparent] = colours.transparent,\
9640 },\
9641\
9642 Invert = {\
9643 [colours.white] = colours.black,\
9644 [colours.orange] = colours.blue,\
9645 [colours.magenta] = colours.green,\
9646 [colours.lightBlue] = colours.brown,\
9647 [colours.yellow] = colours.blue,\
9648 [colours.lime] = colours.purple,\
9649 [colours.pink] = colours.green,\
9650 [colours.grey] = colours.lightGrey,\
9651 [colours.lightGrey] = colours.grey,\
9652 [colours.cyan] = colours.red,\
9653 [colours.purple] = colours.green,\
9654 [colours.blue] = colours.yellow,\
9655 [colours.brown] = colours.lightBlue,\
9656 [colours.green] = colours.purple,\
9657 [colours.red] = colours.cyan,\
9658 [colours.black] = colours.white,\
9659 [colours.transparent] = colours.transparent,\
9660 },\
9661}\
9662\
9663function FilterColour(colour, filter)\
9664 if filter[colour] then\
9665 return filter[colour]\
9666 else\
9667 return colour\
9668 end\
9669end\
9670\
9671DrawCharacters = function (x, y, characters, textColour, bgColour)\
9672 Drawing.WriteStringToBuffer(x, y, tostring(characters), textColour, bgColour)\
9673end\
9674\
9675DrawBlankArea = function (x, y, w, h, colour)\
9676 if colour ~= colours.transparent then\
9677 Drawing.DrawArea (x, y, w, h, \" \", 1, colour)\
9678 end\
9679end\
9680\
9681DrawArea = function (x, y, w, h, character, textColour, bgColour)\
9682 --width must be greater than 1, otherwise we get problems\
9683 if w < 0 then\
9684 w = w * -1\
9685 elseif w == 0 then\
9686 w = 1\
9687 end\
9688\
9689 for ix = 1, w do\
9690 local currX = x + ix - 1\
9691 for iy = 1, h do\
9692 local currY = y + iy - 1\
9693 Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour)\
9694 end\
9695 end\
9696end\
9697\
9698DrawImage = function(_x,_y,tImage, w, h)\
9699 if tImage then\
9700 for y = 1, h do\
9701 if not tImage[y] then\
9702 break\
9703 end\
9704 for x = 1, w do\
9705 if not tImage[y][x] then\
9706 break\
9707 end\
9708 local bgColour = tImage[y][x]\
9709 local textColour = tImage.textcol[y][x] or colours.white\
9710 local char = tImage.text[y][x]\
9711 Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour)\
9712 end\
9713 end\
9714 elseif w and h then\
9715 Drawing.DrawBlankArea(_x, _y, w, h, colours.lightGrey)\
9716 end\
9717end\
9718\
9719--using .nft\
9720LoadImage = function(path, global)\
9721 local image = {\
9722 text = {},\
9723 textcol = {}\
9724 }\
9725 if fs.exists(path) then\
9726 local _io = io\
9727 if OneOS and global then\
9728 _io = OneOS.IO\
9729 end\
9730 local file = _io.open(path, \"r\")\
9731 if not file then\
9732 error('Error Occured. _io:'..tostring(_io)..' OneOS: '..tostring(OneOS)..' OneOS.IO'..tostring(OneOS.IO)..' io: '..tostring(io))\
9733 end\
9734 local sLine = file:read()\
9735 local num = 1\
9736 while sLine do \
9737 table.insert(image, num, {})\
9738 table.insert(image.text, num, {})\
9739 table.insert(image.textcol, num, {})\
9740 \
9741 --As we're no longer 1-1, we keep track of what index to write to\
9742 local writeIndex = 1\
9743 --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour\
9744 local bgNext, fgNext = false, false\
9745 --The current background and foreground colours\
9746 local currBG, currFG = nil,nil\
9747 for i=1,#sLine do\
9748 local nextChar = string.sub(sLine, i, i)\
9749 if nextChar:byte() == 30 then\
9750 bgNext = true\
9751 elseif nextChar:byte() == 31 then\
9752 fgNext = true\
9753 elseif bgNext then\
9754 currBG = Drawing.GetColour(nextChar)\
9755 if currBG == nil then\
9756 currBG = colours.transparent\
9757 end\
9758 bgNext = false\
9759 elseif fgNext then\
9760 currFG = Drawing.GetColour(nextChar)\
9761 if currFG == nil or currFG == colours.transparent then\
9762 currFG = colours.white\
9763 end\
9764 fgNext = false\
9765 else\
9766 if nextChar ~= \" \" and currFG == nil then\
9767 currFG = colours.white\
9768 end\
9769 image[num][writeIndex] = currBG\
9770 image.textcol[num][writeIndex] = currFG\
9771 image.text[num][writeIndex] = nextChar\
9772 writeIndex = writeIndex + 1\
9773 end\
9774 end\
9775 num = num+1\
9776 sLine = file:read()\
9777 end\
9778 file:close()\
9779 else\
9780 return nil\
9781 end\
9782 return image\
9783end\
9784\
9785DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)\
9786 w = w or Drawing.Screen.Width\
9787 h = h or Drawing.Screen.Height\
9788 x = x or 0\
9789 y = y or 0\
9790 x = math.floor((w - #characters) / 2) + x\
9791 y = math.floor(h / 2) + y\
9792\
9793 Drawing.DrawCharacters(x, y, characters, textColour, bgColour)\
9794end\
9795\
9796GetColour = function(hex)\
9797 if hex == ' ' then\
9798 return colours.transparent\
9799 end\
9800 local value = tonumber(hex, 16)\
9801 if not value then return nil end\
9802 value = math.pow(2,value)\
9803 return value\
9804end\
9805\
9806Clear = function (_colour)\
9807 _colour = _colour or colours.black\
9808 Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour)\
9809end\
9810\
9811Buffer = {}\
9812BackBuffer = {}\
9813\
9814TryRestore = false\
9815\
9816\
9817--TODO: make this quicker\
9818-- maybe sort the pixels in order of colour so it doesn't have to set the colour each time\
9819DrawBuffer = function()\
9820 if TryRestore and Restore then\
9821 Restore()\
9822 end\
9823\
9824 for y,row in pairs(Drawing.Buffer) do\
9825 for x,pixel in pairs(row) do\
9826 local shouldDraw = true\
9827 local hasBackBuffer = true\
9828 if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then\
9829 hasBackBuffer = false\
9830 end\
9831 if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then\
9832 shouldDraw = false\
9833 end\
9834 if shouldDraw then\
9835 term.setBackgroundColour(pixel[3])\
9836 term.setTextColour(pixel[2])\
9837 term.setCursorPos(x, y)\
9838 term.write(pixel[1])\
9839 end\
9840 end\
9841 end\
9842 Drawing.BackBuffer = Drawing.Buffer\
9843 Drawing.Buffer = {}\
9844end\
9845\
9846ClearBuffer = function()\
9847 Drawing.Buffer = {}\
9848end\
9849\
9850WriteStringToBuffer = function (x, y, characters, textColour,bgColour)\
9851 for i = 1, #characters do\
9852 local character = characters:sub(i,i)\
9853 Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)\
9854 end\
9855end\
9856\
9857WriteToBuffer = function(x, y, character, textColour,bgColour, cached)\
9858 if not cached and not Drawing.WithinContraint(x, y) then\
9859 return\
9860 end\
9861 x = round(x)\
9862 y = round(y)\
9863\
9864 if textColour == colours.transparent then\
9865 character = ' '\
9866 end\
9867\
9868 if bgColour == colours.transparent then\
9869 Drawing.Buffer[y] = Drawing.Buffer[y] or {}\
9870 Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {\"\", colours.white, colours.black}\
9871 Drawing.Buffer[y][x][1] = character\
9872 Drawing.Buffer[y][x][2] = textColour\
9873 else\
9874 Drawing.Buffer[y] = Drawing.Buffer[y] or {}\
9875 Drawing.Buffer[y][x] = {character, textColour, bgColour}\
9876 end\
9877\
9878 if copyBuffer then\
9879 copyBuffer[y] = copyBuffer[y] or {}\
9880 copyBuffer[y][x] = {character, textColour, bgColour} \
9881 end\
9882end\
9883\
9884DrawCachedBuffer = function(buffer)\
9885 for y, row in pairs(buffer) do\
9886 for x, pixel in pairs(row) do\
9887 WriteToBuffer(x, y, pixel[1], pixel[2], pixel[3], true)\
9888 end\
9889 end\
9890end\
9891\
9892StartCopyBuffer = function()\
9893 copyBuffer = {}\
9894end\
9895\
9896EndCopyBuffer = function()\
9897 local tmpCopy = copyBuffer\
9898 copyBuffer = nil\
9899 return tmpCopy\
9900end\
9901]],\
9902[\"Helpers\"] = [[\
9903LongestString = function(input, key, isKey)\
9904 local length = 0\
9905 if isKey then\
9906 for k, v in pairs(input) do\
9907 local titleLength = string.len(k)\
9908 if titleLength > length then\
9909 length = titleLength\
9910 end\
9911 end\
9912 else\
9913 for i = 1, #input do\
9914 local value = input[i]\
9915 if key then\
9916 if value[key] then\
9917 value = value[key]\
9918 else\
9919 value = ''\
9920 end\
9921 end\
9922 local titleLength = string.len(value)\
9923 if titleLength > length then\
9924 length = titleLength\
9925 end\
9926 end\
9927 end\
9928 return length\
9929end\
9930\
9931Split = function(str,sep)\
9932 sep=sep or'/'\
9933 return str:match(\"(.*\"..sep..\")\")\
9934end\
9935\
9936Extension = function(path, addDot)\
9937 if not path then\
9938 return nil\
9939 elseif not string.find(fs.getName(path), '%.') then\
9940 return ''\
9941 else\
9942 local _path = path\
9943 if path:sub(#path) == '/' then\
9944 _path = path:sub(1,#path-1)\
9945 end\
9946 local extension = _path:gmatch('%.[0-9a-z]+$')()\
9947 if extension then\
9948 extension = extension:sub(2)\
9949 else\
9950 --extension = nil\
9951 return ''\
9952 end\
9953 if addDot then\
9954 extension = '.'..extension\
9955 end\
9956 return extension:lower()\
9957 end\
9958end\
9959\
9960RemoveExtension = function(path)\
9961--local name = string.match(fs.getName(path), '(%a+)%.?.-')\
9962 if not path:find('%.') then\
9963 return path\
9964 end\
9965 local extension = Helpers.Extension(path)\
9966 if extension == path then\
9967 return fs.getName(path)\
9968 end\
9969 return string.gsub(path, extension, ''):sub(1, -2)\
9970end\
9971\
9972RemoveFileName = function(path)\
9973 if string.sub(path, -1) == '/' then\
9974 path = string.sub(path, 1, -2)\
9975 end\
9976 local v = string.match(path, \"(.-)([^\\\\/]-%.?([^%.\\\\/]*))$\")\
9977 if type(v) == 'string' then\
9978 return v\
9979 end\
9980 return v[1]\
9981end\
9982\
9983TruncateString = function(sString, maxLength)\
9984 if #sString > maxLength then\
9985 sString = sString:sub(1,maxLength-3)\
9986 if sString:sub(-1) == ' ' then\
9987 sString = sString:sub(1,maxLength-4)\
9988 end\
9989 sString = sString .. '...'\
9990 end\
9991 return sString\
9992end\
9993\
9994TruncateStringStart = function(sString, maxLength)\
9995 local len = #sString\
9996 if #sString > maxLength then\
9997 sString = sString:sub(len - maxLength, len - 3)\
9998 if sString:sub(-1) == ' ' then\
9999 sString = sString:sub(len - maxLength, len - 4)\
10000 end\
10001 sString = '...' .. sString\
10002 end\
10003 return sString\
10004end\
10005\
10006WrapText = function(text, maxWidth)\
10007 local lines = {''}\
10008 for word, space in text:gmatch('(%S+)(%s*)') do\
10009 local temp = lines[#lines] .. word .. space:gsub('\\n','')\
10010 if #temp > maxWidth then\
10011 table.insert(lines, '')\
10012 end\
10013 if space:find('\\n') then\
10014 lines[#lines] = lines[#lines] .. word\
10015 \
10016 space = space:gsub('\\n', function()\
10017 table.insert(lines, '')\
10018 return ''\
10019 end)\
10020 else\
10021 lines[#lines] = lines[#lines] .. word .. space\
10022 end\
10023 end\
10024 if #lines[1] == 0 then\
10025 table.remove(lines,1)\
10026 end\
10027 return lines\
10028end\
10029\
10030TidyPath = function(path)\
10031 path = '/'..path\
10032 if fs.exists(path) and fs.isDir(path) then\
10033 path = path .. '/'\
10034 end\
10035\
10036 path, n = path:gsub(\"//\", \"/\")\
10037 while n > 0 do\
10038 path, n = path:gsub(\"//\", \"/\")\
10039 end\
10040 return path\
10041end\
10042\
10043Capitalise = function(str)\
10044 return str:sub(1, 1):upper() .. str:sub(2, -1)\
10045end\
10046\
10047Round = function(num, idp)\
10048 local mult = 10^(idp or 0)\
10049 return math.floor(num * mult + 0.5) / mult\
10050end\
10051]],\
10052[\"Object\"] = [[\
10053X = 1\
10054Y = 1\
10055Width = 1\
10056Height = 1\
10057Parent = nil\
10058OnClick = nil\
10059Visible = true\
10060IgnoreClick = false\
10061Name = nil \
10062ClipDrawing = true\
10063UpdateDrawBlacklist = {}\
10064Fixed = false\
10065Ready = false\
10066\
10067DrawCache = {}\
10068\
10069NeedsDraw = function(self)\
10070 if not self.Visible then\
10071 return false\
10072 end\
10073 \
10074 if not self.DrawCache.Buffer or self.DrawCache.AlwaysDraw or self.DrawCache.NeedsDraw then\
10075 return true\
10076 end\
10077\
10078 if self.OnNeedsUpdate then\
10079 if self.OnNeedsUpdate() then\
10080 return true\
10081 end\
10082 end\
10083\
10084 if self.Children then\
10085 for i, v in ipairs(self.Children) do\
10086 if v:NeedsDraw() then\
10087 return true\
10088 end\
10089 end\
10090 end\
10091end\
10092\
10093GetPosition = function(self)\
10094 return self.Bedrock:GetAbsolutePosition(self)\
10095end\
10096\
10097GetOffsetPosition = function(self)\
10098 if not self.Parent then\
10099 return {X = 1, Y = 1}\
10100 end\
10101\
10102 local offset = {X = 0, Y = 0}\
10103 if not self.Fixed and self.Parent.ChildOffset then\
10104 offset = self.Parent.ChildOffset\
10105 end\
10106\
10107 return {X = self.X + offset.X, Y = self.Y + offset.Y}\
10108end\
10109\
10110Draw = function(self)\
10111 if not self.Visible then\
10112 return\
10113 end\
10114\
10115 self.DrawCache.NeedsDraw = false\
10116 local pos = self:GetPosition()\
10117 Drawing.StartCopyBuffer()\
10118\
10119 if self.ClipDrawing then\
10120 Drawing.AddConstraint(pos.X, pos.Y, self.Width, self.Height)\
10121 end\
10122\
10123 if self.OnDraw then\
10124 self:OnDraw(pos.X, pos.Y)\
10125 end\
10126\
10127 self.DrawCache.Buffer = Drawing.EndCopyBuffer()\
10128 \
10129 if self.Children then\
10130 for i, child in ipairs(self.Children) do\
10131 local pos = child:GetOffsetPosition()\
10132 if pos.Y + self.Height > 1 and pos.Y <= self.Height and pos.X + self.Width > 1 and pos.X <= self.Width then\
10133 child:Draw()\
10134 end\
10135 end\
10136 end\
10137\
10138\
10139 if self.OnPostChildrenDraw then\
10140 self:OnPostChildrenDraw(pos.X, pos.Y)\
10141 end\
10142\
10143 if self.ClipDrawing then\
10144 Drawing.RemoveConstraint()\
10145 end \
10146end\
10147\
10148ForceDraw = function(self, ignoreChildren, ignoreParent, ignoreBedrock)\
10149 if not ignoreBedrock and self.Bedrock then\
10150 self.Bedrock:ForceDraw()\
10151 end\
10152 self.DrawCache.NeedsDraw = true\
10153 if not ignoreParent and self.Parent then\
10154 self.Parent:ForceDraw(true, nil, true)\
10155 end\
10156 if not ignoreChildren and self.Children then\
10157 for i, child in ipairs(self.Children) do\
10158 child:ForceDraw(nil, true, true)\
10159 end\
10160 end\
10161end\
10162\
10163OnRemove = function(self)\
10164 if self == self.Bedrock:GetActiveObject() then\
10165 self.Bedrock:SetActiveObject()\
10166 end\
10167end\
10168\
10169local function ParseColour(value)\
10170 if type(value) == 'string' then\
10171 if colours[value] and type(colours[value]) == 'number' then\
10172 return colours[value]\
10173 elseif colors[value] and type(colors[value]) == 'number' then\
10174 return colors[value]\
10175 end\
10176 elseif type(value) == 'number' and (value == colours.transparent or (value >= colours.white and value <= colours.black)) then\
10177 return value\
10178 end\
10179 error('Invalid colour: \"'..tostring(value)..'\"')\
10180end\
10181\
10182Initialise = function(self, values)\
10183 local _new = values -- the new instance\
10184 _new.DrawCache = {\
10185 NeedsDraw = true,\
10186 AlwaysDraw = false,\
10187 Buffer = nil\
10188 }\
10189 setmetatable(_new, {__index = self} )\
10190\
10191 local new = {} -- the proxy\
10192 setmetatable(new, {\
10193 __index = function(t, k)\
10194 if k:find('Color') then\
10195 k = k:gsub('Color', 'Colour')\
10196 end\
10197\
10198 if k:find('Colour') and type(_new[k]) ~= 'table' and type(_new[k]) ~= 'function' then\
10199 if _new[k] then\
10200 return ParseColour(_new[k])\
10201 end\
10202 elseif _new[k] ~= nil then\
10203 return _new[k]\
10204 end\
10205 end,\
10206\
10207 __newindex = function (t,k,v)\
10208 if k:find('Color') then\
10209 k = k:gsub('Color', 'Colour')\
10210 end\
10211\
10212 if k == 'Width' or k == 'X' or k == 'Height' or k == 'Y' then\
10213 v = new.Bedrock:ParseStringSize(new.Parent, k, v)\
10214 end\
10215\
10216 if v ~= _new[k] then\
10217 _new[k] = v\
10218 if t.OnUpdate then\
10219 t:OnUpdate(k)\
10220 end\
10221\
10222 if t.UpdateDrawBlacklist[k] == nil then\
10223 t:ForceDraw()\
10224 end\
10225 end\
10226 end\
10227 })\
10228 if new.OnInitialise then\
10229 new:OnInitialise()\
10230 end\
10231\
10232 return new\
10233end\
10234\
10235AnimateValue = function(self, valueName, from, to, duration, done, tbl)\
10236 tbl = tbl or self\
10237 if type(tbl[valueName]) ~= 'number' then\
10238 error('Animated value ('..valueName..') must be number.')\
10239 elseif not self.Bedrock.AnimationEnabled then\
10240 tbl[valueName] = to\
10241 if done then\
10242 done()\
10243 end\
10244 return\
10245 end\
10246 from = from or tbl[valueName]\
10247 duration = duration or 0.2\
10248 local delta = to - from\
10249\
10250 local startTime = os.clock()\
10251 local previousFrame = startTime\
10252 local frame\
10253 frame = function()\
10254 local time = os.clock()\
10255 local totalTime = time - startTime\
10256 local isLast = totalTime >= duration\
10257\
10258 if isLast then\
10259 tbl[valueName] = to\
10260 self:ForceDraw()\
10261 if done then\
10262 done()\
10263 end\
10264 else\
10265 tbl[valueName] = self.Bedrock.Helpers.Round(from + delta * (totalTime / duration))\
10266 self:ForceDraw()\
10267 self.Bedrock:StartTimer(function()\
10268 frame()\
10269 end, 0.05)\
10270 end\
10271 end\
10272 frame()\
10273end\
10274\
10275Click = function(self, event, side, x, y)\
10276 if self.Visible and not self.IgnoreClick then\
10277 if event == 'mouse_click' and self.OnClick and self:OnClick(event, side, x, y) ~= false then\
10278 return true\
10279 elseif event == 'mouse_drag' and self.OnDrag and self:OnDrag(event, side, x, y) ~= false then\
10280 return true\
10281 elseif event == 'mouse_scroll' and self.OnScroll and self:OnScroll(event, side, x, y) ~= false then\
10282 return true\
10283 else\
10284 return false\
10285 end\
10286 else\
10287 return false\
10288 end\
10289\
10290end\
10291\
10292ToggleMenu = function(self, name, x, y)\
10293 return self.Bedrock:ToggleMenu(name, self, x, y)\
10294end\
10295\
10296function OnUpdate(self, value)\
10297 if value == 'Z' then\
10298 self.Bedrock:ReorderObjects()\
10299 end\
10300end\
10301]],\
10302}\
10303local objects = {\
10304[\"Button\"] = [[\
10305BackgroundColour = colours.lightGrey\
10306ActiveBackgroundColour = colours.blue\
10307ActiveTextColour = colours.white\
10308TextColour = colours.black\
10309DisabledTextColour = colours.lightGrey\
10310Text = \"\"\
10311Toggle = nil\
10312Momentary = true\
10313AutoWidth = true\
10314Align = 'Center'\
10315Enabled = true\
10316\
10317OnUpdate = function(self, value)\
10318 if value == 'Text' and self.AutoWidth then\
10319 self.Width = #self.Text + 2\
10320 end\
10321end\
10322\
10323OnDraw = function(self, x, y)\
10324 local bg = self.BackgroundColour\
10325\
10326 if self.Toggle then\
10327 bg = self.ActiveBackgroundColour\
10328 end\
10329\
10330 local txt = self.TextColour\
10331 if self.Toggle then\
10332 txt = self.ActiveTextColour\
10333 end\
10334 if not self.Enabled then\
10335 txt = self.DisabledTextColour\
10336 end\
10337 Drawing.DrawBlankArea(x, y, self.Width, self.Height, bg)\
10338\
10339 local _x = 1\
10340 if self.Align == 'Right' then\
10341 _x = self.Width - #self.Text - 1\
10342 elseif self.Align == 'Center' then\
10343 _x = math.floor((self.Width - #self.Text) / 2)\
10344 end\
10345\
10346 Drawing.DrawCharacters(x + _x, y-1+math.ceil(self.Height/2), self.Text, txt, bg)\
10347end\
10348\
10349OnLoad = function(self)\
10350 if self.Toggle ~= nil then\
10351 self.Momentary = false\
10352 end\
10353end\
10354\
10355Click = function(self, event, side, x, y)\
10356 if self.Visible and not self.IgnoreClick and self.Enabled and event ~= 'mouse_scroll' then\
10357 if self.OnClick then\
10358 if self.Momentary then\
10359 self.Toggle = true\
10360 self.Bedrock:StartTimer(function()self.Toggle = false end,0.25)\
10361 elseif self.Toggle ~= nil then\
10362 self.Toggle = not self.Toggle\
10363 end\
10364\
10365 self:OnClick(event, side, x, y, self.Toggle)\
10366 else\
10367 self.Toggle = not self.Toggle\
10368 end\
10369 return true\
10370 else\
10371 return false\
10372 end\
10373end\
10374]],\
10375[\"CollectionView\"] = [[\
10376Inherit = 'ScrollView'\
10377UpdateDrawBlacklist = {['NeedsItemUpdate']=true}\
10378\
10379TextColour = colours.black\
10380BackgroundColour = colours.white\
10381Items = false\
10382NeedsItemUpdate = false\
10383SpacingX = 2\
10384SpacingY = 1\
10385\
10386OnDraw = function(self, x, y)\
10387 if self.NeedsItemUpdate then\
10388 self:UpdateItems()\
10389 self.NeedsItemUpdate = false\
10390 end\
10391 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
10392end\
10393\
10394local function MaxIcons(self, obj)\
10395 local x, y = 2, 1\
10396 if not obj.Height or not obj.Width then\
10397 error('You must provide each object\\'s height when adding to a CollectionView.')\
10398 end\
10399 local slotHeight = obj.Height + self.SpacingY\
10400 local slotWidth = obj.Width + self.SpacingX\
10401 local maxX = math.floor((self.Width - 2) / slotWidth)\
10402 return x, y, maxX, slotWidth, slotHeight\
10403end\
10404\
10405local function IconLocation(self, obj, i)\
10406 local x, y, maxX, slotWidth, slotHeight = MaxIcons(self, obj)\
10407 local rowPos = ((i - 1) % maxX)\
10408 local colPos = math.ceil(i / maxX) - 1\
10409 x = x + (slotWidth * rowPos)\
10410 y = y + colPos * slotHeight\
10411 return x, y\
10412end\
10413\
10414local function AddItem(self, v, i)\
10415 local toggle = false\
10416 if not self.CanSelect then\
10417 toggle = nil\
10418 end\
10419 local x, y = IconLocation(self, v, i)\
10420 local item = {\
10421 [\"X\"]=x,\
10422 [\"Y\"]=y,\
10423 [\"Name\"]=\"CollectionViewItem\",\
10424 [\"Type\"]=\"View\",\
10425 [\"TextColour\"]=self.TextColour,\
10426 [\"BackgroundColour\"]=0,\
10427 OnClick = function(itm)\
10428 if self.CanSelect then\
10429 for i2, _v in ipairs(self.Children) do\
10430 _v.Toggle = false\
10431 end\
10432 self.Selected = itm\
10433 end\
10434 end\
10435 }\
10436 for k, _v in pairs(v) do\
10437 item[k] = _v\
10438 end\
10439 self:AddObject(item)\
10440end\
10441\
10442\
10443UpdateItems = function(self)\
10444 self:RemoveAllObjects()\
10445 local groupMode = false\
10446 for k, v in pairs(self.Items) do\
10447 if type(k) == 'string' then\
10448 groupMode = true\
10449 break\
10450 end\
10451 end\
10452\
10453 for i, v in ipairs(self.Items) do\
10454 AddItem(self, v, i)\
10455 end\
10456 self:UpdateScroll()\
10457end\
10458\
10459OnUpdate = function(self, value)\
10460 if value == 'Items' then\
10461 self.NeedsItemUpdate = true\
10462 end\
10463end\
10464]],\
10465[\"ImageView\"] = [[\
10466Image = false\
10467\
10468OnDraw = function(self, x, y)\
10469 Drawing.DrawImage(x, y, self.Image, self.Width, self.Height)\
10470end\
10471\
10472OnLoad = function(self)\
10473 if self.Path and fs.exists(self.Path) then\
10474 self.Image = Drawing.LoadImage(self.Path)\
10475 end\
10476end\
10477\
10478OnUpdate = function(self, value)\
10479 if value == 'Path' then\
10480 if self.Path and fs.exists(self.Path) then\
10481 self.Image = Drawing.LoadImage(self.Path)\
10482 end\
10483 end\
10484end\
10485]],\
10486[\"Label\"] = [[\
10487TextColour = colours.black\
10488BackgroundColour = colours.transparent\
10489Text = \"\"\
10490AutoWidth = false\
10491Align = 'Left'\
10492\
10493local wrapText = function(text, maxWidth)\
10494 local lines = {''}\
10495 for word, space in text:gmatch('(%S+)(%s*)') do\
10496 local temp = lines[#lines] .. word .. space:gsub('\\n','')\
10497 if #temp > maxWidth then\
10498 table.insert(lines, '')\
10499 end\
10500 if space:find('\\n') then\
10501 lines[#lines] = lines[#lines] .. word\
10502 \
10503 space = space:gsub('\\n', function()\
10504 table.insert(lines, '')\
10505 return ''\
10506 end)\
10507 else\
10508 lines[#lines] = lines[#lines] .. word .. space\
10509 end\
10510 end\
10511 if #lines[1] == 0 then\
10512 table.remove(lines,1)\
10513 end\
10514 return lines\
10515end\
10516\
10517OnUpdate = function(self, value)\
10518 if value == 'Text' then\
10519 if self.AutoWidth then\
10520 self.Width = #self.Text\
10521 else\
10522 self.Height = #wrapText(self.Text, self.Width)\
10523 end\
10524 end\
10525end\
10526\
10527OnDraw = function(self, x, y)\
10528 for i, v in ipairs(wrapText(self.Text, self.Width)) do\
10529 local _x = 0\
10530 if self.Align == 'Right' then\
10531 _x = self.Width - #v\
10532 elseif self.Align == 'Center' then\
10533 _x = math.floor((self.Width - #v) / 2)\
10534 end\
10535 Drawing.DrawCharacters(x + _x, y + i - 1, v, self.TextColour, self.BackgroundColour)\
10536 end\
10537end\
10538]],\
10539[\"ListView\"] = [[\
10540Inherit = 'ScrollView'\
10541UpdateDrawBlacklist = {['NeedsItemUpdate']=true}\
10542\
10543TextColour = colours.black\
10544BackgroundColour = colours.white\
10545HeadingColour = colours.lightGrey\
10546SelectionBackgroundColour = colours.blue\
10547SelectionTextColour = colours.white\
10548Items = false\
10549CanSelect = false\
10550Selected = nil\
10551NeedsItemUpdate = false\
10552ItemMargin = 1\
10553HeadingMargin = 0\
10554TopMargin = 0\
10555\
10556OnDraw = function(self, x, y)\
10557 if self.NeedsItemUpdate then\
10558 self:UpdateItems()\
10559 end\
10560 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
10561end\
10562\
10563local function AddItem(self, v, x, y, group)\
10564 local toggle = false\
10565 if not self.CanSelect then\
10566 toggle = nil\
10567 elseif v.Selected then\
10568 toggle = true\
10569 end\
10570 local item = {\
10571 [\"Width\"]=self.Width,\
10572 [\"X\"]=x,\
10573 [\"Y\"]=y,\
10574 [\"Name\"]=\"ListViewItem\",\
10575 [\"Type\"]=\"Button\",\
10576 [\"TextColour\"]=self.TextColour,\
10577 [\"BackgroundColour\"]=0,\
10578 [\"ActiveTextColour\"]=self.SelectionTextColour,\
10579 [\"ActiveBackgroundColour\"]=self.SelectionBackgroundColour,\
10580 [\"Align\"]='Left',\
10581 [\"Toggle\"]=toggle,\
10582 [\"Group\"]=group,\
10583 OnClick = function(itm)\
10584 if self.CanSelect then\
10585 self:SelectItem(itm)\
10586 elseif self.OnSelect then\
10587 self:OnSelect(itm.Text)\
10588 end\
10589 end\
10590 }\
10591 if type(v) == 'table' then\
10592 for k, _v in pairs(v) do\
10593 item[k] = _v\
10594 end\
10595 else\
10596 item.Text = v\
10597 end\
10598 \
10599 local itm = self:AddObject(item)\
10600 if v.Selected then\
10601 self:SelectItem(itm)\
10602 end\
10603end\
10604\
10605UpdateItems = function(self)\
10606 if not self.Items or type(self.Items) ~= 'table' then\
10607 self.Items = {}\
10608 end\
10609 self.Selected = nil\
10610 self:RemoveAllObjects()\
10611 local groupMode = false\
10612 for k, v in pairs(self.Items) do\
10613 if type(k) == 'string' then\
10614 groupMode = true\
10615 break\
10616 end\
10617 end\
10618\
10619 if not groupMode then\
10620 for i, v in ipairs(self.Items) do\
10621 AddItem(self, v, self.ItemMargin, i)\
10622 end\
10623 else\
10624 local y = self.TopMargin\
10625 for k, v in pairs(self.Items) do\
10626 y = y + 1\
10627 AddItem(self, {Text = k, TextColour = self.HeadingColour, IgnoreClick = true}, self.HeadingMargin, y)\
10628 for i, _v in ipairs(v) do\
10629 y = y + 1\
10630 AddItem(self, _v, 1, y, k)\
10631 end\
10632 y = y + 1\
10633 end\
10634 end\
10635 self:UpdateScroll()\
10636 self.NeedsItemUpdate = false\
10637end\
10638\
10639OnKeyChar = function(self, event, keychar)\
10640 if keychar == keys.up or keychar == keys.down then\
10641 local n = self:GetIndex(self.Selected)\
10642 if keychar == keys.up then\
10643 n = n - 1\
10644 else\
10645 n = n + 1\
10646 end\
10647 local new = self:GetNth(n)\
10648 if new then\
10649 self:SelectItem(new)\
10650 end\
10651 elseif keychar == keys.enter and self.Selected then\
10652 self.Selected:Click('mouse_click', 1, 1, 1)\
10653 end\
10654end\
10655\
10656--returns the index/'n' of the given item\
10657GetIndex = function(self, obj)\
10658 local n = 1\
10659 for i, v in ipairs(self.Children) do\
10660 if not v.IgnoreClick then\
10661 if obj == v then\
10662 return n\
10663 end\
10664 n = n + 1\
10665 end\
10666 end\
10667end\
10668\
10669--gets the 'nth' list item (does not include headings)\
10670GetNth = function(self, n)\
10671 local _n = 1\
10672 for i, v in ipairs(self.Children) do\
10673 if not v.IgnoreClick then\
10674 if n == _n then\
10675 return v\
10676 end\
10677 _n = _n + 1\
10678 end\
10679 end\
10680end\
10681\
10682SelectItem = function(self, item)\
10683 for i, v in ipairs(self.Children) do\
10684 v.Toggle = false\
10685 end\
10686 self.Selected = item\
10687 item.Toggle = true\
10688 if self.OnSelect then\
10689 self:OnSelect(item.Text)\
10690 end\
10691end\
10692\
10693OnUpdate = function(self, value)\
10694 if value == 'Items' then\
10695 self.NeedsItemUpdate = true\
10696 end\
10697end\
10698]],\
10699[\"Menu\"] = [[\
10700Inherit = 'View'\
10701\
10702TextColour = colours.black\
10703BackgroundColour = colours.white\
10704HideTop = false\
10705Prepared = false\
10706\
10707OnDraw = function(self, x, y)\
10708 Drawing.IgnoreConstraint = true\
10709 Drawing.DrawBlankArea(x + 1, y + (self.HideTop and 0 or 1), self.Width, self.Height + (self.HideTop and 1 or 0), colours.grey)\
10710 Drawing.IgnoreConstraint = false\
10711 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
10712end\
10713\
10714OnLoad = function(self)\
10715 local owner = self.Owner\
10716 if type(owner) == 'string' then\
10717 owner = self.Bedrock:GetObject(self.Owner)\
10718 end\
10719\
10720 if owner then\
10721 if self.X == 0 and self.Y == 0 then\
10722 local pos = owner:GetPosition()\
10723 self.X = pos.X\
10724 self.Y = pos.Y + owner.Height\
10725 end\
10726 self.Owner = owner\
10727 else\
10728 self.Owner = nil\
10729 end\
10730end\
10731\
10732OnUpdate = function(self, value)\
10733 if value == 'Children' then\
10734 self.Height = #self.Children + 1 + (self.HideTop and 0 or 1)\
10735 if not self.BaseY then\
10736 self.BaseY = self.Y\
10737 end\
10738 if #self.Children > 0 and self.Children[1].Type == 'Button' then\
10739 self.Width = self.Bedrock.Helpers.LongestString(self.Children, 'Text') + 2\
10740 for i, v in ipairs(self.Children) do\
10741 if v.TextColour then\
10742 v.TextColour = self.TextColour\
10743 end\
10744 if v.BackgroundColour then\
10745 v.BackgroundColour = colours.transparent\
10746 end\
10747 if v.Colour then\
10748 v.Colour = colours.lightGrey\
10749 end\
10750 v.Align = 'Left'\
10751 v.X = 1\
10752 v.Y = i + (self.HideTop and 0 or 1)\
10753 v.Width = self.Width\
10754 v.Height = 1\
10755 end\
10756 elseif #self.Children > 0 and self.Children[1].Type == 'MenuItem' then\
10757 local width = 1\
10758 for i, v in ipairs(self.Children) do\
10759 if v.Width > width then\
10760 width = v.Width\
10761 end\
10762 end\
10763 self.Width = width\
10764 for i, v in ipairs(self.Children) do\
10765 if v.TextColour then\
10766 v.TextColour = self.TextColour\
10767 end\
10768 if v.Colour then\
10769 v.Colour = colours.lightGrey\
10770 end\
10771 v.X = 1\
10772 v.Y = i + (self.HideTop and 0 or 1)\
10773 v.Width = width\
10774 v.Height = 1\
10775 end\
10776 end\
10777\
10778 self.Y = self.BaseY\
10779 local pos = self:GetPosition()\
10780 if pos.Y + self.Height + 1 > Drawing.Screen.Height then\
10781 self.Y = self.BaseY - ((self.Height + pos.Y) - Drawing.Screen.Height)\
10782 end\
10783 \
10784 if pos.X + self.Width > Drawing.Screen.Width then\
10785 self.X = Drawing.Screen.Width - self.Width\
10786 end\
10787 end\
10788end\
10789\
10790Close = function(self, isBedrockCall)\
10791 self.Bedrock.Menu = nil\
10792 if not self.Prepared then\
10793 self.Parent:RemoveObject(self)\
10794 else\
10795 self.Visible = false\
10796 end\
10797\
10798 if self.Owner and self.Owner.Toggle then\
10799 self.Owner.Toggle = false\
10800 end\
10801 self.Parent:ForceDraw()\
10802 self = nil\
10803end\
10804\
10805OnChildClick = function(self, child, event, side, x, y)\
10806 self:Close()\
10807end\
10808]],\
10809[\"MenuItem\"] = [[\
10810BackgroundColour = colours.white\
10811TextColour = colours.black\
10812DisabledTextColour = colours.lightGrey\
10813ShortcutTextColour = colours.grey\
10814Text = \"\"\
10815Enabled = true\
10816Shortcut = nil\
10817ShortcutPadding = 2\
10818ShortcutName = nil\
10819\
10820OnUpdate = function(self, value)\
10821 if value == 'Text' then\
10822 if self.Shortcut then\
10823 self.Width = #self.Text + 2 + self.ShortcutPadding + #self.Shortcut\
10824 else\
10825 self.Width = #self.Text + 2\
10826 end\
10827 elseif value == 'OnClick' then\
10828 self:RegisterShortcut()\
10829 end\
10830end\
10831\
10832OnDraw = function(self, x, y)\
10833 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
10834\
10835 local txt = self.TextColour\
10836 if not self.Enabled then\
10837 txt = self.DisabledTextColour\
10838 end\
10839 Drawing.DrawCharacters(x + 1, y, self.Text, txt, colours.transparent)\
10840\
10841 if self.Shortcut then\
10842 local shrt = self.ShortcutTextColour\
10843 if not self.Enabled then\
10844 shrt = self.DisabledTextColour\
10845 end\
10846 Drawing.DrawCharacters(x + self.Width - #self.Shortcut - 1, y, self.Shortcut, shrt, colours.transparent)\
10847 end\
10848end\
10849\
10850ParseShortcut = function(self)\
10851 local special = {\
10852 ['^'] = keys.leftShift,\
10853 ['<'] = keys.delete,\
10854 ['>'] = keys.delete,\
10855 ['#'] = keys.leftCtrl,\
10856 ['~'] = keys.leftAlt,\
10857 }\
10858\
10859 local keys = {}\
10860 for i = 1, #self.Shortcut do\
10861 local c = self.Shortcut:sub(i,i)\
10862 table.insert(keys, special[c] or c:lower())\
10863 end\
10864 return keys\
10865end\
10866\
10867RegisterShortcut = function(self)\
10868 if self.Shortcut then\
10869 self.Shortcut = self.Shortcut:upper()\
10870 self.ShortcutName = self.Bedrock:RegisterKeyboardShortcut(self:ParseShortcut(), function()\
10871 if self.OnClick and self.Enabled then\
10872 if self.Parent.Owner then\
10873 self.Parent:Close()\
10874 self.Parent.Owner.Toggle = true\
10875 self.Bedrock:StartTimer(function()\
10876 self.Parent.Owner.Toggle = false\
10877 end, 0.3)\
10878 end\
10879 return self:OnClick('keyboard_shortcut', 1, 1, 1)\
10880 else\
10881 return false\
10882 end\
10883 end)\
10884 end\
10885end\
10886\
10887OnRemove = function(self)\
10888 if self.ShortcutName then\
10889 self.Bedrock:UnregisterKeyboardShortcut(self.ShortcutName)\
10890 end\
10891end\
10892\
10893OnLoad = function(self)\
10894 if self.OnClick ~= nil then\
10895 self:RegisterShortcut()\
10896 end\
10897 -- self:OnUpdate('Text')\
10898end\
10899]],\
10900[\"NumberBox\"] = [[\
10901Inherit = 'View'\
10902\
10903Value = 1\
10904Minimum = 1\
10905Maximum = 99\
10906BackgroundColour = colours.lightGrey\
10907TextBoxTimer = nil\
10908Width = 7\
10909\
10910OnLoad = function(self)\
10911 self:AddObject({\
10912 X = self.Width - 1,\
10913 Y = 1,\
10914 Width = 1,\
10915 AutoWidth = false,\
10916 Text = '-',\
10917 Type = 'Button',\
10918 Name = 'AddButton',\
10919 BackgroundColour = colours.transparent,\
10920 OnClick = function()\
10921 self:ShiftValue(-1)\
10922 end\
10923 })\
10924\
10925 self:AddObject({\
10926 X = self.Width,\
10927 Y = 1,\
10928 Width = 1,\
10929 AutoWidth = false,\
10930 Text = '+',\
10931 Type = 'Button',\
10932 Name = 'SubButton',\
10933 BackgroundColour = colours.transparent,\
10934 OnClick = function()\
10935 self:ShiftValue(1)\
10936 end\
10937 })\
10938\
10939 self:AddObject({\
10940 X = 1,\
10941 Y = 1,\
10942 Width = self.Width - 2,\
10943 Text = tostring(self.Value),\
10944 Align = 'Center',\
10945 Type = 'TextBox',\
10946 BackgroundColour = colours.transparent,\
10947 OnChange = function(_self, event, keychar)\
10948 if keychar == keys.enter then\
10949 self:SetValue(tonumber(_self.Text))\
10950 self.TextBoxTimer = nil\
10951 end\
10952 if self.TextBoxTimer then\
10953 self.Bedrock:StopTimer(self.TextBoxTimer)\
10954 end\
10955\
10956 self.TextBoxTimer = self.Bedrock:StartTimer(function(_, timer)\
10957 if timer and timer == self.TextBoxTimer then\
10958 self:SetValue(tonumber(_self.Text))\
10959 self.TextBoxTimer = nil\
10960 end\
10961 end, 2)\
10962 end\
10963 })\
10964end\
10965\
10966OnScroll = function(self, event, dir, x, y)\
10967 self:ShiftValue(-dir)\
10968end\
10969\
10970ShiftValue = function(self, delta)\
10971 local val = tonumber(self:GetObject('TextBox').Text) or self.Minimum\
10972 self:SetValue(val + delta)\
10973end\
10974\
10975SetValue = function(self, newValue)\
10976 newValue = newValue or 0\
10977 if self.Maximum and newValue > self.Maximum then\
10978 newValue = self.Maximum\
10979 elseif self.Minimum and newValue < self.Minimum then\
10980 newValue = self.Minimum\
10981 end\
10982 self.Value = newValue\
10983 if self.OnChange then\
10984 self:OnChange()\
10985 end\
10986end\
10987\
10988OnUpdate = function(self, value)\
10989 if value == 'Value' then\
10990 local textbox = self:GetObject('TextBox')\
10991 if textbox then\
10992 textbox.Text = tostring(self.Value)\
10993 end\
10994 end\
10995end\
10996]],\
10997[\"ProgressBar\"] = [[\
10998BackgroundColour = colours.lightGrey\
10999BarColour = colours.blue\
11000TextColour = colours.white\
11001ShowText = false\
11002Value = 0\
11003Maximum = 1\
11004Indeterminate = false\
11005AnimationStep = 0\
11006\
11007OnDraw = function(self, x, y)\
11008 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
11009\
11010 -- if self.Indeterminate then\
11011 -- for i = 1, self.Width do\
11012 -- local s = x + i - 1 + self.AnimationStep\
11013 -- if s % 4 == 1 or s % 4 == 2 then\
11014 -- Drawing.DrawBlankArea(s, y, 1, self.Height, self.BarColour)\
11015 -- end\
11016 -- end\
11017 -- self.AnimationStep = self.AnimationStep + 1\
11018 -- if self.AnimationStep >= 4 then\
11019 -- self.AnimationStep = 0\
11020 -- end\
11021 -- self.Bedrock:StartTimer(function()\
11022 -- self:Draw()\
11023 -- end, 0.25)\
11024 -- else\
11025 local values = self.Value\
11026 local barColours = self.BarColour\
11027 if type(values) == 'number' then\
11028 values = {values}\
11029 end\
11030 if type(barColours) == 'number' then\
11031 barColours = {barColours}\
11032 end\
11033 local total = 0\
11034 local _x = x\
11035 for i, v in ipairs(values) do\
11036 local width = self.Bedrock.Helpers.Round((v / self.Maximum) * self.Width)\
11037 total = total + v\
11038 Drawing.DrawBlankArea(_x, y, width, self.Height, barColours[((i-1)%#barColours)+1])\
11039 _x = _x + width\
11040 end\
11041\
11042 if self.ShowText then\
11043 local text = self.Bedrock.Helpers.Round((total / self.Maximum) * 100) .. '%'\
11044 Drawing.DrawCharactersCenter(x, y, self.Width, self.Height, text, self.TextColour, colours.transparent)\
11045 end\
11046 -- end\
11047end\
11048]],\
11049[\"ScrollBar\"] = [[\
11050BackgroundColour = colours.lightGrey\
11051BarColour = colours.lightBlue\
11052Scroll = 0\
11053MaxScroll = 0\
11054ClickPoint = nil\
11055Fixed = true\
11056\
11057OnUpdate = function(self, value)\
11058 if value == 'Text' and self.AutoWidth then\
11059 self.Width = #self.Text + 2\
11060 end\
11061end\
11062\
11063OnDraw = function(self, x, y)\
11064 local barHeight = self.Height * (self.Height / (self.Height + self.MaxScroll))\
11065 if barHeight < 3 then\
11066 barHeight = 3\
11067 end\
11068 local percentage = (self.Scroll/self.MaxScroll)\
11069\
11070 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
11071 Drawing.DrawBlankArea(x, y + math.ceil(self.Height*percentage - barHeight*percentage), self.Width, barHeight, self.BarColour)\
11072end\
11073\
11074OnScroll = function(self, event, direction, x, y)\
11075 if event == 'mouse_scroll' then\
11076 direction = self.Bedrock.Helpers.Round(direction * 3)\
11077 end\
11078 if self.Scroll < 0 or self.Scroll > self.MaxScroll then\
11079 return false\
11080 end\
11081 local old = self.Scroll\
11082 self.Scroll = self.Bedrock.Helpers.Round(self.Scroll + direction)\
11083 if self.Scroll < 0 then\
11084 self.Scroll = 0\
11085 elseif self.Scroll > self.MaxScroll then\
11086 self.Scroll = self.MaxScroll\
11087 end\
11088\
11089 if self.Scroll ~= old and self.OnChange then\
11090 self:OnChange()\
11091 end\
11092end\
11093\
11094OnClick = function(self, event, side, x, y)\
11095 if event == 'mouse_click' then\
11096 self.ClickPoint = y\
11097 else\
11098 if self.ClickPoint then\
11099 local gapHeight = self.Height - (self.Height * (self.Height / (self.Height + self.MaxScroll)))\
11100 local barHeight = self.Height * (self.Height / (self.Height + self.MaxScroll))\
11101 --local delta = (self.Height + self.MaxScroll) * ((y - self.ClickPoint) / barHeight)\
11102 local delta = ((y - self.ClickPoint)/gapHeight)*self.MaxScroll\
11103 --l(((y - self.ClickPoint)/gapHeight))\
11104 --l(delta)\
11105 self.Scroll = self.Bedrock.Helpers.Round(delta)\
11106 --l(self.Scroll)\
11107 --l('----')\
11108 if self.Scroll < 0 then\
11109 self.Scroll = 0\
11110 elseif self.Scroll > self.MaxScroll then\
11111 self.Scroll = self.MaxScroll\
11112 end\
11113 if self.OnChange then\
11114 self:OnChange()\
11115 end\
11116 end\
11117 end\
11118\
11119 local relScroll = self.MaxScroll * ((y-1)/self.Height)\
11120 if y == self.Height then\
11121 relScroll = self.MaxScroll\
11122 end\
11123 self.Scroll = self.Bedrock.Helpers.Round(relScroll)\
11124\
11125\
11126end\
11127\
11128OnDrag = OnClick\
11129]],\
11130[\"ScrollView\"] = [[\
11131Inherit = 'View'\
11132ChildOffset = false\
11133ContentWidth = 0\
11134ContentHeight = 0\
11135ScrollBarBackgroundColour = colours.lightGrey\
11136ScrollBarColour = colours.lightBlue\
11137\
11138CalculateContentSize = function(self)\
11139 local function calculateObject(obj)\
11140 local pos = obj:GetPosition()\
11141 local x2 = pos.X + obj.Width - 1\
11142 local y2 = pos.Y + obj.Height - 1\
11143 if obj.Children then\
11144 for i, child in ipairs(obj.Children) do\
11145 local _x2, _y2 = calculateObject(child)\
11146 if _x2 > x2 then\
11147 x2 = _x2\
11148 end\
11149 if _y2 > y2 then\
11150 y2 = _y2\
11151 end\
11152 end\
11153 end\
11154 return x2, y2\
11155 end\
11156\
11157 local pos = self:GetPosition()\
11158 local x2, y2 = calculateObject(self)\
11159 self.ContentWidth = x2 - pos.X + 1\
11160 self.ContentHeight = y2 - pos.Y + 1\
11161end\
11162\
11163UpdateScroll = function(self)\
11164 self.ChildOffset.Y = 0\
11165 self:CalculateContentSize()\
11166 if self.ContentHeight > self.Height then\
11167 if not self:GetObject('ScrollViewScrollBar') then\
11168 local _scrollBar = self:AddObject({\
11169 [\"Name\"] = 'ScrollViewScrollBar',\
11170 [\"Type\"] = 'ScrollBar',\
11171 [\"X\"] = self.Width,\
11172 [\"Y\"] = 1,\
11173 [\"Width\"] = 1,\
11174 [\"Height\"] = self.Height,\
11175 [\"BackgroundColour\"] = self.ScrollBarBackgroundColour,\
11176 [\"BarColour\"] = self.ScrollBarColour,\
11177 [\"Z\"]=999\
11178 })\
11179\
11180 _scrollBar.OnChange = function(scrollBar)\
11181 self.ChildOffset.Y = -scrollBar.Scroll\
11182 for i, child in ipairs(self.Children) do\
11183 child:ForceDraw()\
11184 end\
11185 end\
11186 end\
11187\
11188 if self:GetObject('ScrollViewScrollBar') then\
11189 self:GetObject('ScrollViewScrollBar').MaxScroll = self.ContentHeight - self.Height\
11190 end\
11191 else\
11192 self:RemoveObject('ScrollViewScrollBar')\
11193 end\
11194end\
11195\
11196OnScroll = function(self, event, direction, x, y)\
11197 if self:GetObject('ScrollViewScrollBar') then\
11198 self:GetObject('ScrollViewScrollBar'):OnScroll(event, direction, x, y)\
11199 end\
11200end\
11201\
11202OnLoad = function(self)\
11203 if not self.ChildOffset or not self.ChildOffset.X or not self.ChildOffset.Y then\
11204 self.ChildOffset = {X = 0, Y = 0}\
11205 end\
11206 self:UpdateScroll()\
11207end\
11208]],\
11209[\"SecureTextBox\"] = [[\
11210Inherit = 'TextBox'\
11211MaskCharacter = '*'\
11212\
11213OnDraw = function(self, x, y)\
11214 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
11215 if self.CursorPos > #self.Text then\
11216 self.CursorPos = #self.Text\
11217 elseif self.CursorPos < 0 then\
11218 self.CursorPos = 0\
11219 end\
11220 local text = ''\
11221\
11222 for i = 1, #self.Text do\
11223 text = text .. self.MaskCharacter\
11224 end\
11225\
11226 if self.Bedrock:GetActiveObject() == self then\
11227 if #text > (self.Width - 2) then\
11228 text = text:sub(#text-(self.Width - 3))\
11229 self.Bedrock.CursorPos = {x + 1 + self.Width-2, y}\
11230 else\
11231 self.Bedrock.CursorPos = {x + 1 + self.CursorPos, y}\
11232 end\
11233 self.Bedrock.CursorColour = self.TextColour\
11234 end\
11235\
11236 if #tostring(text) == 0 then\
11237 Drawing.DrawCharacters(x + 1, y, self.Placeholder, self.PlaceholderTextColour, self.BackgroundColour)\
11238 else\
11239 if not self.Selected then\
11240 Drawing.DrawCharacters(x + 1, y, text, self.TextColour, self.BackgroundColour)\
11241 else\
11242 for i = 1, #text do\
11243 local char = text:sub(i, i)\
11244 local textColour = self.TextColour\
11245 local backgroundColour = self.BackgroundColour\
11246 if i > self.DragStart and i - 1 <= self.CursorPos then\
11247 textColour = self.SelectedTextColour\
11248 backgroundColour = self.SelectedBackgroundColour\
11249 end\
11250 Drawing.DrawCharacters(x + i, y, char, textColour, backgroundColour)\
11251 end\
11252 end\
11253 end\
11254end\
11255]],\
11256[\"Separator\"] = [[\
11257Colour = colours.grey\
11258\
11259OnDraw = function(self, x, y)\
11260 local char = \"|\"\
11261 if self.Width > self.Height then\
11262 char = '-'\
11263 end\
11264 Drawing.DrawArea(x, y, self.Width, self.Height, char, self.Colour, colours.transparent)\
11265end\
11266]],\
11267[\"TextBox\"] = [[\
11268BackgroundColour = colours.lightGrey\
11269SelectedBackgroundColour = colours.blue\
11270SelectedTextColour = colours.white\
11271TextColour = colours.black\
11272PlaceholderTextColour = colours.grey\
11273Placeholder = ''\
11274AutoWidth = false\
11275Text = \"\"\
11276CursorPos = nil\
11277Numerical = false\
11278DragStart = nil\
11279Selected = false\
11280SelectOnClick = false\
11281ActualDragStart = nil\
11282\
11283OnDraw = function(self, x, y)\
11284 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
11285 if self.CursorPos > #self.Text then\
11286 self.CursorPos = #self.Text\
11287 elseif self.CursorPos < 0 then\
11288 self.CursorPos = 0\
11289 end\
11290 local text = self.Text\
11291 local offset = self:TextOffset()\
11292 if #text > (self.Width - 2) then\
11293 text = text:sub(offset+1, offset + self.Width - 2)\
11294 -- self.Bedrock.CursorPos = {x + 1 + self.Width-2, y}\
11295 -- else\
11296 end\
11297 if self.Bedrock:GetActiveObject() == self then\
11298 self.Bedrock.CursorPos = {x + 1 + self.CursorPos - offset, y}\
11299 self.Bedrock.CursorColour = self.TextColour\
11300 else\
11301 self.Selected = false\
11302 end\
11303\
11304 if #tostring(text) == 0 then\
11305 Drawing.DrawCharacters(x + 1, y, self.Placeholder, self.PlaceholderTextColour, self.BackgroundColour)\
11306 else\
11307 if not self.Selected then\
11308 Drawing.DrawCharacters(x + 1, y, text, self.TextColour, self.BackgroundColour)\
11309 else\
11310 local startPos = self.DragStart - offset\
11311 local endPos = self.CursorPos - offset\
11312 if startPos > endPos then\
11313 startPos = self.CursorPos - offset\
11314 endPos = self.DragStart - offset\
11315 end\
11316 for i = 1, #text do\
11317 local char = text:sub(i, i)\
11318 local textColour = self.TextColour\
11319 local backgroundColour = self.BackgroundColour\
11320\
11321 if i > startPos and i - 1 <= endPos then\
11322 textColour = self.SelectedTextColour\
11323 backgroundColour = self.SelectedBackgroundColour\
11324 end\
11325 Drawing.DrawCharacters(x + i, y, char, textColour, backgroundColour)\
11326 end\
11327 end\
11328 end\
11329end\
11330\
11331TextOffset = function(self)\
11332 if #self.Text < (self.Width - 2) then\
11333 return 0\
11334 elseif self.Bedrock:GetActiveObject() ~= self then\
11335 return 0\
11336 else\
11337 local textWidth = (self.Width - 2)\
11338 local offset = self.CursorPos - textWidth\
11339 if offset < 0 then\
11340 offset = 0\
11341 end\
11342 return offset\
11343 end\
11344end\
11345\
11346OnLoad = function(self)\
11347 if not self.CursorPos then\
11348 self.CursorPos = #self.Text\
11349 end\
11350end\
11351\
11352OnClick = function(self, event, side, x, y)\
11353 if self.Bedrock:GetActiveObject() ~= self and self.SelectOnClick then\
11354 self.CursorPos = #self.Text - 1\
11355 self.DragStart = 0\
11356 self.ActualDragStart = x - 2 + self:TextOffset()\
11357 self.Selected = true\
11358 else\
11359 self.CursorPos = x - 2 + self:TextOffset()\
11360 self.DragStart = self.CursorPos\
11361 self.Selected = false\
11362 end\
11363 self.Bedrock:SetActiveObject(self)\
11364end\
11365\
11366OnDrag = function(self, event, side, x, y)\
11367 self.CursorPos = x - 2 + self:TextOffset()\
11368 if self.ActualDragStart then\
11369 self.DragStart = self.ActualDragStart\
11370 self.ActualDragStart = nil\
11371 end\
11372 if self.DragStart then\
11373 self.Selected = true\
11374 end\
11375end\
11376\
11377OnKeyChar = function(self, event, keychar)\
11378 local deleteSelected = function()\
11379 if self.Selected then\
11380 local startPos = self.DragStart\
11381 local endPos = self.CursorPos\
11382 if startPos > endPos then\
11383 startPos = self.CursorPos\
11384 endPos = self.DragStart\
11385 end\
11386 self.Text = self.Text:sub(1, startPos) .. self.Text:sub(endPos + 2)\
11387 self.CursorPos = startPos\
11388 self.DragStart = nil\
11389 self.Selected = false\
11390 return true\
11391 end\
11392 end\
11393\
11394 if event == 'char' then\
11395 deleteSelected()\
11396 if self.Numerical then\
11397 keychar = tostring(tonumber(keychar))\
11398 end\
11399 if keychar == 'nil' then\
11400 return\
11401 end\
11402 self.Text = string.sub(self.Text, 1, self.CursorPos ) .. keychar .. string.sub( self.Text, self.CursorPos + 1 )\
11403 if self.Numerical then\
11404 self.Text = tostring(tonumber(self.Text))\
11405 if self.Text == 'nil' then\
11406 self.Text = '1'\
11407 end\
11408 end\
11409 \
11410 self.CursorPos = self.CursorPos + 1\
11411 if self.OnChange then\
11412 self:OnChange(event, keychar)\
11413 end\
11414 return false\
11415 elseif event == 'key' then\
11416 if keychar == keys.enter then\
11417 if self.OnChange then\
11418 self:OnChange(event, keychar)\
11419 end\
11420 elseif keychar == keys.left then\
11421 -- Left\
11422 if self.CursorPos > 0 then\
11423 if self.Selected then\
11424 self.CursorPos = self.DragStart\
11425 self.DragStart = nil\
11426 self.Selected = false\
11427 else\
11428 self.CursorPos = self.CursorPos - 1\
11429 end\
11430 if self.OnChange then\
11431 self:OnChange(event, keychar)\
11432 end\
11433 end\
11434 \
11435 elseif keychar == keys.right then\
11436 -- Right \
11437 if self.CursorPos < string.len(self.Text) then\
11438 if self.Selected then\
11439 self.CursorPos = self.CursorPos\
11440 self.DragStart = nil\
11441 self.Selected = false\
11442 else\
11443 self.CursorPos = self.CursorPos + 1\
11444 end\
11445 if self.OnChange then\
11446 self:OnChange(event, keychar)\
11447 end\
11448 end\
11449 \
11450 elseif keychar == keys.backspace then\
11451 -- Backspace\
11452 if not deleteSelected() and self.CursorPos > 0 then\
11453 self.Text = string.sub( self.Text, 1, self.CursorPos - 1 ) .. string.sub( self.Text, self.CursorPos + 1 )\
11454 self.CursorPos = self.CursorPos - 1 \
11455 if self.Numerical then\
11456 self.Text = tostring(tonumber(self.Text))\
11457 if self.Text == 'nil' then\
11458 self.Text = '1'\
11459 end\
11460 end\
11461 if self.OnChange then\
11462 self:OnChange(event, keychar)\
11463 end\
11464 end\
11465 elseif keychar == keys.home then\
11466 -- Home\
11467 self.CursorPos = 0\
11468 if self.OnChange then\
11469 self:OnChange(event, keychar)\
11470 end\
11471 elseif keychar == keys.delete then\
11472 if not deleteSelected() and self.CursorPos < string.len(self.Text) then\
11473 self.Text = string.sub( self.Text, 1, self.CursorPos ) .. string.sub( self.Text, self.CursorPos + 2 ) \
11474 if self.Numerical then\
11475 self.Text = tostring(tonumber(self.Text))\
11476 if self.Text == 'nil' then\
11477 self.Text = '1'\
11478 end\
11479 end\
11480 if self.OnChange then\
11481 self:OnChange(keychar)\
11482 end\
11483 end\
11484 elseif keychar == keys[\"end\"] then\
11485 -- End\
11486 self.CursorPos = string.len(self.Text)\
11487 else\
11488 if self.OnChange then\
11489 self:OnChange(event, keychar)\
11490 end\
11491 return false\
11492 end\
11493 end\
11494end\
11495]],\
11496[\"View\"] = [[\
11497BackgroundColour = colours.transparent\
11498Children = {}\
11499\
11500OnDraw = function(self, x, y)\
11501 if self.BackgroundColour then\
11502 Drawing.DrawBlankArea(x, y, self.Width, self.Height, self.BackgroundColour)\
11503 end\
11504end\
11505\
11506OnInitialise = function(self)\
11507 self.Children = {}\
11508end\
11509\
11510InitialiseFile = function(self, bedrock, file, name)\
11511 local _new = {}\
11512 _new.X = 1\
11513 _new.Y = 1\
11514 _new.Width = Drawing.Screen.Width\
11515 _new.Height = Drawing.Screen.Height\
11516 _new.BackgroundColour = file.BackgroundColour\
11517 _new.Name = name\
11518 _new.Children = {}\
11519 _new.Bedrock = bedrock\
11520 local new = self:Initialise(_new)\
11521 for i, obj in ipairs(file.Children) do\
11522 local view = bedrock:ObjectFromFile(obj, new)\
11523 if not view.Z then\
11524 view.Z = i\
11525 end\
11526 view.Parent = new\
11527 table.insert(new.Children, view)\
11528 end\
11529 return new\
11530end\
11531\
11532function CheckClick(self, object, x, y)\
11533 local offset = {X = 0, Y = 0}\
11534 if not object.Fixed and self.ChildOffset then\
11535 offset = self.ChildOffset\
11536 end\
11537 if object.X + offset.X <= x and object.Y + offset.Y <= y and object.X + offset.X + object.Width > x and object.Y + offset.Y + object.Height > y then\
11538 return true\
11539 end\
11540end\
11541\
11542function DoClick(self, object, event, side, x, y)\
11543 if object then\
11544 if self:CheckClick(object, x, y) then\
11545 local offset = {X = 0, Y = 0}\
11546 if not object.Fixed and self.ChildOffset then\
11547 offset = self.ChildOffset\
11548 end\
11549 return object:Click(event, side, x - object.X - offset.X + 1, y - object.Y + 1 - offset.Y)\
11550 end\
11551 end \
11552end\
11553\
11554Click = function(self, event, side, x, y, z)\
11555 if self.Visible and not self.IgnoreClick then\
11556 for i = #self.Children, 1, -1 do --children are ordered from smallest Z to highest, so this is done in reverse\
11557 local child = self.Children[i]\
11558 if self:DoClick(child, event, side, x, y) then\
11559 if self.OnChildClick then\
11560 self:OnChildClick(child, event, side, x, y)\
11561 end\
11562 return true\
11563 end\
11564 end\
11565 if event == 'mouse_click' and self.OnClick and self:OnClick(event, side, x, y) ~= false then\
11566 return true\
11567 elseif event == 'mouse_drag' and self.OnDrag and self:OnDrag(event, side, x, y) ~= false then\
11568 return true\
11569 elseif event == 'mouse_scroll' and self.OnScroll and self:OnScroll(event, side, x, y) ~= false then\
11570 return true\
11571 else\
11572 return false\
11573 end\
11574 else\
11575 return false\
11576 end\
11577end\
11578\
11579OnRemove = function(self)\
11580 if self == self.Bedrock:GetActiveObject() then\
11581 self.Bedrock:SetActiveObject()\
11582 end\
11583 for i, child in ipairs(self.Children) do\
11584 child:OnRemove()\
11585 end\
11586end\
11587\
11588local function findObjectNamed(view, name, minI)\
11589 local minI = minI or 0\
11590 if view and view.Children then\
11591 for i, child in ipairs(view.Children) do\
11592 if child.Name == name or child == name then\
11593 return child, i, view\
11594 elseif child.Children then\
11595 local found, index, foundView = findObjectNamed(child, name)\
11596 if found and minI <= index then\
11597 return found, index, foundView\
11598 end\
11599 end\
11600 end\
11601 end\
11602end\
11603\
11604function ReorderObjects(self)\
11605 if self.Children then\
11606 table.sort(self.Children, function(a,b)\
11607 return a.Z < b.Z \
11608 end)\
11609 for i, v in ipairs(self.Children) do\
11610 if v.ReorderObjects then\
11611 v:ReorderObjects()\
11612 end\
11613 end\
11614 end\
11615end\
11616\
11617function AddObject(self, info, extra, first)\
11618 if type(info) == 'string' then\
11619 local h = fs.open(self.Bedrock.ViewPath..info..'.view', 'r')\
11620 if h then\
11621 info = textutils.unserialize(h.readAll())\
11622 h.close()\
11623 else\
11624 error('Error in opening object: '..info)\
11625 end\
11626 end\
11627\
11628 if extra then\
11629 for k, v in pairs(extra) do\
11630 if v then\
11631 info[k] = v\
11632 end\
11633 end\
11634 end\
11635\
11636 local view = self.Bedrock:ObjectFromFile(info, self)\
11637 if not view.Z then\
11638 if first then\
11639 view.Z = 1\
11640 else\
11641 view.Z = #self.Children + 1\
11642 end\
11643 end\
11644 \
11645 if first then\
11646 table.insert(self.Children, 1, view)\
11647 else\
11648 table.insert(self.Children, view)\
11649 end\
11650 if self.Bedrock.View then\
11651 self.Bedrock:ReorderObjects()\
11652 end\
11653 self:ForceDraw()\
11654 return view\
11655end\
11656\
11657function GetObject(self, name)\
11658 return findObjectNamed(self, name)\
11659end\
11660\
11661local function findObjects(view, name)\
11662 local objects = {}\
11663 if view and view.Children then\
11664 for i, child in ipairs(view.Children) do\
11665 if child.Name == name or child == name then\
11666 table.insert(objects, child)\
11667 elseif child.Children then\
11668 local objs = findObjects(child, name)\
11669 if objs then\
11670 for i2, v in ipairs(objs) do\
11671 table.insert(objects, v)\
11672 end\
11673 end\
11674 end\
11675 end\
11676 end\
11677 return objects\
11678end\
11679\
11680function GetObjects(self, name)\
11681 return findObjects(self, name)\
11682end\
11683\
11684function RemoveObject(self, name)\
11685 local obj, index, view = findObjectNamed(self, name, minI)\
11686 if index then\
11687 view.Children[index]:OnRemove()\
11688 table.remove(view.Children, index)\
11689 if view.OnUpdate then\
11690 view:OnUpdate('Children')\
11691 end\
11692 return true\
11693 end\
11694 return false\
11695end\
11696\
11697function RemoveObjects(self, name)\
11698 local i = 1\
11699 while self:RemoveObject(name) and i < 100 do\
11700 i = i + 1\
11701 end\
11702 \
11703end\
11704\
11705function RemoveAllObjects(self)\
11706 for i, child in ipairs(self.Children) do\
11707 child:OnRemove()\
11708 self.Children[i] = nil\
11709 end\
11710 self:ForceDraw()\
11711end\
11712]],\
11713[\"Window\"] = [[\
11714Inherit = 'View'\
11715\
11716ToolBarColour = colours.lightGrey\
11717ToolBarTextColour = colours.black\
11718ShadowColour = colours.grey\
11719Title = ''\
11720Flashing = false\
11721CanClose = true\
11722OnCloseButton = nil\
11723OldActiveObject = nil\
11724\
11725LoadView = function(self)\
11726 local view = self:GetObject('View')\
11727 if view.ToolBarColour then\
11728 window.ToolBarColour = view.ToolBarColour\
11729 end\
11730 if view.ToolBarTextColour then\
11731 window.ToolBarTextColour = view.ToolBarTextColour\
11732 end\
11733 view.X = 1\
11734 view.Y = 2\
11735\
11736 view:ForceDraw()\
11737 self:OnUpdate('View')\
11738 if self.OnViewLoad then\
11739 self.OnViewLoad(view)\
11740 end\
11741 self.OldActiveObject = self.Bedrock:GetActiveObject()\
11742 self.Bedrock:SetActiveObject(view)\
11743end\
11744\
11745SetView = function(self, view)\
11746 self:RemoveObject('View')\
11747 table.insert(self.Children, view)\
11748 view.Parent = self\
11749 self:LoadView()\
11750end\
11751\
11752Flash = function(self)\
11753 self.Flashing = true\
11754 self:ForceDraw()\
11755 self.Bedrock:StartTimer(function()self.Flashing = false end, 0.4)\
11756end\
11757\
11758OnDraw = function(self, x, y)\
11759 local toolBarColour = (self.Flashing and colours.grey or self.ToolBarColour)\
11760 local toolBarTextColour = (self.Flashing and colours.black or self.ToolBarTextColour)\
11761 if toolBarColour then\
11762 Drawing.DrawBlankArea(x, y, self.Width, 1, toolBarColour)\
11763 end\
11764 if toolBarTextColour then\
11765 local title = self.Bedrock.Helpers.TruncateString(self.Title, self.Width - 2)\
11766 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, title, toolBarTextColour, toolBarColour)\
11767 end\
11768 Drawing.IgnoreConstraint = true\
11769 Drawing.DrawBlankArea(x + 1, y + 1, self.Width, self.Height, self.ShadowColour)\
11770 Drawing.IgnoreConstraint = false\
11771end\
11772\
11773Close = function(self)\
11774 self.Bedrock:SetActiveObject(self.OldActiveObject)\
11775 self.Bedrock.Window = nil\
11776 self.Bedrock:RemoveObject(self)\
11777 if self.OnClose then\
11778 self:OnClose()\
11779 end\
11780 self = nil\
11781end\
11782\
11783OnUpdate = function(self, value)\
11784 if value == 'View' and self:GetObject('View') then\
11785 self.Width = self:GetObject('View').Width\
11786 self.Height = self:GetObject('View').Height + 1\
11787 self.X = math.ceil((Drawing.Screen.Width - self.Width) / 2)\
11788 self.Y = math.ceil((Drawing.Screen.Height - self.Height) / 2)\
11789 elseif value == 'CanClose' then\
11790 self:RemoveObject('CloseButton')\
11791 if self.CanClose then\
11792 local button = self:AddObject({X = 1, Y = 1, Width = 1, Height = 1, Type = 'Button', BackgroundColour = colours.red, TextColour = colours.white, Text = 'x', Name = 'CloseButton'})\
11793 button.OnClick = function(btn)\
11794 if self.OnCloseButton then\
11795 self:OnCloseButton()\
11796 end\
11797 self:Close()\
11798 end\
11799 end\
11800 end\
11801end\
11802]],\
11803}\
11804BasePath = ''\
11805ProgramPath = nil\
11806\
11807-- Program functions...\
11808\
11809local function main(...)\
11810 -- Code here...\
11811end\
11812\
11813-- Run\
11814local args = {...}\
11815local _, err = pcall(function() main(unpack(args)) end)\
11816if err then\
11817 -- Make a nice error handling screen here...\
11818 term.setBackgroundColor(colors.black)\
11819 term.setTextColor(colors.white)\
11820 term.clear()\
11821 term.setCursorPos(1, 3)\
11822 print(\" An Error Has Occured! D:\\n\\n\")\
11823 print(\" \" .. tostring(err) .. \"\\n\\n\")\
11824 print(\" Press any key to exit...\")\
11825 os.pullEvent(\"key\")\
11826end\
11827\
11828function LoadAPIs(self)\
11829 local function loadAPI(name, content)\
11830 local env = setmetatable({}, { __index = getfenv() })\
11831 local func, err = loadstring(content, name..' (Bedrock API)')\
11832 if not func then\
11833 return false, printError(err)\
11834 end\
11835 setfenv(func, env)\
11836 func()\
11837 local api = {}\
11838 for k,v in pairs(env) do\
11839 api[k] = v\
11840 end\
11841 _G[name] = api\
11842 return true\
11843 end\
11844\
11845 local env = getfenv()\
11846 local function loadObject(name, content)\
11847 loadAPI(name, content)\
11848 if env[name].Inherit then\
11849 if not getfenv()[env[name].Inherit] then \
11850 if objects[env[name].Inherit] then\
11851 loadObject(env[name].Inherit, objects[env[name].Inherit])\
11852 elseif fs.exists(self.ProgramPath..'/Objects/'..env[name].Inherit..'.lua') then\
11853 local h = fs.open(self.ProgramPath..'/Objects/'..env[name].Inherit..'.lua', 'r')\
11854 loadObject(env[name].Inherit, h.readAll())\
11855 h.close()\
11856 loadObject(name, content)\
11857 return\
11858 end\
11859 end\
11860 env[name].__index = getfenv()[env[name].Inherit]\
11861 else\
11862 env[name].__index = Object\
11863 end\
11864 setmetatable(env[name], env[name])\
11865 end\
11866\
11867 for k, v in pairs(apis) do\
11868 loadAPI(k, v)\
11869 if k == 'Helpers' then\
11870 self.Helpers = Helpers\
11871 end\
11872 end\
11873\
11874 for k, v in pairs(objects) do\
11875 loadObject(k, v)\
11876 end\
11877 \
11878 local privateObjPath = self.ProgramPath..'/Objects/'\
11879 if fs.exists(privateObjPath) and fs.isDir(privateObjPath) then\
11880 for i, v in ipairs(fs.list(privateObjPath)) do\
11881 if v ~= '.DS_Store' then\
11882 local name = string.match(v, '(%a+)%.?.-')\
11883 local h = fs.open(privateObjPath..v, 'r')\
11884 loadObject(name, h.readAll())\
11885 h.close()\
11886 end\
11887 end\
11888 end\
11889 \
11890 local privateAPIPath = self.ProgramPath..'/APIs/'\
11891 if fs.exists(privateAPIPath) and fs.isDir(privateAPIPath) then\
11892 for i, v in ipairs(fs.list(privateAPIPath)) do\
11893 if v ~= '.DS_Store' then\
11894 local name = string.match(v, '(%a+)%.?.-')\
11895 local h = fs.open(privateAPIPath..v, 'r')\
11896 loadAPI(name, h.readAll())\
11897 h.close()\
11898 end\
11899 end\
11900 end\
11901end\
11902\
11903AllowTerminate = true\
11904\
11905View = nil\
11906Menu = nil\
11907\
11908ActiveObject = nil\
11909\
11910DrawTimer = nil\
11911DrawTimerExpiry = 0\
11912\
11913IsDrawing = false\
11914\
11915Running = true\
11916\
11917DefaultView = 'main'\
11918\
11919AnimationEnabled = true\
11920\
11921EventHandlers = {\
11922 \
11923}\
11924\
11925ObjectClickHandlers = {\
11926 \
11927}\
11928\
11929ObjectUpdateHandlers = {\
11930 \
11931}\
11932\
11933Timers = {\
11934 \
11935}\
11936\
11937ModifierKeys = {}\
11938KeyboardShortcuts = {}\
11939\
11940keys.leftCommand = 219\
11941keys.rightCommand = 220\
11942\
11943function Initialise(self, programPath)\
11944 self.ProgramPath = programPath or self.ProgramPath\
11945 if not programPath then\
11946 if self.ProgramPath then\
11947 local prgPath = self.ProgramPath\
11948 local prgName = fs.getName(prgPath)\
11949 if prgPath:find('/') then \
11950 self.ProgramPath = prgPath:sub(1, #prgPath-#prgName-1)\
11951 self.ProgramPath = prgPath:sub(1, #prgPath-#prgName-1) \
11952 else \
11953 self.ProgramPath = '' \
11954 end\
11955 else\
11956 self.ProgramPath = ''\
11957 end\
11958 end\
11959 self:LoadAPIs()\
11960 self.ViewPath = self.ProgramPath .. '/Views/'\
11961 --first, check that the barebones APIs are available\
11962 local requiredApis = {\
11963 'Drawing',\
11964 'View'\
11965 }\
11966 local env = getfenv()\
11967 for i,v in ipairs(requiredApis) do\
11968 if not env[v] then\
11969 error('The API: '..v..' is not loaded. Please make sure you load it to use Bedrock.')\
11970 end\
11971 end\
11972\
11973 local copy = { }\
11974 for k, v in pairs(self) do\
11975 if k ~= 'Initialise' then\
11976 copy[k] = v\
11977 end\
11978 end\
11979 return setmetatable(copy, getmetatable(self))\
11980end\
11981\
11982function HandleClick(self, event, side, x, y)\
11983 if self.Menu then\
11984 if not self.View:DoClick(self.Menu, event, side, x, y) then\
11985 self.Menu:Close()\
11986 end\
11987 elseif self.Window then\
11988 if not self.View:CheckClick(self.Window, x, y) then\
11989 self.Window:Flash()\
11990 else\
11991 self.View:DoClick(self.Window, event, side, x, y)\
11992 end\
11993 elseif self.View then\
11994 if self.View:Click(event, side, x, y) ~= false then\
11995 end \
11996 end\
11997end\
11998\
11999function UnregisterKeyboardShortcut(self, name)\
12000 if name then\
12001 self.KeyboardShortcuts[name] = nil\
12002 end\
12003end\
12004\
12005function RegisterKeyboardShortcut(self, keys, func, name)\
12006 name = name or tostring(math.random(1, 10000))\
12007 if type(keys[1]) == 'table' then\
12008 for i, v in ipairs(keys) do\
12009 self.KeyboardShortcuts[name] = {Keys = v, Function = func}\
12010 end\
12011 else\
12012 self.KeyboardShortcuts[name] = {Keys = keys, Function = func}\
12013 end\
12014 return name\
12015end\
12016\
12017function TryKeyboardShortcuts(self, keychar)\
12018 if keychar == keys.backspace then\
12019 keychar = keys.delete\
12020 end\
12021\
12022 local len = 1 -- + keychar\
12023 for k, v in pairs(self.ModifierKeys) do\
12024 len = len + 1\
12025 end\
12026\
12027 for _, shortcut in pairs(self.KeyboardShortcuts) do\
12028 local match = true\
12029 for i2, key in ipairs(shortcut.Keys) do\
12030 if self.ModifierKeys[key] == nil and key ~= keychar then\
12031 match = false\
12032 end\
12033 end\
12034\
12035 if match and #shortcut.Keys == len then\
12036 return shortcut.Function() ~= false\
12037 end\
12038 end\
12039end\
12040\
12041function HandleKeyChar(self, event, keychar)\
12042 if keychar == keys.leftCtrl or keychar == keys.leftShift or keychar == keys.leftAlt or keychar == keys.leftCommand or keychar == keys.rightCommand or keychar == keys.rightCtrl or keychar == keys.rightShift or keychar == keys.rightAlt then\
12043 if keychar == keys.leftCommand or keychar == keys.rightCommand or keychar == keys.rightCtrl then\
12044 keychar = keys.leftCtrl\
12045 elseif keychar == keys.rightAlt then\
12046 keychar = keys.leftAlt\
12047 elseif keychar == keys.rightShift then\
12048 keychar = keys.leftShift\
12049 end\
12050 self.ModifierKeys[keychar] = self:StartTimer(function(_, timer)\
12051 if timer == self.ModifierKeys[keychar] then\
12052 self.ModifierKeys[keychar] = nil\
12053 end\
12054 end, 1)\
12055 elseif self:TryKeyboardShortcuts(keychar) then\
12056 return\
12057 end\
12058\
12059 if self:GetActiveObject() then\
12060 local activeObject = self:GetActiveObject()\
12061 if activeObject.OnKeyChar then\
12062 if activeObject:OnKeyChar(event, keychar) ~= false then\
12063 --self:Draw()\
12064 end\
12065 end\
12066 end\
12067end\
12068\
12069PreparedMenus = {}\
12070\
12071function PrepareMenu(self, name)\
12072 local menu = self:AddObject(name, {Type = 'Menu', X = 1, Y = 1, Prepared = true})\
12073 menu.Visible = false\
12074 self.PreparedMenus[name] = menu\
12075 return menu\
12076end\
12077\
12078function ToggleMenu(self, name, owner, x, y)\
12079 if self.Menu then\
12080 self.Menu:Close()\
12081 return false\
12082 else\
12083 self:SetMenu(name, owner, x, y)\
12084 return true\
12085 end\
12086end\
12087\
12088function SetMenu(self, menu, owner, x, y)\
12089 x = x or 1\
12090 y = y or 1\
12091 if self.Menu then\
12092 self.Menu:Close()\
12093 end \
12094 if menu then\
12095 local pos = owner:GetPosition()\
12096 if self.PreparedMenus[menu] then\
12097 self.Menu = self.PreparedMenus[menu]\
12098 self.Menu.Visible = true\
12099 self.Menu.Owner = owner\
12100 self.Menu.X = pos.X + x - 1\
12101 self.Menu.Y = pos.Y + y\
12102 self.Menu.Z = self.View.Children[#self.View.Children].Z + 1\
12103 self:ReorderObjects()\
12104 else\
12105 self.Menu = self:AddObject(menu, {Type = 'Menu', Owner = owner, X = pos.X + x - 1, Y = pos.Y + y, Z = self.View.Children[#self.View.Children].Z + 1})\
12106 end\
12107 end\
12108end\
12109\
12110function ObjectClick(self, name, func)\
12111 self.ObjectClickHandlers[name] = func\
12112end\
12113\
12114function ClickObject(self, object, event, side, x, y)\
12115 if self.ObjectClickHandlers[object.Name] then\
12116 return self.ObjectClickHandlers[object.Name](object, event, side, x, y)\
12117 end\
12118 return false\
12119end\
12120\
12121function ObjectUpdate(self, name, func)\
12122 self.ObjectUpdateHandlers[name] = func\
12123end\
12124\
12125function UpdateObject(self, object, ...)\
12126 if self.ObjectUpdateHandlers[object.Name] then\
12127 self.ObjectUpdateHandlers[object.Name](object, ...)\
12128 --self:Draw()\
12129 end\
12130end\
12131\
12132function GetAbsolutePosition(self, obj)\
12133 if not obj.Parent then\
12134 return {X = obj.X, Y = obj.Y}\
12135 else\
12136 local pos = self:GetAbsolutePosition(obj.Parent)\
12137 local x = pos.X + obj.X - 1\
12138 local y = pos.Y + obj.Y - 1\
12139 if not obj.Fixed and obj.Parent.ChildOffset then\
12140 x = x + obj.Parent.ChildOffset.X\
12141 y = y + obj.Parent.ChildOffset.Y\
12142 end\
12143 return {X = x, Y = y}\
12144 end\
12145end\
12146\
12147function LoadView(self, name, draw)\
12148 if self.View and self.OnViewClose then\
12149 self.OnViewClose(self.View.Name)\
12150 end\
12151 if self.View then\
12152 self.View:OnRemove()\
12153 end\
12154 local success = false\
12155\
12156 if Drawing.Screen.Width <= 26 and fs.exists(self.ViewPath..name..'-pocket.view') then\
12157 name = name..'-pocket'\
12158 elseif Drawing.Screen.Width <= 39 and fs.exists(self.ViewPath..name..'-turtle.view') then\
12159 name = name..'-turtle'\
12160 end\
12161\
12162 if not fs.exists(self.ViewPath..name..'.view') then\
12163 error('The view: '..name..'.view does not exist.')\
12164 end\
12165\
12166 local h = fs.open(self.ViewPath..name..'.view', 'r')\
12167 if h then\
12168 local view = textutils.unserialize(h.readAll())\
12169 h.close()\
12170 if view then\
12171 self.View = View:InitialiseFile(self, view, name)\
12172 self:ReorderObjects()\
12173\
12174 if OneOS and view.ToolBarColour then\
12175 OneOS.ToolBarColour = view.ToolBarColour\
12176 end\
12177 if OneOS and view.ToolBarTextColour then\
12178 OneOS.ToolBarTextColour = view.ToolBarTextColour\
12179 end\
12180 if not self:GetActiveObject() then\
12181 self:SetActiveObject()\
12182 end\
12183 success = true\
12184 end\
12185 end\
12186\
12187 if success and self.OnViewLoad then\
12188 self.OnViewLoad(name)\
12189 end\
12190\
12191 if draw ~= false then\
12192 self:Draw()\
12193 end\
12194\
12195 if not success then\
12196 error('Failed to load view: '..name..'. It probably isn\\'t formatted correctly. Did you forget a } or ,?')\
12197 end\
12198\
12199 return success\
12200end\
12201\
12202function InheritFile(self, file, name)\
12203 local h = fs.open(self.ViewPath..name..'.view', 'r')\
12204 if h then\
12205 local super = textutils.unserialize(h.readAll())\
12206 if super then\
12207 if type(super) ~= 'table' then\
12208 error('View: \"'..name..'.view\" is not formatted correctly.')\
12209 end\
12210\
12211 for k, v in pairs(super) do\
12212 if not file[k] then\
12213 file[k] = v\
12214 end\
12215 end\
12216 return file\
12217 end\
12218 end\
12219 return file\
12220end\
12221\
12222function ParseStringSize(self, parent, k, v)\
12223 local parentSize = parent.Width\
12224 if k == 'Height' or k == 'Y' then\
12225 parentSize = parent.Height\
12226 end\
12227 local parts = {v}\
12228 if type(v) == 'string' and string.find(v, ',') then\
12229 parts = {}\
12230 for word in string.gmatch(v, '([^,]+)') do\
12231 table.insert(parts, word)\
12232 end\
12233 end\
12234\
12235 v = 0\
12236 for i2, part in ipairs(parts) do\
12237 if type(part) == 'string' and part:sub(#part) == '%' then\
12238 v = v + math.ceil(parentSize * (tonumber(part:sub(1, #part-1)) / 100))\
12239 else\
12240 v = v + tonumber(part)\
12241 end\
12242 end\
12243 return v\
12244end\
12245\
12246function ObjectFromFile(self, file, view)\
12247 local env = getfenv()\
12248 if env[file.Type] then\
12249 if not env[file.Type].Initialise then\
12250 error('Malformed Object: '..file.Type)\
12251 end\
12252 local object = {}\
12253\
12254 if file.InheritView then\
12255 file = self:InheritFile(file, file.InheritView)\
12256 end\
12257 \
12258 object.AutoWidth = true\
12259 for k, v in pairs(file) do\
12260 if k == 'Width' or k == 'X' or k == 'Height' or k == 'Y' then\
12261 v = self:ParseStringSize(view, k, v)\
12262 end\
12263\
12264 if k == 'Width' then\
12265 object.AutoWidth = false\
12266 end\
12267 if k ~= 'Children' then\
12268 object[k] = v\
12269 else\
12270 object[k] = {}\
12271 end\
12272 end\
12273\
12274 object.Parent = view\
12275 object.Bedrock = self\
12276 if not object.Name then\
12277 object.Name = file.Type\
12278 end\
12279\
12280 object = env[file.Type]:Initialise(object)\
12281\
12282 if file.Children then\
12283 for i, obj in ipairs(file.Children) do\
12284 local _view = self:ObjectFromFile(obj, object)\
12285 if not _view.Z then\
12286 _view.Z = i\
12287 end\
12288 _view.Parent = object\
12289 table.insert(object.Children, _view)\
12290 end\
12291 end\
12292\
12293 if not object.OnClick then\
12294 object.OnClick = function(...) return self:ClickObject(...) end\
12295 end\
12296 --object.OnUpdate = function(...) self:UpdateObject(...) end\
12297\
12298 if object.OnUpdate then\
12299 for k, v in pairs(env[file.Type]) do\
12300 object:OnUpdate(k)\
12301 end\
12302\
12303 for k, v in pairs(object.__index) do\
12304 object:OnUpdate(k)\
12305 end\
12306 end\
12307\
12308 if object.Active then\
12309 object.Bedrock:SetActiveObject(object)\
12310 end\
12311 if object.OnLoad then\
12312 object:OnLoad()\
12313 end\
12314 object.Ready = true\
12315 return object\
12316 elseif not file.Type then\
12317 error('No object type specified. (e.g. Type = \"Button\")')\
12318 else\
12319 error('No Object: '..file.Type..'. The API probably isn\\'t loaded')\
12320 end\
12321end\
12322\
12323function ReorderObjects(self)\
12324 if self.View and self.View.Children then\
12325 self.View:ReorderObjects()\
12326 end\
12327end\
12328\
12329function AddObject(self, info, extra, first)\
12330 return self.View:AddObject(info, extra, first)\
12331end\
12332\
12333function GetObject(self, name)\
12334 return self.View:GetObject(name)\
12335end\
12336\
12337function GetObjects(self, name)\
12338 return self.View:GetObjects(name)\
12339end\
12340\
12341function RemoveObject(self, name)\
12342 return self.View:RemoveObject(name)\
12343end\
12344\
12345function RemoveObjects(self, name)\
12346 return self.View:RemoveObjects(name)\
12347end\
12348\
12349DrawEvent = nil\
12350\
12351function HandleDraw(self, event, id)\
12352 if id == self.DrawEvent then\
12353 self.DrawEvent = nil\
12354 self:Draw()\
12355 end\
12356end\
12357\
12358function ForceDraw(self)\
12359 if not self.DrawEvent then--or self.DrawTimerExpiry <= os.clock() then\
12360 self.DrawEvent = math.random()\
12361 os.queueEvent('bedrock_draw', self.DrawEvent)\
12362 -- self:StartTimer(function()\
12363 -- self.DrawTimer = nil\
12364 -- self:Draw()\
12365 -- end, 0.05)\
12366 -- self.DrawTimerExpiry = os.clock() + 0.1\
12367 end\
12368end\
12369\
12370function DisplayWindow(self, _view, title, canClose)\
12371 if canClose == nil then\
12372 canClose = true\
12373 end\
12374 if type(_view) == 'string' then\
12375 local h = fs.open(self.ViewPath.._view..'.view', 'r')\
12376 if h then\
12377 _view = textutils.unserialize(h.readAll())\
12378 h.close()\
12379 end\
12380 end\
12381\
12382 self.Window = self:AddObject({Type = 'Window', Z = 999, Title = title, CanClose = canClose})\
12383 _view.Type = 'View'\
12384 _view.Name = 'View'\
12385 _view.BackgroundColour = _view.BackgroundColour or colours.white\
12386 self.Window:SetView(self:ObjectFromFile(_view, self.Window))\
12387end\
12388\
12389function DisplayAlertWindow(self, title, text, buttons, callback)\
12390 local func = function(btn)\
12391 self.Window:Close()\
12392 if callback then\
12393 callback(btn.Text)\
12394 end\
12395 end\
12396 local children = {}\
12397 local usedX = -1\
12398 if buttons then\
12399 for i, text in ipairs(buttons) do\
12400 usedX = usedX + 3 + #text\
12401 table.insert(children, {\
12402 [\"Y\"]=\"100%,-1\",\
12403 [\"X\"]=\"100%,-\"..usedX,\
12404 [\"Name\"]=text..\"Button\",\
12405 [\"Type\"]=\"Button\",\
12406 [\"Text\"]=text,\
12407 OnClick = func\
12408 })\
12409 end\
12410 end\
12411\
12412 local width = usedX + 2\
12413 if width < 28 then\
12414 width = 28\
12415 end\
12416\
12417 local canClose = true\
12418 if buttons and #buttons~=0 then\
12419 canClose = false\
12420 end\
12421\
12422 local height = 0\
12423 if text then\
12424 height = #Helpers.WrapText(text, width - 2)\
12425 table.insert(children, {\
12426 [\"Y\"]=2,\
12427 [\"X\"]=2,\
12428 [\"Width\"]=\"100%,-2\",\
12429 [\"Height\"]=height,\
12430 [\"Name\"]=\"Label\",\
12431 [\"Type\"]=\"Label\",\
12432 [\"Text\"]=text\
12433 })\
12434 end\
12435 local view = {\
12436 Children = children,\
12437 Width=width,\
12438 Height=3+height+(canClose and 0 or 1),\
12439 OnKeyChar = function(_view, keychar)\
12440 func({Text=buttons[1]})\
12441 end\
12442 }\
12443 self:DisplayWindow(view, title, canClose)\
12444end\
12445\
12446function DisplayTextBoxWindow(self, title, text, callback, textboxText, cursorAtEnd)\
12447 textboxText = textboxText or ''\
12448 local children = {\
12449 {\
12450 [\"Y\"]=\"100%,-1\",\
12451 [\"X\"]=\"100%,-4\",\
12452 [\"Name\"]=\"OkButton\",\
12453 [\"Type\"]=\"Button\",\
12454 [\"Text\"]=\"Ok\",\
12455 OnClick = function()\
12456 local text = self.Window:GetObject('TextBox').Text\
12457 self.Window:Close()\
12458 callback(true, text)\
12459 end\
12460 },\
12461 {\
12462 [\"Y\"]=\"100%,-1\",\
12463 [\"X\"]=\"100%,-13\",\
12464 [\"Name\"]=\"CancelButton\",\
12465 [\"Type\"]=\"Button\",\
12466 [\"Text\"]=\"Cancel\",\
12467 OnClick = function()\
12468 self.Window:Close()\
12469 callback(false)\
12470 end\
12471 }\
12472 }\
12473\
12474 local height = -1\
12475 if text and #text ~= 0 then\
12476 height = #Helpers.WrapText(text, 26)\
12477 table.insert(children, {\
12478 [\"Y\"]=2,\
12479 [\"X\"]=2,\
12480 [\"Width\"]=\"100%,-2\",\
12481 [\"Height\"]=height,\
12482 [\"Name\"]=\"Label\",\
12483 [\"Type\"]=\"Label\",\
12484 [\"Text\"]=text\
12485 })\
12486 end\
12487 table.insert(children,\
12488 {\
12489 [\"Y\"]=3+height,\
12490 [\"X\"]=2,\
12491 [\"Width\"]=\"100%,-2\",\
12492 [\"Name\"]=\"TextBox\",\
12493 [\"Type\"]=\"TextBox\",\
12494 [\"Text\"]=textboxText,\
12495 [\"CursorPos\"]=(cursorAtEnd or 0)\
12496 })\
12497 local view = {\
12498 Children = children,\
12499 Width=28,\
12500 Height=5+height+(canClose and 0 or 1),\
12501 }\
12502 self:DisplayWindow(view, title)\
12503 self.Window:GetObject('TextBox').OnChange = function(txtbox, event, keychar)\
12504 if keychar == keys.enter then\
12505 self.Window:Close()\
12506 callback(true, txtbox.Text)\
12507 end\
12508 end\
12509 self:SetActiveObject(self.Window:GetObject('TextBox'))\
12510 self.Window.OnCloseButton = function()callback(false)end\
12511end\
12512\
12513function DisplayOpenFileWindow(self, title, callback)\
12514 title = title or 'Open File'\
12515 local func = function(btn)\
12516 self.Window:Close()\
12517 if callback then\
12518 callback(btn.Text)\
12519 end\
12520 end\
12521\
12522 local sidebarItems = {}\
12523\
12524 --this is a really, really super bad way of doing it\
12525 local separator = ' !'\
12526\
12527 local function addFolder(path, level)\
12528 for i, v in ipairs(_fs.list(path)) do\
12529 local fPath = path .. '/' .. v\
12530 if fPath ~= '/rom' and _fs.isDir(fPath) then\
12531 table.insert(sidebarItems, level .. v..separator..fPath)\
12532 addFolder(fPath, level .. ' ')\
12533 end\
12534 end\
12535 end\
12536 \
12537 if OneOS then\
12538 _fs = OneOS.FS\
12539 end\
12540\
12541 addFolder('','')\
12542\
12543 local currentFolder = ''\
12544 local selectedPath = nil\
12545\
12546 local goToFolder = nil\
12547\
12548 local children = {\
12549 {\
12550 [\"Y\"]=\"100%,-2\",\
12551 [\"X\"]=1,\
12552 [\"Height\"]=3,\
12553 [\"Width\"]=\"100%\",\
12554 [\"BackgroundColour\"]=colours.lightGrey,\
12555 [\"Name\"]=\"SidebarListView\",\
12556 [\"Type\"]=\"View\"\
12557 },\
12558 {\
12559 [\"Y\"]=\"100%,-1\",\
12560 [\"X\"]=\"100%,-4\",\
12561 [\"Name\"]=\"OkButton\",\
12562 [\"Type\"]=\"Button\",\
12563 [\"Text\"]=\"Ok\",\
12564 [\"BackgroundColour\"]=colours.white,\
12565 [\"Enabled\"]=false,\
12566 OnClick = function()\
12567 if selectedPath then\
12568 self.Window:Close()\
12569 callback(true, Helpers.TidyPath(selectedPath))\
12570 end\
12571 end\
12572 },\
12573 {\
12574 [\"Y\"]=\"100%,-1\",\
12575 [\"X\"]=\"100%,-13\",\
12576 [\"Name\"]=\"CancelButton\",\
12577 [\"Type\"]=\"Button\",\
12578 [\"Text\"]=\"Cancel\",\
12579 [\"BackgroundColour\"]=colours.white,\
12580 OnClick = function()\
12581 self.Window:Close()\
12582 callback(false)\
12583 end\
12584 },\
12585 {\
12586 [\"Y\"]=1,\
12587 [\"X\"]=1,\
12588 [\"Height\"]=\"100%,-3\",\
12589 [\"Width\"]=\"40%,-1\",\
12590 [\"Name\"]=\"SidebarListView\",\
12591 [\"Type\"]=\"ListView\",\
12592 [\"CanSelect\"]=true,\
12593 [\"Items\"]={\
12594 [\"Computer\"] = sidebarItems\
12595 },\
12596 OnSelect = function(listView, text)\
12597 local _,s = text:find(separator)\
12598 if s then\
12599 local path = text:sub(s + 1)\
12600 goToFolder(path)\
12601 end\
12602 end,\
12603 OnClick = function(listView, event, side, x, y)\
12604 if y == 1 then\
12605 goToFolder('/')\
12606 end\
12607 end\
12608 },\
12609 {\
12610 [\"Y\"]=1,\
12611 [\"X\"]=\"40%\",\
12612 [\"Height\"]=\"100%,-3\",\
12613 [\"Width\"]=1,\
12614 [\"Type\"]=\"Separator\"\
12615 },\
12616 {\
12617 [\"Y\"]=1,\
12618 [\"X\"]=\"40%,2\",\
12619 [\"Width\"]=\"65%,-3\",\
12620 [\"Height\"]=1,\
12621 [\"Type\"]=\"Label\",\
12622 [\"Name\"]=\"PathLabel\",\
12623 [\"TextColour\"]=colours.lightGrey,\
12624 [\"Text\"]='/'\
12625 },\
12626 {\
12627 [\"Y\"]=2,\
12628 [\"X\"]=\"40%,1\",\
12629 [\"Height\"]=\"100%,-4\",\
12630 [\"Width\"]=\"65%,-1\",\
12631 [\"Name\"]=\"FilesListView\",\
12632 [\"Type\"]=\"ListView\",\
12633 [\"CanSelect\"]=true,\
12634 [\"Items\"]={},\
12635 OnSelect = function(listView, text)\
12636 selectedPath = Helpers.TidyPath(currentFolder .. '/' .. text)\
12637 self.Window:GetObject('OkButton').Enabled = true\
12638 end,\
12639 OnClick = function(listView, event, side, x, y)\
12640 if y == 1 then\
12641 goToFolder('/')\
12642 end\
12643 end\
12644 },\
12645 }\
12646 local view = {\
12647 Children = children,\
12648 Width=40,\
12649 Height= Drawing.Screen.Height - 4,\
12650 OnCloseButton=function()\
12651 callback(false)\
12652 end\
12653 }\
12654 self:DisplayWindow(view, title)\
12655\
12656 goToFolder = function(path)\
12657 path = Helpers.TidyPath(path)\
12658 self.Window:GetObject('PathLabel').Text = path\
12659 currentFolder = path\
12660\
12661 local filesListItems = {}\
12662 for i, v in ipairs(_fs.list(path)) do\
12663 if not _fs.isDir(currentFolder .. v) then\
12664 table.insert(filesListItems, v)\
12665 end\
12666 end\
12667 self.Window:GetObject('OkButton').Enabled = false\
12668 selectedPath = nil\
12669 self.Window:GetObject('FilesListView').Items = filesListItems\
12670\
12671 end\
12672\
12673 if startPath then\
12674 goToFolder(startPath)\
12675 elseif OneOS then\
12676 goToFolder('/Desktop/Documents/')\
12677 else\
12678 goToFolder('')\
12679 end\
12680\
12681 self.Window.OnCloseButton = function()callback(false)end\
12682end\
12683\
12684function DisplaySaveFileWindow(self, title, callback, extension, startPath)\
12685 local _fs = fs\
12686 if extension and extension:sub(1,1) ~= '.' then\
12687 extension = '.' .. extension\
12688 end\
12689 extension = extension or ''\
12690\
12691 title = title or 'Save File'\
12692 local func = function(btn)\
12693 self.Window:Close()\
12694 if callback then\
12695 callback(btn.Text)\
12696 end\
12697 end\
12698\
12699 local sidebarItems = {}\
12700\
12701 --this is a really, really super bad way of doing it\
12702 local separator = ' !'\
12703\
12704 local function addFolder(path, level)\
12705 for i, v in ipairs(_fs.list(path)) do\
12706 local fPath = path .. '/' .. v\
12707 if fPath ~= '/rom' and _fs.isDir(fPath) then\
12708 table.insert(sidebarItems, level .. v..separator..fPath)\
12709 addFolder(fPath, level .. ' ')\
12710 end\
12711 end\
12712 end\
12713 \
12714 if OneOS then\
12715 _fs = OneOS.FS\
12716 end\
12717 addFolder('','')\
12718\
12719 local currentFolder = ''\
12720 local selectedPath = nil\
12721\
12722 local goToFolder = nil\
12723\
12724 local function updatePath()\
12725 local text = self:GetObject('FileNameTextBox').Text\
12726 if #text == 0 then\
12727 self.Window:GetObject('OkButton').Enabled = false\
12728 selectedPath = Helpers.TidyPath(currentFolder)\
12729 else\
12730 self.Window:GetObject('OkButton').Enabled = true\
12731 selectedPath = Helpers.TidyPath(currentFolder .. '/' .. text .. extension)\
12732 end\
12733 self:GetObject('PathLabel').Text = selectedPath\
12734 end\
12735\
12736 local children = {\
12737 {\
12738 [\"Y\"]=\"100%,-2\",\
12739 [\"X\"]=1,\
12740 [\"Height\"]=3,\
12741 [\"Width\"]=\"100%\",\
12742 [\"BackgroundColour\"]=colours.lightGrey,\
12743 [\"Type\"]=\"View\"\
12744 },\
12745 {\
12746 [\"Y\"]=\"100%,-1\",\
12747 [\"X\"]=\"100%,-4\",\
12748 [\"Name\"]=\"OkButton\",\
12749 [\"Type\"]=\"Button\",\
12750 [\"Text\"]=\"Ok\",\
12751 [\"BackgroundColour\"]=colours.white,\
12752 [\"Enabled\"]=false,\
12753 OnClick = function()\
12754 if selectedPath then\
12755 local text = self:GetObject('FileNameTextBox').Text\
12756 self.Window:Close()\
12757 callback(true, selectedPath, text)\
12758 end\
12759 end\
12760 },\
12761 {\
12762 [\"Y\"]=\"100%,-1\",\
12763 [\"X\"]=\"100%,-13\",\
12764 [\"Name\"]=\"CancelButton\",\
12765 [\"Type\"]=\"Button\",\
12766 [\"Text\"]=\"Cancel\",\
12767 [\"BackgroundColour\"]=colours.white,\
12768 OnClick = function()\
12769 self.Window:Close()\
12770 callback(false)\
12771 end\
12772 },\
12773 {\
12774 [\"Y\"]=\"100%,-2\",\
12775 [\"X\"]=3,\
12776 [\"Width\"]=\"100%,-4\",\
12777 [\"Name\"]=\"PathLabel\",\
12778 [\"Type\"]=\"Label\",\
12779 [\"Text\"]=\"/\",\
12780 [\"TextColour\"]=colours.grey\
12781 },\
12782 {\
12783 [\"Y\"]=\"100%,-1\",\
12784 [\"X\"]=3,\
12785 [\"Width\"]=\"100%,-17\",\
12786 [\"Name\"]=\"FileNameTextBox\",\
12787 [\"Type\"]=\"TextBox\",\
12788 [\"Placeholder\"]=\"File Name\",\
12789 [\"Active\"]=true,\
12790 [\"BackgroundColour\"]=colours.white,\
12791 OnChange = function(_self, event, keychar)\
12792 if keychar == keys.enter then\
12793 self:GetObject('OkButton'):OnClick()\
12794 else\
12795 updatePath()\
12796 end\
12797 end\
12798 },\
12799 {\
12800 [\"Y\"]=1,\
12801 [\"X\"]=2,\
12802 [\"Height\"]=\"100%,-3\",\
12803 [\"Width\"]=\"100%,-1\",\
12804 [\"Name\"]=\"SidebarListView\",\
12805 [\"Type\"]=\"ListView\",\
12806 [\"CanSelect\"]=true,\
12807 [\"Items\"]={\
12808 [\"Computer\"] = sidebarItems\
12809 },\
12810 OnSelect = function(listView, text)\
12811 local _,s = text:find(separator)\
12812 if s then\
12813 local path = text:sub(s + 1)\
12814 goToFolder(path)\
12815 end\
12816 end,\
12817 OnClick = function(listView, event, side, x, y)\
12818 if y == 1 then\
12819 goToFolder('/')\
12820 end\
12821 end\
12822 },\
12823 }\
12824 local view = {\
12825 Children = children,\
12826 Width=35,\
12827 Height= Drawing.Screen.Height - 4,\
12828 OnCloseButton=function()\
12829 callback(false)\
12830 end\
12831 }\
12832 self:DisplayWindow(view, title)\
12833\
12834 self:SetActiveObject(self.Window:GetObject('FileNameTextBox'))\
12835\
12836 goToFolder = function(path)\
12837 path = Helpers.TidyPath(path)\
12838 currentFolder = path\
12839 selectedPath = nil\
12840 updatePath()\
12841 end\
12842\
12843 if startPath then\
12844 goToFolder(startPath)\
12845 elseif OneOS then\
12846 goToFolder('/Desktop/Documents/')\
12847 else\
12848 goToFolder('')\
12849 end\
12850\
12851 self.Window.OnCloseButton = function()callback(false)end\
12852end\
12853\
12854function RegisterEvent(self, event, func)\
12855 if not self.EventHandlers[event] then\
12856 self.EventHandlers[event] = {}\
12857 end\
12858 table.insert(self.EventHandlers[event], func)\
12859end\
12860\
12861function StartRepeatingTimer(self, func, interval)\
12862 local int = interval\
12863 if type(int) == 'function' then\
12864 int = int()\
12865 end\
12866 if not int or int <= 0 then\
12867 return\
12868 end\
12869 local timer = os.startTimer(int)\
12870\
12871 self.Timers[timer] = {func, true, interval}\
12872 return timer\
12873end\
12874\
12875function StartTimer(self, func, delay)\
12876 local timer = os.startTimer(delay)\
12877 self.Timers[timer] = {func, false}\
12878 return timer\
12879end\
12880\
12881function StopTimer(self, timer)\
12882 if self.Timers[timer] then\
12883 self.Timers[timer] = nil\
12884 end\
12885end\
12886\
12887function HandleTimer(self, event, timer)\
12888 if self.Timers[timer] then\
12889 local oldTimer = self.Timers[timer]\
12890 self.Timers[timer] = nil\
12891 local new = nil\
12892 if oldTimer[2] then\
12893 new = self:StartRepeatingTimer(oldTimer[1], oldTimer[3])\
12894 end\
12895 if oldTimer and oldTimer[1] then\
12896 oldTimer[1](new, timer)\
12897 end\
12898 elseif self.OnTimer then\
12899 self.OnTimer(self, event, timer)\
12900 end\
12901end\
12902\
12903function SetActiveObject(self, object)\
12904 if object then\
12905 if object ~= self.ActiveObject then\
12906 self.ActiveObject = object\
12907 object:ForceDraw()\
12908 end\
12909 elseif self.ActiveObject ~= nil then\
12910 self.ActiveObject = nil\
12911 self.CursorPos = nil\
12912 self.View:ForceDraw()\
12913 end\
12914end\
12915\
12916function GetActiveObject(self)\
12917 return self.ActiveObject\
12918end\
12919\
12920OnTimer = nil\
12921OnClick = nil\
12922OnKeyChar = nil\
12923OnDrag = nil\
12924OnScroll = nil\
12925OnViewLoad = nil\
12926OnViewClose = nil\
12927OnDraw = nil\
12928OnQuit = nil\
12929\
12930local eventFuncs = {\
12931 OnClick = {'mouse_click', 'monitor_touch'},\
12932 OnKeyChar = {'key', 'char'},\
12933 OnDrag = {'mouse_drag'},\
12934 OnScroll = {'mouse_scroll'},\
12935 HandleClick = {'mouse_click', 'mouse_drag', 'mouse_scroll', 'monitor_touch'},\
12936 HandleKeyChar = {'key', 'char'},\
12937 HandleTimer = {'timer'},\
12938 HandleDraw = {'bedrock_draw'}\
12939}\
12940\
12941local drawCalls = 0\
12942local ignored = 0\
12943function Draw(self)\
12944 self.IsDrawing = true\
12945 if self.OnDraw then\
12946 self:OnDraw()\
12947 end\
12948\
12949 if self.View and self.View:NeedsDraw() then\
12950 self.View:Draw()\
12951 Drawing.DrawBuffer()\
12952 if isDebug then\
12953 drawCalls = drawCalls + 1\
12954 end\
12955 elseif not self.View then\
12956 print('No loaded view. You need to do program:LoadView first.')\
12957 end \
12958\
12959 if self:GetActiveObject() and self.CursorPos and type(self.CursorPos[1]) == 'number' and type(self.CursorPos[2]) == 'number' then\
12960 term.setCursorPos(self.CursorPos[1], self.CursorPos[2])\
12961 term.setTextColour(self.CursorColour)\
12962 term.setCursorBlink(true)\
12963 else\
12964 term.setCursorBlink(false)\
12965 end\
12966\
12967 self.IsDrawing = false\
12968end\
12969\
12970function EventHandler(self)\
12971 local event = { os.pullEventRaw() }\
12972 \
12973 if self.EventHandlers[event[1]] then\
12974 for i, e in ipairs(self.EventHandlers[event[1]]) do\
12975 e(self, unpack(event))\
12976 end\
12977 end\
12978end\
12979\
12980function Quit(self)\
12981 self.Running = false\
12982 if self.OnQuit then\
12983 self:OnQuit()\
12984 end\
12985 if OneOS then\
12986 OneOS.Close()\
12987 end\
12988end\
12989\
12990function Run(self, ready)\
12991 if not term.isColour or not term.isColour() then\
12992 print('This program requires an advanced (golden) comptuer to run, sorry.')\
12993 error('', 0)\
12994 end\
12995\
12996 for name, events in pairs(eventFuncs) do\
12997 if self[name] then\
12998 for i, event in ipairs(events) do\
12999 self:RegisterEvent(event, self[name])\
13000 end\
13001 end\
13002 end\
13003\
13004 if self.AllowTerminate then\
13005 self:RegisterEvent('terminate', function()error('Terminated', 0) end)\
13006 end\
13007\
13008 if self.DefaultView and self.DefaultView ~= '' and fs.exists(self.ViewPath..self.DefaultView..'.view') then\
13009 self:LoadView(self.DefaultView)\
13010 end\
13011\
13012 if ready then\
13013 ready()\
13014 end\
13015 \
13016 self:Draw()\
13017\
13018 while self.Running do\
13019 self:EventHandler()\
13020 end\
13021end",
13022}
13023
13024local function run(tArgs)
13025
13026 local fnFile, err = loadstring(files['startup'], 'startup')
13027 if err then
13028 error(err)
13029 end
13030
13031 local function split(str, pat)
13032 local t = {}
13033 local fpat = "(.-)" .. pat
13034 local last_end = 1
13035 local s, e, cap = str:find(fpat, 1)
13036 while s do
13037 if s ~= 1 or cap ~= "" then
13038 table.insert(t,cap)
13039 end
13040 last_end = e+1
13041 s, e, cap = str:find(fpat, last_end)
13042 end
13043 if last_end <= #str then
13044 cap = str:sub(last_end)
13045 table.insert(t, cap)
13046 end
13047 return t
13048 end
13049
13050 local function resolveTreeForPath(path, single)
13051 local _files = files
13052 local parts = split(path, '/')
13053 if parts then
13054 for i, v in ipairs(parts) do
13055 if #v > 0 then
13056 if _files[v] then
13057 _files = _files[v]
13058 else
13059 _files = nil
13060 break
13061 end
13062 end
13063 end
13064 elseif #path > 0 and path ~= '/' then
13065 _files = _files[path]
13066 end
13067 if not single or type(_files) == 'string' then
13068 return _files
13069 end
13070 end
13071
13072 local oldFs = fs
13073 local env
13074 env = {
13075 fs = {
13076 list = function(path)
13077 local list = {}
13078 if fs.exists(path) then
13079 list = fs.list(path)
13080 end
13081 for k, v in pairs(resolveTreeForPath(path)) do
13082 if not fs.exists(path .. '/' ..k) then
13083 table.insert(list, k)
13084 end
13085 end
13086 return list
13087 end,
13088
13089 exists = function(path)
13090 if fs.exists(path) then
13091 return true
13092 elseif resolveTreeForPath(path) then
13093 return true
13094 else
13095 return false
13096 end
13097 end,
13098
13099 isDir = function(path)
13100 if fs.isDir(path) then
13101 return true
13102 else
13103 local tree = resolveTreeForPath(path)
13104 if tree and type(tree) == 'table' then
13105 return true
13106 else
13107 return false
13108 end
13109 end
13110 end,
13111
13112 isReadOnly = function(path)
13113 if not fs.isReadOnly(path) then
13114 return false
13115 else
13116 return true
13117 end
13118 end,
13119
13120 getName = fs.getName,
13121
13122 getSize = fs.getSize,
13123
13124 getFreespace = fs.getFreespace,
13125
13126 makeDir = fs.makeDir,
13127
13128 move = fs.move,
13129
13130 copy = fs.copy,
13131
13132 delete = fs.delete,
13133
13134 combine = fs.combine,
13135
13136 open = function(path, mode)
13137 if fs.exists(path) then
13138 return fs.open(path, mode)
13139 elseif type(resolveTreeForPath(path)) == 'string' then
13140 local handle = {close = function()end}
13141 if mode == 'r' then
13142 local content = resolveTreeForPath(path)
13143 handle.readAll = function()
13144 return content
13145 end
13146
13147 local line = 1
13148 local lines = split(content, '\n')
13149 handle.readLine = function()
13150 if line > #lines then
13151 return nil
13152 else
13153 return lines[line]
13154 end
13155 line = line + 1
13156 end
13157 return handle
13158 else
13159 error('Cannot write to read-only file (compilr archived).')
13160 end
13161 else
13162 return fs.open(path, mode)
13163 end
13164 end
13165 },
13166
13167 io = {
13168 input = io.input,
13169 output = io.output,
13170 type = io.type,
13171 close = io.close,
13172 write = io.write,
13173 flush = io.flush,
13174 lines = io.lines,
13175 read = io.read,
13176 open = function(path, mode)
13177 if fs.exists(path) then
13178 return io.open(path, mode)
13179 elseif type(resolveTreeForPath(path)) == 'string' then
13180 local content = resolveTreeForPath(path)
13181 local f = fs.open(path, 'w')
13182 f.write(content)
13183 f.close()
13184 if mode == 'r' then
13185 return io.open(path, mode)
13186 else
13187 error('Cannot write to read-only file (compilr archived).')
13188 end
13189 else
13190 return io.open(path, mode)
13191 end
13192 end
13193 },
13194
13195 loadfile = function( _sFile )
13196 local file = env.fs.open( _sFile, "r" )
13197 if file then
13198 local func, err = loadstring( file.readAll(), fs.getName( _sFile ) )
13199 file.close()
13200 return func, err
13201 end
13202 return nil, "File not found: ".._sFile
13203 end,
13204
13205 dofile = function( _sFile )
13206 local fnFile, e = env.loadfile( _sFile )
13207 if fnFile then
13208 setfenv( fnFile, getfenv(2) )
13209 return fnFile()
13210 else
13211 error( e, 2 )
13212 end
13213 end
13214 }
13215
13216 setmetatable( env, { __index = _G } )
13217
13218 local tAPIsLoading = {}
13219 env.os.loadAPI = function( _sPath )
13220 local sName = fs.getName( _sPath )
13221 if tAPIsLoading[sName] == true then
13222 printError( "API "..sName.." is already being loaded" )
13223 return false
13224 end
13225 tAPIsLoading[sName] = true
13226
13227 local tEnv = {}
13228 setmetatable( tEnv, { __index = env } )
13229 local fnAPI, err = env.loadfile( _sPath )
13230 if fnAPI then
13231 setfenv( fnAPI, tEnv )
13232 fnAPI()
13233 else
13234 printError( err )
13235 tAPIsLoading[sName] = nil
13236 return false
13237 end
13238
13239 local tAPI = {}
13240 for k,v in pairs( tEnv ) do
13241 tAPI[k] = v
13242 end
13243
13244 env[sName] = tAPI
13245 tAPIsLoading[sName] = nil
13246 return true
13247 end
13248
13249 env.shell = shell
13250
13251 setfenv( fnFile, env )
13252 fnFile(unpack(tArgs))
13253end
13254
13255local function extract()
13256 local function node(path, tree)
13257 if type(tree) == 'table' then
13258 fs.makeDir(path)
13259 for k, v in pairs(tree) do
13260 node(path .. '/' .. k, v)
13261 end
13262 else
13263 local f = fs.open(path, 'w')
13264 if f then
13265 f.write(tree)
13266 f.close()
13267 end
13268 end
13269 end
13270 node('', files)
13271end
13272
13273local tArgs = {...}
13274if #tArgs == 1 and tArgs[1] == '--extract' then
13275 extract()
13276else
13277 run(tArgs)
13278end