  # ##################
  #
  # hugelist demo
  #
  #   files tree demo
  #
  # ##################

  # ------------------
  # procs
  # ------------------

  # append:dirs directories hierarchy proc
  # ------
  proc append:dir {confs root pwd left} \
  {
    # root dir
    set rdir [lindex $pwd 0]
    # subdirs
    set pwd [lrange $pwd 1 end]
    # siblings
    if {![catch {set dirs [glob -types d -dir $root/ *]}]} \
    {
      foreach dir $dirs \
      {
        # for each sibling
        set dir [file tail $dir]
          # append dir
        lappend confs [list $dir $left img_dir]
        if {$dir == $rdir} \
        { 
          # subdir of pwd
          set confs [append:dir $confs $root/$rdir $pwd [expr {$left + 15}]]
        }
      }
    }
    return $confs
  }
  
  # create:dirs directories hierarchy proc
  # ------
  proc create:dirs {{path ""}} \
  {
    # the root units
    set units [file volume]
    # the dirs of the current path
    set pwd [file split [file normalize $path]]
    # create the hierarchy
      # root unit of pwd
    set root [lindex $pwd 0]
      # build lists
    set confs {}
    foreach unit $units \
    {
      # append unit
      set left 15
      #if {[string index $unit end] == "/"} { set unit [string range $unit 0 end-1] }
      lappend confs [list $unit $left img_unit]
      # test if root unit of pwd
      if {$unit == $root} \
      { set confs [append:dir $confs $root [lrange $pwd 1 end] 30] }
    }
    # build the new tree
    display:dirs $confs $pwd
  }
  
  # display:dirs directories hierarchy proc
  # ------
  proc display:dirs {confs pwd} \
  {
    # build the new tree
    .hl delete 0 end
    foreach conf $confs \
    {
      foreach {name left image} $conf break
      .hl insert end $name
      .hl itemconfig end -left $left -image $image
    }
    # select the choosed dir
    set n -1
    foreach dir $pwd \
    { 
      foreach item [lrange $confs [incr n] end] \
      {
        if {[string match $dir [lindex $item 0]]} { break }
        incr n
      }
    }
    .hl selection set $n
    .hl yview $n
  }
  
  # select proc
  # ------
  proc select {} \
  {
    # show selected
    update
    # get index
    set n [.hl curselection]
    set cur $n
    # build path
    set path ""
    while {$n >= 0} \
    {
      set path [.hl get $n]/$path
      set left [.hl itemcget $n -left]
      while {$n >= 0 && [.hl itemcget $n -left] >= $left} { incr n -1 }
    }
    # rebuild the tree
    catch {set dirs [glob -types d -dir $path/ *]}
    if {[info exists dirs]} \
    { 
      update
      set bg [.hl cget -selectbg]
      .hl itemconfig $cur -selectbg [.hl cget -selectfg]
      update
      after 50
      .hl itemconfig $cur -selectbg $bg
      update
      .hl yview $cur
      update
      create:dirs $path 
    }
  }
  
  # ------------------
  # show the tree
  # ------------------
  # load the package
  package require Tk 8.4
  lappend auto_path [file join [pwd] ..]
  package require Hugelist 1.3
  namespace import ::hugelist::hugelist

  # create the hugecombo
  wm title . "hierarchy demo"
  hugelist .hl -width 24 -height 12 -rowheight 20 -alternate gray97 \
          -yscrollcommand {.vs set} -activestyle none
  scrollbar .vs -command {.hl yview}
  grid .hl .vs -sticky nsew
  grid rowconfigure . 0 -weight 1
  grid columnconfigure . 0 -weight 1
  bind .hl <<ListboxSelect>> select

  # create the images
  image create photo img_disk -file disk.gif
  image create photo img_dir -file dir.gif

  # create the items
  #create:dirs
  focus -f .hl
  foreach {name left image} \
  {
    A:/       16     img_disk
    C:/       16     img_disk
    ulis      32     img_dir
    src       48     img_dir
    aServer   64     img_dir
    Hugecombo 64     img_dir
    Hugelist  64     img_dir
    Tinycombo 64     img_dir
    bin       48     img_dir
    save      48     img_dir
    D:/       16     img_disk
  } \
  { 
    .hl insert end $name 
    .hl itemconf end -left $left -image $image 
  }
