Rem Project: pathWalker Rem Created: Friday, May 19, 2017 // make if windowed fullscreen set window layout 0,0,0 set window position 0,0 set display mode desktop width(),desktop height(),32 // skinPath$ is the path to the skin file for the window transparency // this tool changes it's work dir so the skin file path must be absolute // you woudn't belive how happy i was the moment i found out i created a "skin.bmp" in every folder global skinPath$ skinPath$=get dir$()+"skin.bmp" // runStr$ will contain the execute string. the programm will exit and run this cmd.exe + with this command if this is set. global runStr$ // variable to save the mouse position. // this will allow to track the mouse outside of the window. // winapi calls do not like globals but arrays are fine. type mousePosType x as integer y as integer endtype dim mousePos(0) as mousePosType // set some globals so the app doesn't need to calculate this everytime. // with the default font, every character is the same width. global G_TW as integer global G_TH as integer G_TW=text width("A") G_TH=text height("Mg") // this saves all the data for one box. // firstLinkedPathIndex and lastLinkedPathIndex defines a range in the paths() array type boxType x1 as integer y1 as integer x2 as integer y2 as integer firstLinkedPathIndex as integer lastLinkedPathIndex as integer endtype dim boxes() as boxType // this saves all the path strings and if the entry is a directory or a file. type pathType name as string isDirectory as integer endtype dim paths() as pathType // load the dll used to get the mouse position. load dll "user32.dll",1 // i get an error if i don't wait here as if the call to the dll is too fast. // i think without the sleep, the app calls a function before the dll is fully loaded... sleep 1 // get the mouse position. call dll 1,"GetCursorPos",mousePos(0) // debug stuff //open console //print to console // open the first box. this is setup to run recursive. openBox(".",get dir$(),-1,-1,-1,-1) // cleanup delete dll 1 // run the command, if set. if runStr$<>"" then execute file "cmd.exe",runStr$,"" : exit end // this function handles the "box". // this contains the "main loop". function openBox(parentPath$,path$,x1parent,y1parent,x2parent,y2parent) // save the old path so it can be reset to this. // then set the work dir to path$ oldpath$=get dir$() set dir path$ // set the x and y coordinates // iff() is my attempt to recreate a call like // "(condition ? if true : else)" // don't know what this is called, but i used it in php and i like it x=iff(x2parent=-1,mousePos(0).x,x2parent) y=iff(y1parent=-1,mousePos(0).y,y1parent+4) // creates a new index in the boxes() array and sets the x1 and y1 values, // adds the file names to the paths() array and sets the x2,y2,first- and lastLinkedPathIndex values // and a check if any of the values are out of bounds. makeBox(x,y) addPaths() checkBoxOutOfBounds(x1parent,y1parent,x2parent,y2parent) // debug stuff //clear console //print boxes().x1;" ";boxes().y1;" ";boxes().x2;" ";boxes().y2 // this sets the window transparency. // it will create a 24bit windows bitmap // and draw a black square for every item in the boxes() array // so those boxes are the only thing that are visible in the window. makeSkin() // this is the "main loop". every box has its own main loop, but only the loop of the last opened box is active and running. repeat // get mouse position every time the loop starts call dll 1,"GetCursorPos",mousePos(0) // display function. may need work if the app runs too slow. // right now the loop redraws every box everytime the loop starts cls drawBoxes() // messy way to get the index value of the item the mouse is hovering. // i=-1 if not inside of the box. if mouseInside(boxes().x1,boxes().y1,boxes().x2,boxes().y2)=1 then i=(mousePos(0).y-boxes().y1)/G_TH else i=-1 // values for the following if checks. // they are wrong if i=-1 x1=boxes().x1 y1=boxes().y1+i*G_TH x2=boxes().x2 y2=y1+G_TH // so they are only called if i>-1 if i>-1 // if the left mouse button is pressed // set runStr$. it will look something like this: /C start "Run File" /D "[PATH]" [FILE NAME] // it is a command for cmd.exe so the file or programm executed is not a child of this window // and my app can close without problems. you will see cmd popup, but i guess that is the least problem. if mouseclick()=1 and runStr$="" then runStr$="/C start "+chr$(34)+"Run File"+chr$(34)+" /D "+chr$(34)+get dir$()+chr$(34)+" "+paths(boxes().firstLinkedPathIndex+i).name : exit if paths(boxes().firstLinkedPathIndex+i).isDirectory=1 then openBox(paths(boxes().firstLinkedPathIndex+i).name,paths(boxes().firstLinkedPathIndex+i).name,x1,y1,x2,y2) endif // if the mouse is on the parent folder item and the left mouse button is pressed // the folder will be opended. // because i=-1 this would not work without this call. if mouseInside(x1parent,y1parent,x2parent,y2parent)=1 and mouseclick()=1 and runStr$="" then runStr$="/C start "+chr$(34)+"Run File"+chr$(34)+" /D "+chr$(34)+get dir$()+chr$(34)+" "+parentPath$ : exit // make things easier for the cpu. sleep 1 // if the window lost focus or the runStr$ is set, exit out of the loop. if HAS FOCUS()=0 or runStr$<>"" then exit // exit the loop if // the mouse is outside of the current box and // the mouse is outside of the parent folder item and // the current box is not the only item in the boxes() array until mouseInside(boxes().x1,boxes().y1,boxes().x2,boxes().y2)=0 and mouseInside(x1parent,y1parent,x2parent,y2parent)=0 and array count(boxes())>0 // cleanup box deletePaths() deleteBox() // set skin again to sync before exit because this will not be called again in the parent loop. makeSkin() // reset work dir set dir oldpath$ ENDFUNCTION function makeSkin() // make a 24bit bmp. this is needed because for whatever reason "set window skin" cannot work with 32bit bmps created with the save image command. createBMP(1,screen width(),screen height()) // draw the background to pink that is used for transparency // rgb(255,0,255)=0xffff00ff drawBMP_box(1,0,0,screen width(),screen height(),0xffff00ff) // draw a black box for every item in the boxes() array for j=0 to array count(boxes()) drawBMP_box(1,boxes(j).x1-1,boxes(j).y1-1,boxes(j).x2+1,boxes(j).y2+1,0xff000000 ) NEXT j // save the bitmap to a file saveBMP(1,1,skinPath$) // set the bitmap as a skin. set window skin skinPath$,255,0,255 ENDFUNCTION // this funtion is kinda messy. function checkBoxOutOfBounds(x1,y1,x2,y2) // get the width and the height w=boxes().x2-boxes().x1 h=boxes().y2-boxes().y1 // no need to check if they go out on the left side of the screen. //if boxes().x1<0 then boxes().x1=0 : boxes().x2=w //if boxes().y1<0 then boxes().y1=0 : boxes().y2=h // handle the box position if it goes outside of the screen. if boxes().x2>screen width() then boxes().x2=x1 : boxes().x1=boxes().x2-w if boxes().y2>screen height() then boxes().y2=screen height() : boxes().y1=boxes().y2-h // no handling if the box height is lagrer than the screen height. // i may add buttons in the future ENDFUNCTION function makeBox(x,y) // create element. the internal itterator is set to the last item. // i only need to work with the last item so i can call the array without an index value array insert at bottom boxes() boxes().x1=x boxes().y1=y // i return the index, but i don't really need it. // i leave it like this for now. ENDFUNCTION index function addPaths() // the first paths() index linked to this box doesn't exist yet. // it will be the first index that i insert below. boxes().firstLinkedPathIndex=array count(paths())+1 // write the file list to the paths() array. perform checklist for files for t=1 to checklist quantity() array insert at bottom paths() paths().name=checklist string$(t) paths().isDirectory=checklist value a(t) if w=x1 and mx=y1 and myscreen width() then x2=screen width() if y2>screen height() then y2=screen height() width=memblock dword(memNr,18) height=memblock dword(memNr,22) y1=height-y1 y2=height-y2 red=rgbr(color) green=rgbg(color) blue=rgbb(color) pos=54+(y*width+x)*3 for y=y2 to y1-1 for x=x1 to x2-1 pos=54+(y*width+x)*3 write memblock byte memNr,pos,blue write memblock byte memNr,pos+1,green write memblock byte memNr,pos+2,red next x next y endfunction // save the bmp to a file function saveBMP(memNr,tmpFileNr,filename$) if file exist(filename$)=1 then delete file filename$ open to write tmpFileNr,filename$ make file from memblock tmpFileNr,memNr close file tmpFileNr endfunction