File Coverage

blib/lib/Tk/GraphItems/Circle.pm
Criterion Covered Total %
statement 15 92 16.3
branch 0 32 0.0
condition 0 7 0.0
subroutine 5 14 35.7
pod 4 7 57.1
total 24 152 15.7


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