# Copyright (c) 2007 bivio Software, Inc. All Rights Reserved. # # Visit http://www.bivio.biz for more info. # # This library is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; If not, you may get a copy from: # http://www.opensource.org/licenses/lgpl-license.html # # $Id: NestedList.pm,v 1.1 2007/03/10 23:12:01 nagler Exp $ package Bivio::UI::XHTML::Widget::NestedList; use strict; use Bivio::Base 'Bivio::UI::Widget::List'; use Bivio::UI::ViewLanguageAUTOLOAD; our($VERSION) = sprintf('%d.%02d', q$Revision: 1.1 $ =~ /\d+/g); sub initialize { my($self) = @_; my($c) = $self->unsafe_get('columns'); $self->die(columns => undef, $c, ': must contain exactly one element') unless @$c == 1; $self->put(_nested_list => Tag( $self->get_or_default(tag => 'ul'), "\n", $self->unsafe_get('class'), )); $self->put(_nested_list_item => Join([ Tag( $self->get_or_default('item_tag', 'li'), $c->[0], $self->unsafe_get('item_class'), ), "\n", ])); $self->put(_nested_list_state => my $state = {}); $self->put(columns => [[\&_render_item, ['node_level'], $c->[0], $self]]); return shift->SUPER::initialize(@_); } sub render { my($self, $source, $buffer) = @_; my($t) = $self->render_attr('_nested_list', $source); my($state) = $self->get('_nested_list_state'); $$t =~ /^(.+\n)(\S+)$/s; %$state = ( level => -1, list_start => $1, list_end => $2, count => 0, ); shift->SUPER::render(@_); _close(-1, $state, $buffer); return; } sub _close { my($to_level, $state, $buffer) = @_; while ($state->{level} > $to_level) { $$buffer .= $state->{list_end}; $state->{level}--; } return; } sub _render_item { my($source, $node_level, $value, $self) = @_; my($state) = $self->get('_nested_list_state'); $state->{count}++; my($b); if ($state->{level} < $node_level) { $b .= $state->{list_start}; $state->{level}++; } else { _close($node_level, $state, \$b); } $self->render_attr('_nested_list_item', $source, \$b); return $b; } 1;