2008-11-11

Filezoo: visual du with aspirations towards file management


Continuing from yesterday, added a click handler for navigating the directory tree and opening files with gnome-open, and fiddled around a bit with the layout. Currently it works as a very bad filesystem browser, which is what I aim to change today. So, onto the plan!

My plan for today consists of five items:
  1. Sort the directory entries by size or name, and have a button to switch between the two.

  2. Make dotfiles appear small when not scaling by size.

  3. Scale directories by the [logarithm of] directory tree size in files.

  4. Zoom with the mouse.

  5. Show directory contents.


I've done prototypes of the first three, so now I need to make them work together nicely. To draw the listing, I need to get the directory entries of the current directory, then compute the relative size for each, sort them, and finally add the parent dir link at the top (unless the current dir is the root dir.) Then, to do zooming with the mouse, I need to further scale each entry at the drawing phase by a factor gotten from the zooming function (some kind of a gaussian hump, I think), which needs to have the definite integral from 0 to 1 amount to 1.

Showing directory contents can be done with limited-depth recursion.

Ok, so, this is probably how I should refactor the code:

let buildDirInfo dir = map fileInfo (ls dir)

let buildLayout files scaler zoomer =
let fileScales = map (tupleWith scaler) files in
let totalSize = sum (map fst fileScales) in
let fileScales = map (fun (s,f) -> (s / totalSize, f) fileScales in
snd (mapAccum (fun acc (s, f) -> (acc+s, (s * zoomer acc, f)) ) 0.0 fileScales)

let stack_do cr f = Cairo.save cr; f cr; Cairo.restore cr

let draw cr scaler zoomer files level =
match level with
| x when x < 0 -> ()
| x -> let layout = buildLayout files scaler zoomer in
stack_do cr
(fun cr -> iter (fun (s, f) ->
drawFile cr scaler zoomer s f level;
translate 0 s) layout)

let drawFile cr scaler zoomer scale file level =
stack_do cr (fun cr ->
drawFileModel f scale;
if (file.type = directory) then
draw cr scaler zoomer (entries file.path) (level - 1))

let fileInfo f = {
name = basename f;
dirname = dirname f;
path = f;
type = fileType f;
size = fileSize f;
recursiveSize = lazy computeRecursiveSize f;
recursiveFileCount = lazy computeRecursiveFileCount f;
permissions = filePermissions f;
}
Post a Comment

Blog Archive