source: trunk/gui/scripts/xyprint.tcl @ 1598

Last change on this file since 1598 was 1598, checked in by gah, 15 years ago
File size: 36.9 KB
Line 
1
2# ----------------------------------------------------------------------
3#  COMPONENT: xyprint - Print X-Y plot.
4#
5# ======================================================================
6#  AUTHOR:  Michael McLennan, Purdue University
7#  Copyright (c) 2004-2005  Purdue Research Foundation
8#
9#  See the file "license.terms" for information on usage and
10#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11# ======================================================================
12package require Itk
13package require BLT
14
15#option add *XyPrint.width 3i widgetDefault
16#option add *XyPrint.height 3i widgetDefault
17option add *XyPrint.gridColor #d9d9d9 widgetDefault
18option add *XyPrint.activeColor blue widgetDefault
19option add *XyPrint.dimColor gray widgetDefault
20option add *XyPrint.controlBackground gray widgetDefault
21option add *XyPrint*font "Arial 10"
22option add *XyPrint*Entry*width "6" widgetDefault
23option add *XyPrint*Entry*background "white" widgetDefault
24
25array set Rappture::axistypes {
26    x x
27    y y
28    x2 x
29    y2 y
30}
31
32itcl::class Rappture::XyPrint {
33    inherit itk::Widget
34
35    constructor {args} {}
36    destructor {}
37
38    private variable _graph "";         # Original graph.
39    private variable _clone "";         # Cloned graph.
40    private variable _preview "";       # Preview image.
41    private variable _savedSettings;    # Array of settings.
42       
43    public method print { graph toolName plotName }
44
45    private method CopyOptions { cmd orig clone }
46    private method CopyBindings { oper orig clone args }
47    private method CloneGraph { orig }
48
49    private method BuildGeneralTab {}
50    private method BuildLayoutTab {}
51    private method BuildLegendTab {}
52    private method BuildAxisTab {}
53    private method SetOption { opt }
54    private method SetComponentOption { comp opt }
55    private method SetNamedComponentOption { comp name opt }
56    private method GetAxis {}
57    private method GetElement { args }
58    private method RegeneratePreview {}
59    private method InitClone {}
60    private method Pixels2Inches { pixels }
61    private method Inches2Pixels { inches }
62
63    private method ApplyGeneralSettings {}
64    private method ApplyLegendSettings {}
65    private method ApplyAxisSettings {}
66    private method ApplyElementSettings {}
67    private method ApplyLayoutSettings {}
68    private method InitializeSettings {}
69    private method CreateSettings { toolName plotName }
70    private method RestoreSettings { toolName plotName }
71    private method SaveSettings { toolName plotName }
72    private method ResetSettings { }
73    private method GetOutput {}
74    private method Done { state }
75    private method DestroySettings {}
76    private method restore { toolName plotName data }
77    private common _settings
78    private common _wait
79}
80
81# ----------------------------------------------------------------------
82# CONSTRUCTOR
83# ----------------------------------------------------------------------
84itcl::body Rappture::XyPrint::constructor { args } {
85    Rappture::dispatcher _dispatcher
86    $_dispatcher register !rebuild
87    $_dispatcher dispatch $this !rebuild "[itcl::code $this Rebuild]; list"
88   
89#     option add hull.width hull.height
90#     pack propagate $itk_component(hull) no
91
92    set w [winfo pixels . 2.5i]
93    set h [winfo pixels . 2i]
94    set _preview [image create photo -width $w -height $h]
95    itk_component add tabs {
96        blt::tabset $itk_interior.tabs \
97            -highlightthickness 0 -tearoff 0 -side top \
98            -bd 0 -gap 0 -tabborderwidth 1 \
99            -outerpad 1 -background grey
100    } {
101        keep -cursor
102        ignore -highlightthickness -borderwidth -background
103    }
104    itk_component add preview {
105        label $itk_interior.preview \
106            -highlightthickness 0 -bd 0 -image $_preview -width 2.5i \
107                -height 2.25i -background grey -padx 10 -pady 10
108    } {
109        ignore -background
110    }
111    itk_component add ok {
112        button $itk_interior.ok -text "Print" \
113            -highlightthickness 0 \
114            -command [itcl::code $this Done 1] \
115            -compound left \
116            -image [Rappture::icon download]
117    }
118    itk_component add cancel {
119        button $itk_interior.cancel -text "Cancel" \
120            -highlightthickness 0 \
121            -command [itcl::code $this Done 0] \
122            -compound left \
123            -image [Rappture::icon cancel]
124    }
125    blt::table $itk_interior \
126        0,0 $itk_component(preview) -cspan 2 -fill both \
127        1,0 $itk_component(tabs) -fill both -cspan 2 \
128        2,1 $itk_component(cancel) -padx 2 -pady 2 -width .9i -fill y \
129        2,0 $itk_component(ok) -padx 2 -pady 2 -width .9i -fill y
130    blt::table configure $itk_interior r1 -resize none
131    blt::table configure $itk_interior r1 -resize both
132
133    BuildGeneralTab
134    BuildAxisTab
135    BuildLegendTab
136    BuildLayoutTab
137    eval itk_initialize $args
138}
139
140# ----------------------------------------------------------------------
141# DESTRUCTOR
142# ----------------------------------------------------------------------
143itcl::body Rappture::XyPrint::destructor {} {
144    destroy $_clone
145    image delete $_preview
146    array unset _settings $this-*
147}
148
149itcl::body Rappture::XyPrint::DestroySettings {} {
150    destroy $_clone
151    array unset _settings $this-*
152    set _clone ""
153    set _graph ""
154}
155
156itcl::body Rappture::XyPrint::Done { state } {
157    set _wait($this) $state
158}
159
160itcl::body Rappture::XyPrint::print { graph toolName plotName } {
161    set _graph $graph
162    set _clone [CloneGraph $graph]
163    InitClone
164    InitializeSettings
165    # RestoreSettings $toolName $plotName
166    set _wait($this) 0
167    tkwait variable [itcl::scope _wait($this)]
168    set output ""
169    if { $_wait($this) } {
170        set output [GetOutput]
171    }
172    # SaveSettings $toolName $plotName
173    DestroySettings
174    return $output
175}
176
177itcl::body Rappture::XyPrint::GetOutput {} {
178    # Get the selected format of the download.
179    set page $itk_component(graph_page)
180    set format [$page.format current]
181
182    if { $format == "jpg" } {
183        set img [image create photo]
184        $_clone snap $img
185        set bytes [$img data -format "jpeg -quality 100"]
186        set bytes [Rappture::encoding::decode -as b64 $bytes]
187        image delete $img
188        return [list .jpg $bytes]
189    } elseif { $format == "png" } {
190        set img [image create photo]
191        $_clone snap $img
192        set bytes [$img data -format "png"]
193        set bytes [Rappture::encoding::decode -as b64 $bytes]
194        image delete $img
195        return [list .png $bytes]
196    }
197
198    # Handle encapsulated postscript or portable document format.
199
200    # Append an "i" for the graph postscript component.
201    set w $_settings($this-layout-width)i
202    set h $_settings($this-layout-height)i
203
204    $_clone postscript configure \
205        -maxpect false \
206        -decoration yes \
207        -center yes \
208        -width $w -height $h
209   
210    set psdata [$_clone postscript output]
211
212    if 1 {
213        set f [open "junk.raw" "w"]
214        puts -nonewline $f $psdata
215        close $f
216    }
217
218    set cmd ""
219    # | eps2eps << $psdata
220    lappend cmd "|" "/usr/bin/gs" \
221        "-q" "-sDEVICE=epswrite" "-sstdout=%stderr" \
222        "-sOutputFile=-" "-dNOPAUSE" "-dBATCH" "-dSAFER" \
223        "-dDEVICEWIDTH=250000" "-dDEVICEHEIGHT=250000" "-" "<<" "$psdata"
224    if { $format == "pdf" } {
225        # | eps2eps << $psdata | ps2pdf
226        lappend cmd "|" "/usr/bin/gs" \
227            "-q" "-sDEVICE=pdfwrite" "-sstdout=%stderr" \
228            "-sOutputFile=-" "-dNOPAUSE" "-dBATCH" "-dSAFER" \
229            "-dCompatibilityLevel=1.4" "-c" ".setpdfwrite" "-f" "-"
230    }
231    if { [catch {
232        set f [open $cmd "r"]
233        fconfigure $f -translation binary -encoding binary
234        set output [read $f]
235        close $f
236    } err ] != 0 } {
237        global errorInfo
238        puts stderr "failed to generate file: $err\n$errorInfo"
239        return ""
240    }
241    if 0 {
242        set f [open "junk.$format" "w"]
243        fconfigure $f -translation binary -encoding binary
244        puts -nonewline $f $output
245        close $f
246    }
247    return [list .$format $output]
248}
249
250itcl::body Rappture::XyPrint::CopyOptions { cmd orig clone } {
251    set all [eval $orig $cmd]
252    set configLine $clone
253    foreach arg $cmd {
254        lappend configLine $arg
255    }
256    foreach option $all {
257        if { [llength $option] != 5 } {
258            continue
259        }
260        set switch [lindex $option 0]
261        set initial [lindex $option 3]
262        set current [lindex $option 4]
263        if { [string compare $initial $current] == 0 } {
264            continue
265        }
266        lappend configLine $switch $current
267    }
268    eval $configLine
269}
270
271itcl::body Rappture::XyPrint::CloneGraph { orig } {
272    set top $itk_interior
273    set clone [blt::graph $top.graph]
274    CopyOptions "configure" $orig $clone
275    # Axis component
276    foreach axis [$orig axis names] {
277        if { [$orig axis cget $axis -hide] } {
278            continue
279        }
280        if { [$clone axis name $axis] == "" } {
281            $clone axis create $axis
282        }
283        CopyOptions [list axis configure $axis] $orig $clone
284    }
285    foreach axis { x y x2 y2 } {
286        $clone ${axis}axis use [$orig ${axis}axis use]
287    }
288    # Pen component
289    foreach pen [$orig pen names] {
290        if { [$clone pen name $pen] == "" } {
291            $clone pen create $pen
292        }
293        CopyOptions [list pen configure $pen] $orig $clone
294    }
295    # Marker component
296    foreach marker [$orig marker names] {
297        $clone marker create [$orig marker type $marker] -name $marker
298        CopyBindings marker $orig $clone $marker
299        CopyOptions [list marker configure $marker] $orig $clone
300    }
301    # Element component
302    foreach elem [$orig element names] {
303        $clone element create $elem
304        CopyOptions [list element configure $elem] $orig $clone
305    }
306    # Fix element display list
307    $clone element show [$orig element show]
308    # Legend component
309    CopyOptions {legend configure} $orig $clone
310    # Postscript component
311    CopyOptions {postscript configure} $orig $clone
312    # Grid component
313    CopyOptions {grid configure} $orig $clone
314    # Grid component
315    CopyOptions {crosshairs configure} $orig $clone
316    return $clone
317}
318
319itcl::body Rappture::XyPrint::InitClone {} {
320   
321    $_clone configure -width 3.4i -height 3.4i -background white \
322        -borderwidth 0 \
323        -leftmargin 0 \
324        -rightmargin 0 \
325        -topmargin 0 \
326        -bottommargin 0
327   
328    # Kill the title and create a border around the plot
329    $_clone configure \
330        -title "" \
331        -plotborderwidth 1 -plotrelief solid  \
332        -plotbackground white -plotpadx 0 -plotpady 0
333    #
334    set _fonts(legend) [font create -family times -size 10 -weight normal]
335    update
336    $_clone legend configure \
337        -position right \
338        -font $_fonts(legend) \
339        -hide yes -borderwidth 0 -background white -relief solid \
340        -anchor nw -activeborderwidth 0
341    #
342    foreach axis [$_clone axis names] {
343        if { [$_clone axis cget $axis -hide] } {
344            continue
345        }
346        set _fonts($axis-ticks) [font create -family courier -size 10 \
347                                     -weight normal -slant roman]
348        set _fonts($axis-title) [font create -family symbol -size 10 \
349                                     -weight normal -slant roman]
350        puts stderr "tick fonts $_fonts($axis-ticks):  [font configure $_fonts($axis-ticks)]"
351        puts stderr "title fonts $_fonts($axis-title): [font configure $_fonts($axis-title)]"
352        update
353        $_clone axis configure $axis -ticklength 5  \
354            -majorticks {} -minorticks {}
355        $_clone axis configure $axis \
356            -tickfont $_fonts($axis-ticks) \
357            -titlefont $_fonts($axis-title)
358    }
359    #$_clone grid off
360    #$_clone yaxis configure -rotate 90
361    #$_clone y2axis configure -rotate 270
362    foreach elem [$_clone element names] {
363        $_clone element configure $elem -linewidth 1 \
364            -pixels 3
365    }
366    # Create markers representing lines at zero for the x and y axis.
367    $_clone marker create line -name x-zero \
368        -coords "0 -Inf 0 Inf" -dashes 1 -hide yes
369    $_clone marker create line -name y-zero \
370        -coords "-Inf 0 Inf 0" -dashes 1 -hide yes
371}
372
373itcl::body Rappture::XyPrint::SetOption { opt } {
374    set new $_settings($this-graph-$opt)
375    set old [$_clone cget -$opt]
376    set code [catch [list $_clone configure -$opt $new] err]
377    if { $code != 0 } {
378        bell
379        global errorInfo
380        puts stderr "$err: $errorInfo"
381        set _settings($this-graph-$opt) $old
382    }
383}
384
385itcl::body Rappture::XyPrint::SetComponentOption { comp opt } {
386    set new $_settings($this-$comp-$opt)
387    set old [$_clone $comp cget -$opt]
388    set code [catch [list $_clone $comp configure -$opt $new] err]
389    if { $code != 0 } {
390        bell
391        global errorInfo
392        puts stderr "$err: $errorInfo"
393        set _settings($this-$comp-$opt) $old
394    }
395}
396
397itcl::body Rappture::XyPrint::SetNamedComponentOption { comp name opt } {
398    set new $_settings($this-$comp-$opt)
399    set old [$_clone $comp cget $name -$opt]
400    set code [catch [list $_clone $comp configure $name -$opt $new] err]
401    if { $code != 0 } {
402        bell
403        global errorInfo
404        puts stderr "$err: $errorInfo"
405        set _settings($this-$comp-$opt) $old
406    }
407}
408
409itcl::body Rappture::XyPrint::RegeneratePreview {} {
410    update
411    set img [image create photo]
412
413    set w [Inches2Pixels $_settings($this-layout-width)]
414    set h [Inches2Pixels $_settings($this-layout-height)]
415    set pixelsPerInch [winfo pixels . 1i]
416    set sx [expr 2.5*$pixelsPerInch/$w]
417    set sy [expr 2.0*$pixelsPerInch/$h]
418    set s [expr min($sx,$sy)]
419    $_clone snap $img -width $w -height $h
420
421    if 0 {
422    if { ![winfo exists .labeltest] } {
423        toplevel .labeltest -bg red
424        label .labeltest.label -image $img
425        pack .labeltest.label -fill both
426    }
427    }
428    set pw [expr int(round($s * $w))]
429    set ph [expr int(round($s * $h))]
430    $_preview configure -width $pw -height $ph
431    #.labeltest.label configure -image $img
432    blt::winop resample $img $_preview box
433    image delete $img
434}
435
436itcl::body Rappture::XyPrint::Pixels2Inches { pixels } {
437    if { [llength $pixels] == 2 } {
438        set pixels [lindex $pixels 0]
439    }
440    set pixelsPerInch [winfo pixels . 1i]
441    set inches [expr { double($pixels) / $pixelsPerInch }]
442    return [format %.3g ${inches}]
443}
444
445itcl::body Rappture::XyPrint::Inches2Pixels { inches } {
446    return  [winfo pixels . ${inches}i]
447}
448
449
450itcl::body Rappture::XyPrint::GetAxis {} {
451    set axis [$itk_component(axis_combo) current]
452    foreach option { min max loose title stepsize subdivisions } {
453        set _settings($this-axis-$option) [$_clone axis cget $axis -$option]
454    }
455    set type $Rappture::axistypes($axis)
456    if { [$_clone grid cget -map${type}] == $axis } {
457        set _settings($this-axis-grid) 1
458    }  else {
459        set _settings($this-axis-grid) 0
460    }
461    set _settings($this-axis-zero) [$_clone marker cget ${type}-zero -hide]
462}
463
464itcl::body Rappture::XyPrint::GetElement { args } {
465    set index 1
466    foreach elem [$_clone element show] {
467        set _settings($this-element-$index) $elem
468        incr index
469    }
470    set index [$itk_component(element_slider) get]
471    set elem $_settings($this-element-$index)
472    set _settings($this-element-symbol) [$_clone element cget $elem -symbol]
473    set _settings($this-element-color) [$_clone element cget $elem -color]
474    set _settings($this-element-dashes) [$_clone element cget $elem -dashes]
475    set _settings($this-element-hide) [$_clone element cget $elem -hide]
476    set _settings($this-element-label) [$_clone element cget $elem -label]
477    set page $itk_component(legend_page)
478    $page.color value [$page.color label $_settings($this-element-color)]
479    $page.symbol value [$page.symbol label $_settings($this-element-symbol)]
480    $page.dashes value [$page.dashes label $_settings($this-element-dashes)]
481    #FixElement
482}
483
484itcl::body Rappture::XyPrint::BuildLayoutTab {} {
485    itk_component add layout_page {
486        frame $itk_component(tabs).layout_page
487    }
488    set page $itk_component(layout_page)
489    $itk_component(tabs) insert end "layout" \
490        -text "Layout" -padx 2 -pady 2 -window $page -fill both
491
492    label $page.width_l -text "width" 
493    entry $page.width -width 6 \
494        -textvariable [itcl::scope _settings($this-layout-width)]
495    bind  $page.width <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
496
497    label $page.height_l -text "height"
498    entry $page.height -width 6 \
499        -textvariable [itcl::scope _settings($this-layout-height)]
500    bind  $page.height <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
501
502    label $page.margin_l -text "Margins" 
503
504    label $page.left_l -text "left"
505    entry $page.left -width 6 \
506        -textvariable [itcl::scope _settings($this-layout-leftmargin)]
507    bind  $page.left <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
508
509    label $page.right_l -text "right"
510    entry $page.right -width 6 \
511        -textvariable [itcl::scope _settings($this-layout-rightmargin)]
512    bind  $page.right <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
513
514    label $page.top_l -text "top"
515    entry $page.top -width 6 \
516        -textvariable [itcl::scope _settings($this-layout-topmargin)]
517    bind  $page.top <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
518
519    label $page.bottom_l -text "bottom"
520    entry $page.bottom -width 6 \
521        -textvariable [itcl::scope _settings($this-layout-bottommargin)]
522    bind  $page.bottom <KeyPress-Return> [itcl::code $this ApplyLayoutSettings]
523
524    blt::table $page \
525        1,0 $page.width_l -anchor e \
526        1,1 $page.width -fill x -cspan 2 \
527        1,3 $page.height_l -anchor e \
528        1,4 $page.height -fill x -cspan 2 \
529        3,2 $page.top_l -anchor e \
530        3,3 $page.top -fill x \
531        4,0 $page.left_l -anchor e \
532        4,1 $page.left -fill x  \
533        4,4 $page.right_l -anchor e \
534        4,5 $page.right -fill x \
535        5,2 $page.bottom_l -anchor e \
536        5,3 $page.bottom -fill x 
537
538    blt::table configure $page r* -resize none
539    blt::table configure $page r2 -resize both
540    blt::table configure $page c2 c4 -width .5i
541    blt::table configure $page r6 -height .125i
542}
543
544
545itcl::body Rappture::XyPrint::BuildGeneralTab {} {
546    itk_component add graph_page {
547        frame $itk_component(tabs).graph_page
548    }
549    set page $itk_component(graph_page)
550    $itk_component(tabs) insert end "graph" \
551        -text "General" -padx 2 -pady 2 -window $page -fill both
552
553    label $page.format_l -text "format"
554    Rappture::Combobox $page.format -width 30 -editable no
555    $page.format choices insert end \
556        "eps" "EPS Encapsulated PostScript"  \
557        "pdf" "PDF Portable Document Format" \
558        "jpg"  "JPEG Joint Photographic Experts Group Format" \
559        "png"  "PNG Portable Network Graphics Format"         
560
561    bind $page.format <<Value>> [itcl::code $this ApplyGeneralSettings]
562
563    label $page.style_l -text "style"
564    Rappture::Combobox $page.style -width 20 -editable no
565    $page.style choices insert end \
566        "ieee" "IEEE Journal"  \
567        "gekco" "G Klimeck" 
568    bind $page.style <<Value>> [itcl::code $this ApplyGeneralSettings]
569
570    checkbutton $page.remember -text "remember settings" \
571        -variable [itcl::scope _settings($this-general-remember)] 
572
573    blt::table $page \
574        2,0 $page.format_l -anchor e \
575        2,1 $page.format -fill x \
576        3,0 $page.style_l -anchor e \
577        3,1 $page.style -fill x \
578        5,0 $page.remember -cspan 2 -anchor w
579    blt::table configure $page r* -resize none
580    blt::table configure $page r4 -resize both
581
582}
583   
584itcl::body Rappture::XyPrint::ApplyLegendSettings {} {
585    set page $itk_component(legend_page)
586    set _settings($this-legend-position)  [$page.position current]
587    set _settings($this-legend-anchor)    [$page.anchor current]
588    foreach option { hide position anchor borderwidth } {
589        SetComponentOption legend $option
590    }
591    ApplyElementSettings
592}
593
594itcl::body Rappture::XyPrint::BuildLegendTab {} {
595    itk_component add legend_page {
596        frame $itk_component(tabs).legend_page
597    }
598    set page $itk_component(legend_page)
599    $itk_component(tabs) insert end "legend" \
600        -text "Legend" -padx 2 -pady 2 -window $page -fill both
601
602    checkbutton $page.show -text "show legend" \
603        -offvalue 1 -onvalue 0 \
604        -variable [itcl::scope _settings($this-legend-hide)]  \
605        -command [itcl::code $this ApplyLegendSettings]
606
607    label $page.position_l -text "position"
608    Rappture::Combobox $page.position -width 15 -editable no
609    $page.position choices insert end \
610        "leftmargin" "left margin"  \
611        "rightmargin" "right margin"  \
612        "bottommargin" "bottom margin"  \
613        "topmargin" "top margin"  \
614        "plotarea" "inside plot"
615    bind $page.position <<Value>> [itcl::code $this ApplyLegendSettings]
616
617    Rappture::Combobox $page.anchor -width 10 -editable no
618    $page.anchor choices insert end \
619        "nw" "northwest"  \
620        "n" "north"  \
621        "ne" "northeast"  \
622        "sw" "southwest"  \
623        "s" "south"  \
624        "se" "southeast"  \
625        "c" "center"  \
626        "e" "east"  \
627        "w" "west" 
628    bind $page.anchor <<Value>> [itcl::code $this ApplyLegendSettings]
629
630    checkbutton $page.border -text "border" \
631        -font "Arial 10"  \
632        -variable [itcl::scope _settings($this-legend-borderwidth)] \
633        -onvalue 1 -offvalue 0 \
634        -command [itcl::code $this ApplyLegendSettings]
635
636    label $page.slider_l -text "legend\nentry"  -font "Arial 10" -justify right
637    itk_component add element_slider {
638        ::scale $page.slider -from 1 -to 1 \
639            -orient horizontal -width 12 \
640            -command [itcl::code $this GetElement]
641    }
642    checkbutton $page.hide -text "hide" \
643        -font "Arial 10"  \
644        -variable [itcl::scope _settings($this-element-hide)] \
645        -command [itcl::code $this ApplyElementSettings]
646
647    label $page.label_l -text "label" -font "Arial 10"
648    entry $page.label \
649        -background white \
650        -font "Arial 10" \
651        -textvariable [itcl::scope _settings($this-element-label)]
652    bind  $page.label <KeyPress-Return> [itcl::code $this ApplyElementSettings]
653
654    label $page.color_l -text "color "  -font "Arial 10"
655    Rappture::Combobox $page.color -width 15 -editable no
656    $page.color choices insert end \
657        "#000000" "black" \
658        "#ffffff" "white" \
659        "#0000cd" "blue" \
660        "#cd0000" "red" \
661        "#00cd00" "green" \
662        "#3a5fcd" "royal blue" \
663        "#cdcd00" "yellow" \
664        "#cd1076" "deep pink" \
665        "#009acd" "deep sky blue" \
666        "#00c5cd" "torquise" \
667        "#a2b5cd" "light steel blue" \
668        "#7ac5cd" "cadet blue" \
669        "#66cdaa" "aquamarine" \
670        "#a2cd5a" "dark olive green" \
671        "#cd9b9b" "rosy brown"
672    bind $page.color <<Value>> [itcl::code $this ApplyElementSettings]
673
674    label $page.dashes_l -text "line style"  -font "Arial 10"
675    Rappture::Combobox $page.dashes -width 15 -editable no
676    $page.dashes choices insert end \
677        "" "solid"  \
678        "1" "dot" \
679        "5 2" "dash" \
680        "2 4 2" "dashdot" \
681        "2 4 2 2" "dashdotdot"
682    bind $page.dashes <<Value>> [itcl::code $this ApplyElementSettings]
683
684    label $page.symbol_l -text "symbol"  -font "Arial 10"
685    Rappture::Combobox $page.symbol -editable no
686    $page.symbol choices insert end \
687        "none" "none"  \
688        "square" "square" \
689        "circle" "circle" \
690        "diamond" "diamond" \
691        "plus" "plus" \
692        "cross" "cross" \
693        "splus" "skinny plus"  \
694        "scross" "skinny cross" \
695        "triangle" "triangle"
696    bind $page.symbol <<Value>> [itcl::code $this ApplyElementSettings]
697
698    blt::table $page \
699        1,0 $page.show -cspan 2 -anchor w \
700        1,2 $page.border -cspan 2 -anchor w \
701        2,0 $page.position_l -anchor e \
702        2,1 $page.position -fill x \
703        2,2 $page.anchor -fill x  -cspan 2 \
704        3,0 $page.slider_l -anchor e \
705        3,1 $page.slider -fill x -cspan 4 \
706        4,0 $page.label_l -anchor e \
707        4,1 $page.label -fill x -cspan 3 \
708        5,0 $page.color_l -anchor e \
709        5,1 $page.color -fill x \
710        5,2 $page.symbol_l -anchor e \
711        5,3 $page.symbol -fill both \
712        6,0 $page.dashes_l -anchor e \
713        6,1 $page.dashes -fill x \
714
715    blt::table configure $page r* -resize none
716    blt::table configure $page r8 -resize both
717
718}
719
720itcl::body Rappture::XyPrint::BuildAxisTab {} {
721    itk_component add axis_page {
722        frame $itk_component(tabs).axis_page
723    }
724    set page $itk_component(axis_page)
725    $itk_component(tabs) insert end "axis" \
726        -text "Axis" -padx 2 -pady 2 -window $page -fill both
727   
728    label $page.axis_l -text "axis"  -font "Arial 10"
729    itk_component add axis_combo {
730        Rappture::Combobox $page.axis -width 20 -editable no
731    }
732    bind $itk_component(axis_combo) <<Value>> [itcl::code $this GetAxis]
733
734    label $page.title_l -text "title"  -font "Arial 10"
735    entry $page.title \
736        -textvariable [itcl::scope _settings($this-axis-title)]
737    bind  $page.title <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
738
739    label $page.min_l -text "min"  -font "Arial 10"
740    entry $page.min -width 10 \
741        -textvariable [itcl::scope _settings($this-axis-min)]
742    bind  $page.min <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
743
744    label $page.max_l -text "max"  -font "Arial 10"
745    entry $page.max -width 10 \
746        -textvariable [itcl::scope _settings($this-axis-max)]
747    bind  $page.max <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
748
749    label $page.subdivisions_l -text "subdivisions"  -font "Arial 10"
750    entry $page.subdivisions \
751        -textvariable [itcl::scope _settings($this-axis-subdivisions)]
752    bind  $page.subdivisions <KeyPress-Return> \
753        [itcl::code $this ApplyAxisSettings]
754
755    label $page.stepsize_l -text "step size"  -font "Arial 10"
756    entry $page.stepsize \
757        -textvariable [itcl::scope _settings($this-axis-stepsize)]
758    bind  $page.stepsize <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
759
760    checkbutton $page.loose -text "loose limits" \
761        -onvalue "always" -offvalue "0" \
762        -variable [itcl::scope _settings($this-axis-loose)] \
763        -command [itcl::code $this ApplyAxisSettings]
764
765    label $page.plotpadx_l -text "pad x-axis" 
766    entry $page.plotpadx -width 6 \
767        -textvariable [itcl::scope _settings($this-graph-plotpadx)]
768    bind  $page.plotpadx <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
769
770    label $page.plotpady_l -text "pad y-axis"
771    entry $page.plotpady -width 6 \
772        -textvariable [itcl::scope _settings($this-graph-plotpady)]
773    bind  $page.plotpady <KeyPress-Return> [itcl::code $this ApplyAxisSettings]
774
775    checkbutton $page.grid -text "show grid lines" \
776        -variable [itcl::scope _settings($this-axis-grid)] \
777        -command [itcl::code $this ApplyAxisSettings]
778
779    checkbutton $page.zero -text "mark zero" \
780        -offvalue 1 -onvalue 0 \
781        -variable [itcl::scope _settings($this-axis-zero)] \
782        -command [itcl::code $this ApplyAxisSettings]
783
784    label $page.tickfont_l -text "tick font"
785    Rappture::Combobox $page.tickfontfamily -width 10 -editable no
786    $page.tickfontfamily choices insert end \
787        "courier" "Courier" \
788        "helvetica" "Helvetica"  \
789        "new*century*schoolbook"  "New Century Schoolbook" \
790        "symbol"  "Symbol" \
791        "times"  "Times"         
792    bind $page.tickfontfamily <KeyPress-Return> \
793        [itcl::code $this ApplyAxisSettings]
794
795    Rappture::Combobox $page.tickfontsize -width 4 -editable no
796    $page.tickfontsize choices insert end \
797        "8" "8" \
798        "10" "10" \
799        "11" "11" \
800        "12" "12" \
801        "14" "14" \
802        "17" "17" \
803        "18" "18" \
804        "20" "20"
805    bind  $page.tickfontsize <KeyPress-Return> \
806        [itcl::code $this ApplyAxisSettings]
807
808    Rappture::PushButton $page.tickfontbold \
809        -onimage [Rappture::icon format-text-bold] \
810        -offimage [Rappture::icon format-text-bold] \
811        -command [itcl::code $this ApplyAxisSettings] \
812        -variable [itcl::scope _settings($this-axis-tickfont-bold)]
813
814    Rappture::PushButton $page.tickfontitalic \
815        -onimage [Rappture::icon format-text-italic] \
816        -offimage [Rappture::icon format-text-italic] \
817        -command [itcl::code $this ApplyAxisSettings] \
818        -variable [itcl::scope _settings($this-axis-tickfont-italic)]
819
820    blt::table $page \
821        1,0 $page.axis_l -anchor e  -pady 4 \
822        1,1 $page.axis -fill x -cspan 4 \
823        2,1 $page.title_l -anchor e \
824        2,2 $page.title -fill x -cspan 3 \
825        3,1 $page.min_l -anchor e \
826        3,2 $page.min -fill x \
827        3,3 $page.max_l -anchor e \
828        3,4 $page.max -fill both \
829        5,1 $page.stepsize_l -anchor e \
830        5,2 $page.stepsize -fill both \
831        5,3 $page.subdivisions_l -anchor e \
832        5,4 $page.subdivisions -fill both \
833        6,1 $page.plotpadx_l -anchor e \
834        6,2 $page.plotpadx -fill both \
835        6,3 $page.plotpady_l -anchor e \
836        6,4 $page.plotpady -fill both \
837        7,1 $page.loose -cspan 2 -anchor w \
838        7,3 $page.grid -anchor w -cspan 2 \
839        8,1 $page.zero -cspan 2 -anchor w \
840        9,1 $page.tickfont_l -anchor e \
841        9,2 $page.tickfontfamily -fill x \
842        9,3 $page.tickfontsize -fill x \
843        9,4 $page.tickfontbold -anchor e \
844        9,5 $page.tickfontitalic -anchor e
845}
846
847itcl::body Rappture::XyPrint::ApplyGeneralSettings {} {
848    RegeneratePreview
849}
850
851itcl::body Rappture::XyPrint::ApplyLegendSettings {} {
852    set page $itk_component(legend_page)
853    set _settings($this-legend-position)  [$page.position current]
854    set _settings($this-legend-anchor)    [$page.anchor current]
855
856    foreach option { hide position anchor borderwidth } {
857        SetComponentOption legend $option
858    }
859    ApplyElementSettings
860}
861
862itcl::body Rappture::XyPrint::ApplyAxisSettings {} {
863    set plotpadx [Inches2Pixels $_settings($this-graph-plotpadx)]
864    set plotpady [Inches2Pixels $_settings($this-graph-plotpady)]
865    SetOption plotpadx
866    SetOption plotpady
867    set axis [$itk_component(axis_combo) current]
868    set type $Rappture::axistypes($axis)
869    if { $_settings($this-axis-grid) } {
870        $_clone grid configure -hide no -map${type} ${axis}
871    } else {
872        $_clone grid configure -hide no -map${type} ""
873    }
874    foreach option { min max loose title stepsize subdivisions } {
875        SetNamedComponentOption axis $axis $option
876    }
877    $_clone marker configure ${type}-zero -hide $_settings($this-axis-zero)
878    GetAxis
879    RegeneratePreview
880}
881
882itcl::body Rappture::XyPrint::ApplyElementSettings {} {
883    set index [$itk_component(element_slider) get]
884    set elem $_settings($this-element-$index)
885    set page $itk_component(legend_page)
886    set _settings($this-element-color)  [$page.color current]
887    set _settings($this-element-symbol) [$page.symbol current]
888    set _settings($this-element-dashes) [$page.dashes current]
889    foreach option { symbol color dashes hide label } {
890        SetNamedComponentOption element $elem $option
891    }
892    RegeneratePreview
893}
894
895itcl::body Rappture::XyPrint::ApplyLayoutSettings {} {
896    foreach opt { leftmargin rightmargin topmargin bottommargin } {
897        set new [Inches2Pixels $_settings($this-layout-$opt)]
898        set old [$_clone cget -$opt]
899        set code [catch [list $_clone configure -$opt $new] err]
900        if { $code != 0 } {
901            bell
902            global errorInfo
903            puts stderr "$err: $errorInfo"
904            set _settings($this-layout-$opt) [Pixel2Inches $old]
905        }
906    }
907    RegeneratePreview
908}
909
910
911itcl::body Rappture::XyPrint::InitializeSettings {} {
912    # General settings
913
914    # Always set to "eps" "ieee"
915    set _settings($this-general-format) eps
916    set _settings($this-general-style) ieee
917    set _settings($this-general-remember) 1
918    set page $itk_component(graph_page)
919    $page.format value [$page.format label $_settings($this-general-format)]
920    $page.style value [$page.style label $_settings($this-general-style)]
921
922    # Layout settings
923    set _settings($this-layout-width) [Pixels2Inches [$_clone cget -width]]
924    set _settings($this-layout-height) [Pixels2Inches [$_clone cget -height]]
925    set _settings($this-layout-leftmargin) \
926        [Pixels2Inches [$_clone cget -leftmargin]]
927    set _settings($this-layout-rightmargin) \
928        [Pixels2Inches [$_clone cget -rightmargin]]
929    set _settings($this-layout-topmargin) \
930        [Pixels2Inches [$_clone cget -topmargin]]
931    set _settings($this-layout-bottommargin) \
932        [Pixels2Inches [$_clone cget -bottommargin]]
933
934    # Legend settings
935    set page $itk_component(legend_page)
936
937    set names [$_clone element show]
938    $itk_component(element_slider) configure -from 1 -to [llength $names]
939    set state [expr  { ([llength $names] < 2) ? "disabled" : "normal" } ]
940    $page.slider configure -state $state
941    $page.slider_l configure -state $state
942    # Always initialize the slider to the first entry in the element list.
943    $itk_component(element_slider) set 1
944    # Always set the borderwidth to be not displayed
945    set _settings($this-legend-borderwidth) 0
946
947    set _settings($this-legend-hide) [$_clone legend cget -hide]
948    set _settings($this-legend-position) [$_clone legend cget -position]
949    set _settings($this-legend-anchor) [$_clone legend cget -anchor]
950    $page.position value \
951        [$page.position label $_settings($this-legend-position)]
952    $page.anchor value [$page.anchor label $_settings($this-legend-anchor)]
953    GetElement
954
955    # Axis settings
956    set names [lsort [$_clone axis names]]
957    $itk_component(axis_combo) choices delete 0 end
958    foreach axis $names {
959        if { ![$_clone axis cget $axis -hide] } {
960            $itk_component(axis_combo) choices insert end $axis $axis
961        }
962        lappend axisnames $axis
963    }
964    # Always hide the zero line.
965    set _settings($this-axis-zero) 1
966
967    # Pick the first axis to initially display
968    set axis [lindex $axisnames 0]
969    $itk_component(axis_combo) value $axis
970    blt::table configure $page r* -resize none
971    blt::table configure $page r9 -resize both
972    set _settings($this-graph-plotpadx) [Pixels2Inches [$_clone cget -plotpadx]]
973    set _settings($this-graph-plotpady) [Pixels2Inches [$_clone cget -plotpady]]
974    GetAxis
975}
976
977
978itcl::body Rappture::XyPrint::restore { toolName plotName data } {
979    set key [list $toolName $plotName]
980    set _savedSettings($key) $data
981}
982
983itcl::body Rappture::XyPrint::RestoreSettings { toolName plotName } {
984    if { ![file readable "~/.rappture"] } {
985        return;                         # No file or not readable
986    }
987    # Read the file by sourcing it into a safe interpreter The only commands
988    # executed will be "xyprint" which will simply add the data into an array
989    # _savedSettings.
990    set parser [interp create -safe]
991    $parser alias xyprint [itcl::code $this restore]
992    set f [open $file "r"]
993    set code [read $f]
994    close $f
995    $parser eval $code
996   
997    # Now see if there's an entry for this tool/plot combination.  The data
998    # associated with the variable is itself code to update the graph (clone).
999    set key [list $toolName $plotName]
1000    if { [info exists _savedSettings($key)] }  {
1001        $parser alias "xygraph" $_clone
1002        $parser eval $_savedSettings($key)
1003    }
1004    foreach {name value} [$parser eval "array get general"] {
1005        set _settings($this-graph-$name) $value
1006    }
1007    interp delete $parser
1008}
1009
1010itcl::body Rappture::XyPrint::ResetSettings {} {
1011    # Revert the widget back to the original graph's settings
1012    destroy $_clone
1013    set _clone [CloneGraph $graph]
1014    InitClone
1015    InitializeSettings
1016}
1017
1018itcl::body Rappture::XyPrint::SaveSettings { toolName plotName } {
1019    if { ![file writable "~/.rappture"] } {
1020        return
1021    }
1022    set out [CreateSettings $toolName $plotName]
1023    # Write the settings out
1024    set f [open ".rappture" "w" 0600]
1025    foreach key [lsort [array names _savedSettings]] {
1026        set tool [lindex $key 0]
1027        set plot [lindex $key 1]
1028        if { $plotName == "plot" && $toolName == "$tool" } {
1029            continue
1030        }
1031        puts $f "xyprint \"$tool\" \"$plot\" \{"
1032        puts $f "$_savedSettings($key)"
1033        puts $f "\}\n"
1034    }
1035    # Now write the new setting
1036    puts $f "xyprint \"$toolName\" \"$plotName\" \{"
1037    puts $f "$out"
1038    puts $f "\}\n"
1039    close $f
1040}
1041
1042itcl::body Rappture::XyPrint::CreateSettings { toolName plotName } {
1043    # Create stanza associated with tool and plot title.
1044    # General settings
1045    append out "\n"
1046    append out "xyprint \"\$toolName\" \"\$plotName\" \{\n"
1047    append out "  set general(format) $_settings($this-general-format)\n"
1048    append out "  set general(style) $_settings($this-general-style)\n"
1049    append out "  set general(remember) 1\n"
1050
1051    # Layout settings
1052    append out "  xygraph configure \\\n"
1053    append out "    -width \"[Pixels2Inches [$_clone cget -width]]\" \\\n"
1054    append out "    -height \"[Pixels2Inches [$_clone cget -height]]\" \\\n"
1055    append out "    -leftmargin \"[Pixels2Inches [$_clone cget -leftmargin]]\" \\\n"
1056    append out "    -rightmargin \"[Pixels2Inches [$_clone cget -rightmargin]]\" \\\n"
1057    append out "    -topmargin \"[Pixels2Inches [$_clone cget -topmargin]]\" \\\n"
1058    append out "    -bottommargin \"[Pixels2Inches [$_clone cget -bottommargin]]\"\\\n"
1059    append out "    -plotpadx \"[Pixels2Inches [$_clone cget -plotpadx]]\" \\\n"
1060    append out "    -plotpady \"[Pixels2Inches [$_clone cget -plotpady]]\" \n"
1061
1062    # Legend settings
1063    append out "  xygraph legend configure \\\n"
1064    append out "    -position \"[$_clone legend cget -position]\" \\\n"
1065    append out "    -anchor \"[$_clone legend cget -anchor]\" \\\n"
1066    append out "    -borderwidth \"[$_clone legend cget -borderwidth]\" \\\n"
1067    append out "    -hide \"[$_clone legend cget -hide]\" \n"
1068   
1069    # Element settings
1070    foreach elem [$_clone element show] {
1071        append out "  if \{ \[xygraph element exists \"$elem\"\] \} \{\n"
1072        append out "    xygraph element configure \"$elem\" \\\n"
1073        append out "      -symbol \"[$_clone element cget $elem -symbol]\" \\\n"
1074        append out "      -color \"[$_clone element cget $elem -color]\" \\\n"
1075        append out "      -dashes \"[$_clone element cget $elem -dashes]\" \\\n"
1076        append out "      -hide \"[$_clone element cget $elem -hide]\" \\\n"
1077        append out "      -label \"[$_clone element cget $elem -label]\" \n"
1078        append out "  \}\n"
1079    }
1080   
1081    # Axis settings
1082    foreach axis [$_clone axis names] {
1083        if { [$_clone axis cget $axis -hide] } {
1084            continue
1085        }
1086        append out "  if \{ \[xygraph axis names \"$axis\"\] == \"$axis\" \} \{\n"
1087        append out "    xygraph axis configure \"$axis\" \\\n"
1088        append out "      -hide \"[$_clone axis cget $axis -hide]\" \\\n"
1089        append out "      -min \"[$_clone axis cget $axis -min]\" \\\n"
1090        append out "      -max \"[$_clone axis cget $axis -max]\" \\\n"
1091        append out "      -loose \"[$_clone axis cget $axis -loose]\" \\\n"
1092        append out "      -title \"[$_clone axis cget $axis -title]\" \\\n"
1093        append out "      -stepsize \"[$_clone axis cget $axis -stepsize]\" \\\n"
1094        append out "      -subdivisions \"[$_clone axis cget $axis -subdivisions]\"\n"
1095        set hide [$_clone marker cget ${axis}-zero -hide]
1096        append out "    xygraph marker configure \"${axis}-zero\" -hide $hide\n"
1097        append out "  \}\n"
1098    }   
1099    append out "  xygraph grid configure \\\n"
1100    append out "    -hide \"[$_clone grid cget -hide]\" \\\n"
1101    append out "    -mapx \"[$_clone grid cget -mapx]\" \\\n"
1102    append out "    -mapy \"[$_clone grid cget -mapy]\"\n"
1103    append out "\}\n"
1104    return $out
1105}
1106
Note: See TracBrowser for help on using the repository browser.