File Coverage

blib/lib/Widget/Meta.pm
Criterion Covered Total %
statement 33 33 100.0
branch 16 16 100.0
condition 2 2 100.0
subroutine 13 13 100.0
pod 11 11 100.0
total 75 75 100.0


line stmt bran cond sub pod time code
1             package Widget::Meta;
2              
3 2     2   51046 use strict;
  2         4  
  2         1507  
4             $Widget::Meta::VERSION = '0.06';
5              
6             =head1 Name
7              
8             Widget::Meta - Metadata for user interface widgets
9              
10             =head1 Synopsis
11              
12             use Widget::Meta;
13              
14             my @wms;
15             push @wms, Widget::Meta->new(
16             name => 'foo',
17             type => 'text',
18             tip => 'Fill me in',
19             size => 32,
20             );
21              
22             push @wms, Widget::Meta->new(
23             name => 'bar',
24             type => 'select',
25             tip => 'Pick a number from 1 to 3',
26             options => [[1 => 'One'], [2 => 'Two'], [3 => 'Three']],
27             );
28              
29             # And later, assuming functions for generating UI fields...
30             for my $wm (@wms) {
31             if ($wm->type eq 'text')
32             output_text_field($wm);
33             } elsif ($wm->type eq 'select') {
34             output_select_list($wm);
35             } else {
36             die "Huh, wha?";
37             }
38             }
39              
40             =head1 Description
41              
42             This class specifies simple objects that describe UI widgets. The idea is to
43             associate Widget::Meta objects with the attributes of a class in order to
44             automate the generation of UI widgets for instances of the class. At its core,
45             this class a very simple module that stores value and returns them on
46             demand. The assigning of values to its attributes and checking the validity of
47             those attributes happens entirely in the C constructor. Its attributes
48             are read-only; the C attribute is actually a code reference, the
49             return value of which is returned for every call to the C accessor.
50              
51             =head1 Class Interface
52              
53             =head2 Constructor
54              
55             =head3 new
56              
57             my $wm = Widget::Meta->new(%params);
58              
59             Constructs and returns a new Widget::Meta object. The attributes of the Widget::Meta
60             object can be set via the following parameters:
61              
62             =over
63              
64             =item type
65              
66             The type of widget for which the Widget::Meta object provides meta data. This
67             can be any string, but typically is "text", "textarea", "checkbox", and the
68             like. Defaults to "text".
69              
70             =item name
71              
72             The name of the widget. Defaults to an empty string.
73              
74             =item value
75              
76             The default value to use in the widget. Defaults to C.
77              
78             =item tip
79              
80             A tip to be used in the display of the widget describing what it's data will be
81             used for. This may be provides as minor help text in a UI, such as a "tooltip".
82             Defaults to an empty string.
83              
84             =item size
85              
86             The size of the widget. This can be used in any number of ways, such as to define
87             the display size of a text box. Must be an integer. Defaults to 0.
88              
89             =item length
90              
91             The length of the widget. This is usually used to limit the lenght of a string
92             to be entered into a widge such as a text box. Must be an integer. Defaults to
93             0.
94              
95             =item rows
96              
97             The number of rows to be used in a widget, such as a textarea widget. Must be
98             an integer. Defaults to 0.
99              
100             =item cols
101              
102             The number of columns to be used in a widget, such as a textarea widget. Must
103             be an integer. Defaults to 0.
104              
105             =item checked
106              
107             A boolean indicating whether a widget such as a radio button or checkbox
108             should be checked by default when it displays. Defaults to a false value.
109              
110             =item options
111              
112             An array of array references or a code reference describing the possible
113             values for a widget such as a select list. If an array is passed, each item of
114             the array must be a two-item array reference, the first item being the value
115             and the second item being the label to be used for the value. If a code
116             reference is passed, it must return an array or array references in the same
117             format when executed.
118              
119             =back
120              
121             =cut
122              
123             my $error_handler = sub {
124             require Carp;
125             Carp::croak(@_);
126             };
127              
128             my $defopt = sub {[]};
129             sub new {
130 11     11 1 11564 my $class = shift;
131 11 100       48 $error_handler->("Odd number of parameters in call to new() when named "
132             . "parameters were expected" ) if @_ % 2;
133              
134             # Get the parameters. Default value to undef.
135 10         48 my %self = ( value => undef, @_);
136              
137             # Set the default type of widget.
138 10   100     52 $self{type} ||= 'text';
139              
140             # Set empty string defaults.
141 10         17 for my $p (qw(tip name)) {
142 20 100       117 $self{$p} = '' unless defined $self{$p};
143             }
144              
145             # Set integer defaults to 0.
146 10         23 for my $p (qw(rows cols length size)) {
147 34 100       139 if (defined $self{$p}) {
148 9 100       56 $error_handler->(ucfirst($p) . " parameter must be an integer")
149             unless $self{$p} =~ /^\d+$/;
150             } else {
151 25         66 $self{$p} = 0;
152             }
153             }
154              
155             # Set checked to boolean value.
156 6 100       19 $self{checked} = $self{checked} ? 1 : 0;
157              
158             # Set up options code reference.
159 6 100       17 if (my $opt = $self{options}) {
160 3         6 my $ref = ref $opt;
161 3 100       14 if ($ref eq 'ARRAY') {
162 1     2   4 $self{options} = sub { $opt };
  2         12  
163             } else {
164 2 100       9 $error_handler->("Options must be either an array of arrays or a "
165             . "code reference")
166             unless $ref eq 'CODE';
167             }
168             } else {
169 3         6 $self{options} = $defopt;
170             }
171              
172             # Make it so!
173 5         36 return bless \%self, $class;
174             }
175              
176             ##############################################################################
177              
178             =head2 Accessors
179              
180             =head3 type
181              
182             my $type = $wm->type;
183              
184             Returns the string defining the type of widget to be created.
185              
186             =cut
187              
188 5     5 1 26 sub type { shift->{type} }
189              
190             ##############################################################################
191              
192             =head3 name
193              
194             my $name = $wm->name;
195              
196             Returns the name of the widget to be created.
197              
198             =cut
199              
200 3     3 1 12 sub name { shift->{name} }
201              
202             ##############################################################################
203              
204             =head3 value
205              
206             my $value = $wm->value;
207              
208             Returns the value to be displayed in the widget.
209              
210             =cut
211              
212 3     3 1 13 sub value { shift->{value} }
213              
214             ##############################################################################
215              
216             =head3 tip
217              
218             my $tip = $wm->tip;
219              
220             Returns the helpful tip to be displayed in the widget.
221              
222             =cut
223              
224 4     4 1 20 sub tip { shift->{tip} }
225              
226             ##############################################################################
227              
228             =head3 size
229              
230             my $size = $wm->size;
231              
232             Returns the display size of the widget. Useful for "text" or "password"
233             widgets, among others.
234              
235             =cut
236              
237 4     4 1 20 sub size { shift->{size} }
238              
239             ##############################################################################
240              
241             =head3 length
242              
243             my $length = $wm->length;
244              
245             Returns the maximum lenght of the value allowed in the widget. Useful for
246             "text" or "textarea" widgets, among others.
247              
248             =cut
249              
250 3     3 1 12 sub length { shift->{length} }
251              
252             ##############################################################################
253              
254             =head3 rows
255              
256             my $rows = $wm->rows;
257              
258             Returns the number of rows to be used to display the widget, for example for a
259             "textarea" widget.
260              
261             =cut
262              
263 4     4 1 20 sub rows { shift->{rows} }
264              
265             ##############################################################################
266              
267             =head3 cols
268              
269             my $cols = $wm->cols;
270              
271             Returns the number of columns to be used to display the widget, for example
272             for a "textarea" widget.
273              
274             =cut
275              
276 4     4 1 21 sub cols { shift->{cols} }
277              
278             ##############################################################################
279              
280             =head3 checked
281              
282             my $checked = $wm->checked;
283              
284             Returns true if the widget should be checked, and false if it should not. Used
285             for "checkbox" and "radio button" widgets and the like.
286              
287             =cut
288              
289 4     4 1 17 sub checked { shift->{checked} }
290              
291             ##############################################################################
292              
293             =head3 options
294              
295             my $options = $wm->options;
296             for my $opt (@$options) {
297             print "Value: $opt->[0]\nLabel: $opt->[1]\n\n";
298             }
299              
300             Returns an array reference of two-item array references. Each of these
301             two-item array references represents a possible value for the widget, with the
302             first item containing the value and the second item containing its label.
303             Returns an empty array if there are no options. Usefull for select lists,
304             pulldowns, and the like.
305              
306             =cut
307              
308             sub options {
309 8     8 1 315 my $code = shift->{options};
310 8         17 return $code->(@_);
311             }
312              
313             1;
314             __END__