App-Widget

 view release on metacpan or  search on metacpan

lib/App/Widget/TreeSelector.pm  view on Meta::CPAN


######################################################################
## $Id: TreeSelector.pm 7850 2006-09-21 16:49:54Z spadkins $
######################################################################

package App::Widget::TreeSelector;
$VERSION = (q$Revision: 7850 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers generated by svn

use App;
use App::Widget::HierSelector;
@ISA = ( "App::Widget::HierSelector" );

use strict;

=head1 NAME

App::Widget::TreeSelector - An HTML tree view

=head1 SYNOPSIS

   use App::Widget::TreeSelector;

   $name = "get_data";
   $w = App::Widget::TreeSelector->new($name);
   print $w->html();

=cut

=head1 DESCRIPTION

This class implements a graphical tree view such as is used in
Windows Explorer.

=cut

######################################################################
# INITIALIZATION
######################################################################

# uncomment this when I need to do more than just call SUPER::_init()
#sub _init {
#   my $self = shift;
#   $self->SUPER::_init(@_);
#}

######################################################################
# OUTPUT METHODS
######################################################################

sub html {
    my $self = shift;
    my $context = $self->{context};
    my $name    = $self->{name};
    my $node    = $self->node_list();

    my ($nodebase, $nodeidx, $nodenumber, $nodelevel, $maxnodelevel);
    my (@nextnodebase, @nextnodeidx, @nextnodelevel, @shownnodenumber, @shownnodelevel);

    @nextnodebase  = ("");   # the next nodenumber to check is "$nodebase$nodeidx" (nodenumber = "1" is first)
    @nextnodeidx   = (1);    # check nodenumber "1" next
    @nextnodelevel = (1);    # index into the resulting table that the folder icon will go
    @shownnodenumber = ();   # list of the nodenumbers which are to be shown
    @shownnodelevel  = ();   # the levels at which those shown nodes exist
    $maxnodelevel    = 0;

    while ($#nextnodebase > -1) {
        $nodebase  = pop(@nextnodebase);   # get info about next node to check
        $nodeidx   = pop(@nextnodeidx);
        $nodelevel = pop(@nextnodelevel);
        $nodenumber = "$nodebase$nodeidx"; # create its node number

        if (defined $node->{$nodenumber}) {      # if the node exists...
            push(@shownnodenumber, $nodenumber); #   take note that it exists so that we can display it
            push(@shownnodelevel,  $nodelevel);  #   take note of its depth (so we display it properly)
            push(@nextnodebase,    $nodebase);   #   let's search for the node's brother (same depth, next idx)
            push(@nextnodeidx,     $nodeidx+1);  #   (next idx)
            push(@nextnodelevel,   $nodelevel);  #   (same level)
            $maxnodelevel = $nodelevel+1 if ($nodelevel+1 > $maxnodelevel);  # maxnodelevel will be # cols in table

            if ($node->{$nodenumber}{open}) {           # if the node is open...
                push(@nextnodebase,  "${nodenumber}."); #   let's search for the node's children (1 deeper, idx 1)
                push(@nextnodeidx,   1);                #   (idx is 1)
                push(@nextnodelevel, $nodelevel+1);     #   (1 deeper)
            }
        }
    }

    my ($row, $col, $row2, @colislink);
    my ($html_url_dir, $imgstart, $imgend, $imgbuttonstart, $imgbuttonend);
    my ($html, $label, $colspan, $isparent, $open);

    for ($row = $#shownnodenumber; $row >= 0; $row--) {
        $nodenumber = $shownnodenumber[$row];
        $nodelevel  = $shownnodelevel[$row];
        $col = $nodelevel - 1;
        for ($row2 = $row-1; $row2 >= 0; $row2--) {
            $colislink[$row2][$col] = 1;
            last if ($shownnodelevel[$row2] == $nodelevel - 1);
        }
    }

    $html_url_dir   = $self->{context}->get_option("html_url_dir");
    $imgstart       = "<img src=\"$html_url_dir/images/TreeSelector/";



( run in 1.179 second using v1.01-cache-2.11-cpan-98e64b0badf )