OS:
http://pastebin.com/2P2pjvJu
Spoiler
local running=1
local size={term.getSize()}
function KaoSOS()
local function count(input)
if type(input)~="table" then
print("incorrect input: "..tostring(input))
sleep(2)
return
end
local int=0
for a in pairs(input) do
int=int+1
end
return int
end
local function getlongest(input)
if type(input)~="table" then
print("incorrect input")
return
end
local int=0
for k,v in pairs(input) do
for a,b in pairs(v) do
if string.len(:D/>/>>int then
int=#b
end
end
end
return int
end
function addparam(params)
print('Current parameters: ')
for k,v in pairs(params) do
print(v)
end
write('enter new parameter: ')
params[(#params or 0)+1]=read()
return 'added'
end
function createnew()
term.clear()
term.setCursorPos(1,1)
write('enter new file name: ')
local new=read()
if new=='' then
print('Invalid entry')
sleep(2)
elseif fs.exists(new) then
print('File already exists')
sleep(2)
else
shell.run('edit',new)
end
end
function check(input)
return menu2.generate({{{'run',{function() running=0 shell.run(input) running=1 term.clear() end}}, {'run with parameters',{runwith,input}}},{{'edit',{function() running=0 shell.run("edit",input) running=1 term.clear() end}}, {'delete',{fs.delete,input}}}},15,3,2,size[1]-4,size[2]-2)
end
function runwith(input,params)
local params=params or {}
while menu2.generate({{{'done',{function() running=0 shell.run(input,unpack(params)) running=1 term.clear() end}},{'add param',{addparam,params}}}},15,3,2,size[1]-4,size[2]-2)=='added' do
end
end
while true do
local tall={}
if shell.dir()=='' then
tall['tdirs']={{}}
else
tall['tdirs']={{{'[..]',{shell.setDir,shell.resolve("..")}}}}
end
tall['tfiles']={{{'#new',{createnew}}}}
for k,v in pairs(fs.list(shell.dir())) do
if fs.isDir(shell.resolve(v)) then
var='tdirs'
else
var='tfiles'
end
if #tall[var][#tall[var]]==3 then
tall[var][#tall[var]+1]={}
end
tall[var][#tall[var]][#tall[var][#tall[var]]+1]={((var=='tdirs' and '['..v..']') or v),{((var=='tdirs' and shell.setDir) or check),shell.resolve(v)}}
end
for k,v in pairs(tall['tfiles']) do
tall['tdirs'][#tall['tdirs']+1]=v
end
local size={term.getSize()}
--drawborder()
running=1
menu2.generate(tall['tdirs'],15,3,2,size[1]-4,size[2]-2)
end
end
local function drawborder()
local size={term.getSize()}
for i=1,size[2] do
term.setCursorPos(2,i)
if i==1 then
write('/'..string.rep('-',size[1]-4)..'')
elseif i==size[2] then
write(''..string.rep('-',size[1]-4)..'/')
else
write('|')
term.setCursorPos(size[1]-1,i)
write('|')
end
end
end
function cyclingborder(processor,delim)
while true do
if processor<=size[1]-4 then
side='top'
break
else
processor=processor-(size[1]-2)
if processor<=size[2] then
side='right'
break
else
processor=processor-size[2]
if processor<=size[1]-4 then
side='bottom'
break
else
processor=processor-(size[1]-2)
if processor<=size[2] then
side='left'
break
else
processor=processor-size[2]
end
end
end
end
end
term.setCursorPos((side=='top' and processor+2) or (side=='bottom' and size[1]-processor-1) or (side=='left' and 2) or (side=='right' and size[1]-1),(side=='top' and 1) or (side=='bottom' and size[2]) or (side=='left' and size[2]-processor) or (side=='right' and processor))
write(delim or '*')
end
co1=coroutine.create(function() local a=0 while true do a=a+1 drawborder() cyclingborder(a) cyclingborder(a+1) cyclingborder(a+2) cyclingborder(a+3) sleep(0.1) end end)
co2=coroutine.create(KaoSOS)
term.clear()
os.queueEvent('start')
while true do
events={os.pullEvent()}
coroutine.resume(co2,unpack(events))
if running==1 then coroutine.resume(co1,unpack(events)) end
end
Menu API:
http://pastebin.com/X9cC2MS3
Spoiler
--[SYNTAX:
apiname.generate(table, separator, x1, y1, x2, y2, delim1, delim2)
an example of its use can be found at http://pastebin.com/LTBY9xcW
table - a table of all the options selectable and what to do if each option is selected
the format of table is:
table[y][x][1]='displayed option'
table[y][x][2]=another table where the first value is the function to call (exclude the brackets after it and do not make it a string, it is a function) and all values after it are passed to the function as arguments
separator - the x distance between the first character of each option (default is 10)
x1,y1,x2 and y2 are used to generate a box in which the menu is generated
x1 and y1 are the co-ordinates of the top left corner
x2 and y2 are the co-ordinates of the bottom right corner
delim1 and 2 are the character to display before and after the selected option (default is '>' and '<')
]
function generate(input,dist,offsetx,offsety,limx,limy,delim1,delim2)
--[Required functions]
local function pullfirst(input)
local first=input[1]
local temp={}
for k,v in pairs(input) do
if k~=1 then
temp[#temp+1]=v
end
end
return first,temp
end
local function cleararea(...)
local pos={term.getCursorPos()}
local args={...}
for y=args[2], args[2]+args[4]-1 do
term.setCursorPos(args[1],y)
write(string.rep(' ',args[3]-args[1]+1))
end
term.setCursorPos(pos[1],pos[2])
end
--[Gathering initial information and declaring variables]
local scrolledx=0
local scrolledy=0
local selectedx=1
local selectedy=1
local lastx=0
dist=dist or 10
local columnmaxlen={}
local maxlen=0
for b,y in pairs(input) do
for a,x in pairs(y) do
if columnmaxlen[a] or 0<string.len(x[1]) then
columnmaxlen[a]=string.len(x[1])
end
end
end
for a,b in pairs(columnmaxlen) do
if string.len(:P/>/>>maxlen then
maxlen=string.len(:)/>/>
end
end
while true do
--[Render the menu]
cleararea(offsetx,offsety,limx,limy)
lastx=0
for b,y in pairs(input) do
for a,x in pairs(y) do
currentlen=dist*(a-scrolledx-1)+columnmaxlen[a]
if b>scrolledy and b<=limy-offsety+scrolledy+1 and a>scrolledx and currentlen<limx-offsetx+1 then
lastx=(lastx<=a and a) or lastx
if a==selectedx and b==selectedy then
term.setCursorPos(offsetx+a*dist-scrolledx*dist-dist,offsety+b-1-scrolledy)
write((delim1 or '>')..x[1]..(delim2 or delim1 or '<'))
else
term.setCursorPos(offsetx+1+a*dist-scrolledx*dist-dist,offsety+b-1-scrolledy)
write(x[1])
end
end
end
end
print('')
--[Detect keypresses for interface and adjust variables accordingly]
while true do
local event,key=os.pullEvent('key')
if key==203 and selectedx>1 then
selectedx=selectedx-1
if selectedx<=scrolledx then
scrolledx=scrolledx-1
end
break
elseif key==205 and selectedx<#input[selectedy] then
selectedx=selectedx+1
if selectedx>lastx then
scrolledx=scrolledx+1
end
break
elseif key==200 and selectedy>1 then
selectedy=selectedy-1
if selectedy<=scrolledy then
scrolledy=scrolledy-1
end
break
elseif key==208 and selectedy<#input then
selectedy=selectedy+1
if selectedy>limy-offsety+scrolledy+1 then
scrolledy=scrolledy+1
end
break
elseif key==28 then
local cmd={pullfirst(input[selectedy][selectedx][2])}
return cmd[1](unpack(cmd[2]))
end
end
if selectedx>#input[selectedy] then
selectedx=#input[selectedy]
end
end
end
EDIT: in case that was unclear: the border stops generating after you edit a file from the browser