File Coverage

blib/lib/Tk/Help.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Tk::Help;
2              
3 1     1   59371 use vars qw($VERSION);
  1         2  
  1         76  
4             $VERSION = '0.3';
5              
6 1     1   424 use Tk qw(Ev);
  0            
  0            
7             use Tk::widgets qw(HList ROText Tree);
8             use base qw(Tk::Toplevel);
9              
10             use strict;
11             use warnings;
12              
13             Construct Tk::Widget 'Help';
14              
15             my %components;
16             my %options;
17              
18             sub ClassInit {
19             my($self, $args) = @_;
20             $self->SUPER::ClassInit($args);
21             }
22              
23             sub Populate {
24             my($self, $args) = @_;
25              
26             $options{'globalfontfamily'} = delete $args->{-globalfontfamily} || undef;
27             $options{'detailsbackground'} = delete $args->{-detailsbackground} || 'white';
28             $options{'detailsborderwidth'} = delete $args->{-detailsborderwidth} || 10;
29             $options{'detailsfontfamily'} = delete $args->{-detailsfontfamily} || $options{'globalfontfamily'};
30             $options{'detailsfontsize'} = delete $args->{-detailsfontsize} || 8;
31             $options{'detailsforeground'} = delete $args->{-detailsforeground} || (($^O eq 'MSWin32') ? 'SystemWindowText' : 'black');
32             $options{'detailsheaderfontfamily'} = delete $args->{-detailsheaderfontfamily} || $options{'globalfontfamily'};
33             $options{'detailsheaderfontsize'} = delete $args->{-detailsheaderfontsize} || 9;
34             $options{'detailsheaderforeground'} = delete $args->{-detailsheaderforeground} || (($^O eq 'MSWin32') ? 'SystemWindowText' : 'black');
35             $options{'detailsmenu'} = delete $args->{-detailsmenu} || 0;
36             $options{'detailswidth'} = delete $args->{-detailswidth} || 40;
37             $options{'height'} = delete $args->{-height} || (($^O eq 'MSWin32') ? 30 : 40);
38             $options{'icon'} = delete $args->{-icon} || undef;
39             $options{'listbackground'} = delete $args->{-listbackground} || Tk::NORMAL_BG;
40             $options{'listborderwidth'} = delete $args->{-listborderwidth} || 0;
41             $options{'listcursor'} = delete $args->{-listcursor} || 'hand2';
42             $options{'listfontfamily'} = delete $args->{-listfontfamily} || $options{'globalfontfamily'};
43             $options{'listfontsize'} = delete $args->{-listfontsize} || 8;
44             $options{'listforeground'} = delete $args->{-listforeground} || (($^O eq 'MSWin32') ? 'SystemWindowText' : 'black');
45             $options{'listselectbackground'} = delete $args->{-listselectbackground} || $options{'listbackground'};
46             $options{'listselectforeground'} = delete $args->{-listselectforeground} || 'blue';
47             $options{'listtype'} = delete $args->{-listtype} || 'HList';
48             $options{'listwidth'} = delete $args->{-listwidth} || 25;
49             $options{'resizable'} = delete $args->{-resizable} || 0;
50             $options{'variable'} = delete $args->{-variable} || undef;
51              
52             $self->SUPER::Populate($args);
53             $self->ConfigSpecs();
54              
55             # sets the icon if specified
56             if($options{'icon'}) {
57             $self->iconimage(${$options{'icon'}});
58             }
59             # turns off resizeing
60             unless($options{'resizable'}) {
61             $self->resizable(0, 0);
62             }
63             # sets the cursor to the os default instead of hand2
64             if($options{'listcursor'} eq 'default') {
65             $options{'listcursor'} = undef;
66             }
67              
68             # begin building the frames for the entire help system
69             # one main frame to contain the other two frames, list and details
70             $components{'main'} = $self->Component('Frame', 'main');
71             $components{'main'}->grid();
72             $components{'listframe'} = $components{'main'}->Frame(-background => $options{'listbackground'},
73             -borderwidth => $options{'listborderwidth'})->grid(($components{'detailsframe'} = $components{'main'}->Frame(-background => $options{'detailsbackground'},
74             -borderwidth => $options{'detailsborderwidth'})), -sticky => 'nsew');
75              
76             # create the list
77             $components{'list'} = $components{'listframe'}->Scrolled($options{'listtype'},
78             -background => $options{'listbackground'},
79             -borderwidth => 0,
80             -browsecmd => sub{&populatedetails},
81             -cursor => $options{'listcursor'},
82             -font => [-family => $options{'listfontfamily'}, -size => $options{'listfontsize'}],
83             -foreground => $options{'listforeground'},
84             -height => $options{'height'},
85             -highlightthickness => 0,
86             -relief => 'flat',
87             -scrollbars => 'osoe',
88             -selectbackground => $options{'listselectbackground'},
89             -selectborderwidth => 0,
90             -selectforeground => $options{'listselectforeground'},
91             -width => $options{'listwidth'})->grid();
92              
93             # assign a references to our hash to a scalar to simplify the iteration syntax
94             my $helptext = \@{$options{'variable'}};
95             # iterate through the array
96             for(my $i = 0; $i < @$helptext; $i++) {
97             # iterate through the arrayrefs
98             for(my $n = 0; $n < @{$$helptext[$i]}; $n++) {
99             # if this isn't the first arrayref in the array...
100             if($i) {
101             # if this isn't the first arrayref...
102             if($n) {
103             # insert the title in the list
104             $components{'list'}->add('0.'.$i.'0.'.$n,
105             -text => $$helptext[$i]->[$n]->{'-title'});
106             # if this is the first arrayref...
107             } else {
108             # insert the title in the list
109             $components{'list'}->add('0.'.$i.$n,
110             -text => $$helptext[$i]->[$n]->{'-title'});
111             }
112             # if this is the first arrayref in the array...
113             } else {
114             # insert the title in the list
115             $components{'list'}->add($i,
116             -text => $$helptext[$i]->[$n]->{'-title'});
117             }
118             }
119             }
120              
121             # this is needed for the indicators to be created when using Tk::Tree
122             if($options{'listtype'} eq 'Tree') {
123             $components{'list'}->autosetmode();
124             }
125              
126             # create the details
127             $components{'detailstext'} = $components{'detailsframe'}->Scrolled('ROText',
128             -background => $options{'detailsbackground'},
129             -font => [-family => $options{'detailsfontfamily'}, -size => $options{'detailsfontsize'}],
130             -foreground => $options{'detailsforeground'},
131             -height => $options{'height'},
132             -relief => 'flat',
133             -scrollbars => 'oe',
134             -width => $options{'detailswidth'},
135             -wrap => 'word')->grid();
136              
137             # turn off the right-click menu in the ROText object
138             unless($options{'detailsmenu'}) {
139             $components{'detailstext'}->menu(undef);
140             }
141             # create the tag for the details headers
142             $components{'detailstext'}->tagConfigure('header',
143             -font => [-family => $options{'detailsheaderfontfamily'}, -size => $options{'detailsheaderfontsize'}, -weight => 'bold'],
144             -foreground => $options{'detailsheaderforeground'});
145             # insert the header into the details frame
146             $components{'detailstext'}->insert('end', $$helptext[0]->[0]->{'-header'}."\n\n", 'header');
147             # insert the text into the details frame
148             $components{'detailstext'}->insert('end', $$helptext[0]->[0]->{'-text'});
149              
150             # bring the help window into focus
151             $self->focusForce();
152             }
153              
154             sub populatedetails {
155             my $number = shift();
156             my $intnumber = 0;
157             my $helptext = \@{$options{'variable'}};
158              
159             if($number =~ m/^0\.(\d)\d\.(\d+)/) {
160             $number = $1;
161             $intnumber = $2;
162             } elsif($number =~ m/^0\.(\d)\d/) {
163             $number = $1;
164             }
165             # remove all the existing text from the details frame
166             $components{'detailstext'}->delete('1.0', 'end');
167             # insert the header and text for the listitem that was clicked
168             $components{'detailstext'}->insert('end', $$helptext[$number]->[$intnumber]->{'-header'}."\n\n", 'header');
169             $components{'detailstext'}->insert('end', $$helptext[$number]->[$intnumber]->{'-text'});
170             }
171              
172             1;
173              
174             __END__