· 5 years ago · Jan 25, 2021, 01:36 AM
1--[[
2 Mouse File Browser
3 by:
4 Stiepen irc(Kilobyte)
5 Cruor
6 BigSHinyToys
7
8 note: send link to nightin9ale on CC forums
9--]]
10
11local tArgs = {...}
12local ver = "1.4"
13local sTitle = "File Browser"
14local bugTest, norun, dir, showAll
15local _tArgs = {}
16local config = "mouse.cfg"
17
18local temp
19if shell and shell.getRunningProgram then
20 temp = shell.getRunningProgram()
21end
22
23temp = temp or "/bla"
24local localPath = string.sub(temp,1,#temp-string.len(fs.getName(temp)))
25temp = nil -- just because not needed
26
27-- load config file
28
29local configSet = {}
30local cnf = {}
31
32if fs.exists(localPath.."/"..config) then
33 local file = fs.open(localPath.."/"..config,"r")
34 if file then
35 local item = file.readLine()
36 while item do
37 table.insert(cnf,item)
38 item = file.readLine()
39 end
40 file.close()
41 end
42end
43
44for i = 1,10 do
45 local test,data = pcall(textutils.unserialize,cnf[i])
46 if test then
47 configSet[i] = data
48 else
49 configSet[i] = nil
50 end
51end
52cnf = nil
53
54-- color configuration work in progress
55local titleBar = configSet[1] or {txt = colors.white,back = colors.gray}
56local addressBar = configSet[2] or {txt = colors.white,back = colors.lightGray}
57local itemWindo = configSet[3] or {txt = colors.white,back = colors.black}
58local rcmList = configSet[4] or {txt = colors.white,back = colors.lightGray} -- rcm = Right Click Menu List
59local rcmTitle = configSet[5] or {txt = colors.white,back = colors.blue}
60local dialogTitle = configSet[6] or {txt = colors.white,back = colors.gray}
61local dialogWindo = configSet[7] or {txt = colors.white,back = colors.lightGray}
62local scrollCol = configSet[8] or {off = colors.gray, button = colors.gray,back = colors.lightGray}
63
64local tIcons = configSet[9] or {
65 back = {tCol = "lightGray",bCol = "gray",txt = " < "},
66 disk = {tCol = "yellow",bCol = "gray",txt = "[*]"},
67 audio = {tCol = "red",bCol = "gray",txt = "(o)"},
68 folder = {tCol = "lightGray",bCol = "gray",txt = "[=]"},
69 file = {tCol = nil ,bCol = nil ,txt = nil}
70}
71
72local customLaunch = configSet[10] or {
73 ["Edit"] = "rom/programs/edit",
74 ["Paint"] = "rom/programs/color/paint"
75}
76
77local function saveCFG(overWrite)
78 if not fs.exists(localPath.."/"..config) or overWrite then
79 local cnf = {}
80 local file = fs.open(localPath.."/"..config,"w")
81 if file then
82 file.write(textutils.serialize(titleBar).."\n")
83 file.write(textutils.serialize(addressBar).."\n")
84 file.write(textutils.serialize(itemWindo).."\n")
85 file.write(textutils.serialize(rcmList).."\n")
86 file.write(textutils.serialize(rcmTitle).."\n")
87 file.write(textutils.serialize(dialogTitle).."\n")
88 file.write(textutils.serialize(dialogWindo).."\n")
89 file.write(textutils.serialize(scrollCol).."\n")
90 file.write(textutils.serialize(tIcons).."\n")
91 file.write(textutils.serialize(customLaunch).."\n")
92 file.close()
93 elseif overWrite then
94 end
95 end
96end
97
98saveCFG()
99
100-- end configuration
101
102local function help()
103 print([[Usage: browser [-d] [-h] [-a] [-u] [--debug] [--help] [--dir <dir>] [--all] [--update]
104--debug or -d: enable debug mode
105--help or -h: display this screen
106--dir: define initial directory
107--all or -a: show hidden files
108--update -u: update]])
109end
110
111local function inBouwndry(clickX,clickY,boxX,boxY,width,hight)
112 return ( clickX >= boxX and clickX < boxX + width and clickY >= boxY and clickY < boxY + hight )
113end
114
115local function update()
116 print("Checking for Updates")
117 local isHTTP = false
118 local response
119 if http then
120 isHTTP = true
121 print("http on")
122 response = http.get("http://pastebin.com/raw.php?i=rLbnyM1U")
123 end
124 local flag = false
125 local isNewFlag = false
126 local newVerID
127 if response and isHTTP then
128 print("recived")
129 local sInfo = response.readLine()
130 print(sInfo)
131 while sInfo do
132 print(sInfo)
133 if flag then
134 if sInfo == ver then
135 print("Mouse File Browser is up to date")
136 break
137 else
138 newVerID = sInfo
139 flag = false
140 isNewFlag = true
141 end
142 elseif sInfo == sTitle then
143 flag = true
144 elseif isNewFlag then
145 isNewFlag = sInfo
146 response.close()
147 break
148 end
149 sInfo = response.readLine()
150 end
151 if isNewFlag then
152 print("New vershion avalible "..newVerID)
153 print('downloading to \Browser')
154 if fs.exists("Browser") then
155 write("Browser exists OverWrite Browser Y/N : ")
156 local input = string.lower(read())
157 while input ~= "y" and input ~= "n" do
158 print("y or n required")
159 input = string.lower(read())
160 end
161 if input == "y" then
162 print("Over Writeing Browser")
163 print("Downloading new File")
164 local response = http.get("http://pastebin.com/raw.php?i="..isNewFlag)
165 if response then
166 print("file downloaded")
167 print("installing")
168 fs.delete("Browser")
169 local handel = fs.open("Browser","w")
170 if handel then
171 handel.write(response.readAll())
172 handel.close()
173 print("Update Complete")
174 end
175 response.close()
176 end
177 else
178 print("Update aborted")
179 end
180 else
181 print("Downloading new File")
182 local response = http.get("http://pastebin.com/raw.php?i="..isNewFlag)
183 if response then
184 print("file downloaded")
185 print("installing")
186 local handel = fs.open("Browser","w")
187 if handel then
188 handel.write(response.readAll())
189 handel.close()
190 print("Update Complete")
191 end
192 response.close()
193 end
194 end
195 end
196 elseif isHTTP then
197 print("Error downloading update file Please contact BigSHinyToys on the CC forums")
198 print("http://www.computercraft.info/forums2/index.php?/topic/5509-advanced-computer-mouse-file-browser/")
199 elseif not isHTTP then
200 print("HTTP API is turned off")
201 print("Access Computer Craft Configer and change line")
202 print([[enableapi_http {
203# Enable the "http" API on Computers
204general=false
205}
206TO THIS :
207enableapi_http {
208# Enable the "http" API on Computers
209general=true
210}]])
211 end
212 notCMD = false
213 norun = true
214end
215
216for a = 1, #tArgs do
217 if tArgs[a]:sub(1,2) == "--" then
218 local cmd = tArgs[a]:sub(3):lower()
219 if cmd == "debug" then
220 bugTest = true
221 elseif cmd == "help" then
222 help()
223 norun = true
224 elseif cmd == "dir" then
225 dir = tArgs[a+1]
226 a = a + 1
227 elseif cmd == "all" then
228 showAll = true
229 elseif cmd == "update" then
230 update()
231 end
232 elseif tArgs[a]:sub(1,1) == "-" then
233 for b = 2, #tArgs[a] do
234 cmd = tArgs[a]:sub(b, b)
235 if cmd == "d" then
236 bugTest = true
237 elseif cmd == "h" then
238 help()
239 norun = true
240 elseif cmd == "p" then
241 dir = tArgs[a+1]
242 a = a + 1
243 elseif cmd == "a" then
244 showAll = true
245 elseif cmd == "u" then
246 update()
247 end
248 end
249 else
250 table.insert(_tArgs, tArgs[a])
251 end
252end
253
254if (not dir) and shell and shell.dir then
255 dir = shell.dir()
256end
257
258if dir and shell and shell.resolve then
259 dir = shell.resolve(dir)
260end
261
262dir = dir or "/"
263
264if bugTest then -- this is that the var is for testing
265 print("Dir: "..dir)
266 os.startTimer(4)
267 os.pullEvent()
268end
269
270local function clear()
271 term.setBackgroundColor(colors.black)
272 term.setTextColor(colors.white)
273 term.clear()
274 term.setCursorBlink(false)
275 term.setCursorPos(1,1)
276end
277
278--[[
279 Code thanks to Cruor
280 http://www.computercraft.info/forums2/index.php?/topic/5802-support-for-shell/
281]]--
282
283local function fixArgs(...)
284 local tReturn={}
285 local str=table.concat({...}," ")
286 local sMatch
287 while str and #str>0 do
288 if string.sub(str,1,1)=="\"" then
289 sMatch, str=string.match(str, "\"(.-)\"%s*(.*)")
290 else
291 sMatch, str=string.match(str, "(%S+)%s*(.*)")
292 end
293 table.insert(tReturn,sMatch)
294 end
295 return tReturn
296end
297
298--[[ end Cruor function ]]--
299
300
301-- modified read made to play nice with coroutines
302
303local function readMOD( _sReplaceChar, _tHistory,_wdth)
304 local sLine = ""
305 term.setCursorBlink( true )
306
307 local nHistoryPos = nil
308 local nPos = 0
309 if _sReplaceChar then
310 _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
311 end
312
313 local sx, sy = term.getCursorPos()
314
315 local w, h = term.getSize()
316 if _wdth and type(_wdth) == "number" then
317 w = sx + _wdth - 1
318 end
319
320 local function redraw( _sCustomReplaceChar )
321 local nScroll = 0
322 if sx + nPos >= w then
323 nScroll = (sx + nPos) - w
324 end
325
326 term.setCursorPos( sx + _wdth - 1, sy )
327 term.write(" ")
328 term.setCursorPos( sx, sy )
329 local sReplace = _sCustomReplaceChar or _sReplaceChar
330 if sReplace then
331 term.write( string.rep(sReplace,_wdth) )
332 else
333 term.write( string.sub( sLine, nScroll + 1 ,nScroll + _wdth) )
334 end
335 term.setCursorPos( sx + nPos - nScroll, sy )
336 end
337
338 while true do
339 local sEvent, param = os.pullEvent()
340 if sEvent == "char" then
341 sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
342 nPos = nPos + 1
343 redraw()
344
345 elseif sEvent == "key" then
346
347 if param == keys.left then
348 -- Left
349 if nPos > 0 then
350 nPos = nPos - 1
351 redraw()
352 end
353
354 elseif param == keys.right then
355 -- Right
356 if nPos < string.len(sLine) then
357 nPos = nPos + 1
358 redraw()
359 end
360
361 elseif param == keys.up or param == keys.down then
362 -- Up or down
363 if _tHistory then
364 redraw(" ");
365 if param == keys.up then
366 -- Up
367 if nHistoryPos == nil then
368 if #_tHistory > 0 then
369 nHistoryPos = #_tHistory
370 end
371 elseif nHistoryPos > 1 then
372 nHistoryPos = nHistoryPos - 1
373 end
374 else
375 -- Down
376 if nHistoryPos == #_tHistory then
377 nHistoryPos = nil
378 elseif nHistoryPos ~= nil then
379 nHistoryPos = nHistoryPos + 1
380 end
381 end
382
383 if nHistoryPos then
384 sLine = _tHistory[nHistoryPos]
385 nPos = string.len( sLine )
386 else
387 sLine = ""
388 nPos = 0
389 end
390 redraw()
391 end
392 elseif param == keys.backspace then
393 -- Backspace
394 if nPos > 0 then
395 redraw(" ");
396 sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
397 nPos = nPos - 1
398 redraw()
399 end
400 elseif param == keys.home then
401 -- Home
402 nPos = 0
403 redraw()
404 elseif param == keys.delete then
405 if nPos < string.len(sLine) then
406 redraw(" ");
407 sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
408 redraw()
409 end
410 elseif param == keys["end"] then
411 -- End
412 nPos = string.len(sLine)
413 redraw()
414 end
415 elseif sEvent == "redraw" then
416 redraw()
417 elseif sEvent == "return" then
418 term.setCursorBlink( false )
419 return sLine
420 end
421 end
422
423 term.setCursorBlink( false )
424
425 return sLine
426end
427
428-- end modified read
429
430local function printC(posX,posY,textCol,backCol,text)
431 term.setCursorPos(posX,posY)
432 term.setTextColor(colors[textCol] or textCol)
433 term.setBackgroundColor(colors[backCol] or backCol)
434 term.write(text)
435end
436
437local function InputBox(title)
438 local boxW,boxH = 26,3
439 local termX,termY = term.getSize()
440 local ofsX,ofsY = math.ceil((termX/2) - (boxW/2)) , math.ceil((termY/2) - (boxH/2)) -- offset from top left
441 local options = {"ok","cancel"}
442
443 local selected = 1
444 local space = 0
445 local range = {}
446 for i = 1,#options do
447 range[i] = {s = space,f = space + string.len(options[i])}
448 space = space + string.len(options[i])+3
449 end
450 local ofC = (boxW/2) - (space/2)
451
452 local function drawBox()
453 printC(ofsX,ofsY,colors.black,colors.blue,string.rep(" ",boxW))
454 printC(ofsX+1,ofsY,colors.black,colors.gray,(title or "User Input"))
455 printC(ofsX,ofsY+1,colors.black,colors.white,string.rep(" ",boxW))
456 printC(ofsX,ofsY+2,colors.black,colors.white,string.rep(" ",boxW))
457 printC(ofsX,ofsY+3,colors.black,colors.white,string.rep(" ",boxW))
458
459 for i = 1,#options do
460 if i == selected then
461 term.setBackgroundColor(colors.lightGray)
462 term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)
463 term.write("["..options[i].."]")
464 term.setBackgroundColor(colors.white)
465 term.write(" ")
466 else
467 term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)
468 term.write(" "..options[i].." ")
469 end
470 end
471
472 printC(ofsX+2,ofsY+2,colors.black,colors.lightGray,string.rep(" ",boxW-4))
473 end
474 drawBox()
475 term.setCursorPos(ofsX+2,ofsY+2)
476 local co = coroutine.create(function() return readMOD(nil,nil,boxW - 4) end)
477 while true do
478 local event = {os.pullEvent()}
479 if event[1] == "key" or event[1] == "char" then
480 if event[2] == 28 then
481 local test,data = coroutine.resume(co,"return")
482 return data
483 else
484 coroutine.resume(co,unpack(event))
485 end
486 elseif event[1] == "mouse_click" then
487 if event[4] == ofsY + 3 then
488 for i = 1,#options do
489 if event[3] >= range[i].s + ofC + ofsX - 1 and event[3] <= range[i].f + ofC + ofsX then
490 if options[i] == "ok" then
491 local test,data = coroutine.resume(co,"return")
492 return data
493 elseif options[i] == "cancel" then
494 return false
495 end
496 end
497 end
498 end
499 end
500 end
501end
502
503local function dialogBox(title,message,options, h, w)
504 term.setCursorBlink(false)
505 local selected = 1
506 title = title or ""
507 message = message or ""
508 options = options or {}
509 local boxW,boxH = (w or 26), (h or 3)
510 local termX,termY = term.getSize()
511 local ofsX,ofsY = math.ceil((termX/2) - (boxW/2)) , math.ceil((termY/2) - (boxH/2)) -- offset from top left
512
513 local space = 0
514 local range = {}
515 for i = 1,#options do
516 range[i] = {s = space,f = space + string.len(options[i])}
517 space = space + string.len(options[i])+3
518 end
519 local ofC = math.ceil((boxW/2)) - math.ceil((space/2))
520
521 local function drawBox()
522 printC(ofsX,ofsY,dialogTitle.txt,dialogTitle.back," "..title..string.rep(" ",boxW-#title-5).."_[]")
523 term.setBackgroundColor(colors.red)
524 term.setTextColor(colors.white)
525 term.write("X")
526 printC(ofsX,ofsY+1,dialogWindo.txt,dialogWindo.back,string.sub(" "..message..string.rep(" ",boxW),1,boxW))
527 term.setCursorPos(ofsX,ofsY+2)
528 term.write(string.rep(" ",boxW))
529 term.setCursorPos(ofsX,ofsY+3)
530 term.write(string.rep(" ",boxW))
531 for i = 1,#options do
532 if i == selected then
533 printC(range[i].s + ofC + ofsX - 1,ofsY + 3,"black","lightGray","["..options[i].."]")
534 term.setBackgroundColor(dialogWindo.back)
535 term.setTextColor(dialogWindo.txt)
536 term.write(" ")
537 else
538 term.setCursorPos(range[i].s + ofC + ofsX - 1,ofsY + 3)
539 term.write(" "..options[i].." ")
540 end
541 end
542 term.setCursorPos(ofsX + ofC + space,ofsY + 3)
543 term.write(string.rep(" ",boxW - (ofC + space)))
544 term.setBackgroundColor(colors.black)
545 term.setTextColor(colors.white)
546 end
547 while true do
548 drawBox()
549 event = {os.pullEvent()}
550 if event[1] == "key" then
551 if event[2] == 203 then -- left
552 selected = selected - 1
553 if selected < 1 then
554 selected = #options
555 end
556 elseif event[2] == 205 then -- right
557 selected = selected + 1
558 if selected > #options then
559 selected = 1
560 end
561 elseif event[2] == 28 then -- enter
562 return selected , options[selected]
563 end
564 elseif event[1] == "mouse_click" then
565
566 if bugTest then term.write("M "..event[2].." X "..event[3].." Y "..event[4].." ") end
567
568 if event[2] == 1 then
569 if event[4] == ofsY + 3 then
570 for i = 1,#options do
571 if event[3] >= range[i].s + ofC + ofsX - 1 and event[3] <= range[i].f + ofC + ofsX then
572 return i , options[i]
573 end
574 end
575 end
576 end
577 end
578 end
579end
580
581local flag = true
582local fSlash = "/"
583local path = {dir:match("[^/]+")}
584local function stringPath() -- compacted this a lot
585 return fSlash..table.concat(path,fSlash)
586end
587
588local function osRunSpaces(sFileLocation,...) -- getRunningProgram() ["shell"] = shell
589 clear()
590 if os.newThread then
591 os.newThread(false,...)
592 else
593 local fProg,probblem = loadfile(sFileLocation)
594 if fProg then
595 local tEnv = {["shell"] = {}}
596 setmetatable(tEnv.shell,{ __index = shell})
597 tEnv.shell.getRunningProgram = function()
598 return sFileLocation
599 end
600 setmetatable(tEnv,{ __index = _G})
601 setfenv(fProg,tEnv)
602 local test,probblem = pcall(fProg,...)
603 if not test then
604 print(probblem)
605 dialogBox("ERROR",tostring(probblem),{"ok"},3,30)
606 else
607 return true
608 end
609 else
610 print(probblem)
611 dialogBox("ERROR",tostring(probblem),{"ok"},3,30)
612 end
613 end
614end
615
616local function rClickMenu(title,tList,tItem,posX,posY)
617
618 term.setCursorBlink(false)
619 local BoxTitle = title
620 local choices = {}
621 local termX,termY = term.getSize()
622 local offX,offY
623
624 local width = #BoxTitle + 2
625 local hight
626
627 for k,v in pairs(tList) do
628 if v ~= nil then
629 table.insert(choices,k)
630 end
631 if width < #k + 2 then
632 width = #k + 2
633 end
634 end
635
636 if #choices == 0 then
637 return
638 end
639
640 hight = #choices + 1
641 table.sort(choices)
642
643 offX,offY = math.ceil((termX/2) - (width/2)),math.ceil((termY/2) - (hight/2))
644
645 if posX and posY then -- offX,offY = posX,posY
646 if posX >= termX - width - 1 then
647 offX = termX - width - 1
648 else
649 offX = posX
650 end
651 if posY >= termY - hight then
652 offY = termY - hight
653 else
654 offY = posY
655 end
656 end
657
658 local function reDrawer()
659 printC(offX,offY,rcmTitle.txt,rcmTitle.back," "..BoxTitle..string.rep(" ",width - #BoxTitle - 1))
660 for i = 1,#choices do
661 printC(offX,offY + i,rcmList.txt,rcmList.back," "..choices[i]..string.rep(" ",width - #choices[i] - 1))
662 end
663 end
664
665 while true do
666 reDrawer()
667 local event = {os.pullEvent()}
668 if event[1] == "mouse_click" then
669 if event[2] == 1 then -- event[3] = x event[4] = y
670 if event[4] > offY and event[4] < hight + offY and event[3] >= offX and event[3] < width + offX then
671 --dialogBox("ERROR:",type(tList[choices[event[4] - offY]]),{"ok"})
672 if type(tList[choices[event[4] - offY]]) == "function" then
673 return tList[choices[event[4] - offY]](tItem)
674 elseif type(tList[choices[event[4] - offY]]) == "table" then
675 return rClickMenu("Options",tList[choices[event[4] - offY]],tItem,event[3],event[4])
676 elseif type(tList[choices[event[4] - offY]]) == "string" then
677 return osRunSpaces(
678 unpack(
679 fixArgs(
680 tList[choices[event[4] - offY]].." \""..stringPath()..fSlash..tItem.n.."\""
681 )
682 )
683 )
684 else
685 dialogBox("ERROR:","somthing up with new rMenu",{"ok"})
686 end
687 else
688 return
689 end
690 elseif event[2] == 2 then
691 return
692 end
693 end
694 end
695
696end
697
698local function preferences()
699 local tItem = {
700 {txt = "Title Bar",it = titleBar},
701 {txt = "Address Bar",it = addressBar},
702 {txt = "Item Windo", it = itemWindo},
703 {txt = "Title Right Click Title",it = rcmTitle},
704 {txt = "Right Click Menu",it = rcmList},
705 {txt = "Title Dialog Box",it = dialogTitle},
706 {txt = "Dialog Box",it = dialogWindo},
707 {txt = "Scroll Bar",it = scrollCol}
708 }
709 local topL,topR = 13,5
710 local width,hight = 23,6
711 local bottomL,bottomR = topL + width,topR + hight
712
713 local listOffset = 0
714 local sel = 1
715 local otherSel = 1
716 local otherItems = {}
717
718 if tItem[sel] then
719 for k,v in pairs(tItem[sel].it) do
720 table.insert(otherItems,{txt = k,it = v})
721 end
722 end
723
724 local function draw()
725 printC(topL,topR,titleBar.txt,titleBar.back,string.sub(" Preferences "..string.rep(" ",width),1,width))
726 for i = 0,12,4 do
727 for a = 1,4 do
728 --printC(topL + (a*12)-12 ,topR + ((i+4)/4),4,2^(a+i-1)," "..tostring(2^(a+i-1)))
729 printC(topL + a-1 ,topR + ((i+4)/4),4,2^(a+i-1)," ")
730 end
731 end
732 local sSel = " "
733 for i = 1,hight - 2 do
734 if i == sel - listOffset then
735 sSel = ">"
736 end
737 if tItem[i+listOffset] then
738 printC(topL + 4 ,topR + i,colors.black,colors.white,string.sub(sSel..tItem[i+listOffset].txt..string.rep(" ",width),1,width - 4))
739 else
740 printC(topL + 4 ,topR + i,colors.black,colors.white,sSel..string.rep(" ",width-5))
741 end
742 if i == sel - listOffset then
743 sSel = " "
744 end
745 end
746 term.setCursorPos(topL,topR + hight - 1)
747 local loop = 1
748 local length = 0
749 for i = 1,#otherItems do
750 if otherSel == i then
751 sSel = ">"
752 end
753 if colors.black == otherItems[i].it or colors.gray == otherItems[i].it then
754 term.setTextColor(colors.white)
755 else
756 term.setTextColor(colors.black)
757 end
758 term.setBackgroundColor(otherItems[i].it)
759 term.write(sSel..tostring(otherItems[i].txt).." ")
760 length = length + #otherItems[i].txt + 2
761 if otherSel == i then
762 sSel = " "
763 end
764 loop = loop+1
765 end
766 term.setBackgroundColor(colors.white)
767 term.write(string.rep(" ",width - length))
768 end
769 while true do
770 draw()
771 local event = {os.pullEvent()}
772 if event[1] == "mouse_click" and event[2] == 1 then
773 if inBouwndry(event[3],event[4],topL,topR,width,hight) then
774 local inSideX,inSideY = event[3] - topL,event[4] - topR
775 if inBouwndry(inSideX+1,inSideY,1,1,4,4) and tItem[sel] then
776 --[[
777 term.setCursorPos(1,1)
778 term.setBackgroundColor(2^(inSideX + ((inSideY*4)-4)))
779 print(2^(inSideX + ((inSideY*4)-4))," ",inSideX + ((inSideY*4)-4)," ")
780 ]]--
781 tItem[sel]["it"][otherItems[otherSel].txt] = (2^(inSideX + ((inSideY*4)-4)))
782 end
783 end
784 elseif event[1] == "key" then
785 if event[2] == 200 then
786 sel = sel - 1
787 elseif event[2] == 208 then
788 sel = sel + 1
789 elseif event[2] == 203 then
790 otherSel = otherSel - 1
791 elseif event[2] == 205 then
792 otherSel = otherSel + 1
793 elseif event[2] == 28 then
794 if dialogBox("Confirm","Save prefrences?",{"Yes","No"}) == 1 then
795 saveCFG(true)
796 end
797 return
798 end
799 end
800 if sel < 1 then
801 sel = 1
802 elseif sel > #tItem then
803 sel = #tItem
804 end
805 if sel > listOffset + hight - 2 then
806 listOffset = listOffset + 1
807 elseif sel - listOffset < 1 then
808 listOffset = listOffset - 1
809 end
810
811 otherItems = {}
812 if tItem[sel] then
813 for k,v in pairs(tItem[sel].it) do
814 table.insert(otherItems,{txt = k,it = v})
815 end
816 end
817
818 if otherSel < 1 then
819 otherSel = 1
820 elseif otherSel > #otherItems then
821 otherSel = #otherItems
822 end
823
824 if bugTest then
825 term.setBackgroundColor(colors.black)
826 term.setTextColor(colors.white)
827 term.setCursorPos(1,1)
828 term.clearLine()
829 term.write("sel "..sel.." offset "..listOffset)
830 end
831 end
832end
833
834local function fileSelect(mode) -- save_file open_file browse < not yet implemented
835
836 local title = sTitle.." "..ver
837 local bRun = true
838 local clipboard = nil
839 local cut = false
840
841 local termX,termY = term.getSize()
842 local offsetX,offsetY = 1,1
843 local hight,width = math.ceil(termY-2),math.ceil(termX-2)
844 local oldHight,oldWidth
845
846 -- offsets
847 local boxOffX,boxOffY = offsetX,offsetY + 2
848 local boxH,boxW = hight - 2 ,width - 2
849
850 local barX,barY = offsetX + 1,offsetY + 2
851 local barH,barW = 1,width - 1
852
853 local tbarX,tbarY = offsetX + 1,offsetY + 1
854 local tbarH,tbarW = 1,width - 1
855
856 local exitX,exitY = offsetX + width - 1 ,offsetY + 1
857
858 local pading = string.rep(" ",boxW)
859 local list
860
861 local listOff = 0
862
863 local sPath
864 local tItemList = {}
865
866 local function newList()
867 listOff = 0
868 flag = true
869 tItemList = {{n = "..", id = "back"}} -- adds a back item at top of list
870 sPath = stringPath()
871 local folders = {}
872 local files = {}
873 local disks = {}
874 if not fs.exists(sPath) then
875 path = {}
876 sPath = stringPath()
877 dialogBox("ERROR:","Path no longer exists",{"ok"})
878 end
879 local test,list = pcall(fs.list,sPath) -- stopes fs.list crash
880 if list == nil then
881 list = {}
882 dialogBox("ERROR : ","fs.list crashed",{"ok"})
883 end
884 if #path == 0 then
885 for i,v in pairs(rs.getSides()) do
886 if disk.isPresent(v) then
887 if disk.hasData(v) then
888 table.insert(tItemList,{n = disk.getMountPath(v), id = "disk",s = v})
889 disks[disk.getMountPath(v)] = true
890 elseif disk.hasAudio(v) then
891 table.insert(tItemList,{n = disk.getAudioTitle(v), id = "audio",s = v})
892 end
893 end
894 end
895 end
896 for i,v in pairs(list) do
897 if fs.isDir(sPath..fSlash..v) then
898 table.insert(folders,v)
899 else
900 table.insert(files,v)
901 end
902 end
903 table.sort(folders)
904 table.sort(files)
905 for i,v in pairs(folders) do
906 if disks[v] == nil then
907 table.insert(tItemList,{n = v, id = "folder"})
908 end
909 end
910 for i,v in pairs(files) do
911 table.insert(tItemList,{n = v, id = "file"})
912 end
913 end
914
915 local function paste()
916 if cut then
917 local s, m = pcall(
918 function()
919 fs.move(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash..clipboard[2])
920 cut = false
921 clipboard = nil
922 end)
923 if not s then
924 dialogBox("Error", (m or "Couldn't move"), {"ok"}, 4, 30)
925 end
926 if bugTest then
927 local x, y = term.getCursorPos()
928 term.setCursorPos(1, ({term.getSize()})[2])
929 write("from "..clipboard[1]..fSlash..clipboard[2].." to "..stringPath()..fSlash..clipboard[2])
930 end
931 else
932 local s, m = pcall(function()
933 if fs.exists(stringPath()..fSlash..clipboard[2]) then
934 fs.copy(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash.."copy-"..clipboard[2])
935 else
936 fs.copy(clipboard[1]..fSlash..clipboard[2], stringPath()..fSlash..clipboard[2])
937 end
938 end)
939 if not s then
940 dialogBox("Error", (m or "Couldn't copy"), {"ok"}, 4, 30)
941 end
942 if bugTest then
943 local x, y = term.getCursorPos()
944 term.setCursorPos(1, ({term.getSize()})[2])
945 write("from "..clipboard[1]..fSlash..clipboard[2].." to "..stringPath()..fSlash..clipboard[2])
946 end
947 end
948 newList()
949 end
950
951 -- this section bellow handles the right click menu
952
953 local tmenu = {
954 disk = {
955 ["Open"] = function(tItem)
956 table.insert(path,tItem.n)
957 newList()
958 end,
959 ["Copy"] = function(tItem)
960 clipboard = {stringPath(), tItem.n}
961 cut = false
962 end,
963 ["Eject"] = function(tItem)
964 if dialogBox("Confirm","Eject "..fSlash..tItem.n.." "..tItem.s,{"yes","no"}) == 1 then
965 disk.eject(tItem.s)
966 newList()
967 end
968 end,
969 ["ID label"] = function(tItem)
970 dialogBox("ID label",disk.getDiskID(tItem.s).." "..tostring(disk.getLabel(tItem.s)),{"ok"})
971 end,
972 ["Set label"] = function(tItem)
973 local name = InputBox("Label?")
974 if name then
975 disk.setLabel(tItem.s,name)
976 end
977 end,
978 ["Clear label"] = function(tItem)
979 if dialogBox("Confirm","Cleal Label from "..tItem.s,{"yes","no"}) == 1 then
980 disk.setLabel(tItem.s)
981 end
982 end
983 },
984 folder = {
985 ["Open"] = function(temp)
986 table.insert(path,temp.n)
987 newList()
988 end,
989 ["Copy"] = function(tItem)
990 clipboard = {stringPath(), tItem.n}
991 cut = false
992 end,
993 ["Cut"] = function(tItem)
994 clipboard = {stringPath(), tItem.n}
995 cut = true
996 end,
997 ["Delete"] = function(tItem)
998 if dialogBox("Confirm","Delete "..tItem.id.." "..tItem.n,{"yes","no"}) == 1 then
999 if fs.isReadOnly(stringPath()..fSlash..tItem.n) then
1000 dialogBox("ERROR",tItem.id.." Is read Only",{"ok"})
1001 else
1002 fs.delete(stringPath()..fSlash..tItem.n)
1003 newList()
1004 end
1005 end
1006 end,
1007 ["Rename"] = function(tItem)
1008 local sName = InputBox("New Name")
1009 if type(sName) == "string" and sName ~= "" then
1010 local s, m = pcall(function()
1011 fs.move(stringPath()..fSlash..tItem.n,stringPath()..fSlash..sName)
1012 end)
1013 if not s then
1014 dialogBox("Error", (m or "Rename failed"), {"ok"})
1015 end
1016 end
1017 newList()
1018 end
1019 },
1020 file = {
1021 ["Run"] = {
1022 ["Run"] = function(tItem)
1023 osRunSpaces(stringPath()..fSlash..tItem.n)
1024 end,
1025 ["Run CMD"] = function(tItem)
1026 local cmd = InputBox("Commands")
1027 if cmd then
1028 osRunSpaces(stringPath()..fSlash..tItem.n,unpack(fixArgs(cmd)))
1029 end
1030 end,
1031 },
1032 ["Open With"] = customLaunch,
1033 ["Rename"] = function(tItem)
1034 local sName = InputBox("New Name")
1035 if type(sName) == "string" and sName ~= "" then
1036 local s, m = pcall(function()
1037 fs.move(stringPath()..fSlash..tItem.n,stringPath()..fSlash..sName)
1038 end)
1039 if not s then
1040 dialogBox("Error", (m or "Rename failed"), {"ok"})
1041 end
1042 end
1043 newList()
1044 end,
1045 ["Delete"] = function(tItem)
1046 if dialogBox("Confirm","Delete "..tItem.id.." "..tItem.n,{"yes","no"}) == 1 then
1047 if fs.isReadOnly(stringPath()..fSlash..tItem.n) then
1048 dialogBox("ERROR",tItem.id.." Is read Only",{"ok"})
1049 else
1050 fs.delete(stringPath()..fSlash..tItem.n)
1051 newList()
1052 end
1053 end
1054 end,
1055 ["Cut"] = function(tItem)
1056 clipboard = {stringPath(), tItem.n}
1057 cut = true
1058 end,
1059 ["Copy"] = function(tItem)
1060 clipboard = {stringPath(), tItem.n}
1061 cut = false
1062 end
1063 },
1064 audio = {
1065 ["Play"] = 1,
1066 ["Eject"] = 1
1067 },
1068 back = {
1069 },
1070 blank = { -- tmenu.blank.Paste =
1071 ["Paste"] = nil,
1072 ["New File"] = function()
1073 local name = InputBox()
1074 if name then
1075 if fs.exists(stringPath()..fSlash..name) then
1076 dialogBox("ERROR","Name exists",{"ok"})
1077 else
1078 local file = fs.open(stringPath()..fSlash..name,"w")
1079 if file then
1080 file.write("")
1081 file.close()
1082 newList()
1083 else
1084 dialogBox("ERROR","File not created",{"ok"})
1085 end
1086 end
1087 end
1088 end,
1089 ["New Folder"] = function()
1090 local name = InputBox()
1091 if name then
1092 if fs.exists(stringPath()..fSlash..name) then
1093 dialogBox("ERROR","Name exists",{"ok"})
1094 else
1095 if pcall(fs.makeDir,stringPath()..fSlash..name) then
1096 newList()
1097 else
1098 dialogBox("ERROR","Access Denied",{"ok"})
1099 end
1100 end
1101 end
1102 end,
1103 ["Preferences"] = preferences
1104 },
1105 }
1106
1107 -- end right click menu
1108
1109 local function scrollBar(posX,posY)
1110 if posX == boxOffX+boxW+1 and posY > boxOffY and posY <= boxOffY+boxH then
1111 if #tItemList > boxH then
1112 if posY == boxOffY + 1 then
1113 listOff = 0
1114 elseif posY == boxOffY+boxH then
1115 listOff = #tItemList + 1 - boxH
1116 else
1117 listOff = math.ceil((posY - boxOffY - 1 )*(((#tItemList - boxH+2)/boxH)))
1118 end
1119 flag = true
1120 end
1121 end
1122 end
1123
1124 newList()
1125
1126 while bRun do
1127 if flag then
1128 flag = false
1129 -- clear
1130 if oldHight ~= hight and oldWidth ~= width then
1131 term.setBackgroundColor(colors.black)
1132 term.clear()
1133 oldHight,oldWidth = hight,width
1134 end
1135 -- draw top title bar
1136 local b = tbarW - #title -2
1137 if b < 0 then
1138 b = 0
1139 end
1140 printC(tbarX,tbarY,titleBar.txt,titleBar.back,string.sub(" "..title,1,tbarW)..string.rep(" ",b))
1141 term.setTextColor(colors.white)
1142 term.setBackgroundColor(colors.red)
1143 term.write("X")
1144
1145 -- draw location bar
1146 local a = barW - #sPath - 1
1147 if a < 0 then
1148 a = 0
1149 end
1150 local tmppath = sPath
1151 if shell and shell.getDisplayName then
1152 tmppath = shell.getDisplayName(sPath)
1153 --dialogBox("yay")
1154 else
1155 --dialogBox("moop")
1156 end
1157 tmppath = tmppath or sPath
1158 local a = barW - #tmppath - 1
1159 if a < 0 then
1160 a = 0
1161 end
1162 printC(barX,barY,addressBar.txt,addressBar.back,string.sub(" "..tmppath,1,barW)..string.rep(" ",a))
1163
1164 -- draw scroll bar
1165 if #tItemList > boxH then
1166 term.setBackgroundColor(scrollCol.back)
1167 for i = 1,boxH do
1168 term.setCursorPos(boxOffX+boxW+1,i + boxOffY)
1169 local scroll = math.floor( boxH* (listOff/(#tItemList-boxH+2)) )+1
1170 if i == scroll then
1171 term.setBackgroundColor(scrollCol.button)
1172 term.write(" ")
1173 term.setBackgroundColor(scrollCol.back)
1174 else
1175 term.write(" ")
1176 end
1177 end
1178 else
1179 term.setBackgroundColor(scrollCol.off)
1180 for i = 1,boxH do
1181 term.setCursorPos(boxOffX+boxW+1,i + boxOffY)
1182 term.write(" ")
1183 end
1184 end
1185
1186 -- draw main section
1187
1188 for i = 1,boxH do -- listOff
1189 local sel = i+listOff
1190 if tItemList[sel] then
1191 printC(1+boxOffX,i+boxOffY,(tIcons[tItemList[sel].id].tCol or itemWindo.txt),(tIcons[tItemList[sel].id].bCol or itemWindo.back),( tIcons[tItemList[sel].id].txt or " "))
1192 printC(4+boxOffX,i+boxOffY,itemWindo.txt,itemWindo.back,string.sub(" "..tItemList[sel].n..pading,1,boxW-3))
1193 else
1194 printC(1+boxOffX,i+boxOffY,itemWindo.txt,itemWindo.back,pading)
1195 end
1196 end
1197
1198 if bugTest then
1199 printC(1,1,"black","white",listOff.." "..boxOffY.." "..boxH)
1200 end
1201
1202 end
1203
1204 -- react to events
1205 local event = {os.pullEvent()}
1206
1207 if event[1] == "mouse_click" then
1208 if inBouwndry(event[3],event[4],boxOffX+1,boxOffY+1,boxW,boxH) then
1209 local selected = tItemList[event[4]+listOff-boxOffY]
1210 if selected and inBouwndry(event[3],event[4],boxOffX+1,event[4],#selected.n + 4,1) then
1211 if event[2] == 1 then -- left mouse
1212 if selected.id == "back" then
1213 table.remove(path,#path)
1214 newList()
1215 elseif selected.id == "folder" or selected.id == "disk" then
1216 table.insert(path,selected.n)
1217 newList()
1218 elseif selected.id == "file" then
1219 if dialogBox("Run file ?",selected.n,{"yes","no"}) == 1 then
1220 osRunSpaces(stringPath()..fSlash..selected.n)
1221 end
1222 flag = true
1223 end
1224 elseif event[2] == 2 then -- right mouse
1225 rClickMenu("Options",tmenu[selected.id],selected,event[3],event[4])
1226 flag = true
1227 end
1228 elseif event[2] == 2 then -- right clicking not on object
1229 if clipboard then
1230 tmenu.blank.Paste = paste
1231 else
1232 tmenu.blank.Paste = nil
1233 end
1234 rClickMenu("Options",tmenu["blank"],selected,event[3],event[4])
1235 flag = true
1236 end
1237 elseif event[2] == 1 and event[3] == exitX and event[4] == exitY then
1238 if dialogBox("Confirm","Exit application",{"yes","no"}) == 1 then
1239 bRun = false
1240 end
1241 flag = true
1242 elseif event[2] == 1 then
1243 scrollBar(event[3],event[4])
1244 end
1245 elseif event[1] == "mouse_scroll" then -- flag this needs new math
1246 local old = listOff
1247 listOff = listOff + event[2]
1248 if listOff < 0 then
1249 listOff = 0
1250 end
1251 if #tItemList + 1 - boxH > 0 and listOff > #tItemList + 1 - boxH then
1252 listOff = #tItemList + 1 - boxH
1253 elseif listOff > 0 and #tItemList + 1 - boxH < 0 then
1254 listOff = 0
1255 end
1256 if listOff ~= old then
1257 flag = true
1258 end
1259
1260 elseif event[1] == "mouse_drag" then -- scroll bar
1261 scrollBar(event[3],event[4])
1262 elseif event[1] == "disk" or event[1] == "disk_eject" then
1263 newList()
1264 elseif event[1] == "window_resize" then
1265 termX,termY = term.getSize()
1266 offsetX,offsetY = 1,1
1267 hight,width = math.ceil(termY-2),math.ceil(termX-2)
1268
1269 boxOffX,boxOffY = offsetX,offsetY + 2
1270 boxH,boxW = hight - 2 ,width - 2
1271
1272 barX,barY = offsetX + 1,offsetY + 2
1273 barH,barW = 1,width - 1
1274
1275 tbarX,tbarY = offsetX + 1,offsetY + 1
1276 tbarH,tbarW = 1,width - 1
1277
1278 exitX,exitY = offsetX + width - 1 ,offsetY + 1
1279 pading = string.rep(" ",boxW)
1280
1281 flag = true
1282 elseif event[1] == "redraw" then
1283 flag = true
1284 end
1285 end
1286end
1287
1288local function main()
1289 if term.isColor() then
1290 clear()
1291 fileSelect()
1292 clear()
1293 else
1294 error("Not an Advanced Computer (gold) ")
1295 end
1296end
1297
1298local trash = (norun or main())