This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KingofGamesYami's profile picture

Filebrowser Help

Started by KingofGamesYami, 18 October 2014 - 01:46 AM
KingofGamesYami #1
Posted 18 October 2014 - 03:46 AM
I've been working on and off on a new OS, but I've run into a snag. My filebrowser is acting up when I try to add additional options.
The installer can be found here: http://pastebin.com/m7VH2PFt (understand, this is BETA). It's not released yet. The part I'm trying to get to work is this section:


local function fileBrowse( dir )
	dir = dir or "/"
	local list = fs.list( dir )
	local dirs, files = {}, {}
	for k, v in pairs( list ) do
		if fs.isDir( fs.combine( dir, v ) ) and v:sub( 1, 1 ) ~= "." then
			table.insert( dirs, v )
		elseif v:sub( 1, 1 ) ~= "." then
			table.insert( files, v )
		end
	end
	table.sort( dirs )
	table.sort( files )
	local selected = menu( dir, unpack( dirs ), unpack( files ) ) --#This line
	if selected == "New dir" then
		term.clear()
		term.setCursorPos( 1, 1 )
		term.write( "Dir name: " .. dir )
		local dName = read()
		fs.makeDir( fs.combine( dir, dName ) )
	elseif selected == "New file" then
		term.clear()
		term.setCursorPos( 1, 1 )
		term.write( "File name: " )
		local fName = read()
		shell.run( "edit " .. fs.combine( dir, fName ) )
	else
		local path = fs.combine( dir, selected )
		if fs.isDir( path ) then
			return fileBrowse( path )
		end
		return path
	end
end
Here's what I'm attempting to change the marked line to:

	local selected = menu( dir, unpack( dirs ), unpack( files ), "New dir", "New file" ) --#This line
When I change it, it only shows 2 dirs/files and "New dir" and "New file" for reasons unknown to me.

And, just in case (although this works perfectly), here's the menu function:


local function menu( title, ... )
    --edit the background color to make the GUI more unique
	term.setBackgroundColor( colors.black )
	local debug = false --#turn to true to see what it's thinking
	local tArgs = { ... }
	local pages = {[1]={}}
	for i = 1, #tArgs, 1 do
		if #pages[ #pages ] == 7 then
			pages[ #pages + 1 ] = {}
		end
		pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
	end
	local maxLen = 0
	for k, v in ipairs( tArgs ) do
		if #v > maxLen then maxLen = #v end
	end
	local maxx, maxy = term.getSize()
	if maxLen > maxx - 20 then
		error( 'longest string is too long', 2 )
	end
	local centerx = math.ceil( maxx/2 )
	local centery
	local yValue = {}
	local page = 1
	local selected = math.ceil( #pages[ page ] / 2 )
	local function render()
		local tbl = pages[ page ]
		centery = (maxy/2) - #tbl/2
		term.clear()
		term.setCursorPos( centerx - #title/2 + 1, 2 )
		term.write( title )
		for i = 1, #tbl do
			term.setCursorPos( centerx - (#tbl[i]/2), centery + i )
			yValue[ i ] = centery + i
			term.write( tbl[ i ] )
		end
		if pages[ page - 1 ] then
			term.setCursorPos( 3, centery + #tbl/2 + 1 )
			term.write( "previous" )
		end
		if pages[ page + 1 ] then
			term.setCursorPos( maxx - 5, centery + #tbl/2 + 1 )
			term.write( "next" )
		end
		local str = "(" .. page .. "/" .. #pages .. ")"
		term.setCursorPos( centerx - (#str/2), maxy )
		term.write( str )
	end
	while true do
		render()
		if debug then
			term.setCursorPos( 1, 1 )
			term.write( selected )
			term.setCursorPos( 1, 2 )
			term.write( page )
		end
		if term.isColor() then
			term.setTextColor( colors.yellow )
		end
		if selected == "previous" and not pages[ page - 1 ] then
			selected = math.ceil( #pages[ page ]/2 )
		elseif selected == "next" and not pages[ page + 1 ] then
			selected = math.ceil( #pages[ page ]/2 )
		end
		if type( selected ) == "number" then
			term.setCursorPos( centerx - (#pages[page][selected]/2) - 3, yValue[ selected ] )
			term.write( "[" )
			term.setCursorPos( centerx + (#pages[page][selected]/2) + 2, yValue[ selected ] )
			term.write( "]" )
		elseif selected == "previous" then
			term.setCursorPos( 1, centery + #pages[ page ]/2 + 1 )
			term.write( "[" )
			term.setCursorPos( 12, centery + #pages[ page ]/2 + 1 )
			term.write( "]" )
		elseif selected == "next" then
			term.setCursorPos( maxx - 7, centery + #pages[ page ]/2 + 1 )
			term.write( "[" )
			term.setCursorPos( maxx, centery + #pages[ page ]/2 + 1 )
			term.write( "]" )
		end
		if term.isColor() then
			term.setTextColor( colors.white )
		end
		local event, key = os.pullEvent( "key" )
		local old = selected
		if key == 200 and type( selected ) == "number" and pages[ page ][ selected - 1 ] then
			selected = selected - 1
		elseif key == 208 and type( selected ) == "number" and pages[ page ][ selected + 1 ] then
			selected = selected + 1
		elseif key == 28 then
			if type( selected ) == "number" then
				return pages[ page ][ selected ]
			elseif selected == "next" and pages[ page + 1 ] then
				page = page + 1
			elseif selected == "previous" and pages[ page - 1 ] then
				page = page - 1
			end
		elseif key == 203 then
			if selected == "next" then
				selected = math.ceil( #pages[ page ]/2 )
			elseif type( selected ) == "number" and pages[ page - 1 ] then
				selected = "previous"
			end
		elseif key == 205 then
			if selected == "previous" then
				selected = math.ceil( #pages[ page ]/2 )
			elseif type( selected ) == "number" and pages[ page + 1 ] then
				selected = "next"
			end
		end
	end
end
Edited on 18 October 2014 - 01:50 AM
Gumball #2
Posted 19 October 2014 - 04:31 AM
Checking the code right now, will post in a minute.

Sorry, im good at LUA/ComputerCraft, I understand some but couldn't understand it all D; sorry, I can't but, actually POST what it does and not say "acting up".
AgentE382 #3
Posted 19 October 2014 - 05:17 AM
From the Lua 5.1 Reference Manual (emphasis mine):
Both function calls and vararg expressions can result in multiple values. If an expression is used as a statement (only possible for function calls (see §2.4.6)), then its return list is adjusted to zero elements, thus discarding all returned values. If an expression is used as the last (or the only) element of a list of expressions, then no adjustment is made (unless the call is enclosed in parentheses). In all other contexts, Lua adjusts the result list to one element, discarding all values except the first one.
In other words, since the function calls to unpack aren't last, you will only get the first element from each list. What you'll need to do is combine everything into one big table, then unpack it all at once.

Just a note, your code was actually broken even before you noticed it. Try creating five directories next to each other. It won't list them, even though it'll list all of the files you have. By adding those extra strings at the end of your menu function call parameter list, you cut off the file list, just like the file list cut off the directory list before.
Edited on 19 October 2014 - 03:19 AM
KingofGamesYami #4
Posted 19 October 2014 - 04:18 PM
From the Lua 5.1 Reference Manual (emphasis mine):
Both function calls and vararg expressions can result in multiple values. If an expression is used as a statement (only possible for function calls (see §2.4.6)), then its return list is adjusted to zero elements, thus discarding all returned values. If an expression is used as the last (or the only) element of a list of expressions, then no adjustment is made (unless the call is enclosed in parentheses). In all other contexts, Lua adjusts the result list to one element, discarding all values except the first one.
In other words, since the function calls to unpack aren't last, you will only get the first element from each list. What you'll need to do is combine everything into one big table, then unpack it all at once.

Just a note, your code was actually broken even before you noticed it. Try creating five directories next to each other. It won't list them, even though it'll list all of the files you have. By adding those extra strings at the end of your menu function call parameter list, you cut off the file list, just like the file list cut off the directory list before.
Yeah, that sounds like the problem. I tried moving the unpacks to the end, it worked better, but left out all directories other than rom. I'll try doing the big table thing later.
Lyqyd #5
Posted 19 October 2014 - 07:29 PM
Yeah, the point of that quoted passage is that you can only have one unpack() actually work in a single set of arguments, and if any of them are going to work, they need to be the very last element. So, the folders table will only give you the first element in it, probably /rom/, and the files table will give you its whole contents.