File Coverage

blib/lib/Tk/GraphItems/TextBox.pm
Criterion Covered Total %
statement 12 107 11.2
branch 0 36 0.0
condition 0 9 0.0
subroutine 4 13 30.7
pod 4 7 57.1
total 20 172 11.6


line stmt bran cond sub pod time code
1             package Tk::GraphItems::TextBox;
2              
3              
4             =head1 NAME
5              
6             Tk::GraphItems::TextBox - Display nodes of relation-graphs on a Tk::Canvas
7              
8             =head1 SYNOPSIS
9              
10              
11             require Tk::GraphItems::TextBox;
12             require Tk::GraphItems::Connector;
13             ...
14             my $node = Tk::GraphItems::TextBox->new( canvas=> $can,
15             text => "new_node",
16             font => ['Courier',8],
17             x => 50,
18             y => 50 );
19             $node->move( 10, 0 );
20             $node->set_coords( 50, 50 );
21             $node->text( $node->text()."\nanother_line" );
22             $node->colour( 'red' );
23              
24              
25              
26              
27              
28              
29             =head1 DESCRIPTION
30              
31             Tk::GraphItems::TextBox provides objects to display nodes of relation-graphs on a Tk::Canvas widget.
32              
33             =head1 METHODS
34              
35             B supports the following methods:
36              
37             =over 4
38              
39             =item B canvas=> $a_canvas,
40             x => $x_coord,
41             y => $y_coord,
42             text => $textB,
43             font => $aTkFont B<)>
44              
45             Return a new TextBox instance and display it on the given 'Canvas'. The canvas-items will be destroyed with the TextBox-instance when it goes out of scope.
46              
47             =item B $x, $y B<)>
48              
49             Set the (center)coordinates of this node.
50             If two references are given as argumnents, the referenced Scalar-variables will get tied to the coordinates properties of the node.
51              
52             =item B
53              
54             Return the (center)coordinates of this node.
55              
56             =item B $d_x, $d_y B<)>
57              
58             Move the node by ( $d_x, $d_y ) points.
59              
60             =item B [$a_string] B<)>
61              
62             Sets the displayed text to $a_string, if the argument is given. Returns the current text, if called without an argument.
63              
64             =item B [$a_Tk_colour] B<)>
65              
66             Sets the background to $a_Tk_colour, if the argument is given. Returns the current colour, if called without an argument.
67              
68             =item B 'event', $coderef B<)>
69              
70             Binds the given 'event' sequence to $coderef. This binding will exist for all TextBox instances on the Canvas displaying the invoking object. The binding will not exist for TextBox items that are displayed on other Canvas instances. The TextBox instance which is the 'current' one at the time the event is triggered will be passed to $coderef as an argument. If $coderef contains an empty string, the binding for 'event' is deleted.
71              
72             =item B
73              
74             Returns a true value in case a occured after the last . You may want to check this when binding to , to make sure the action was a 'click' and not a 'drag'.
75              
76             =back
77              
78             =head1 SEE ALSO
79              
80             Documentation of Tk::GraphItems::Connector.
81             Examples in Tk/GraphItems/Examples.
82              
83             =head1 AUTHOR
84              
85             Christoph Lamprecht, ch.l.ngre@online.de
86              
87             =head1 COPYRIGHT AND LICENSE
88              
89             Copyright (C) 2007 by Christoph Lamprecht
90              
91             This library is free software; you can redistribute it and/or modify
92             it under the same terms as Perl itself, either Perl version 5.8.7 or,
93             at your option, any later version of Perl 5 you may have available.
94              
95              
96              
97              
98             =cut
99              
100 3     3   2287 use 5.008;
  3         8  
  3         228  
101             our $VERSION = '0.11';
102              
103             #use Data::Dumper;
104 3     3   18 use Carp;
  3         13  
  3         232  
105 3     3   17 use warnings;
  3         4  
  3         94  
106 3     3   15 use strict;
  3         5  
  3         3568  
107             require Tk::GraphItems::Node;
108             require Tk::GraphItems::TiedCoord;
109             our @ISA = ('Tk::GraphItems::Node');
110              
111              
112             sub initialize{
113 0     0 0   my $self = shift;
114              
115 0 0         if (@_%2) {
116 0           croak "wrong number of args! ";
117             }
118            
119 0           my %args = @_;
120 0           my ($can,$x,$y,$text,$font,$colour)
121             = @args{qw/canvas x y text font colour/};
122 0           eval {$can->isa('Tk::Canvas')};
  0            
123 0 0         croak "this is not a 'Canvas':<$can> $@" if $@;
124 0 0         unless ($can->Exists){croak "This Canvas does not Exist:<$can>"};
  0            
125 0           my $text_id;
126             my @coords;
127 0 0         @coords= map {ref($_)?$$_:$_} ($x,$y);
  0            
128 0 0         my @font = (-font=>$font) if $font;
129              
130 0           eval{$text_id = $can->createText(@coords,
  0            
131             -text => $text,
132             @font,
133             -tags =>['TextBoxText',
134             'TextBox',
135             'TextBoxBind']);
136             };
137 0 0         croak "could not create TextBox at coords <$x>,<$y>: $@" if $@;
138              
139 0           my $p = 3;
140 0           my @bbox = $can->bbox($text_id);
141 0           @bbox = ($bbox[0] -$p,$bbox[1]-$p,$bbox[2]+$p,$bbox[3]+$p);
142 0           my $box_id = $can->createRectangle(
143             @bbox,
144             -fill => 'white',
145             -tags =>['TextBoxBox',
146             'TextBox',
147             'TextBoxBind']);
148 0           $self->{text_id} = $text_id;
149 0           $self->{box_id} = $box_id;
150 0           $self->{dependents} = {};
151 0           $self->{canvas} = $can;
152            
153 0           $self->SUPER::initialize;
154              
155 0           $self->_create_canvas_layers;
156 0           $self->_set_layer(2);
157 0           $self->_set_canvas_bindings;
158 0 0 0       if (ref $x and ref $y) {
159 0           $self->_tie_coords($x,$y);
160             }
161 0 0         $self->colour($colour) if $colour;
162 0           return $self;
163              
164             }
165              
166              
167             sub _set_canvas_bindings{
168 0     0     my ($self) = @_;
169 0           my $can = $self->{canvas};
170 0 0         return if $can->{TextBoxBindings_done};
171              
172 0           $self->_set_canvas_bindings_for_tag('TextBox');
173              
174 0           $can->{TextBoxBindings_done}= 1;
175             }
176              
177              
178             sub bind_class{
179 0     0 1   my ($self,$event,$code) = @_;
180 0           my $can = $self->{canvas};
181 0           $self->_bind_this_class($event,'TextBoxBind',$code);
182             }
183              
184             sub canvas_items{
185 0     0 0   my $self = shift;
186 0           return (@$self{qw/ box_id text_id/});
187             }
188              
189             sub connector_coords{
190 0     0 0   my ($self,$dependent) = @_;
191 0           my ($x,$y) = $self->get_coords;
192 0 0         if (!defined $dependent){
193 0           return($x,$y);
194             }
195 0           my $where = $dependent->{master}{$self};
196 0 0         my $other = $where eq 'source'? 'target':'source';
197 0           my $c_c = $dependent->get_coords($other);
198 0           my @bbox = ($self->{canvas})->coords($self->{box_id});
199 0           my $height = $bbox[3]-$bbox[1];
200 0           my $width = $bbox[2]-$bbox[0];
201 0           my $b_r = $height / $width;
202 0   0       my $c_r= ($c_c->[1]-$y)/(($c_c->[0]-$x)||0.01);
203 0 0         if (abs ($b_r) > abs ($c_r)) { #r or l
204 0 0         if ($c_c->[0] > $x) { #right
205             #print "right\n";
206 0           $x = $bbox[2];
207 0           $y = $y+($c_r * $width /2);
208             } else { #left
209             #print "left\n";
210 0           $x = $bbox[0];
211 0           $y = $y-($c_r * $width /2);
212             }
213             } else { # b or t
214 0 0         if ($c_c->[1] < $y) { #top
215             #print "top\n";
216 0           $y = $bbox[1];
217 0   0       $x = $x-((1/($c_r||0.01))*$height /2);
218             } else { #bottom
219             #print "bottom\n";
220 0           $y = $bbox[3];
221 0   0       $x = $x+((1/($c_r||0.01))*$height /2);
222             }
223             }
224 0           return($x,$y);
225              
226             }
227              
228             sub _set_coords{
229 0     0     my ($self,$x,$y)=@_;
230 0           my ($can,$t_id,$b_id) = @$self{qw/canvas text_id box_id/};
231 0           my $p = 3;
232 0           $can->coords($t_id,$x,$y);
233 0           my @bbox = $can->bbox($t_id);
234 0           @bbox = ($bbox[0] -$p,$bbox[1]-$p,$bbox[2]+$p,$bbox[3]+$p);
235 0           $can->coords($b_id,@bbox);
236              
237 0           for ($self->dependents) {
238 0           $_->position_changed($self);
239             }
240             }
241              
242             sub text{
243 0     0 1   my $self = shift;
244 0           my $can = $self->get_canvas;
245 0 0         if (@_) {
246 0           $can->itemconfigure($self->{text_id},-text=>$_[0]);
247             #call _set_coords to resize TextBox
248 0           $self->_set_coords($self->get_coords);
249 0           return $self;
250             } else {
251 0           return $can->itemcget($self->{text_id},'-text');
252             }
253             }
254              
255             sub colour{
256 0     0 1   my $self = shift;
257 0           my $can = $self->get_canvas;
258 0 0         if (@_) {
259 0           eval{$can->itemconfigure($self->{box_id},-fill=>$_[0]);};
  0            
260 0 0         croak " setting colour to <$_[0]> not possible: $@" if $@;
261 0           return $self;
262             } else {
263 0           return $can->itemcget($self->{box_id},'-fill');
264             }
265             }
266             sub get_coords{
267 0     0 1   my$self = shift;
268 0           my $can = $self->get_canvas;
269 0           my @coords = $can->coords($self->{text_id});
270 0 0         return wantarray ? @coords:\@coords;
271             }
272              
273              
274             1;
275              
276             __END__