File Coverage

blib/lib/Layout/Manager.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Layout::Manager;
2 1     1   42846 use Moose;
  0            
  0            
3              
4             our $AUTHORITY = 'cpan:GPHAT';
5             our $VERSION = '0.35';
6              
7             sub do_layout {
8             my ($self, $container) = @_;
9              
10             die('Need a container') unless defined($container);
11              
12             return 0 unless $container->component_count;
13              
14             return 0 if $container->prepared && $self->_check_container($container);
15              
16             # Layout child containers first, since we can't fit them into this one
17             # without knowing the sizes.
18             foreach my $comp (@{ $container->components }) {
19              
20             next unless defined($comp) && $comp->visible;
21              
22             if($comp->can('do_layout')) {
23             $comp->do_layout($comp);
24             }
25             }
26              
27             $container->prepared(1);
28             return 1;
29             }
30              
31             sub _check_container {
32             my ($self, $cont) = @_;
33              
34             foreach my $comp (@{ $cont->components }) {
35              
36             unless($comp->prepared) {
37             $cont->prepared(0);
38             return 0;
39             }
40             if($comp->can('do_layout')) {
41             if(!$self->_check_container($comp)) {
42             $comp->prepared(0);
43             return 0;
44             }
45             }
46             }
47              
48             return 1;
49             }
50              
51             __PACKAGE__->meta->make_immutable;
52              
53             no Moose;
54              
55             1;
56             __END__
57             =head1 NAME
58              
59             Layout::Manager - 2D Layout Management
60              
61             =head1 SYNOPSIS
62              
63             Layout::Manager provides a simple interface for creating layout managers, or
64             classes that size and position components within a container.
65              
66             A few managers are provided for reference, but this module is primarily meant
67             to serve as a base for outside implementations.
68              
69             use Layout::Manager;
70              
71             my $foo = Layout::Manager->new;
72             $foo->do_layout($component);
73              
74             =head1 USING A LAYOUT MANAGER
75              
76             Layout::Manager relies on L<Graphics::Primitive::Container> as a source for
77             it's components.
78              
79             Various implementations of Layout::Manager will require you do add components
80             with slightly different second arguments, but the general case will be:
81              
82             $lm->add_component($comp, $constraints);
83              
84             The contents of B<$constraints> must be discerned by reading the documentation
85             for the layout manager you are using.
86              
87             The B<$comp> argument must be a L<Graphics::Primitive::Component>.
88              
89             Layout manager works hand-in-hand with Graphics::Primitive, so you'll want to
90             check out the L<lifecyle|Graphics::Primitive::Component#LIFECYCLE> documented
91             in L<Graphics::Primitive::Component>. It will look something like this:
92              
93             $cont->add_component($foo, { some => metadata });
94             $driver->prepare($cont);
95             my $lm = new Layout::Manager::SomeImplementation;
96             $lm->do_layout($cont);
97             $driver->pack($cont);
98             $driver->draw($cont);
99              
100             When you are ready to lay out your container, you'll need to call the
101             L<do_layout> method with a single argument: the component in which you are
102             laying things out. When I<do_layout> returns all of the components should be
103             resized and repositioned according to the rules of the Layout::Manager
104             implementation.
105              
106             =head2 PREPARATION
107              
108             Subsequent calls to do_layout will be ignored if the Container is prepared.
109             The Container's C<prepared> flag and the flags of all it's children are
110             checked, so any modifications to B<any> child component will cause the entire
111             container (and any container children) to be laid out again.
112              
113             =head1 WRITING A LAYOUT MANAGER
114              
115             Layout::Manager provides all the methods necessary for your implementation,
116             save the I<do_layout> method. This method will be called when it is time to
117             layout the components.
118              
119             The I<add_component> method takes two arguments: the component and a second,
120             abritrary piece of data. If your layout manager is simple, like
121             L<Compass|Layout::Manager::Compass>, you may only require a simple variable
122             like "NORTH". If you create something more complex the second argument may be
123             a hashref or an object.
124              
125             The value of the I<components> method is an arrayref of hashrefs. The
126             hashrefs have two keys:
127              
128             =over
129              
130             =item B<component>
131              
132             The component to be laid out.
133              
134             =item B<args>
135              
136             The argument provided to I<add_component>.
137              
138             =back
139              
140             =head1 TIPS
141              
142             Layout manager implementations should honor the I<visible> attribute of a
143             component, as those components need to be ignored.
144              
145             =head1 METHODS
146              
147             =head2 do_layout
148              
149             Lays out this manager's components in the specified container.
150              
151             =head1 AUTHOR
152              
153             Cory Watson, C<< <gphat@cpan.org> >>
154              
155             =head1 SEE ALSO
156              
157             perl(1), L<Graphics::Primitive>
158              
159             =head1 COPYRIGHT & LICENSE
160              
161             Copyright 2008 - 2010 Cory G Watson
162              
163             This program is free software; you can redistribute it and/or modify it
164             under the same terms as Perl itself.