-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmps_form.pro
1925 lines (1590 loc) · 70.6 KB
/
cmps_form.pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;+
; NAME:
; CMPS_FORM
;
; PURPOSE:
; This function puts up a form the user can configure a PostScript
; device driver. The function result (if the user selects either the
; ACCEPT or CREATE FILE buttons) can be sent directly to the DEVICE
; procedure by means of its _Extra keyword. User's predefined
; configurations may be retrieved from a common block.
;
; AUTHOR:
; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
; $Id: cmps_form.pro,v 1.1 2009/02/03 00:54:38 gpi Exp $
;
; Based almost entirely on, but a totally revamped version of, CMPS_FORM by
; FANNING SOFTWARE CONSULTING (David Fanning Ph.D.) http://www.dfanning.com
;
; MAJOR TOPICS:
; Device Drivers, Hardcopy Output, PostScript Output
;
; PROCEDURE:
; This is a pop-up form widget. It is a modal or blocking widget.
; Keywords appropriate for the PostScript DEVICE command are returned.
;
; Use your LEFT mouse button to move the "Plot Window" around the page.
; Use your RIGHT mouse button to draw your own "Plot Window" on the page.
;
; HELP:
; formInfo = CMPS_FORM(/Help)
;
; CALLING SEQUENCE:
; formInfo = CMPS_FORM(xoffset, yoffset, Cancel=cancelButton)
;
; OPTIONAL INPUTS:
;
; XOFFSET -- Optional xoffset of the top-level base of cmps_form. Default is
; to try to center the form on the display.
;
; YOFFSET -- Optional yoffset of the top-level base of cmps_form. Default is
; to try to center the form on the display.
;
; INPUT KEYWORD PARAMETERS:
;
; BITS_PER_PIXEL -- The initial configuration of the bits per pixel button.
;
; BLOCKING -- Set this keyword to make this a blocking widget under IDL 5.0.
; (All widget programs block under IDL 4.0.)
;
; COLOR -- The initial configuration of the color switch.
;
; DEFAULTS -- A stucture variable of the same type and structure as the
; RETURN VALUE of cmps_form. It will set initial conditions. This makes
; it possible to start cmps_form up again with the same values it had the
; last time it was called. For example:
;
; mysetup = cmps_form()
; newsetup = cmps_form(Defaults=mysetup)
;
; ENCAPSULATED -- The initial configuration of the encapsulated switch.
;
; FILENAME -- The initial filename to be used on the form.
;
; HELP -- Prints a helpful message in the output log.
;
; INCHES -- The initial configuration of the inches/cm switch.
;
; INITIALIZE -- If this keyword is set, the program immediately returns the
; "localdefaults" structure. This gives you the means to configue the
; PostScript device without interrupting the user.
;
; SELECT -- used only when INITIALIZE is set. Set SELECT to a
; string which identifies the predefined configuration to
; be returned by cmps_form when INITIALIZE is set. This is
; a convenient way to select a predefined config
; non-interactively.
;
; LANDSCAPE -- The initial configuration of the landscape/portrait switch.
;
; LOCALDEFAULTS -- A structure like the DEFAULTS structure. If specified,
; then it is added as a predefined configuration entry called "Local".
; See below for a further discussion of predefined configurations.
;
; PREDEFINED -- An alternate way to specify predefined
; configurations. Pass an array of structures to
; populate the "predefined" dropbox in the
; dialog. This array, if specified, overrides the the
; common block technique.
;
; XOFFSET -- The initial XOffSet of the PostScript window.
;
; YOFFSET -- The initial YOffSet of the PostScript window.
;
; XSIZE -- The initial XSize of the PostScript window.
;
; YSIZE -- The initial YSize of the PostScript window.
;
; ASPECT -- The aspect ratio of the window (Y/X). This keyword can
; substitute for one of XSIZE or YSIZE.
;
; PRESERVE_ASPECT -- Set this keyword if you want to hold the
; aspect ratio constant.
;
; PAPERSIZE -- If set, allows user to specify the size of the paper
; media to be printed on, as a scalar string. NOTE:
; this specification cannot be passed to DEVICE, but
; can be selected for completeness's sake. Default is
; 'Letter'.
;
; MARGINSIZE -- Size of the margins on all sides. Default is 0.25 inches.
; When MARGINSIZE is non-zero, a graphic cannot directly
; abut the edge of the page. This is normally a good thing,
; since there is often a non-printable region which borders
; the page.
;
; DEFAULTPAPER -- Default paper size to use, when it is unspecified
; in a predefined, "local", or "default"
; configuration. This value also overrides any
; configuration from common blocks. European users
; will probably set this to 'A4'.
;
; PARENT -- if this widget is invoked by another widget program,
; then this keyword parameter must be set to the top level
; widget which is to serve as the group leader. Failure
; to do so will result in unexpected behavior. IDL 4
; programs do not need to pass this parameter. Default:
; NONE.
;
; OUTPUT KEYWORD PARAMETERS
;
; CANCEL -- This is an OUTPUT keyword. It is used to check if the user
; selected the "Cancel" button on the form. Check this variable rather
; than the return value of the function, since the return value is designed
; to be sent directly to the DEVICE procedure. The varible is set to 1 if
; the user selected the "Cancel" button. Otherwise, it is set to 0.
;
; CREATE -- This output keyword can be used to determine if the user
; selected the 'Create File' button rather than the 'Accept' button.
; The value is 1 if selected, and 0 otherwise.
;
; PAPERSIZE -- If set to a named variable, any newly selected paper
; size is returned in that variable.
;
; XPAGESIZE -- Size of paper in "X" dimension, in units given by
; the returned config structure.
;
; YPAGESIZE -- Size of paper in "Y" dimension, in units given by
; the returned config structure.
;
; PAGEBOX -- specifies the page rectangle relative to the plot
; window, in normalized units. A 4-vector of the form
; [XLL, YLL, XUR, YUR] is returned, giving the positions
; of the lower left (LL) and upper right (UR) corners of
; the page with respect to the plot window. Thus, the
; following command:
;
; PLOT, x, y, position=PAGEBOX
;
; will construct a graphic whose plot region exactly
; fills the page (with no margin around the edges).
;
; Naturally, the page is usually larger than the
; graphics window, so the normalized coordinates will
; usually fall outside the range [0,1].
;
; However, the bounding box constructed by the
; Postscript driver includes only the graphics window.
; Anything drawn outside of it may be clipped or
; discarded.
;
; RETURN VALUE:
;
; formInfo = { cmps_form_INFO, $
; xsize:0.0, $ ; The x size of the plot
; xoff:0.0, $ ; The x offset of the plot
; ysize:0.0, $ ; The y size of the plot
; yoff:0.0 $ ; The y offset of the plot
; filename:'', $ ; The name of the output file
; inches:0 $ ; Inches or centimeters?
; color:0, $ ; Color on or off?
; bits_per_pixel:0, $ ; How many bits per image pixel?
; encapsulated:0,$ ; Encapsulated or regular PostScript?
; isolatin1:0,$ ; Encoded with ISOLATIN1?
; landscape:0 } ; Landscape or portrait mode?
;
; USAGE:
;
; The calling procedure for this function in a widget program will
; look something like this:
;
; info.ps_config = cmps_form(/Initialize)
;
; formInfo = cmps_form(Cancel=canceled, Create=create, $
; Defaults=info.ps_config)
;
; IF NOT canceled THEN BEGIN
; IF create THEN BEGIN
; thisDevice = !D.Name
; Set_Plot, "PS"
; Device, _Extra=formInfo
;
; Enter Your Graphics Commands Here!
;
; Device, /Close
; Set_Plot, thisDevice
; info.ps_config = formInfo
; ENDIF ELSE
; info.ps_config = formInfo
; ENDIF
;
; MAJOR FUNCTIONS and PROCEDURES:
;
; None. Designed to work originally in conjunction with XWindow, a
; resizable graphics window. [ NOTE: this modified version of
; cmps_form, by Craig Markwardt, is incompatible with the original
; version of XWINDOW. ]
;
; MODIFICATION HISTORY:
;
; Based on cmps_form of : David Fanning, RSI, March 1995.
; Major rewrite by: Craig Markwardt, October 1997.
; - Drawing and updating of form and sample box are now modular
; - Option of storing more than one predefined postscript configuration
; - Selection of paper size by name
; - Access to predfined configurations through (optional) common
; block
; Several additions, CM, April 1998 VERSION CM2.0
; - better integration of paper sizes throughout program.
; Predefined configurations now also know about paper.
; - allow passing predefined configurations instead of using
; common block
; - addition of ISOLATIN selection, and streamlining of dialog
; appearance
; Fixed bug in INITIALIZE w.r.t. paper sizes, CM, Nov 1998
; Added SELECT keyword, CM, 09 Dec 1998
; Added Parent keyword to allow modal widgets in IDL 5, 19 Jan 1999
; Added "Choose" button for filename selection, 19 Sep 1999
; Added ability to program different button names, 19 Sep 1999
; Added ASPECT and PRESERVE_ASPECT, based on work by Aaron Barth, 18
; Oct 1999
; Removed NOCOMMON documentation and logic, 19 Oct 1999, CM
; Added aspect to cmps_form_numevents (per Aaron Barth), 18 Oct 1999
; Corrected small bug under Initialize keyword (inches), 18 Oct 1999
; Made call to *_pscoord more consistent, 18 Oct 1999
; Added XPAGESIZE, YPAGESIZE and PAGEBOX keywords, 19 Oct 1999
; Small cosmetic cleanup, CM, 01 Feb 2000
; Fix for IDL 5.5's handling of structures with arrays, CM, 11 Dec 2001
; Replaced obsolete PICKFILE call with DIALOG_PICKFILE, Jeff Guerber,
; 24 Sep 2004
; Transfer DEFAULTS and LOCALDEFAULTS values via STRUCT_ASSIGN,/NOZERO
; instead of EXECUTE, Jeff Guerber, 24 Sep 2004.
; Set CANCELBUTTON and CREATEBUTTON immediately on entry, so they're
; defined even if user kills the window, Jeff Guerber, 24 Sep 2004.
;
; COMMON BLOCKS:
;
; The user may store frequently used or helpful configurations in a
; common block, and cmps_form() will attempt to access them. This
; provides a way for the user to have persistent, named,
; configurations.
;
; NOTE: this format has changed since the last version. You may
; have to quit your IDL session for the changes to take effect
; properly. If you have place a predefined configuration in your
; startup file, you should review the new format.
;
; COMMON CMPS_FORM_CONFIGS, cmps_form_DEFAULT_PAPERSIZE, $
; cmps_form_STDCONFIGS
;
; cmps_form_DEFAULT_PAPERSIZE - a string designating the default
; paper size, when none is given.
; The predefined configurations
; offerred by this program will
; respect the default value. (See
; also the DEFAULTPAPER keyword.)
;
; cmps_form_STDCONFIGS - An array of cmps_form_CONFIG structures,
; each containing information about one
; predefined configuration, such as its
; name and size of paper. Each "config"
; element is a cmps_form_INFO structure,
; which contains the actual postscript
; configuration.
;
; See the IDL source code cmps_form_LOAD_CONFIGS for an example of how
; to make a list of configurations. One possibility would be to
; declare and populate the common block from within the user's
; start-up script, allowing the same configurations to appear in
; every session.
;
; cmps_form() takes its initial list of configurations from this
; common block if it exists. A default list is provided ala the
; procedure cmps_form_LOAD_CONFIGS. Any modifications that take place
; during the cmps_form() widget session are not transferred back to
; the common block upon return. It might be useful to be able to do
; this, through some form of 'save' procedure.
;
; Also, if the PREDEFINED keyword is used, then the common block is
; not consulted.
;
; $Id: cmps_form.pro,v 1.1 2009/02/03 00:54:38 gpi Exp $
;
;-
; Copyright (C) 1996-1997, David Fanning
; Copyright (C) 1997-2001, Craig Markwardt
; This software is provided as is without any warranty whatsoever.
; Permission to use, copy, modify, and distribute modified or
; unmodified copies is granted, provided this copyright and disclaimer
; are included unchanged.
;-
; ***************************************************************
; Utility routines
forward_function filepath
; Convert from inches and centimeters to WIDGET_DRAW pixels
pro cmps_form_Draw_Coords, drawpixperunit, xoff, yoff, xsize, ysize
if n_elements(xoff) GT 0 then xoff = xoff * drawpixperunit + 1
if n_elements(yoff) GT 0 then yoff = yoff * drawpixperunit + 1
if n_elements(xsize) GT 0 then xsize = xsize * drawpixperunit
if n_elements(ysize) GT 0 then ysize = ysize * drawpixperunit
return
end
; Perform the opposite conversion of cmps_form_DRAW_COORDS
pro cmps_form_Real_Coords, drawpixperunit, xoff, yoff, xsize, ysize
if n_elements(xoff) GT 0 then xoff = (xoff-1) / drawpixperunit
if n_elements(yoff) GT 0 then yoff = (yoff-1) / drawpixperunit
if n_elements(xsize) GT 0 then xsize = xsize / drawpixperunit
if n_elements(ysize) GT 0 then ysize = ysize / drawpixperunit
return
end
Pro cmps_form_Select_File, event
; Allows the user to select a filename for writing.
Widget_Control, event.top, Get_UValue=info, /No_Copy
; Start with the name in the filename widget.
Widget_Control, info.idfilename, Get_Value=initialFilename
initialFilename = initialFilename(0)
filename = Dialog_Pickfile(/Write, File=initialFilename)
IF filename NE '' THEN $
Widget_Control, info.idfilename, Set_Value=filename
Widget_Control, event.top, Set_UValue=info, /No_Copy
END ;*******************************************************************
; Calculate a list of vertices to be plotted as a box in the
; draw widget.
Function cmps_form_PlotBox_Coords, xsize, ysize, xoff, yoff, drawpixperunit
; This function converts sizes and offsets to appropriate
; Device coordinates for drawing the PLOT BOX on the PostScript
; page. The return value is a [2,5] array.
returnValue = IntArr(2,5)
xs = xsize
ys = ysize
xof = xoff
yof = yoff
cmps_form_draw_coords, drawpixperunit, xof, yof, xs, ys
; Add one because we do for the page outline
xcoords = Round([xof, xof+xs, xof+xs, xof, xof]) + 1
ycoords = Round([yof, yof, yof+ys, yof+ys, yof]) + 1
returnValue(0,*) = xcoords
returnValue(1,*) = ycoords
RETURN, returnValue
END ;*******************************************************************
; Convert between the IDL-form of PS coordinates (including the
; strange definition of YOFFSET and XOFFSET) to a more
; "human-readable" form where the Xoffset and YOFFSET always refer to
; the lower-left hand corner of the output
pro cmps_form_conv_pscoord, info, xpagesize, ypagesize, $
toidl=toidl, tohuman=tohuman
if info.landscape EQ 1 then begin
ixoff=info.xoff
iyoff=info.yoff
if keyword_set(tohuman) then begin
info.yoff = ixoff
info.xoff = xpagesize - iyoff
endif else if keyword_set(toidl) then begin
info.xoff = iyoff
info.yoff = xpagesize - ixoff
endif
endif
return
end
; Return names of paper sizes
function cmps_form_papernames
return, ['Letter','Legal','Tabloid','Ledger','Executive','Monarch', $
'Statement','Folio','Quarto','C5','B4','B5','Dl','A0','A1', $
'A2','A3','A4','A5','A6']
end
; Select a paper size based on number or string. Returns x and
; y page sizes, accouting for the units of measurement and the
; orientation of the page.
pro cmps_form_select_papersize, papertype, xpagesize, ypagesize, $
inches=inches, landscape=landscape, index=index
; Letter Legal Tabloid Ledger Executive Monarch Statement Folio
xpaper = [612., 612, 792, 792, 540, 279, 396, 612, $
$; Quarto C5 B4 B5 Dl A0 A1 A2 A3 A4 A5 A6
610, 459,729,516,312,2380,1684,1190,842,595,420,297]
; Letter Legal Tabloid Ledger Executive Monarch Statement Folio
ypaper = [792., 1008, 1224, 1224, 720, 540, 612, 936, $
$; Quarto C5 B4 B5 Dl A0 A1 A2 A3 A4 A5 A6
780, 649,1032,729,624,3368,2380,1684,1190,842,595,421]
names = cmps_form_papernames()
sz = size(papertype)
tp = sz(sz(0) + 1)
if tp GT 0 AND tp LT 6 then begin
index = fix(papertype)
endif else if tp EQ 7 then begin
index = where(strupcase(papertype) EQ strupcase(names), ict)
if ict EQ 0 then index = 0
endif else $
index = 0
index = index(0)
xpagesize = xpaper(index) / 72. ; Convert to inches
ypagesize = ypaper(index) / 72.
xpagesize = xpagesize(0)
ypagesize = ypagesize(0)
if NOT keyword_set(inches) then begin
xpagesize = xpagesize * 2.54
ypagesize = ypagesize * 2.54
endif
if keyword_set(landscape) then begin
temp = xpagesize
xpagesize = ypagesize
ypagesize = temp
endif
return
end
; cmps_form_LOAD_CONFIGS
;
; Loads a set of default configurations into the output variables,
;
; CONFIGNAMES - array of names for configurations.
;
; CONFIGS - array of cmps_form_INFO structures, each with a separate
; configuration in it, and corresponding to the
; configuration name.
;
; Intended as an intelligent default when no other is specified.
;
pro cmps_form_load_configs, defaultpaper, configs
; This is the default paper size, when none is given
defaultpaper = 'Letter'
; Here is how the cmps_form_INFO structure is defined. Refer to it
; when creating new structures.
template = { cmps_form_INFO, $
xsize:0.0, $ ; The x size of the plot
xoff:0.0, $ ; The x offset of the plot
ysize:0.0, $ ; The y size of the plot
yoff:0.0, $ ; The y offset of the plot
filename:'', $ ; The name of the output file
inches:0, $ ; Inches or centimeters?
color:0, $ ; Color on or off?
bits_per_pixel:0, $ ; How many bits per image pixel?
encapsulated:0,$ ; Encapsulated or regular PostScript?
isolatin1:0,$ ; Encoding is not ISOLATIN1
landscape:0 } ; Landscape or portrait mode?
pctemplate = { cmps_form_CONFIG, $
config:{cmps_form_INFO}, $
configname: '', $ ; Name of configuration
papersize: '' } ; Size of paper for configuration
; Set of default configurations (no ISOLATIN1 encoding)
; 1. 7x5 inch color plot region in portrait
; 2. 7.5x10 inch centered color plot region, covering almost whole
; portrait page (0.5 inch margins)
; 3. 10x7.5 inch centered color plot region, covering almost whole
; landscape page (0.5 inch margins)
; 4. 7x5 inch gray plot region in portrait (IDL default config)
configs = [{cmps_form_CONFIG, config:$
{cmps_form_INFO, 7.0, 0.75, 5.0, 5.0, 'idl.ps', 1, 1, 8, 0, 0, 0},$
configname:'Half Portrait (color)', papersize:defaultpaper}, $
{cmps_form_CONFIG, config:$
{cmps_form_INFO, 7.5, 0.50, 10., 0.5, 'idl.ps', 1, 1, 8, 0, 0, 0},$
configname:'Full Portrait (color)', papersize:defaultpaper}, $
{cmps_form_CONFIG, config:$
{cmps_form_INFO, 10., 0.50, 7.5, 10.5,'idl.ps', 1, 1, 8, 0, 0, 1},$
configname:'Full Landscape (color)', papersize:defaultpaper}, $
{cmps_form_CONFIG, config:$
{cmps_form_INFO, 18., 1.5, 26.7, 1.5, 'idl.ps', 0, 1, 8, 0, 0, 0},$
configname:'A4 Portrait (color)', papersize:'A4'}, $
{cmps_form_CONFIG, config:$
{cmps_form_INFO, 26.7, 1.5, 18.,28.2039,'idl.ps',0,1, 8, 0, 0, 1},$
configname:'A4 Landscape (color)', papersize:'A4'}, $
{cmps_form_CONFIG, config:$
{cmps_form_INFO, 17.78,1.91,12.70,12.70,'idl.ps',0,1, 4, 0, 0, 0},$
configname:'IDL Standard', papersize:defaultpaper} ]
return
end
;
; cmps_form_Update_Info
;
; This procedure modifies an "info" structure, according to new
; specifications about the PS configuration. This is the central
; clearing house for self-consistent modification of the info structure.
;
; INPUTS
; info - info structure to be modified
; keywords- IDL keywords are contain information is folded
; into the "info" structure.
; Valid keywords are:
; XSIZE, YSIZE,
; XOFF, YOFF - size and offset of plotting region in
; "human" coordinates. This is the
; natural size as measured from the
; lower-left corner of the page in its
; proper orientation (not the IDL
; definition!). These are the same
; values that are printed in the form's
; Size and Offset fields.
; INCHES - whether dimensions are in inches or
; centimeters (1=in, 0=cm)
; COLOR - whether output is color (1=y, 0=n)
; BITS_PER_PIXEL- number of bits per pixel (2,4,8)
; ENCAPSULATED - whether output is EPS (1=EPS, 0=PS)
; LANDSCAPE - whether output is portrait or
; landscape (1=land, 0=port)
; FILENAME - output file name (with respect to
; current directory)
;
Pro cmps_form_Update_Info, info, set=set, _EXTRA=newdata
if n_elements(newdata) GT 0 then $
names = Tag_Names(newdata)
set = keyword_set(set)
centerfactor = 1.0
FOR j=0, N_Elements(names)-1 DO BEGIN
case strupcase(names(j)) of
'XSIZE': info.devconfig.xsize = float(newdata.xsize)
'YSIZE': info.devconfig.ysize = float(newdata.ysize)
'XOFF': info.devconfig.xoff = float(newdata.xoff)
'YOFF': info.devconfig.yoff = float(newdata.yoff)
'INCHES': BEGIN
inches = fix(newdata.inches)
if inches NE 0 then inches = 1
if set NE 1 then begin
convfactor = 1.0
if info.devconfig.inches EQ 0 AND inches EQ 1 then $
convfactor = 1.0/2.54 $ ; centimeters to inches
else if info.devconfig.inches EQ 1 AND inches EQ 0 then $
convfactor = 2.54 ; inches to centimeters
info.devconfig.xsize = info.devconfig.xsize * convfactor
info.devconfig.ysize = info.devconfig.ysize * convfactor
info.devconfig.xoff = info.devconfig.xoff * convfactor
info.devconfig.yoff = info.devconfig.yoff * convfactor
info.xpagesize = info.xpagesize * convfactor
info.ypagesize = info.ypagesize * convfactor
info.marginsize = info.marginsize * convfactor
info.drawpixperunit = info.drawpixperunit / convfactor
endif
info.devconfig.inches = inches
end
'LANDSCAPE': begin
landscape= fix(newdata.landscape)
if landscape NE 0 then landscape = 1
if landscape NE info.devconfig.landscape AND $
set NE 1 then begin
temp = info.xpagesize
info.xpagesize = info.ypagesize
info.ypagesize = temp
; Since the margins are bound to be way out of wack,
; we could recenter here.
xsize = info.devconfig.xsize
ysize = info.devconfig.ysize
centerfactor = 2.0
; We will have to redraw the reserve pixmap
info.pixredraw = 1
endif
info.devconfig.landscape = landscape
end
'COLOR': begin
info.devconfig.color = fix(newdata.color)
if info.devconfig.color NE 0 then info.devconfig.color = 1
end
'ENCAPSULATED': begin
info.devconfig.encapsulated = fix(newdata.encapsulated)
if info.devconfig.encapsulated NE 0 then $
info.devconfig.encapsulated = 1
end
'ISOLATIN1': begin
info.devconfig.isolatin1 = fix(newdata.isolatin1)
if info.devconfig.isolatin1 NE 0 then $
info.devconfig.isolatin1 = 1
end
'BITS_PER_PIXEL': begin
bpp = fix(newdata.bits_per_pixel)
if bpp LT 1 then bpp = 2
if bpp GT 2 AND bpp LT 4 then bpp = 4
if bpp GT 4 AND bpp LT 8 then bpp = 8
if bpp GT 8 then bpp = 8
info.devconfig.bits_per_pixel = bpp
end
'FILENAME': begin
if string(newdata.filename) NE info.devconfig.filename then $
info.filechanged = 1
info.devconfig.filename = string(newdata.filename)
end
endcase
endfor
; Now check the sizes and offsets, to be sure they are sane for the
; particular landscape/portrait and inch/cm settings that have been
; chosen.
pgwid = info.xpagesize
pglen = info.ypagesize
pgmar = info.marginsize
if set NE 1 then begin
info.devconfig.xsize = (pgmar) > info.devconfig.xsize < (pgwid-2.*pgmar)
info.devconfig.ysize = (pgmar) > info.devconfig.ysize < (pglen-2.*pgmar)
info.devconfig.xoff = (pgmar) > info.devconfig.xoff < (pgwid-info.devconfig.xsize - pgmar)
info.devconfig.yoff = (pgmar) > info.devconfig.yoff < (pglen-info.devconfig.ysize - pgmar)
if info.devconfig.xsize + info.devconfig.xoff GT (pgwid-pgmar) then $
info.devconfig.xoff = (pgwid - info.devconfig.xsize) / centerfactor
if info.devconfig.ysize + info.devconfig.yoff GT (pglen-pgmar) then $
info.devconfig.yoff = (pglen - info.devconfig.ysize) / centerfactor
endif
; Preserve aspect ratio if necessary
if (info.preserve_aspect EQ 1) then begin
sizeratio = info.aspect / (info.ypagesize / info.xpagesize)
if (sizeratio GE 1) then $
info.devconfig.xsize = info.devconfig.ysize / info.aspect $
else $
info.devconfig.ysize = info.devconfig.xsize * info.aspect
endif
return
end
;
; PRO cmps_form_DRAW_BOX
;
; Draw the "sample" box in the draw widget. If necessary, also
; redraws the backing reserve pixmap.
;
pro cmps_form_draw_box, xsize, ysize, xoff, yoff, info
; First order of business is to make a new reserve pixmap, if
; necessary.
if info.pixredraw EQ 1 then begin
; Operate on the pixmap first
wset, info.idpixwid
erase
; Make background ...
tv, replicate(info.bkgcolor, info.xpixwinsize, info.ypixwinsize)
; ... and page outline
coords = cmps_form_plotbox_coords(info.xpagesize, info.ypagesize, $
0.,0., info.drawpixperunit)
plots, coords(0,*), coords(1,*), /device, color=info.pagecolor
info.pixredraw = 0
endif
; Now, we transfer the reserve pixmap to the screen
wset, info.idwid
device, copy=[0, 0, info.xpixwinsize, info.ypixwinsize, 0, 0, $
info.idpixwid]
; Finally we overlay the plot region
coords = cmps_form_plotbox_coords(xsize, ysize, xoff, yoff,info.drawpixperunit)
plots, coords(0,*), coords(1,*), color=info.boxcolor, /device
return
end
;
; cmps_form_DRAW_FORM
;
; Update the widget elements of the cmps_form form, using the INFO structure.
;
; If the NOBOX keyword is set, then the draw widget is not updated.
;
pro cmps_form_draw_form, info, nobox=nobox
; Draw the DRAW widget if needed
if NOT keyword_set(nobox) then $
cmps_form_draw_box, info.devconfig.xsize, info.devconfig.ysize, $
info.devconfig.xoff, info.devconfig.yoff, info
; Update the numeric text fields
xsizestr = strtrim(string(info.devconfig.xsize, format='(F6.2)'), 2)
ysizestr = strtrim(string(info.devconfig.ysize, format='(F6.2)'), 2)
xoffstr = strtrim(string(info.devconfig.xoff, format='(F6.2)'), 2)
yoffstr = strtrim(string(info.devconfig.yoff, format='(F6.2)'), 2)
widget_control, info.idxsize, set_value=xsizestr
widget_control, info.idysize, set_value=ysizestr
widget_control, info.idxoff, set_value=xoffstr
widget_control, info.idyoff, set_value=yoffstr
widget_control, info.idaspect, set_button=(info.preserve_aspect EQ 1)
; Set EPS (encapsulated ps) buttons
Widget_Control, info.idencap, Set_Button=(info.devconfig.encapsulated EQ 1)
; Set color buttons.
Widget_Control, info.idcolor, Set_Button=(info.devconfig.color EQ 1)
; Set inch/cm buttons.
Widget_Control, info.idinch, Set_Button=(info.devconfig.inches EQ 1)
Widget_Control, info.idcm, Set_Button=(info.devconfig.inches EQ 0)
; Set bits_per_pixel buttons.
Widget_Control, info.idbit2, Set_Button=(info.devconfig.bits_per_pixel EQ 2)
Widget_Control, info.idbit4, Set_Button=(info.devconfig.bits_per_pixel EQ 4)
Widget_Control, info.idbit8, Set_Button=(info.devconfig.bits_per_pixel EQ 8)
Widget_Control, info.idbitbase, Sensitive=(info.devconfig.color EQ 1)
; Set encoding button
widget_control, info.idisolatin1, Set_Button=(info.devconfig.isolatin1 EQ 1)
; Set default filename.
Widget_Control, info.idfilename, Get_Value=wfilename
if string(wfilename(0)) NE info.devconfig.filename then begin
Widget_Control, info.idfilename, Set_Value=info.devconfig.filename
; Put caret at end of pathname text so that filename itself is visible
Widget_Control, info.idfilename, $
Set_Text_Select=[ strlen(info.devconfig.filename), 0 ]
endif
; Set protrait/landscape button.
Widget_Control, info.idland, Set_Button=(info.devconfig.landscape EQ 1)
Widget_Control, info.idport, Set_Button=(info.devconfig.landscape EQ 0)
; Set Paper
pn = cmps_form_papernames()
xp = strtrim(string(info.xpagesize, format='(F10.2)'),2)
yp = strtrim(string(info.ypagesize, format='(F10.2)'),2)
un = 'in'
if NOT info.devconfig.inches then un = 'cm'
paperlab = string(pn(info.paperindex), xp, un, yp, un, $
format='(" Paper: ",A0," (",A0,A0," x ",A0,A0,") ")')
Widget_Control, info.idpaperlabel, set_value=paperlab
return
end
Pro cmps_form_Null_Events, event
END ;*******************************************************************
Function cmps_form_What_Button_Type, event
; Checks event.type to find out what kind of button
; was clicked in a draw widget. This is NOT an event handler.
type = ['DOWN', 'UP', 'MOTION', 'SCROLL']
Return, type(event.type)
END ;*******************************************************************
Function cmps_form_What_Button_Pressed, event
; Checks event.press to find out what kind of button
; was pressed in a draw widget. This is NOT an event handler.
button = ['NONE', 'LEFT', 'MIDDLE', 'NONE', 'RIGHT']
Return, button(event.press)
END ;*******************************************************************
Function cmps_form_What_Button_Released, event
; Checks event.release to find out what kind of button
; was released in a draw widget. This is NOT an event handler.
button = ['NONE', 'LEFT', 'MIDDLE', 'NONE', 'RIGHT']
Return, button(event.release)
END ;*******************************************************************
;
; cmps_form_NUMEVENTS
;
; Events sent to the numeric text field widgets are sent here. We
; harvest the data values from the text field and update the screen.
;
Pro cmps_form_NumEvents, event
; If an event comes here, read the offsets and sizes from the
; form and draw the appropriately sized box in the draw widget.
Widget_Control, event.top, Get_UValue= info, /No_Copy
; Get current values for offset and sizes
Widget_Control, info.idxsize, Get_Value=xsize
Widget_Control, info.idysize, Get_Value=ysize
Widget_Control, info.idxoff, Get_Value=xoff
Widget_Control, info.idyoff, Get_Value=yoff
xsize = xsize(0)
ysize = ysize(0)
xoff = xoff(0)
yoff = yoff(0)
if info.preserve_aspect EQ 1 then begin
if event.id EQ info.idysize then xsize = ysize / info.aspect $
else ysize = xsize * info.aspect
endif
; Fold this information into the "info" structure
cmps_form_update_info, info, xsize=xsize, ysize=ysize, xoff=xoff, yoff=yoff
; Update form and redraw sample box
cmps_form_draw_form, info
; Put the info structure back into the top-level base
Widget_Control, event.top, Set_UValue=info, /No_Copy
END ;*******************************************************************
Pro cmps_form_Move_Box, event
; This is the event handler that allows the user to "move"
; the plot box around in the page window. It will set the
; event handler back to "cmps_form_Box_Events" when it senses an
; "UP" draw button event and it will also turn cmps_form_Draw_Motion_Events
; OFF.
; Get the info structure out of the top-level base.
Widget_Control, event.top, Get_UValue=info, /No_Copy
whatButtonType = cmps_form_What_Button_Type(event)
dpu = info.drawpixperunit
ixmin = 0.
iymin = 0.
ixsize = info.devconfig.xsize
iysize = info.devconfig.ysize
cmps_form_draw_coords, dpu, ixmin, iymin, ixsize, iysize
; Now ixmin,iymin have the minimum values of x and y, in pixels
; ixsize and iysize are the size of the box, in pixels
ixmax = info.xpagesize
iymax = info.ypagesize
cmps_form_draw_coords, dpu, ixmax, iymax
; ixmax and iymax are the max values of x and y, in pixels
; info.ideltx/y contains the offset of the lower left corner of the box,
; with respect to the mouse's position
ixoff = event.x + info.ideltx
iyoff = event.y + info.idelty
; Keep box inside the page
if ixoff LT ixmin then ixoff = ixmin
if iyoff LT iymin then iyoff = iymin
if (ixoff+ixsize) GT ixmax then ixoff = ixmax - ixsize
if (iyoff+iysize) GT iymax then iyoff = iymax - iysize
IF whatButtonType EQ 'UP' THEN Begin
; When the button is "up" the moving event is over. We reset the
; event function and update the information about the box's position
Widget_Control, info.iddraw, Draw_Motion_Events=0, $ ; Motion events off
Event_Pro='cmps_form_Box_Events' ; Change to normal processing
cmps_form_real_coords, dpu, ixoff, iyoff, ixsize, iysize
; Update the info structure
cmps_form_update_info, info, xoff=ixoff, yoff=iyoff
; Draw it
cmps_form_draw_form, info
; Put the info structure back in the top-level base and RETURN
Widget_Control, event.top, Set_UValue=info, /No_Copy
Return
ENDIF
; You come to this section of the code for all events except
; an UP button event. Most of the action in this event handler
; occurs here.
cmps_form_real_coords, dpu, ixoff, iyoff, ixsize, iysize
; Simply draw the new box
cmps_form_draw_box, ixsize, iysize, ixoff, iyoff, info
; Put the info structure back into the top-level base.
Widget_Control, event.top, Set_UValue=info, /No_Copy
END ;*******************************************************************
Pro cmps_form_Grow_Box, event
; This event handler is summoned when a RIGHT button is clicked
; in the draw widget. It allows the user to draw the outline of a
; box with the mouse. It will continue drawing the new box shape
; until an UP event is detected. Then it will set the event handler
; back to cmps_form_Box_Events and turn cmps_form_Draw_Motion_Events to OFF.
; Get the info structure out of the top-level base.
Widget_Control, event.top, Get_UValue=info, /No_Copy
whatButtonType = cmps_form_What_Button_Type(event)
dpu = info.drawpixperunit
ixmin = 0.
iymin = 0.
ixsize = info.devconfig.xsize
iysize = info.devconfig.ysize
cmps_form_draw_coords, dpu, ixmin, iymin, ixsize, iysize
; Now ixmin,iymin have the minimum values of x and y, in pixels
; ixsize and iysize are the size of the box, in pixels
ixmax = info.xpagesize
iymax = info.ypagesize
cmps_form_draw_coords, dpu, ixmax, iymax
; ixmax and iymax are the max values of x and y, in pixels
; Keep box inside the page
if event.x LT ixmin then event.x = ixmin
if event.x GT ixmax then event.x = ixmax
if event.y LT iymin then event.y = iymin
if event.y GT iymax then event.y = iymax
; Decide on which corner is the lower left (it's arbitrary)
ixoff = min([info.imousex, event.x])
iyoff = min([info.imousey, event.y])
ixsize = max([info.imousex, event.x]) - ixoff
iysize = max([info.imousey, event.y]) - iyoff
;; Enforce the aspect ratio
if info.preserve_aspect EQ 1 then begin
sizeratio = info.aspect / (info.ypagesize / info.xpagesize)
if (sizeratio GE 1) then ixsize = iysize / info.aspect $
else iysize = ixsize * info.aspect
if info.imousex GT event.x then ixoff = info.imousex - ixsize
if info.imousey GT event.y then iyoff = info.imousey - iysize
endif
IF whatButtonType EQ 'UP' THEN Begin
; When the button is "up" the moving event is over. We reset the
; event function and update the information about the box's position
Widget_Control, info.iddraw, Draw_Motion_Events=0, $ ; Motion events off
Event_Pro='cmps_form_Box_Events' ; Change to normal processing
cmps_form_real_coords, dpu, ixoff, iyoff, ixsize, iysize