File Coverage

blib/lib/Data/Page/Viewport.pm
Criterion Covered Total %
statement 51 57 89.4
branch 10 20 50.0
condition 11 15 73.3
subroutine 7 9 77.7
pod 0 3 0.0
total 79 104 75.9


line stmt bran cond sub pod time code
1             package Data::Page::Viewport;
2              
3             # Name:
4             # Data::Page::Viewport.
5             #
6             # Documentation:
7             # POD-style documentation is at the end. Extract it with pod2html.*.
8             #
9             # Reference:
10             # Object Oriented Perl
11             # Damian Conway
12             # Manning
13             # 1-884777-79-1
14             # P 114
15             #
16             # Note:
17             # o Tab = 4 spaces || die.
18             #
19             # Author:
20             # Ron Savage
21             # Home page: http://savage.net.au/index.html
22             #
23             # Licence:
24             # Australian copyright (c) 1999-2002 Ron Savage.
25             #
26             # All Programs of mine are 'OSI Certified Open Source Software';
27             # you can redistribute them and/or modify them under the terms of
28             # The Artistic License, a copy of which is available at:
29             # http://www.opensource.org/licenses/index.html
30              
31 1     1   26769 use strict;
  1         2  
  1         91  
32 1     1   5 use warnings;
  1         1  
  1         27  
33 1     1   3 no warnings 'redefine';
  1         2  
  1         42  
34              
35             require 5.005_62;
36              
37 1     1   876 use Set::Window;
  1         1242  
  1         986  
38              
39             require Exporter;
40              
41             our @ISA = qw(Exporter);
42              
43             # Items to export into callers namespace by default. Note: do not export
44             # names by default without a very good reason. Use EXPORT_OK instead.
45             # Do not simply export all your public functions/methods/constants.
46              
47             # This allows declaration use Data::Page::Viewport ':all';
48             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
49             # will save memory.
50             our %EXPORT_TAGS = ( 'all' => [ qw(
51              
52             ) ] );
53              
54             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
55              
56             our @EXPORT = qw(
57              
58             );
59             our $VERSION = '1.06';
60              
61             # -----------------------------------------------
62              
63             # Encapsulated class data.
64              
65             {
66             my(%_attr_data) =
67             ( # Alphabetical order.
68             _data_size => - 1,
69             _old_style => 0,
70             _page_size => - 1,
71             );
72              
73             sub _default_for
74             {
75 0     0   0 my($self, $attr_name) = @_;
76              
77 0         0 $_attr_data{$attr_name};
78             }
79              
80             sub _standard_keys
81             {
82 1     1   10 sort keys %_attr_data;
83             }
84              
85             } # End of Encapsulated class data.
86              
87             # -----------------------------------------------
88              
89             sub current
90             {
91 0     0 0 0 my($self) = @_;
92              
93 0         0 $$self{'_current'};
94              
95             } # End of current.
96              
97             # -----------------------------------------------
98              
99             sub new
100             {
101 1     1 0 23 my($caller, %arg) = @_;
102 1         3 my($caller_is_obj) = ref($caller);
103 1   33     6 my($class) = $caller_is_obj || $caller;
104 1         4 my($self) = bless({}, $class);
105              
106 1         4 for my $attr_name ($self -> _standard_keys() )
107             {
108 3         11 my($arg_name) = $attr_name =~ /^_(.*)/;
109              
110 3 50       7 if (exists($arg{$arg_name}) )
    0          
111             {
112 3         11 $$self{$attr_name} = $arg{$arg_name};
113             }
114             elsif ($caller_is_obj)
115             {
116 0         0 $$self{$attr_name} = $$caller{$attr_name};
117             }
118             else
119             {
120 0         0 $$self{$attr_name} = $self -> _default_for($attr_name);
121             }
122             }
123              
124 1         3 $$self{'_current'} = 0;
125 1         2 $$self{'_port'} = {};
126 1         2 $$self{'_port'}{'inner'} = {};
127 1         3 $$self{'_port'}{'inner'}{'top'} = 0; # Top (upwards on screen) and bottom of viewport.
128 1         4 $$self{'_port'}{'inner'}{'bottom'} = $$self{'_page_size'} - 1;
129 1         2 $$self{'_port'}{'outer'} = {};
130 1         2 $$self{'_port'}{'outer'}{'top'} = 0; # Top and bottom of fixed data.
131 1         3 $$self{'_port'}{'outer'}{'bottom'} = $$self{'_data_size'};
132 1         9 $$self{'_inner'} = Set::Window -> new_lr($$self{'_port'}{'inner'}{'top'}, $$self{'_port'}{'inner'}{'bottom'});
133 1         9 $$self{'_outer'} = Set::Window -> new_lr($$self{'_port'}{'outer'}{'top'}, $$self{'_port'}{'outer'}{'bottom'});
134 1         10 $$self{'_page_size'} = $$self{'_page_size'} - 1;
135              
136 1         4 $self;
137              
138             } # End of new.
139              
140             # -----------------------------------------------
141              
142             sub offset
143             {
144 24     24 0 9662 my($self, $offset) = @_;
145 24         73 ($$self{'_port'}{'inner'}{'top'}, $$self{'_port'}{'inner'}{'bottom'}) = $$self{'_inner'} -> bounds();
146              
147 24 100       245 if ($offset > 0)
    50          
148             {
149 14         19 $$self{'_current'} += $offset;
150 14 100       42 $$self{'_current'} = $$self{'_port'}{'outer'}{'bottom'} if ($$self{'_current'} > $$self{'_port'}{'outer'}{'bottom'});
151 14 0       32 my($permit) = $$self{'_old_style'} ? 1 : $$self{'_current'} > $$self{'_port'}{'inner'}{'bottom'} ? 1 : 0;
    50          
152              
153             # If we are scrolling down, and the scroll would leave something visible
154             # within the viewport, then permit the scroll.
155              
156 14   66     108 while ($permit && ($offset > 0) && ( ($$self{'_port'}{'inner'}{'top'} + $$self{'_page_size'}) < $$self{'_port'}{'outer'}{'bottom'}) )
      100        
157             {
158 27         221 $offset--;
159              
160 27         74 $$self{'_inner'} = $$self{'_inner'} -> offset(1);
161 27         443 ($$self{'_port'}{'inner'}{'top'}, $$self{'_port'}{'inner'}{'bottom'}) = $$self{'_inner'} -> bounds();
162             }
163             }
164             elsif ($offset < 0)
165             {
166 10         16 $$self{'_current'} += $offset; # + because offset is -!
167 10 100       30 $$self{'_current'} = $$self{'_port'}{'outer'}{'top'} if ($$self{'_current'} < $$self{'_port'}{'outer'}{'top'});
168 10 0       22 my($permit) = $$self{'_old_style'} ? 1 : $$self{'_current'} < $$self{'_port'}{'inner'}{'top'} ? 1 : 0;
    50          
169              
170             # If we are scrolling up, and the scroll would leave something visible
171             # within the viewport, then permit the scroll.
172              
173 10   66     84 while ($permit && ($offset < 0) && ( ($$self{'_port'}{'inner'}{'bottom'} - $$self{'_page_size'}) > $$self{'_port'}{'outer'}{'top'}) )
      100        
174             {
175 16         116 $offset++;
176              
177 16         43 $$self{'_inner'} = $$self{'_inner'} -> offset(- 1);
178 16         218 ($$self{'_port'}{'inner'}{'top'}, $$self{'_port'}{'inner'}{'bottom'}) = $$self{'_inner'} -> bounds();
179             }
180             }
181              
182             # Return the viewport, knowing now that when the user calls bounds(),
183             # there will definitely be something visible within the viewport.
184              
185 24         312 $$self{'_inner'} -> intersect($$self{'_outer'});
186              
187             } # End of offset.
188              
189             # -----------------------------------------------
190              
191             1;
192              
193             __END__