Index: branches/uiuc_vtk_viewers/gui/scripts/vtkisosurfaceviewer.tcl
===================================================================
--- branches/uiuc_vtk_viewers/gui/scripts/vtkisosurfaceviewer.tcl	(revision 5033)
+++ branches/uiuc_vtk_viewers/gui/scripts/vtkisosurfaceviewer.tcl	(revision 5049)
@@ -113,4 +113,5 @@
     private method SetCurrentFieldName { dataobj }
     private method SetLegendTip { x y }
+    private method SetMinMaxGauges { min max }
     private method SetObjectStyle { dataobj comp }
     private method SetOrientation { side }
@@ -119,4 +120,5 @@
     private method SetupKeyboardBindings {}
     private method Slice {option args}
+    private method ToggleCustomRange { args }
     private method ViewToQuaternion {} {
         return [list $_view(-qw) $_view(-qx) $_view(-qy) $_view(-qz)]
@@ -174,4 +176,6 @@
 
     private variable _mouseOver "";     # what called LegendRangeAction, vmin or vmax
+    private variable _customRangeClick 1;   # what called ToggleCustomRange
+    private variable _ignoreRangeUpdate 0;  # update min/max gauges without redrawing
 }
 
@@ -260,4 +264,6 @@
         -colormapvisible            1
         -customrange                0
+        -customrangemin             0
+        -customrangemax             1
         -cutplaneedges              0
         -cutplanelighting           1
@@ -775,6 +781,7 @@
                 # customrangevmin and customrangevmax
                 foreach {min max} $lim break
-                $itk_component(min) value $min
-                $itk_component(max) value $max
+                SetMinMaxGauges $min $max
+                set _settings(-customrangemin) $min
+                set _settings(-customrangemax) $max
 
                 continue
@@ -783,6 +790,5 @@
             foreach {fmin fmax} $_limits($fname) break
             if { ! $_settings(-customrange) } {
-                $itk_component(min) value $fmin
-                $itk_component(max) value $fmax
+                SetMinMaxGauges $fmin $fmax
             }
             if { $fmin > $min } {
@@ -1486,12 +1492,14 @@
                 SendCmd "dataset maprange all"
             } else {
-                foreach { vmin vmax } $_limits($_curFldName) break
                 if { $_settings(-customrange) } {
-                    if { [$itk_component(min) value] > $vmin } {
-                        set vmin [$itk_component(min) value]
-                    }
-                    if { [$itk_component(max) value] < $vmax } {
-                        set vmax [$itk_component(max) value]
-                    }
+                    set vmin [$itk_component(min) value]
+                    set vmax [$itk_component(max) value]
+                } else {
+                    foreach { vmin vmax } $_limits($_curFldName) break
+                    # set the min / max gauges with limits from the field
+                    # the legend's min and max text will be updated
+                    # when the legend is redrawn in DrawLegend
+                    set _ignoreRangeUpdate 1
+                    SetMinMaxGauges $vmin $vmax
                 }
                 SendCmd "dataset maprange explicit $vmin $vmax $_curFldName"
@@ -1571,26 +1579,17 @@
         }
         "-range" {
-            foreach { vmin vmax } $_limits($_curFldName) break
-            if { $_settings(-customrange) } {
-                $itk_component(l_min) configure -state normal
-                $itk_component(min) configure -state normal
-                $itk_component(l_max) configure -state normal
-                $itk_component(max) configure -state normal
-                if { [$itk_component(min) value] > $vmin } {
+            if { ! $_ignoreRangeUpdate } {
+                if { $_settings(-customrange) } {
                     set vmin [$itk_component(min) value]
-                }
-                if { [$itk_component(max) value] < $vmax } {
                     set vmax [$itk_component(max) value]
-                }
-            } else {
-                $itk_component(l_min) configure -state disabled
-                $itk_component(min) configure -state disabled
-                $itk_component(l_max) configure -state disabled
-                $itk_component(max) configure -state disabled
-            }
-            GenerateContourList
-            SendCmd [list contour3d contourlist $_contourList(values)]
-            SendCmd "dataset maprange explicit $vmin $vmax $_curFldName"
-            DrawLegend
+                } else {
+                    foreach { vmin vmax } $_limits($_curFldName) break
+                }
+                GenerateContourList
+                SendCmd [list contour3d contourlist $_contourList(values)]
+                SendCmd "dataset maprange explicit $vmin $vmax $_curFldName"
+                DrawLegend
+            }
+            set _ignoreRangeUpdate 0
         }
         "-xcutplanevisible" - "-ycutplanevisible" - "-zcutplanevisible" {
@@ -1818,7 +1817,11 @@
             -text "Use Custom Range:" \
             -variable [itcl::scope _settings(-customrange)] \
-            -command [itcl::code $this AdjustSetting -range] \
             -font "Arial 9"
     }
+    # use a trace so we can adjust the value of our variable
+    # and still have the ToggleCustomRange command called,
+    # which doesn't seem to happen when using -command.
+    trace add variable _settings(-customrange) write \
+        [itcl::code $this ToggleCustomRange]
 
     itk_component add l_min {
@@ -2914,12 +2917,108 @@
             # only set custom range if value changed
             if {[$itk_component($which) value] != $value} {
+                # turn on crange first to enable and update the gauge,
+                # then change the value in the gauge
+                set _customRangeClick 0
+                $itk_component(crange) select
                 $itk_component($which) value $value
-                $itk_component(crange) select
-            }
-            AdjustSetting -range
+            }
         }
         default {
             error "bad option \"$option\": should be enter, leave, activate, validate, apply"
         }
+    }
+}
+
+
+# ----------------------------------------------------------------------
+# USAGE: ToggleCustomRange
+#
+# Called whenever the custom range is turned on or off. Used to save
+# the custom min and custom max set by the user. When the -customrange
+# setting is turned on, the range min and range max gauges are set
+# with the last value set by the user, or the default range if no
+# previous min and max were set.
+#
+# When the custom range is turned on, we check how it was turned on
+# by querying _customRangeClick. If the variable is 1, this means
+# the user clicked the crange checkbutton and we should pull the
+# custom range values from our backup variables. If the variable is 0,
+# the custom range was enabled through the user manipulating the
+# min and max value in the legend.
+#
+# ----------------------------------------------------------------------
+itcl::body Rappture::VtkIsosurfaceViewer::ToggleCustomRange {args} {
+
+    if { ! $_settings(-customrange) } {
+        # custom range was turned off
+
+        # disable the min/max labels and gauge widgets
+        $itk_component(l_min) configure -state disabled
+        $itk_component(min) configure -state disabled
+        $itk_component(l_max) configure -state disabled
+        $itk_component(max) configure -state disabled
+
+        # backup the custom range
+        set _settings(-customrangemin) [$itk_component(min) value]
+        set _settings(-customrangemax) [$itk_component(max) value]
+
+        # set the gauges to dataset's min and max
+        foreach { vmin vmax } $_limits($_curFldName) break
+        SetMinMaxGauges $vmin $vmax
+    } else {
+        # custom range was turned on
+
+        # enable the min/max labels and gauge widgets
+        $itk_component(l_min) configure -state normal
+        $itk_component(min) configure -state normal
+        $itk_component(l_max) configure -state normal
+        $itk_component(max) configure -state normal
+
+        # if the custom range is being turned on by clicking the
+        # checkbox, restore the min and max gauges from the backup
+        # variables. otherwise, new values for the min and max
+        # widgets will be set later from the legend's editor.
+        if { $_customRangeClick } {
+            SetMinMaxGauges $_settings(-customrangemin) $_settings(-customrangemax)
+        }
+
+        # reset the click flag
+        set _customRangeClick 1
+    }
+    AdjustSetting -range
+}
+
+
+# ----------------------------------------------------------------------
+# USAGE: SetMinMaxGauges <min> <max>
+#
+# Set the min and max gauges in the correct order, avoiding the
+# error where you try to set the min > max before updating the max or
+# set the max < min before updating the min.
+#
+# There are five range cases to consider with our current range validation.
+# For example:
+# [2,3] -> [0,1]       : update min first, max last
+# [2,3] -> [4,5]       : update max first, min last
+# [2,3] -> [0,2.5]     : update min or max first
+# [2,3] -> [2.5,5]     : update min or max first
+# [2,3] -> [2.25,2.75] : update min or max first
+#
+# In 4 of the cases we can update min first and max last, so we only
+# need to check the case where old max < new min, where we update
+# max first and min last.
+# ----------------------------------------------------------------------
+itcl::body Rappture::VtkIsosurfaceViewer::SetMinMaxGauges {min max} {
+
+    if { [$itk_component(max) value] < $min} {
+        # old max < new min
+        # shift range toward right
+        # extend max first, then update min
+        $itk_component(max) value $max
+        $itk_component(min) value $min
+    } else {
+        # extend min first, then update max
+        $itk_component(min) value $min
+        $itk_component(max) value $max
     }
 }
