File Coverage

blib/lib/CAD/Drawing/GUI.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package CAD::Drawing::GUI;
2              
3 1     1   31510 use CAD::Drawing::GUI::View;
  0            
  0            
4              
5             our $VERSION = '0.01_01';
6              
7             use strict;
8             use warnings;
9             use Carp;
10              
11             =head1 NAME
12              
13             CAD::Drawing::GUI - A can of worms uncapped and recapped.
14              
15             =head1 DESCRIPTION
16              
17             This module organizes one or more CAD::Drawing::GUI::View objects around
18             one or more CAD::Drawing objects. This should be fun.
19              
20             =head1 SYNOPSIS
21              
22             write me
23              
24             =head1 AUTHOR
25              
26             Eric L. Wilhelm
27              
28             http://scratchcomputing.com
29              
30             =head1 COPYRIGHT
31              
32             This module is copyright (C) 2004-2006 by Eric L. Wilhelm.
33              
34             =head1 LICENSE
35              
36             This module is distributed under the same terms as Perl. See the Perl
37             source package for details.
38              
39             You may use this software under one of the following licenses:
40              
41             (1) GNU General Public License
42             (found at http://www.gnu.org/copyleft/gpl.html)
43             (2) Artistic License
44             (found at http://www.perl.com/pub/language/misc/Artistic.html)
45              
46             =head1 Modifications
47              
48             The source code of this module is made freely available and
49             distributable under the GPL or Artistic License. Modifications to and
50             use of this software must adhere to one of these licenses. Changes to
51             the code should be noted as such and this notification (as well as the
52             above copyright information) must remain intact on all copies of the
53             code.
54              
55             Additionally, while the author is actively developing this code,
56             notification of any intended changes or extensions would be most helpful
57             in avoiding repeated work for all parties involved. Please contact the
58             author with any such development plans.
59              
60             =head1 SEE ALSO
61              
62             CAD::Drawing::GUI::View
63              
64             =cut
65              
66              
67             =head1 Constructor
68              
69             =head2 new
70              
71             $gui = CAD::Drawing::GUI->new();
72              
73             =cut
74             sub new {
75             my $caller = shift;
76             my $class = ref($caller) || $caller;
77             my $self = {@_};
78             $self->{b_cache} = {}; # binding cache?
79             bless($self, $class);
80             return($self);
81             } # end subroutine new definition
82             ########################################################################
83              
84             =head1 Drawing Management Methods
85              
86             =head2 add_drawing
87              
88             Adds a drawing to the control of the $gui object. Returns the id for
89             this drawing. These id's are not re-used.
90              
91             $number = $gui->add_drawing($drw, \%options);
92              
93             =cut
94             sub add_drawing {
95             my $self = shift;
96             my ($drw, $opts) = @_;
97             $self->{drws} or ($self->{drws} = []);
98             my $index = scalar(@{$self->{drws}});
99             $self->{drws}[$index] = $drw;
100             # this should show-up on all existing views and be drawn on any new
101             # views.
102             if($self->{views}) {
103             foreach my $view (@{$self->{views}}) {
104             $view->add_drawing($index, $drw);
105             }
106             }
107             return($index);
108             } # end subroutine add_drawing definition
109             ########################################################################
110              
111             =head2 drw_update
112              
113             Updates all of the canvases with the drawing numbered $n and item $addr.
114              
115             $gui->drw_update($n, $addr);
116              
117             =cut
118             sub drw_update {
119             my $self = shift;
120             my ($n, $addr) = @_;
121             $self->{views} or croak("no views");
122             my $drw = $self->{drws}[$n];
123             $drw or croak("no drawing numbered $n");
124             foreach my $view (@{$self->{views}}) {
125             $view->drawing_update($n, $drw, $addr);
126             }
127             } # end subroutine drw_update definition
128             ########################################################################
129              
130             =head1 View Methods
131              
132             =head2 add_view
133              
134             my $view = $mw->CADView();
135             $gui->add_view($view);
136              
137             =cut
138             sub add_view {
139             my $self = shift;
140             my ($view) = @_;
141             $self->{views} or ($self->{views} = []);
142             my $index = scalar(@{$self->{views}});
143             $self->{views}[$index] = $view;
144             $view or croak('add_view($view)');
145             $view->configure('-parent' => $self);
146             for(my $d = 0; $d < @{$self->{drws}}; $d++) {
147             my $drawing = $self->{drws}[$d];
148             $drawing or next;
149             $view->add_drawing($d, $drawing);
150             }
151             } # end subroutine add_view definition
152             ########################################################################
153              
154             =head2 new_view
155              
156             Creates a new CAD::Drawing::GUI::View object, packs, and returns it. If
157             you want more control, see add_view().
158              
159             my $view = $gui->new_view($mw, \%options);
160              
161             =cut
162             sub new_view {
163             my $self = shift;
164             my ($mw, $opts) = @_;
165             my %options;
166             if(defined($opts)) {
167             if(ref($opts) eq "HASH") {
168             %options = %$opts;
169             }
170             else {
171             croak("not a hash reference: ", ref($opts), "\n");
172             }
173             }
174             my %default = (
175             width => 800,
176             height => 600,
177             zoom => "fit",
178             );
179             unless($options{size}) {
180             foreach my $item ("width", "height") {
181             my $val = $options{$item};
182             $val || ($val = $default{$item});
183             push(@{$options{size}}, $val);
184             }
185             }
186             my ($width,$height) = @{$options{size}};
187             my $view = $mw->CADView(
188             # XXX need to inform view about it's owner ($self)!
189             -parent => $self,
190             -width => $width,
191             -height => $height,
192             -backcolor => 'white',
193             );
194             $view->pack(-fill => 'both', -expand => 1);
195             # $view->configure('-parent' => $self);
196             # print "widget options:", join("\n ", "", map({join(":", @$_)} $view->configure())), "\n";
197             $view->view_bindings();
198             $self->add_view($view);
199             $view->update();
200             $view->viewAll();
201             return($view);
202             } # end subroutine new_view definition
203             ########################################################################
204              
205             =head2 view_bindings
206              
207             Activate the view_bindings for all views (this is done automatically
208             with the new_view() method.)
209              
210             $gui->view_bindings();
211              
212             =cut
213             sub view_bindings {
214             my $self = shift;
215             my $toggle = shift;
216             # XXX toggle is currently ignored
217             $self->{views} or croak("no views to bind");
218             foreach my $view (@{$self->{views}}) {
219             $view->view_bindings();
220             }
221             } # end subroutine view_bindings definition
222             ########################################################################
223              
224             =head2 key_bindings
225              
226             Activates the default keybindings for all mainwindows.
227              
228             $gui->key_bindings();
229              
230             These are
231              
232             Esc - Stop current command
233             q - Exit (should this call some hook?)
234              
235             =cut
236             sub key_bindings {
237             my $self = shift;
238             $self->{views} or croak("no views to bind");
239             my %bindings = (
240             '' => sub {
241             my $top = shift;
242             # my $view = $self->{views}[0];
243             # my $mw = $view->toplevel();
244             ## print "bye\n";
245             $top->destroy();
246             },
247             '' => sub {
248             $self->event_done();
249             },
250             );
251             my %tops = $self->view_parents();
252             foreach my $string (keys(%tops)) {
253             my ($top, @views) = @{$tops{$string}};
254             foreach my $key (keys(%bindings)) {
255             $top->bind($key,
256             sub {
257             $bindings{$key}->($top);
258             }
259             );
260             }
261              
262             }
263             } # end subroutine key_bindings definition
264             ########################################################################
265              
266             =head2 view_key_bindings
267              
268             Activates view-related (zoom, measure, etc) keybindings for all
269             mainwindows.
270              
271             $gui->view_key_bindings();
272              
273             =cut
274             sub view_key_bindings {
275             my $self = shift;
276             $self->{views} or croak("no views to bind");
277             my %bindings = (
278             '' => sub {
279             my $self = shift;
280             # XXX need a way to hand these an statusline object
281             ## print "measuring $self\n";
282             $self->free_dist();
283             },
284             '' => sub {
285             my $self = shift;
286             ## print "zooming $self\n";
287             # XXX need a way to hand these an statusline object
288             $self->windowzoom();
289             },
290             );
291             my %tops = $self->view_parents();
292             # Each toplevel gets the binding
293             foreach my $string (keys(%tops)) {
294             my ($top, @views) = @{$tops{$string}};
295             foreach my $key (keys(%bindings)) {
296             my $current = $top->bind($key);
297             ## $current and print "bind $key has a function\n";
298             $top->bind($key,
299             sub {
300             # unhook anything that was already going
301             $self->event_done();
302             foreach my $view (@views) {
303             ## print "bind: $view\n";
304             $self->{b_cache}{$view} = [
305             $view, $bindings{$key}->($view)
306             ];
307             }
308             }
309             );
310             }
311             }
312              
313             } # end subroutine view_key_bindings definition
314             ########################################################################
315              
316             =head2 view_parents
317              
318             Returns a hash of the parents of the gui object's views. This hash is
319             keyed by the string representation of the toplevel, and each entry
320             contains an array reference with the toplevel and it's views.
321              
322             $gui->view_parents();
323              
324             =cut
325             sub view_parents {
326             my $self = shift;
327             $self->{views} or croak("no views to unbind");
328             my %tops;
329             foreach my $view (@{$self->{views}}) {
330             my $top = $view->parent();
331             ## print "top is $top\n";
332             $tops{$top} or ($tops{$top} = [$top]);
333             push(@{$tops{$top}}, $view);
334             }
335             return(%tops);
336             } # end subroutine view_parents definition
337             ########################################################################
338              
339             =head2 event_done
340              
341             Calls bind_off() for all views.
342              
343             $gui->event_done();
344              
345             =cut
346             sub event_done {
347             my $self = shift;
348             $self->{views} or croak("no views to unbind");
349             foreach my $key (keys(%{$self->{b_cache}})) {
350             my ($view, $tmp, $was) = @{$self->{b_cache}{$key}};
351             ## print "unhook $view\n";
352             $view->bind_off($tmp, $was);
353             delete($self->{b_cache}{$key});
354             }
355             } # end subroutine event_done definition
356             ########################################################################
357              
358             =head2 click_bind
359              
360             Calls $view->click_bind() for each active view. See the
361             documentation of CAD::GUI::View ($button is optional and defaults to
362             1.)
363              
364             $gui->click_bind($sub, $button);
365              
366             =cut
367             sub click_bind {
368             my $self = shift;
369             $self->{views} or croak("no views to bind");
370             foreach my $view (@{$self->{views}}) {
371             $view->click_bind(@_);
372             }
373             } # end subroutine click_bind definition
374             ########################################################################
375              
376             1;