Ignore:
Timestamp:
Mar 22, 2016 10:56:21 PM (8 years ago)
Author:
ldelgass
Message:

Add custom range support to glyph viewer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/vtkglyphviewer.tcl

    r6175 r6182  
    7272    private method Connect {}
    7373    private method CurrentDatasets {args}
     74    private method DisableMouseRotationBindings {}
    7475    private method Disconnect {}
    7576    private method DoResize {}
     
    8687    private method IsValidObject { dataobj }
    8788    private method LeaveLegend {}
     89    private method LegendPointToValue { x y }
     90    private method LegendRangeAction { option args }
     91    private method LegendRangeValidate { widget which value }
    8892    private method LegendTitleAction { option }
    8993    private method MotionLegend { x y }
     94    private method MouseOver2Which {}
    9095    private method Pan {option x y}
    9196    private method PanCamera {}
     
    103108    private method SetCurrentFieldName { dataobj }
    104109    private method SetLegendTip { x y }
     110    private method SetMinMaxGauges { min max }
    105111    private method SetObjectStyle { dataobj comp }
    106112    private method SetOrientation { side }
     
    110116    private method SetupMouseZoomBindings {}
    111117    private method Slice {option args}
     118    private method ToggleCustomRange { args }
    112119    private method ViewToQuaternion {} {
    113120        return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)]
     
    117124    private variable _arcball ""
    118125
    119     private variable _dlist ""     ;    # list of data objects
    120     private variable _obj2ovride   ;    # maps dataobj => style override
    121     private variable _datasets     ;    # contains all the dataobj-component
    122                                    ;    # datasets in the server
    123     private variable _colormaps    ;    # contains all the colormaps
    124                                    ;    # in the server.
     126    private variable _dlist "";         # list of data objects
     127    private variable _obj2ovride;       # maps dataobj => style override
     128    private variable _datasets;         # contains all the dataobj-component
     129                                        # datasets in the server
     130    private variable _colormaps;        # contains all the colormaps
     131                                        # in the server.
    125132    # The name of the current colormap used.  The colormap is global to all
    126133    # heightmaps displayed.
    127134    private variable _currentColormap ""
    128135
    129     private variable _click        ;    # info used for rotate operations
    130     private variable _limits       ;    # autoscale min/max for all axes
    131     private variable _view         ;    # view params for 3D view
     136    private variable _click;            # info used for rotate operations
     137    private variable _limits;           # autoscale min/max for all axes
     138    private variable _view;             # view params for 3D view
    132139    private variable _settings
    133140    private variable _changed
    134141    private variable _reset 1;          # Connection to server has been reset.
    135142
    136     private variable _first ""     ;    # This is the topmost dataset.
     143    private variable _first "";         # This is the topmost dataset.
    137144    private variable _start 0
    138145    private variable _title ""
     
    149156    private variable _curFldName ""
    150157    private variable _curFldLabel ""
     158    private variable _curFldComp 3
     159    private variable _mouseOver "";     # what called LegendRangeAction:
     160                                        # vmin or vmax
     161    private variable _customRangeClick 1; # what called ToggleCustomRange
    151162
    152163    private common _downloadPopup;      # download options from popup
     
    228239        -colormap               BCGYR
    229240        -colormapvisible        1
     241        -customrange            0
     242        -customrangemin         0
     243        -customrangemax         1
    230244        -cutplaneedges          0
    231245        -cutplanelighting       1
     
    304318    }
    305319
     320    # add an editor for adjusting the legend min and max values
     321    itk_component add editor {
     322        Rappture::Editor $itk_interior.editor \
     323            -activatecommand [itcl::code $this LegendRangeAction activate] \
     324            -validatecommand [itcl::code $this LegendRangeAction validate] \
     325            -applycommand [itcl::code $this LegendRangeAction apply]
     326    }
     327
    306328    set c $itk_component(view)
    307329    bind $c <Configure> [itcl::code $this EventuallyResize %w %h]
     
    446468    bind $itk_component(view) <ButtonRelease-1> \
    447469        [itcl::code $this Rotate release %x %y]
     470}
     471
     472itcl::body Rappture::VtkGlyphViewer::DisableMouseRotationBindings {} {
     473    # Bindings for rotation via mouse
     474    bind $itk_component(view) <ButtonPress-1> ""
     475    bind $itk_component(view) <B1-Motion> ""
     476    bind $itk_component(view) <ButtonRelease-1> ""
    448477}
    449478
     
    722751            if { ![info exists _limits($fname)] } {
    723752                set _limits($fname) $lim
     753
     754                # set reasonable defaults for
     755                # customrangevmin and customrangevmax
     756                foreach {min max} $lim break
     757                SetMinMaxGauges $min $max
     758                set _settings(-customrangemin) $min
     759                set _settings(-customrangemax) $max
     760
    724761                continue
    725762            }
    726763            foreach {min max} $lim break
    727764            foreach {fmin fmax} $_limits($fname) break
     765            if { ! $_settings(-customrange) } {
     766                SetMinMaxGauges $fmin $fmax
     767            }
    728768            if { $fmin > $min } {
    729769                set fmin $min
     
    10461086        # These are settings that rely on a dataset being loaded.
    10471087        InitSettings \
    1048             -field \
     1088            -field -range \
    10491089            -glyphedges -glyphlighting -glyphnormscale -glyphopacity \
    10501090            -glyphorient -glyphscale -glyphscalemode -glyphshape -glyphwireframe
     
    10711111        set _reset 0
    10721112    }
     1113    #DrawLegend
    10731114
    10741115    # Actually write the commands to the server socket.  If it fails, we don't
     
    14171458                set _curFldName $fname
    14181459                set _curFldLabel $label
     1460                set _curFldComp $components
    14191461            } else {
    14201462                puts stderr "unknown field \"$fname\""
    14211463                return
    14221464            }
    1423             #if { ![info exists _limits($_curFldName)] } {
    1424             #    SendCmd "dataset maprange all"
    1425             #} else {
    1426             #    SendCmd "dataset maprange explicit $_limits($_curFldName) $_curFldName"
    1427             #}
     1465            if { ![info exists _limits($_curFldName)] } {
     1466                SendCmd "dataset maprange all"
     1467            } else {
     1468                if { $_settings(-customrange) } {
     1469                    set vmin [$itk_component(min) value]
     1470                    set vmax [$itk_component(max) value]
     1471                } else {
     1472                    foreach { vmin vmax } $_limits($_curFldName) break
     1473                    # set the min / max gauges with limits from the field
     1474                    # the legend's min and max text will be updated
     1475                    # when the legend is redrawn in DrawLegend
     1476                    SetMinMaxGauges $vmin $vmax
     1477                }
     1478                SendCmd "dataset maprange explicit $vmin $vmax $_curFldName point_data $_curFldComp"
     1479            }
    14281480            #SendCmd "cutplane colormode $_colorMode $_curFldName"
    14291481            SendCmd "glyphs colormode $_colorMode $_curFldName"
     
    15201572                }
    15211573            }
     1574        }
     1575        "-range" {
     1576            if { $_settings(-customrange) } {
     1577                set vmin [$itk_component(min) value]
     1578                set vmax [$itk_component(max) value]
     1579            } else {
     1580                foreach { vmin vmax } $_limits($_curFldName) break
     1581            }
     1582            SendCmd "dataset maprange explicit $vmin $vmax $_curFldName point_data $_curFldComp"
     1583            DrawLegend
    15221584        }
    15231585        "-xcutplanevisible" - "-ycutplanevisible" - "-zcutplanevisible" {
     
    16281690
    16291691itcl::body Rappture::VtkGlyphViewer::BuildGlyphTab {} {
    1630 
    16311692    set fg [option get $itk_component(hull) font Font]
    16321693    #set bfg [option get $itk_component(hull) boldFont Font]
     
    17811842    bind $inner.colormap <<Value>> \
    17821843        [itcl::code $this AdjustSetting -colormap]
     1844
     1845    # add widgets for setting a custom range on the legend
     1846
     1847    itk_component add crange {
     1848        checkbutton $inner.crange \
     1849            -text "Use Custom Range:" \
     1850            -variable [itcl::scope _settings(-customrange)] \
     1851            -command [itcl::code $this ToggleCustomRange] \
     1852            -font "Arial 9"
     1853    }
     1854
     1855    itk_component add l_min {
     1856        label $inner.l_min -text "Min" -font "Arial 9"
     1857    }
     1858    itk_component add min {
     1859        Rappture::Gauge $inner.min -font "Arial 9" \
     1860            -validatecommand [itcl::code $this LegendRangeValidate "" vmin]
     1861    }
     1862    bind $itk_component(min) <<Value>> \
     1863        [itcl::code $this AdjustSetting -range]
     1864
     1865    itk_component add l_max {
     1866        label $inner.l_max -text "Max" -font "Arial 9"
     1867    }
     1868    itk_component add max {
     1869        Rappture::Gauge $inner.max -font "Arial 9" \
     1870            -validatecommand [itcl::code $this LegendRangeValidate "" vmax]
     1871    }
     1872    bind $itk_component(max) <<Value>> \
     1873        [itcl::code $this AdjustSetting -range]
     1874
     1875    $itk_component(min) configure -state disabled
     1876    $itk_component(max) configure -state disabled
    17831877
    17841878    blt::table $inner \
     
    18031897        12,0 $inner.legend      -anchor w -pady 2 \
    18041898        13,0 $inner.opacity_l   -anchor w -pady 2 \
    1805         13,1 $inner.opacity     -anchor w -pady 2 -fill x
     1899        13,1 $inner.opacity     -anchor w -pady 2 -fill x \
     1900        14,0 $inner.crange      -anchor w -pady 2 -cspan 2 \
     1901        15,0 $inner.l_min       -anchor w -pady 2 \
     1902        15,1 $inner.min         -anchor w -pady 2 -fill x \
     1903        16,0 $inner.l_max       -anchor w -pady 2 \
     1904        16,1 $inner.max         -anchor w -pady 2 -fill x \
    18061905
    18071906    blt::table configure $inner r* c* -resize none
    1808     blt::table configure $inner r14 c1 -resize expand
     1907    blt::table configure $inner r17 c1 -resize expand
    18091908}
    18101909
     
    24092508}
    24102509
     2510# ----------------------------------------------------------------------
     2511# USAGE: LegendPointToValue <x> <y>
     2512#
     2513# Convert an x,y point on the legend to a numeric field value.
     2514# ----------------------------------------------------------------------
     2515itcl::body Rappture::VtkGlyphViewer::LegendPointToValue { x y } {
     2516    set fname $_curFldName
     2517
     2518    set font "Arial 8"
     2519    set lineht [font metrics $font -linespace]
     2520
     2521    set ih [image height $_image(legend)]
     2522    set iy [expr $y - ($lineht + 2)]
     2523
     2524    # Compute the value of the point
     2525    if { [info exists _limits($fname)] } {
     2526        if { $_settings(-customrange) } {
     2527            set vmin [$itk_component(min) value]
     2528            set vmax [$itk_component(max) value]
     2529        } else {
     2530            foreach { vmin vmax } $_limits($fname) break
     2531        }
     2532        set t [expr 1.0 - (double($iy) / double($ih-1))]
     2533        set value [expr $t * ($vmax - $vmin) + $vmin]
     2534    } else {
     2535        set value 0.0
     2536    }
     2537    return $value
     2538}
     2539
    24112540#
    24122541# SetLegendTip --
     
    24532582
    24542583    # Compute the value of the point
    2455     if { [info exists _limits($_curFldName)] } {
    2456         foreach { vmin vmax } $_limits($_curFldName) break
    2457         set t [expr 1.0 - (double($iy) / double($ih-1))]
    2458         set value [expr $t * ($vmax - $vmin) + $vmin]
    2459     } else {
    2460         set value 0.0
    2461     }
     2584    set value [LegendPointToValue $x $y]
     2585
     2586    # Setup the location of the tooltip
    24622587    set tx [expr $x + 15]
    24632588    set ty [expr $y - 5]
     2589
     2590    # Setup the text for the tooltip
    24642591    Rappture::Tooltip::text $c [format "$title %g" $value]
     2592
     2593    # Show the tooltip
    24652594    Rappture::Tooltip::tooltip show $c +$tx,+$ty
    24662595}
     
    25902719    $c itemconfigure title -text $title
    25912720    if { [info exists _limits($_curFldName)] } {
    2592         foreach { vmin vmax } $_limits($_curFldName) break
     2721        if { $_settings(-customrange) } {
     2722            set vmin [$itk_component(min) value]
     2723            set vmax [$itk_component(max) value]
     2724        } else {
     2725            foreach { vmin vmax } $_limits($_curFldName) break
     2726        }
    25932727        $c itemconfigure vmin -text [format %g $vmin]
    25942728        $c itemconfigure vmax -text [format %g $vmax]
     
    26082742    $c raise sensor
    26092743    $c coords vmin $x [expr {$h - 2}]
     2744
     2745    $c bind vmin <ButtonPress> [itcl::code $this LegendRangeAction popup vmin]
     2746    $c bind vmin <Enter> [itcl::code $this LegendRangeAction enter vmin]
     2747    $c bind vmin <Leave> [itcl::code $this LegendRangeAction leave vmin]
     2748
     2749    $c bind vmax <ButtonPress> [itcl::code $this LegendRangeAction popup vmax]
     2750    $c bind vmax <Enter> [itcl::code $this LegendRangeAction enter vmax]
     2751    $c bind vmax <Leave> [itcl::code $this LegendRangeAction leave vmax]
    26102752}
    26112753
     
    26482790            error "bad option \"$option\": should be post, enter, leave or save"
    26492791        }
     2792    }
     2793}
     2794
     2795# ----------------------------------------------------------------------
     2796# USAGE: LegendRangeValidate <widget> <which> <value>
     2797#
     2798# Used internally to validate a legend range min/max value.
     2799# Returns a boolean value telling if <value> was accepted (1) or rejected (0)
     2800# If the value is rejected, a tooltip/warning message is popped up
     2801# near the widget that asked for the validation, specified by <widget>
     2802#
     2803# <widget> is the widget where a tooltip/warning message should show up on
     2804# <which> is either "vmin" or "vmax".
     2805# <value> is the value to be validated.
     2806# ----------------------------------------------------------------------
     2807itcl::body Rappture::VtkGlyphViewer::LegendRangeValidate {widget which value} {
     2808    #check for a valid value
     2809    if {[string is double $value] != 1} {
     2810        set msg "should be valid number"
     2811        if {$widget != ""} {
     2812            Rappture::Tooltip::cue $widget $msg
     2813        } else {
     2814            # error "bad value \"$value\": $msg"
     2815            error $msg
     2816        }
     2817        return 0
     2818    }
     2819
     2820    switch -- $which {
     2821        vmin {
     2822            # check for min > max
     2823            if {$value > [$itk_component(max) value]} {
     2824                set msg "min > max, change max first"
     2825                if {$widget != ""} {
     2826                    Rappture::Tooltip::cue $widget $msg
     2827                } else {
     2828                    # error "bad value \"$value\": $msg"
     2829                    error $msg
     2830                }
     2831                return 0
     2832            }
     2833        }
     2834        vmax {
     2835            # check for max < min
     2836            if {$value < [$itk_component(min) value]} {
     2837                set msg "max < min, change min first"
     2838                if {$widget != ""} {
     2839                    Rappture::Tooltip::cue $widget $msg
     2840                } else {
     2841                    # error "bad value \"$value\": $msg"
     2842                    error $msg
     2843                }
     2844                return 0
     2845            }
     2846        }
     2847        default {
     2848            error "bad option \"$which\": should be vmin, vmax"
     2849        }
     2850    }
     2851}
     2852
     2853itcl::body Rappture::VtkGlyphViewer::MouseOver2Which {} {
     2854    switch -- $_mouseOver {
     2855        vmin {
     2856            set which min
     2857        }
     2858        vmax {
     2859            set which max
     2860        }
     2861        default {
     2862            error "bad _mouseOver \"$_mouseOver\": should be vmin, vmax"
     2863        }
     2864    }
     2865    return $which
     2866}
     2867
     2868# ----------------------------------------------------------------------
     2869# USAGE: LegendRangeAction enter <which>
     2870# USAGE: LegendRangeAction leave <which>
     2871#
     2872# USAGE: LegendRangeAction popup <which>
     2873# USAGE: LegendRangeAction activate
     2874# USAGE: LegendRangeAction validate <value>
     2875# USAGE: LegendRangeAction apply <value>
     2876#
     2877# Used internally to handle the mouseover and popup entry for the field range
     2878# inputs.  The enter option is invoked when the user moves the mouse over the
     2879# min or max field range. The leave option is invoked when the user moves the
     2880# mouse away from the min or max field range. The popup option is invoked when
     2881# the user click's on a field range. The popup option stores internally which
     2882# widget is requesting a popup ( in the _mouseOver variable) and calls the
     2883# activate command of the widget. The widget's activate command calls back to
     2884# this method to get the xywh dimensions of the popup editor. After the user
     2885# changes focus or sets the value in the editor, the editor calls this methods
     2886# validate and apply options to set the value.
     2887# ----------------------------------------------------------------------
     2888itcl::body Rappture::VtkGlyphViewer::LegendRangeAction {option args} {
     2889    set c $itk_component(view)
     2890
     2891    switch -- $option {
     2892        enter {
     2893            set which [lindex $args 0]
     2894            $c itemconfigure $which -fill red
     2895        }
     2896        leave {
     2897            set which [lindex $args 0]
     2898            $c itemconfigure $which -fill $itk_option(-plotforeground)
     2899        }
     2900        popup {
     2901            DisableMouseRotationBindings
     2902            set which [lindex $args 0]
     2903            set _mouseOver $which
     2904            $itk_component(editor) activate
     2905        }
     2906        activate {
     2907            foreach { x1 y1 x2 y2 } [$c bbox $_mouseOver] break
     2908            set which [MouseOver2Which]
     2909            set info(text) [$itk_component($which) value]
     2910            set info(x) [expr $x1 + [winfo rootx $c]]
     2911            set info(y) [expr $y1 + [winfo rooty $c]]
     2912            set info(w) [expr $x2 - $x1]
     2913            set info(h) [expr $y2 - $y1]
     2914            return [array get info]
     2915        }
     2916        validate {
     2917            if {[llength $args] != 1} {
     2918                error "wrong # args: should be \"editor validate value\""
     2919            }
     2920
     2921            set value [lindex $args 0]
     2922            if {[LegendRangeValidate $itk_component(editor) $_mouseOver $value] == 0} {
     2923                return 0
     2924            }
     2925
     2926            # value was good, apply it
     2927            # reset the mouse rotation bindings
     2928            SetupMouseRotationBindings
     2929        }
     2930        apply {
     2931            if {[llength $args] != 1} {
     2932                error "wrong # args: should be \"editor apply value\""
     2933            }
     2934            set value [string trim [lindex $args 0]]
     2935
     2936            set which [MouseOver2Which]
     2937
     2938            # only set custom range if value changed
     2939            if {[$itk_component($which) value] != $value} {
     2940                # set the flag stating the custom range came from the legend
     2941                # change the value in the gauge
     2942                # turn on crange to enable the labels and gauges
     2943                # call AdjustSetting -range (inside ToggleCustomRange)
     2944                # to update drawing and legend
     2945                set _customRangeClick 0
     2946                $itk_component($which) value $value
     2947                $itk_component(crange) select
     2948                ToggleCustomRange
     2949            }
     2950        }
     2951        default {
     2952            error "bad option \"$option\": should be enter, leave, activate, validate, apply"
     2953        }
     2954    }
     2955}
     2956
     2957# ----------------------------------------------------------------------
     2958# USAGE: ToggleCustomRange
     2959#
     2960# Called whenever the custom range is turned on or off. Used to save
     2961# the custom min and custom max set by the user. When the -customrange
     2962# setting is turned on, the range min and range max gauges are set
     2963# with the last value set by the user, or the default range if no
     2964# previous min and max were set.
     2965#
     2966# When the custom range is turned on, we check how it was turned on
     2967# by querying _customRangeClick. If the variable is 1, this means
     2968# the user clicked the crange checkbutton and we should pull the
     2969# custom range values from our backup variables. If the variable is 0,
     2970# the custom range was enabled through the user manipulating the
     2971# min and max value in the legend.
     2972# ----------------------------------------------------------------------
     2973itcl::body Rappture::VtkGlyphViewer::ToggleCustomRange {args} {
     2974    if { ! $_settings(-customrange) } {
     2975        # custom range was turned off
     2976
     2977        # disable the min/max labels and gauge widgets
     2978        $itk_component(l_min) configure -state disabled
     2979        $itk_component(min) configure -state disabled
     2980        $itk_component(l_max) configure -state disabled
     2981        $itk_component(max) configure -state disabled
     2982
     2983        # backup the custom range
     2984        set _settings(-customrangemin) [$itk_component(min) value]
     2985        set _settings(-customrangemax) [$itk_component(max) value]
     2986
     2987        # set the gauges to dataset's min and max
     2988        foreach { vmin vmax } $_limits($_curFldName) break
     2989        SetMinMaxGauges $vmin $vmax
     2990    } else {
     2991        # custom range was turned on
     2992
     2993        # enable the min/max labels and gauge widgets
     2994        $itk_component(l_min) configure -state normal
     2995        $itk_component(min) configure -state normal
     2996        $itk_component(l_max) configure -state normal
     2997        $itk_component(max) configure -state normal
     2998
     2999        # if the custom range is being turned on by clicking the
     3000        # checkbox, restore the min and max gauges from the backup
     3001        # variables. otherwise, new values for the min and max
     3002        # widgets will be set later from the legend's editor.
     3003        if { $_customRangeClick } {
     3004            SetMinMaxGauges $_settings(-customrangemin) $_settings(-customrangemax)
     3005        }
     3006
     3007        # reset the click flag
     3008        set _customRangeClick 1
     3009    }
     3010    AdjustSetting -range
     3011}
     3012
     3013# ----------------------------------------------------------------------
     3014# USAGE: SetMinMaxGauges <min> <max>
     3015#
     3016# Set the min and max gauges in the correct order, avoiding the
     3017# error where you try to set the min > max before updating the max or
     3018# set the max < min before updating the min.
     3019#
     3020# There are five range cases to consider with our current range validation.
     3021# For example:
     3022# [2,3] -> [0,1]       : update min first, max last
     3023# [2,3] -> [4,5]       : update max first, min last
     3024# [2,3] -> [0,2.5]     : update min or max first
     3025# [2,3] -> [2.5,5]     : update min or max first
     3026# [2,3] -> [2.25,2.75] : update min or max first
     3027#
     3028# In 4 of the cases we can update min first and max last, so we only
     3029# need to check the case where old max < new min, where we update
     3030# max first and min last.
     3031# ----------------------------------------------------------------------
     3032itcl::body Rappture::VtkGlyphViewer::SetMinMaxGauges {min max} {
     3033
     3034    if { [$itk_component(max) value] < $min} {
     3035        # old max < new min
     3036        # shift range toward right
     3037        # extend max first, then update min
     3038        $itk_component(max) value $max
     3039        $itk_component(min) value $min
     3040    } else {
     3041        # extend min first, then update max
     3042        $itk_component(min) value $min
     3043        $itk_component(max) value $max
    26503044    }
    26513045}
     
    27253119                set _curFldName $fname
    27263120                set _curFldLabel $label
     3121                set _curFldComp $components
    27273122            }
    27283123        }
    27293124    }
    27303125    $itk_component(field) value $_curFldLabel
    2731 }
     3126    if { $_settings(-customrange) } {
     3127        set limits [list [$itk_component(min) value] [$itk_component(max) value]]
     3128        SendCmd "dataset maprange explicit $limits $_curFldName point_data $_curFldComp"
     3129    } else {
     3130        if { ![info exists _limits($_curFldName)] } {
     3131            SendCmd "dataset maprange all"
     3132        } else {
     3133            set limits $_limits($_curFldName)
     3134            SendCmd "dataset maprange explicit $limits $_curFldName point_data $_curFldComp"
     3135        }
     3136    }
     3137}
Note: See TracChangeset for help on using the changeset viewer.