Anuncios Google

Explorador de archivos sencillo en LuaDEV (rápido, con FOR)

Antes que nada... que no hay otros tutoriales de exploradores? Si, pero algunos no son eficientes (se alentan cuando hay muchos archivos en una carpeta) o presentan bugs (como al entrar a una carpeta vacía), por eso me dí a la tarea de facilitarles un nuevo tutorial, con poco code y corrigiendo las deficiencias que pudiera haber en otros.

Empezaremos definiendo algunas variables que necesitaremos:

lista,ant = files.list("ms0:/"),"ms0:/"
ini,sel = 1,1

La variable lista tendrá... pues eso, la lista de archivos. La variable ant almacenará la ruta que contiene los elementos que estamos viendo, y nos servirá para regresar. Por qué defino una variable y no uso la ruta de alguno de los elementos? Porque obtendríamos un bonito error al tratar de regresar después de entrar a una carpeta vacía (porque no hay elementos para tomar su ruta y regresar). Las variables ini y sel nos darán el punto de inicio para imprimir la lista de archivos, y el elemento seleccionado, respectivamente.
También vamos a necesitar una variable extra, muy importante para evitar que nuestro explorador se alente si hay muchos archivos, la definimos así:

  if #lista > 15 then lim=15 else lim=#lista end

15 es un número cualquiera que me acabo de sacar de la manga, es el número máximo de elementos que se van a imprimir en pantalla (que variará de acuerdo al tamaño de fuente que usemos). Así, si hay más de 15 elementos en la ruta actual, sólo se imprimen 15 (y si son menos, pues se imprimen todos).

Abrimos nuestro ciclo infinito como siempre, leemos controles y declaramos una variable que nos va servir para imprimir la lista sin que se sobrepongan los elementos:

while true do
controls.read()
  y=25

Ese 25 de nuevo es ficticio, indica dónde se va empezar a imprimir nuestra lista de archivos. Abro una megacondición, para englobar todo el code que no necesito ejecutar en caso de que la carpeta esté vacía:

if #lista > 0 then

Vamos a imprimir la lista usando un sencillo for, que inicie en nuestra variable ini y termine en lim (con esto evitaremos lentitud en nuestro explorador):

 for i=ini,lim do

Por ahora, todo lo imprimiremos del mismo tamaño y color, sólo poniendo el elemento seleccionado un poco a la derecha para reconocerlo:

	if i==sel then
	  screen.print(25,y,files.nopath(lista[i].name))
	else
	  screen.print(5,y,files.nopath(lista[i].name))
	end

Y cerramos el for, moviendo la variable y para que los otros elementos no se sobrepongan:

	  y=y+15
  end

Toca hacer el scroll. Va ser un poco más complejo debido a que tenemos una variable extra (lim), así que pongo el code y explico:

	  if controls.press("down") or controls.r() then
		if sel<lim then sel=sel+1
		  elseif lim+1<=#lista then
			ini,sel,lim=ini+1,sel+1,lim+1
		  end
	  end

Cuando presionemos la flecha abajo, primero va verificar si el elemento seleccionado (sel) está antes del final de la lista (lim). Si lo está, sumamos uno a sel (sin tocar las otras variables), pero si ya está al final de la lista (sel=lim) verifica si hay más elementos para mostrar (lim+1<=#lista) y de haberlos suma 1 a todas las variables (ini, sel, lim). Le añadí una comprobación para el gatillo R, para lograr un efecto de scroll rápido (que no es muy preciso que digamos, pero se ve bien xD).
Para desplazarnos hacia arriba es lo mismo, sólo que usaremos ini en lugar de lim, otros botones, e invertiremos los signos de las sumas y comparaciones:

  if controls.press("up") or controls.l() then
    if sel>ini then sel=sel-1
      elseif ini-1>=1 then
	ini,sel,lim=ini-1,sel-1,lim-1
       end
  end

Ahora haremos el code que nos permitirá entrar a las carpetas. Básicamente comprobamos si se pulsa X sobre una carpeta, en caso afirmativo guardamos la ruta en la variable ant (para regresar después) y recargamos la lista de archivos, así como las variables ini, sel y lim. Queda entonces como sigue:

	if controls.press("cross") and lista[sel].directory then
	  ant=lista[sel].name
		lista = files.list(ant)
		  ini,sel = 1,1
		if #lista > 15 then lim=15 else lim=#lista end
	end

Cerramos la megacondición añadiendo su respectivo else, por si la carpeta está vacía imprima el aviso correspondiente:

else
  screen.print(5,25,"CARPETA VACÍA")
end

Vamos a añadir ahora el code para regresar. Lo haremos fuera de la megacondición para que, en caso de entrar a una carpeta vacía, la única opción que tengamos sea regresar (regresaremos con el círculo).
Para esta parte primero vamos a redefinir ant, usando la función files.nofile para tumbarle la última parte a la ruta que contiene (por ejemplo, si ant fuera PSP/GAME, al usar files.nofile quedaría como PSP), y de nuevo recargamos tanto la lista de archivos como las variables ini, sel y lim, quedando como sigue:

	if controls.press("circle") then
	  ant=files.nofile(ant)
		lista = files.list(ant)
		  ini,sel = 1,1
		if #lista > 15 then lim=15 else lim=#lista end
	end

Ya para terminar, colocamos nuestro flip y cerramos el while:

screen.flip()
end

En este punto, nuestro explorador ya funciona. Se vería así:

Vamos a añadirle alguna que otra cosilla, para hacerlo más vistoso (y de paso, para mostrarles un truco para no llenar de condiciones repetitivas el code). Primeramente, vamos a colorear los elementos, dependiendo de su tipo. Para empezar, vamos a definir una tabla al inicio de nuestro script, con un color para cada tipo de archivo, así:

fcolor={
pbp=color.new(125,0,0),
mp3=color.new(125,125,0),
png=color.new(0,125,0),
lua=color.new(0,125,125)
}

Con esos pocos basta para el ejemplo xD. En nuestro for que imprime la lista de archivos, añadimos esta condición:

	if lista[i].directory then ccolor=color.new(0,0,125)
	  else ccolor=nil end

Que lo que hace es verificar si el elemento que toca imprimir es una carpeta. En caso afirmativo define un color (ccolor), y en caso contrario le asigna valor nil (nulo o nada, ahora veremos por qué). Los prints que usamos anteriormente los vamos a cambiar por algo más complejo, así:

	if i==sel then
	  screen.print(10,y,files.nopath(lista[i].name),0.9,ccolor or fcolor[files.ext(lista[i].name)] or color.new(155,155,155),color.new(0,0,0))
	else
	  screen.print(5,y,files.nopath(lista[i].name),0.6,ccolor or fcolor[files.ext(lista[i].name)] or color.new(155,155,155),color.new(0,0,0))
	end

Por qué tan largos? Por qué tanto or dentro del print? Es válido..? Vamos por partes y desde lo más básico. En Lua se permite que un argumento de una función se asigne entre varios posibles usando or. En nuestro caso se procede de la siguiente forma:

  • Si existe la variable ccolor (si el elemento que toca imprimir es carpeta) se usa ese valor (en nuestro caso color azul).
  • Si no existe ccolor (por eso asigamos el valor de nil a la variable si el elemento no es carpeta), se trata de obtener el color de la tabla que definimos al principio, usando la extensión del elemento actual (obtenida con la función files.ext). En caso de que exista, se usa ese valor.
  • Si tampoco existiera el color en la tabla (que caray... se nos olvidó definirlo xD), se usa el tercer valor (un color gris claro en este caso), como color por default.

En otras palabras, asignar argumentos de esa manera conlleva condiciones implícitas. Si el primer argumento no es usable, verifica si el segundo lo es. Si no, verifica el tercero y así sucesivamente hasta que encuentre uno que pueda usar (de los posibles que le damos, por eso puse un color fijo al final). Con esta propiedad de Lua, logramos colorear los elementos de acuerdo a su tipo, sin usar más que una condición y sin levantar errores cuando no tenemos un color definido para algún tipo de archivo. Mejor aún, si queremos añadir más colores para otros tipos de archivos, sólo los añadimos a la tabla y listo, no hay necesidad de modificar el resto de nuestro script.
Aprovechamos también para imprimir el elemento seleccionado un poco más grande que el resto.

En este punto, nuestro explorador se vería así:

Bastante más agradable no? Y cuando volteamos a ver nuestro script, resulta aún más agradable al contener sólo 51 líneas. Le podemos añadir fondo, funciones para trabajar con los archivos, la hora, la fecha... de aquí en adelante queda a criterio de cada quién ;)

DESCARGAR CÓDIGO ENTERO


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de gdljjrod

Listo port a ONElua

Aquí les dejamos el script para lo nuevo en onelua

color.loadpalette()
 
fcolor={pbp=color.green,mp3=color.yellow,png=color.new(0,125,0),lua=color.chocolate}
lista,ant = files.list("ms0:/"),"ms0:/"
ini,sel = 1,1
if #lista > 15 then lim=15 else lim=#lista end
 
while true do
screen.clear(color.navy)
buttons.read()
y=25
buttons.interval(10,10)--aqui modifica y checa los cambios al presionar arriba y abajo recomendado (10,10)
if #lista > 0 then
	for i=ini,lim do
		if lista[i].directory then ccolor=color.red else ccolor=nil end
 
		if i==sel then
			screen.print(10,y,lista[i].name,0.9,ccolor or fcolor[lista[i].ext] or color.new(155,155,155))
		else
			screen.print(5,y,lista[i].name,0.6,ccolor or fcolor[lista[i].ext] or color.new(155,155,155))
		end
		y+=15
	end
 
	if buttons.cross and lista[sel].directory then
		ant=lista[sel].path
		lista = files.list(ant)
		ini,sel = 1,1
		if #lista > 15 then lim=15 else lim=#lista end
	end
 
	if buttons.down or buttons.r then
		if sel<lim then sel+=1
		elseif lim+1<=#lista then
			ini,sel,lim=ini+1,sel+1,lim+1
		end
	end
 
	if buttons.up or buttons.l then
		if sel>ini then sel-=1
		elseif ini-1>=1 then
			ini,sel,lim=ini-1,sel-1,lim-1
		end
	end
 
else
	screen.print(5,25,"CARPETA VACÍA")
end
 
	if buttons.circle then
		ant=files.nofile(ant)
		lista = files.list(ant)
		ini,sel = 1,1
		if #lista > 15 then lim=15 else lim=#lista end
	end
 
screen.flip()
end


 

Sencillo y eficáz

Un código relativamente corto para hacer un explorador que funciona a la perfección, anda que si lo hiciera yo estaría eso más lleno de ifs...

 

PD: Va genial!

Salu2!

Imagen de -chus-

excelente

Muy buen tutorial, buena explicacion, sin duda nos servirá de mucho, hay detalles que no sabia XD gracias Rober :D

Imagen de Jepte

sencillo genial y rápido

sencillo genial y rápido explorador XD

Imagen de -DjB

Sencillo, poco code, fácil de

Sencillo, poco code, fácil de usar y lo mejor de todo que no se usan tanto IFs como en el otro con FOR.

Felicidades, me gusta y buen tuto, sigue así.

Pd: Por qué no eres coder? Si haces muchas cosas muy geniales.


Imagen de gdljjrod

Es programador

Solo que no lleva su banderita xD

Imagen de -DjB

Jejeje por eso digo.

Jejeje por eso digo.

Imagen de gdljjrod

Simple y genial

Muy buen tutorial, no cabe duda, realmente es muy simple el code sin tener que incorporar miles de if´s, todo con un bonito FOR para el explorador de archivos.

Y nuevo para mi en el IF para tomar el color

fcolor[files.ext(lista[i].name)]

Se entiende que en esa pequeña linea de code detecta el color según el tipo de archivo. Xd


 

Si, creo que se me olvidó dar

Si, creo que se me olvidó dar una breve explicación de esa línea, pero mirando la documentación de LuaDEV entenderán que files.ext nos regresa la extensión de un archivo, y eso se usa como índice para tratar de obtener un color de la tabla fcolor. Normalmente si el color no existiera saltaría un error, pero como colocamos los or, pues lo evitamos :)

Imagen de Chimecho

Creo que...

¿Los índices eran case sensitive? Si es así, deberías poner un :tolower() a la extensión y ya está :D

Si pensé eso, pero por alguna

Si pensé eso, pero por alguna extraña razón LuaDEV los nombres los imprime en mayus, y no peta usando los índices en minus. Está raro no?

Imagen de Chimecho

Es extraño...

A menos de que dev haya considerado eso y haya puesto un tolower en el files.ext o:

Imagen de Jepte

creo que si por que en hm7

creo que si por que en hm7 tengo que poner:

if string.sub(string.lower(carpeta[archivo].name),-3)=="png" then

Imagen de Chimecho

Una cosa

Es más rápido si haces el lower afuera y el sub dentro, porque el lower recorre toda la cadena y a como lo tienes, recorrería TODA la cadena y luego separaría los últimos 3 caracteres. En cambio de la forma que te digo primero separaría los 3 caracteres y luego el .lower recorrería esos 3 :)

 

Saludos!



PSP FAT [5.00 M33-6] [6.60 ME] [Hard Moded] / Nintendo Wii [4.1U] [cIOS Hermes] [D2X cIOS] / iPhone 3G [4.2.1] [BB 05.13.04] [redsn0w] / iPod Touch 4 [6.1] [evasi0n]

07/05/10: Tuve el placer de llamarle con todo derecho "N00B" a molotovi xDDD

Recuerda: Sé el intérprete -_-

Imagen de Jepte

mmm, no lo pensé ya que no es

mmm, no lo pensé ya que no es tan necesario pero tienes razón lo tendré en cuenta :) .

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.