Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / sun4-solaris / Tk / demos / widtrib / plop.pl
CommitLineData
86530b38
AT
1# Plot a series of continuous functions on a Perl/Tk Canvas.
2#
3# This program is described in the Perl/Tk column from Volume 1, Issue 1 of
4# The Perl Journal (http://tpj.com/tpj), and is included in the Perl/Tk
5# distribution with permission. It has been modified slightly to conform
6# to the widget demo standard.
7
8#!/usr/local/bin/perl -w
9#
10# plot_program - plot a series of continuous functions on a Perl/Tk Canvas.
11#
12# Stephen O. Lidie, Lehigh University Computing Center, lusol@Lehigh.EDU
13# 96/01/27.
14#
15# Copyright (C) 1996 - 1998 Stephen O. Lidie. All rights reserved.
16#
17# This program is free software; you can redistribute it and/or modify it under
18# the same terms as Perl itself.
19
20require 5.002;
21use strict;
22use Tk;
23use Tk::Dialog;
24use Tk::LabEntry;
25eval {require "plop.fnc";}; # user supplied math functions
26
27# Predeclare global subroutines and variables.
28
29sub collect_errors;
30sub display_coordinates;
31sub initialize_canvas;
32sub initialize_dialogs;
33sub initialize_functions;
34sub initialize_menus;
35sub make_menubutton;
36sub plot_functions;
37sub update_functions;
38
39my $VERSION = '1.0';
40
41# The default sample functions and limits, each in a different color.
42
43my (@FUNCTIONS) = ('sin($x)', 'cos($x)', 'exp($x)', '$x', 'int($x)');
44my (@COLORS) = qw(red green blue orange olivedrab magenta black salmon purple);
45my $NUM_COLORS = scalar @COLORS;
46my ($X_MIN, $X_MAX, $Y_MIN, $Y_MAX) = (-5, 5, -5, 5);
47my ($DX, $DY) = ($X_MAX - $X_MIN, $Y_MAX - $Y_MIN);
48
49# Declare constants that configure the plotting area: a square approximately
50# 500 pixels on a side, with left/right and top/bottom margins of 80 pixles
51# where we can paint axes labels. With this layout there is a 340x340 area
52# available for graphs.
53
54my $MIN_PXL = 0; # minimum Canvas pixel coordinate
55my $MAX_PXL = 300; # maximum Canvas pixel coordinate
56my $MARGIN = 80; # margin size, in pixels
57my $ALEN = $MAX_PXL - 2 * $MARGIN; # X/Y axes length, in pixels
58
59# Declare Perl/Tk widgets and other data.
60
61my $CANV; # Canvas widget used for plotting functions
62my $DIALOG_ABOUT; # Dialog widget showing "About" information
63my $DIALOG_USAGE; # Dialog widget describing plot usage
64my $MBF; # Menubutton frame
65my $MW = MainWindow->new; # program's main window
66my $ORIGINAL_CURSOR = ($MW->configure(-cursor))[3]; # restore this cursor
67my $TEXT; # Text widget showing function definitions
68
69# %ERRORS is a hash to collect eval() and -w errors. The keys are the error
70# messages themselves and the values are the number of times a particular
71# error was detected.
72
73my %ERRORS;
74
75# Begin main.
76
77initialize_dialogs;
78initialize_menus;
79initialize_canvas;
80initialize_functions;
81
82# End main.
83
84sub collect_errors {
85
86 # Update the hash %ERRORS with the latest eval() error message. Remove
87 # the eval() line number (it's useless to us) to maintain a compact hash.
88
89 my($error) = @_;
90
91 $error =~ s/eval\s+(\d+)/eval/;
92 $ERRORS{$error}++;
93
94} # end collect_errors
95
96sub display_coordinates {
97
98 # Print Canvas and Plot coordinates.
99
100 my($canvas) = @_;
101
102 my $e = $canvas->XEvent;
103 my($canv_x, $canv_y) = ($e->x, $e->y);
104 my($x, $y);
105 $x = $X_MIN + $DX * (($canv_x - $MARGIN) / $ALEN);
106 $y = $Y_MAX - $DY * (($canv_y - $MARGIN) / $ALEN);
107 print STDOUT "\nCanvas x = $canv_x, Canvas y = $canv_y.\n";
108 print STDOUT "Plot x = $x, Plot y = $y.\n";
109
110} # end display_coordinates
111
112sub initialize_canvas {
113
114 # Create the Canvas widget and draw axes and labels.
115
116 my($label_offset, $tick_length) = (20, 5);
117
118 $CANV = $MW->Canvas(
119 -width => $MAX_PXL + $MARGIN * 2,
120 -height => $MAX_PXL,
121 -relief => 'sunken',
122 );
123 $CANV->pack;
124 $CANV->Tk::bind('<Button-1>' => \&display_coordinates);
125
126 $CANV->create('text',
127 225, 25,
128 -text => 'Plot Continuous Functions Of The Form y=f($x)',
129 -fill => 'blue',
130 );
131
132 # Create the line to represent the X axis and label it. Then label the
133 # minimum and maximum X values and draw tick marks to indicate where they
134 # fall. The axis limits are LabEntry widgets embedded in Canvas windows.
135
136 $CANV->create('line',
137 $MIN_PXL + $MARGIN, $MAX_PXL - $MARGIN,
138 $MAX_PXL - $MARGIN, $MAX_PXL - $MARGIN,
139 );
140
141 $CANV->create('window',
142 $MIN_PXL + $MARGIN, $MAX_PXL - $label_offset,
143 -window => $MW->LabEntry(
144 -textvariable => \$X_MIN,
145 -label => 'X Minimum',
146 -width => 5,
147 ),
148 );
149 $CANV->create('line',
150 $MIN_PXL + $MARGIN, $MAX_PXL - $MARGIN - $tick_length,
151 $MIN_PXL + $MARGIN, $MAX_PXL - $MARGIN + $tick_length,
152 );
153
154 $CANV->create('window',
155 $MAX_PXL - $MARGIN, $MAX_PXL - $label_offset,
156 -window => $MW->LabEntry(
157 -textvariable => \$X_MAX,
158 -label => 'X Maximum',
159 -width => 5,
160 ),
161 );
162 $CANV->create('line',
163 $MAX_PXL - $MARGIN, $MAX_PXL - $MARGIN - $tick_length,
164 $MAX_PXL - $MARGIN, $MAX_PXL - $MARGIN + $tick_length,
165 );
166
167 # Create the line to represent the Y axis and label it. Then label the
168 # minimum and maximum Y values and draw tick marks to indicate where they
169 # fall. The axis limits are LabEntry widgets embedded in Canvas windows.
170
171 $CANV->create('line',
172 $MAX_PXL - $MARGIN, $MIN_PXL + $MARGIN,
173 $MAX_PXL - $MARGIN, $MAX_PXL - $MARGIN,
174 );
175
176 $CANV->create('window',
177 $MAX_PXL + $label_offset, $MIN_PXL + $MARGIN,
178 -window => $MW->LabEntry(
179 -textvariable => \$Y_MAX,
180 -label => 'Y Maximum',
181 -width => 5,
182 ),
183 );
184 $CANV->create('line',
185 $MAX_PXL - $MARGIN - $tick_length, $MIN_PXL + $MARGIN,
186 $MAX_PXL - $MARGIN + $tick_length, $MIN_PXL + $MARGIN,
187 );
188
189 $CANV->create('window',
190 $MAX_PXL + $label_offset, $MAX_PXL - $MARGIN,
191 -window => $MW->LabEntry(
192 -textvariable => \$Y_MIN,
193 -label => 'Y Minimum',
194 -width => 5,
195 ),
196 );
197 $CANV->create('line',
198 $MAX_PXL - $MARGIN - $tick_length, $MAX_PXL - $MARGIN,
199 $MAX_PXL - $MARGIN + $tick_length, $MAX_PXL - $MARGIN,
200 );
201
202} # end initialize_canvas
203
204sub initialize_dialogs {
205
206 # Create all application Dialog objects.
207
208 $DIALOG_ABOUT = $MW->Dialog(
209 -title => 'About',
210 -text =>
211"plot_program $VERSION\n\n95/12/04\n\nThis program is described in the Perl/Tk column from Volume 1, Issue 1 of The Perl Journal (http://tpj.com/tpj), and is included in the Perl/Tk distribution with permission.",
212 -bitmap => 'info',
213 -buttons => ['Dismiss'],
214 );
215 $DIALOG_ABOUT->configure(-wraplength => '6i');
216 $DIALOG_USAGE = $MW->Dialog(
217 -title => 'Usage',
218 -buttons => ['Dismiss'],
219 );
220 $DIALOG_USAGE->Subwidget('message')->configure(
221 -wraplength => '4i',
222 -text => "plot_program iterates over the range of values X Minimum to X Maximum, setting the variable \$x to each value in turn, then evaluates each f(\$x) and paints a point on the Y axis. The X axis increment is (Xmax - Xmin) / $ALEN.\n\nJust enter your functions in the Text widget and click the Plot button.\n\nYou can define a file named \"plop.fnc\" that contains additional private math functions, which is automatically \"require\"d by plot_program. In this file are your private functions that you can plot.\n\nPressing button one on the pointing device displays on standard output the current canvas and plot X and Y coordinates.",
223 );
224
225} # end initialize_dialogs
226
227sub initialize_functions {
228
229 # Pack a spacer Frame and then display instructions in a Label widget.
230
231# $MW->Frame(-height => 10)->pack;
232 $MW->Label(
233 -text => 'Enter your functions here',
234 -foreground => 'blue',
235 )->pack;
236
237 # Create a Frame with a scrollable Text widget that displays the function
238 # list, and a Button to initiate plot activities.
239
240 my $functions_frame = $MW->Frame;
241 $functions_frame->pack;
242 $TEXT = $functions_frame->Text(-height => 3);
243 $TEXT->pack;
244 $functions_frame->AddScrollbars($TEXT);
245 $functions_frame->configure(-scrollbars => 'e');
246 update_functions;
247
248 my $buttons_frame = $MW->Frame;
249 $buttons_frame->pack(-padx => 10, -pady => 5, -expand => 1, -fill => 'x');
250 my @pack_attributes = qw(-side left -fill x -expand 1);
251 $buttons_frame->Button(
252 -text => 'Plot',
253 -command => \&plot_functions,
254 )->pack(@pack_attributes);
255
256} # end initialize_functions
257
258sub initialize_menus {
259
260 # Create the Menubuttons and their associated Menu items.
261
262 $MBF = $MW->Frame(-relief => 'raised', -borderwidth => 1);
263 $MBF->pack(-fill => 'x');
264
265 make_menubutton($MBF, 'File', 0, 'left',
266 [
267 ['Quit', [$MW => 'bell'], 0],
268 ],
269 );
270 make_menubutton($MBF, 'Help', 0, 'right',
271 [
272 ['About', [$DIALOG_ABOUT => 'Show'], 0],
273 ['', undef, 0],
274 ['Usage', [$DIALOG_USAGE => 'Show'], 0],
275 ],
276 );
277
278} # end initialize_menus
279
280sub make_menubutton {
281
282 # Make a Menubutton widget; note that the Menu is automatically created.
283 # If the label is '', make a separator.
284
285 my($mbf, $mb_label, $mb_label_underline, $pack, $mb_list_ref) = @_;
286
287 my $mb = $mbf->Menubutton(
288 -text => $mb_label,
289 -underline => $mb_label_underline,
290 );
291 my $mb_list;
292 foreach $mb_list (@{$mb_list_ref}) {
293 $mb_list->[0] eq '' ? $mb->separator :
294 $mb->command(
295 -label => $mb_list->[0],
296 -command => $mb_list->[1],
297 -underline => $mb_list->[2],
298 );
299 }
300 $mb->pack(-side => $pack);
301
302} # end make_menubutton
303
304sub plot_functions {
305
306 # Plot all the functions.
307
308 my($x, $y, $canv_x, $canv_y) = (0, 0, 0, 0);
309 $canv_x = $MIN_PXL + $MARGIN; # X minimum
310 $MW->configure(-cursor => 'watch');
311 $DX = $X_MAX - $X_MIN; # update delta X
312 $DY = $Y_MAX - $Y_MIN; # update delta Y
313 $CANV->delete('plot'); # erase all previous plots
314
315 # Fetch the newline-separated Text widget contents and update the function
316 # list @FUNCTIONS. Also update the Text widget with the new colors.
317
318 @FUNCTIONS = ();
319 foreach (split /\n/, $TEXT->get('0.0', 'end')) {
320 next if $_ eq '';
321 push @FUNCTIONS, $_;
322 }
323 update_functions;
324 $MW->idletasks;
325
326 %ERRORS = ();
327 local $SIG{'__WARN__'} = sub {collect_errors($_[0])};
328
329ALL_X_VALUES:
330 for ($x = $X_MIN; $x <= $X_MAX; $x += ($X_MAX - $X_MIN) / $ALEN) {
331
332 ALL_FUNCTIONS:
333 foreach (0 .. $#FUNCTIONS) {
334 next if $FUNCTIONS[$_] =~ /^ERROR:/;
335 $y = eval $FUNCTIONS[$_];
336 if ($::EVAL_ERROR) {
337 collect_errors($::EVAL_ERROR);
338 next;
339 }
340 $canv_y = (($Y_MAX - $y) / $DY) * $ALEN + $MARGIN;
341 $CANV->create('text', $canv_x, $canv_y,
342 -fill => $COLORS[$_ % $NUM_COLORS],
343 -tags => ['plot'],
344 -text => '.',
345 ) if $canv_y > $MIN_PXL + $MARGIN and
346 $canv_y < $MAX_PXL - $MARGIN;
347 } # forend ALL_FUNCTIONS
348
349 $canv_x++; # next X pixel
350
351 } # forend ALL_X_VALUES
352
353 $MW->configure(-cursor => $ORIGINAL_CURSOR);
354 $MW->idletasks;
355
356 # Print all the eval() errors to alert the user of malformed functions.
357
358 print STDOUT "\n" if %ERRORS;
359 foreach (keys %ERRORS) {
360 print STDOUT "$ERRORS{$_} occurrences of $_";
361 }
362
363} # end plot_functions
364
365sub update_functions {
366
367 # Insert the function list into the Text widget.
368
369 $TEXT->delete('0.0', 'end');
370 my $i = 0;
371 foreach (@FUNCTIONS) {
372 $TEXT->insert('end', "$_\n", [$i]);
373 $TEXT->tagConfigure($i,
374 -foreground => $COLORS[$i % $NUM_COLORS],
375 -font => 'fixed',
376 );
377 $i++;
378 }
379 $TEXT->yview('end');
380
381} # end update_function_list