Browse Source

*** empty log message ***

Mark Mine 24 years ago
parent
commit
60313b33fa

+ 2 - 1
direct/src/cluster/ClusterConfig.py

@@ -7,7 +7,8 @@ import string
 # For mono-modelcave-pipe0, I decided to set the offsets in the
 # actual configuration for the display.
 
-ClientConfigs = {'mono-modelcave-pipe0': [ [Vec3(0,0,0),Vec3(0,0,0)] ] }
+ClientConfigs = {'mono-modelcave-pipe0': [ [Vec3(0,0,0),Vec3(0,0,0)] ],
+                 'single': [ [Vec3(0,0,0),Vec3(0,0,0)] ]}
 
 # The following is a fake configuration to show an example with two servers.
 # 'two-server' : [ [Vec3(0,0,0),Vec3(-60,0,0)],

+ 2 - 5
direct/src/tkpanels/DirectSessionPanel.py

@@ -490,13 +490,10 @@ class DirectSessionPanel(AppShell):
         self.gridSize['command'] = direct.grid.setGridSize
         self.gridSize.pack(fill = X, expand = 0)
 
-        self.gridSnapAngle = Dial.Dial(
+        self.gridSnapAngle = Dial.AngleDial(
             gridPage,
             text = 'Snap Angle',
-            min = 0.0, max = 360.0,
-            numTicks = 12,
-            fRollover = 0,
-            initialValue = direct.grid.getSnapAngle())
+            value = direct.grid.getSnapAngle())
         self.gridSnapAngle['command'] = direct.grid.setSnapAngle
         self.gridSnapAngle.pack(fill = X, expand = 0)
 

+ 4 - 4
direct/src/tkpanels/ParticlePanel.py

@@ -279,23 +279,23 @@ class ParticlePanel(AppShell):
         zSpinPage = self.factoryNotebook.add('ZSpinParticleFactory')
         self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Initial Angle',
                              'Starting angle in degrees',
-                             fRollover = 1,
+                             dial_fRollover = 1,
                              command = self.setFactoryZSpinInitialAngle)
         self.createAngleDial(
             zSpinPage, 'Z Spin Factory',
             'Initial Angle Spread',
             'Spread of the initial angle',
-            fRollover = 1,
+            dial_fRollover = 1,
             command = self.setFactoryZSpinInitialAngleSpread)
         self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Final Angle',
                              'Final angle in degrees',
-                             fRollover = 1,
+                             dial_fRollover = 1,
                              command = self.setFactoryZSpinFinalAngle)
         self.createAngleDial(
             zSpinPage, 'Z Spin Factory',
             'Final Angle Spread',
             'Spread of the final angle',
-            fRollover = 1,
+            dial_fRollover = 1,
             command = self.setFactoryZSpinFinalAngleSpread)
         # Oriented page #
         orientedPage = self.factoryNotebook.add('OrientedParticleFactory')

+ 36 - 39
direct/src/tkpanels/Placer.py

@@ -241,48 +241,42 @@ class Placer(AppShell):
         
         # Create the dials
         self.hprH = self.createcomponent('hprH', (), None,
-                                         Dial.Dial, (hprInterior,),
-                                         text = 'H', fRollover = 0,
-                                         max = 360.0, numTicks = 12,
-                                         initialValue = 0.0,
+                                         Dial.AngleDial, (hprInterior,),
+                                         text = 'H', value = 0.0,
                                          label_foreground = 'blue')
         self.hprH['command'] = self.xform
         self.hprH['commandData'] = ['h']
         self.hprH['callbackData'] = ['h']
-        self.hprH.onReturn = self.xformStart
-        self.hprH.onReturnRelease = self.xformStop
-        self.hprH.onPress = self.xformStart
-        self.hprH.onRelease = self.xformStop
+        self.hprH['onReturnPress'] = self.xformStart
+        self.hprH['onReturnRelease'] = self.xformStop
+        self.hprH['onButtonPress'] = self.xformStart
+        self.hprH['onButtonRelease'] = self.xformStop
         self.hprH.pack(expand=1,fill='both')
         
         self.hprP = self.createcomponent('hprP', (), None,
-                                         Dial.Dial, (hprInterior,),
-                                         text = 'P', fRollover = 0,
-                                         max = 360.0, numTicks = 12,
-                                         initialValue = 0.0,
+                                         Dial.AngleDial, (hprInterior,),
+                                         text = 'P', value = 0.0,
                                          label_foreground = 'red')
         self.hprP['command'] = self.xform
         self.hprP['commandData'] = ['p']
         self.hprP['callbackData'] = ['p']
-        self.hprP.onReturn = self.xformStart
-        self.hprP.onReturnRelease = self.xformStop
-        self.hprP.onPress = self.xformStart
-        self.hprP.onRelease = self.xformStop
+        self.hprP['onReturnPress'] = self.xformStart
+        self.hprP['onReturnRelease'] = self.xformStop
+        self.hprP['onButtonPress'] = self.xformStart
+        self.hprP['onButtonRelease'] = self.xformStop
         self.hprP.pack(expand=1,fill='both')
         
         self.hprR = self.createcomponent('hprR', (), None,
-                                         Dial.Dial, (hprInterior,),
-                                         text = 'R', fRollover = 0,
-                                         max = 360.0, numTicks = 12,
-                                         initialValue = 0.0,
+                                         Dial.AngleDial, (hprInterior,),
+                                         text = 'R', value = 0.0,
                                          label_foreground = '#00A000')
         self.hprR['command'] = self.xform
         self.hprR['commandData'] = ['r']
         self.hprR['callbackData'] = ['r']
-        self.hprR.onReturn = self.xformStart
-        self.hprR.onReturnRelease = self.xformStop
-        self.hprR.onPress = self.xformStart
-        self.hprR.onRelease = self.xformStop
+        self.hprR['onReturnPress'] = self.xformStart
+        self.hprR['onReturnRelease'] = self.xformStop
+        self.hprR['onButtonPress'] = self.xformStart
+        self.hprR['onButtonRelease'] = self.xformStop
         self.hprR.pack(expand=1,fill='both')
 
         # Create and pack the Scale Controls
@@ -321,43 +315,46 @@ class Placer(AppShell):
         self.scaleX = self.createcomponent('scaleX', (), None,
                                            Dial.Dial, (scaleInterior,),
                                            text = 'X Scale',
-                                           initialValue = 1.0,
+                                           min = 0.0001, value = 1.0,
+                                           resetValue = 1.0,
                                            label_foreground = 'Red')
         self.scaleX['command'] = self.xform
         self.scaleX['commandData'] = ['sx']
         self.scaleX['callbackData'] = ['sx']
-        self.scaleX.onReturn = self.xformStart
-        self.scaleX.onReturnRelease = self.xformStop
-        self.scaleX.onPress = self.xformStart
-        self.scaleX.onRelease = self.xformStop
+        self.scaleX['onReturnPress'] = self.xformStart
+        self.scaleX['onReturnRelease'] = self.xformStop
+        self.scaleX['onButtonPress'] = self.xformStart
+        self.scaleX['onButtonRelease'] = self.xformStop
         self.scaleX.pack(expand=1,fill='both')
         
         self.scaleY = self.createcomponent('scaleY', (), None,
                                            Dial.Dial, (scaleInterior,),
                                            text = 'Y Scale',
-                                           initialValue = 1.0,
+                                           min = 0.0001, value = 1.0,
+                                           resetValue = 1.0,
                                            label_foreground = '#00A000')
         self.scaleY['command'] = self.xform
         self.scaleY['commandData'] = ['sy']
         self.scaleY['callbackData'] = ['sy']
-        self.scaleY.onReturn = self.xformStart
-        self.scaleY.onReturnRelease = self.xformStop
-        self.scaleY.onPress = self.xformStart
-        self.scaleY.onRelease = self.xformStop
+        self.scaleY['onReturnPress'] = self.xformStart
+        self.scaleY['onReturnRelease'] = self.xformStop
+        self.scaleY['onButtonPress'] = self.xformStart
+        self.scaleY['onButtonRelease'] = self.xformStop
         self.scaleY.pack(expand=1,fill='both')
         
         self.scaleZ = self.createcomponent('scaleZ', (), None,
                                            Dial.Dial, (scaleInterior,),
                                            text = 'Z Scale',
-                                           initialValue = 1.0,
+                                           min = 0.0001, value = 1.0,
+                                           resetValue = 1.0,
                                            label_foreground = 'Blue')
         self.scaleZ['command'] = self.xform
         self.scaleZ['commandData'] = ['sz']
         self.scaleZ['callbackData'] = ['sz']
-        self.scaleZ.onReturn = self.xformStart
-        self.scaleZ.onReturnRelease = self.xformStop
-        self.scaleZ.onPress = self.xformStart
-        self.scaleZ.onRelease = self.xformStop
+        self.scaleZ['onReturnPress'] = self.xformStart
+        self.scaleZ['onReturnRelease'] = self.xformStop
+        self.scaleZ['onButtonPress'] = self.xformStart
+        self.scaleZ['onButtonRelease'] = self.xformStop
         self.scaleZ.pack(expand=1,fill='both')
 
         # Make sure appropriate labels are showing

+ 78 - 449
direct/src/tkwidgets/Dial.py

@@ -7,11 +7,6 @@ import math
 import string
 import operator
 
-# TODO:
-# More standardized use of 'max' and 'min'
-# Better floater style action
-# New option? 'delta'? 'repeatVal'? 'modulus'
-
 TWO_PI = 2.0 * math.pi
 ONEPOINTFIVE_PI = 1.5 * math.pi
 POINTFIVE_PI = 0.5 * math.pi
@@ -26,89 +21,45 @@ class Dial(Pmw.MegaWidget):
         INITOPT = Pmw.INITOPT
         optiondefs = (
             # Widget relief
-            ('relief',          GROOVE,         INITOPT),
+            ('relief',            GROOVE,         None),
             # Widget borderwidth
-            ('borderwidth',     2,              INITOPT),
-            # Relief of dial inset
-            ('canvas_relief',   GROOVE,         INITOPT),
-            # Borderwidth of dial inset
-            ('canvas_bd',       2,              INITOPT),
-            # Size of edge of dial inset
-            ('edgeLength',      50,             INITOPT),            
-            ('initialValue',    0.0,            INITOPT),
-            # Snap to angle on/off
-            ('fSnap',           0,              None),
-            # Do values rollover (i.e. accumulate) with multiple revolutions
-            ('fRollover',       1,              None),
-            ('command',         None,           None),
-            ('commandData',     [],             None),
-            ('callbackData',    [],           None),
-            ('text',           'Dial Widget',   self.updateLabel),
-            ('numTicks',        10,             self.createTicks),
-            ('numDigits',       2,              self.updateEntryFormat),
-            ('min',             0.0,            self.setScaleFactor),
-            ('max',             1.0,            self.setScaleFactor),
+            ('borderwidth',       2,              None),
+            ('value',             0.0,            INITOPT),
+            ('resetValue',        0.0,            self.setResetValue),
+            ('text',              'Dial Widget',  self.setLabel),
+            ('numDigits',         2,              self.setEntryFormat),
+            ('command',           None,           None),
+            ('commandData',       [],             None),
+            ('callbackData',      [],             self.setCallbackData),
+            ('min',               0.0,            self.setMin),
+            ('max',               1.0,            self.setMax),
+            ('onReturnPress',     None,           None),
+            ('onReturnRelease',   None,           None),
+            ('onButtonPress',     None,           self.setButtonPressCmd),
+            ('onButtonRelease',   None,           self.setButtonReleaseCmd),
             )
         self.defineoptions(kw, optiondefs)
         
         # Initialize the superclass
         Pmw.MegaWidget.__init__(self, parent)
 
-        # Set up some local and instance variables        
-        dim = self['edgeLength']
-        self.sfGridDelta = dim / 10
-        half = self.half = int(dim/2.0)
-        radius = self.radius = half - 4
-
-        # Running total which increments/decrements every time around dial
-        self.baseVal = 0.0
-        # Determines value of one dial revolution
-        self.scaleFactor = 1.0
-        self.dialAngle = None
-        # Current value
-        self.value = self['initialValue']
-
         # Create the components
         interior = self.interior()
         interior.configure(relief = self['relief'], bd = self['borderwidth'])
         
-        # The canvas 
-        self._canvas = self.createcomponent('canvas', (), None,
-                                            Canvas, (interior,),
-                                            width = dim + 12, height = dim,
-                                            scrollregion = ((- half),(- half),
-                                                            half, half))
-        self._canvas.grid(rowspan = 2, columnspan = 2)
-
-        # The shuttle ring
-        self._canvas.create_oval(-half, -half, half, half,
-                                 fill = 'white', tags = ('ring',))
-
-        # The dial face
-        self._canvas.create_oval(-radius, -radius, radius, radius,
-                                 fill = 'white', tags = ('dial',))
-        self.createTicks()
-
-        # The velocity knob
-        self._canvas.create_oval(-radius * INNER_SF, -radius * INNER_SF,
-                                 radius * INNER_SF, radius * INNER_SF,
-                                 fill = '#909090', tags = ('velocityKnob',))
-
-        # The indicator
-        self._canvas.create_line(0, 0, 0, (- radius), width = 2,
-                                 tags = ('indicator', 'dial'))
-
-        # The Scale Factor marker
-        self._canvas.create_polygon( half + 4, - 4, half + 12, 0,
-                                     half + 4, + 4, fill = '#A0A0A0',
-                                     tags = ('sfMarker',))
-        self.sfy = 0
-
-        # The Dial's label
+        # The Dial 
+        self._dial = self.createcomponent('dial', (), None,
+                                          MiniDial, (interior,),
+                                          value = self['value'])
+        # Attach dial to entry
+        self._dial['command'] = self.setEntry
+        self._dial.grid(rowspan = 2, columnspan = 2)
+
+        # The Label
         self._label = self.createcomponent('label', (), None,
                                            Label, (interior,),
                                            text = self['text'],
-                                           font = ('MS Sans Serif', 12, 'bold'),
+                                           font = ('MS Sans Serif',12,'bold'),
                                            anchor = CENTER)
         self._label.grid(row = 0, col = 2, sticky = EW)
 
@@ -123,404 +74,78 @@ class Dial(Pmw.MegaWidget):
         self._entryBackground = self._entry.cget('background')
         interior.columnconfigure(2, weight = 1)
 
-        # The popup menu
-        self._popupMenu = Menu(interior, tearoff = 0)
-        self._fAngleSnap = IntVar()
-        self._fAngleSnap.set(self['fSnap'])
-        self._popupMenu.add_checkbutton(label = 'Angle snap',
-                                        variable = self._fAngleSnap,
-                                        command = self.setAngleSnap)
-        self._fRollover = IntVar()
-        self._fRollover.set(self['fRollover'])
-        self._popupMenu.add_checkbutton(label = 'Rollover',
-                                        variable = self._fRollover,
-                                        command = self.setRollover)
-
-        sfMenu = Menu(interior, tearoff = 1)
-        self.expVar = DoubleVar()
-        self.expVar.set(0)
-        for exp in range (MAX_EXP, -(MAX_EXP + 1), -1):
-            sf = "%g" % math.pow(10, exp)
-            sfMenu.add_radiobutton(label = sf, value = exp,
-                                   variable = self.expVar,
-                                   command = self.setScaleFactor)
-        sfMenu.add_command(label = 'Scale Factor...',
-                           command = self.getScaleFactor)
-        self._popupMenu.add_cascade(label = 'Scale Factor',
-                                    menu = sfMenu)
-        self._popupMenu.add_command(label = 'Reset Dial',
-                                    command = self.reset)
-
-        # Add event bindings
-        self._canvas.tag_bind('ring', '<Enter>', self.highlightRing)
-        self._canvas.tag_bind('ring', '<Leave>', self.restoreRing)
-        self._canvas.tag_bind('ring', '<ButtonPress-1>', self.ringMouseDown)
-        self._canvas.tag_bind('ring', '<B1-Motion>', self.ringMouseMotion)
-        self._canvas.tag_bind('ring', '<ButtonRelease-1>', self.ringMouseUp)
-        self._canvas.tag_bind('dial', '<ButtonPress-1>', self.mouseDown)
-        self._canvas.tag_bind('dial', '<B1-Motion>', self.mouseMotion)
-        self._canvas.tag_bind('dial', '<Shift-B1-Motion>', self.shiftMouseMotion)
-        self._canvas.tag_bind('dial', '<ButtonRelease-1>', self.mouseUp)
-        self._canvas.tag_bind('sfMarker', '<Enter>', self.highlightSFMarker)
-        self._canvas.tag_bind('sfMarker', '<Leave>', self.restoreSFMarker)
-        self._canvas.tag_bind('velocityKnob', '<Enter>', self.highlightKnob)
-        self._canvas.tag_bind('velocityKnob', '<Leave>', self.restoreKnob)
-        self._canvas.tag_bind('sfMarker', '<ButtonPress-1>', self.sfMouseDown)
-        self._canvas.tag_bind('sfMarker', '<B1-Motion>', self.sfMouseMotion)
-        self._canvas.tag_bind('sfMarker', '<ButtonRelease-1>', self.sfMouseUp)
-        self._canvas.tag_bind('velocityKnob', '<ButtonPress-1>', self.knobMouseDown)
-        self._canvas.tag_bind('velocityKnob', '<B1-Motion>', self.knobMouseMotion)
-        self._canvas.tag_bind('velocityKnob', '<ButtonRelease-1>', self.knobMouseUp)
-        self._canvas.bind('<ButtonPress-3>', self.popupDialMenu)
-        self._canvas.bind('<Double-ButtonPress-1>', self.mouseReset)
-        self._canvas.bind('<Up>', self.expUp)
-        self._canvas.bind('<Down>', self.expDown)
-
         # Make sure input variables processed 
         self.initialiseoptions(Dial)
-        
-    def updateLabel(self):
-        self._label['text'] = self['text']
-
-    def createTicks(self):
-        self._canvas.delete('ticks')
-        # Based upon input snap angle, how many ticks
-        numTicks = self['numTicks']
-        # Compute snapAngle (radians)
-        self.snapAngle = snapAngle = TWO_PI / numTicks
-        # Create the ticks at the snap angles
-        for ticknum in range(numTicks):
-            angle = snapAngle * ticknum
-            # convert to canvas coords
-            angle = angle - POINTFIVE_PI
-            # Compute tick endpoints
-            startx = math.cos(angle) * self.radius
-            starty = math.sin(angle) * self.radius
-            # Elongate ticks at 90 degree points
-            if (angle % POINTFIVE_PI) == 0.0:
-                sf = 0.6
-            else:
-                sf = 0.8
-            endx = startx * sf
-            endy = starty * sf
-            self._canvas.create_line(startx, starty, endx, endy,
-                                     tags = ('ticks','dial'))
-
-    def mouseDown(self,event):
-        apply(self.onPress, self['callbackData'])
-        self.lastAngle = dialAngle = self.computeDialAngle(event)
-        self.computeValueFromAngle(dialAngle)
 
-    def mouseUp(self,event):
-        apply(self.onRelease, self['callbackData'])
-
-    def shiftMouseMotion(self,event):
-        self.mouseMotion(event, 1)
-
-    def mouseMotion(self, event, fShift = 0):
-        dialAngle = self.computeDialAngle(event, fShift)
-        self.computeValueFromAngle(dialAngle)
+    def set(self, value, fCommand = 1):
+        # Pass fCommand to dial which will return it to self.setEntry
+        self._dial['commandData'] = [fCommand]
+        self._dial.set(value)
         
-    def computeDialAngle(self,event, fShift = 0):
-        x = self._canvas.canvasx(event.x)
-        y = self._canvas.canvasy(event.y)
-        rawAngle = math.atan2(y,x)
-        # Snap to grid
-        # Convert to dial coords to do snapping
-        dialAngle = rawAngle + POINTFIVE_PI
-        if operator.xor(self['fSnap'], fShift):
-            dialAngle = round(dialAngle / self.snapAngle) * self.snapAngle
-        return dialAngle
-
-    def computeValueFromAngle(self, dialAngle):
-        delta = self.delta
-        dialAngle = dialAngle % TWO_PI
-        # Check for rollover, if necessary
-        if (self.lastAngle > ONEPOINTFIVE_PI) and (dialAngle < POINTFIVE_PI):
-            self.baseVal = self.baseVal + delta
-        elif (self.lastAngle < POINTFIVE_PI) and (dialAngle > ONEPOINTFIVE_PI):
-            self.baseVal = self.baseVal - delta
-        self.lastAngle = dialAngle
-        # Update value and entry
-        newValue = self['min'] + self.baseVal + delta * (dialAngle / TWO_PI)
-        self.dialAngle = dialAngle
-        self.set(newValue)
-
     def get(self):
-        return self.value
-    
-    def set(self, value, fCommand = 1):
-        if not self['fRollover']:
-            if value > self['max']:
-                self.baseVal = 0.0
-            value = ((value - self['min']) %
-                     (self['max'] - self['min'])) + self['min']
-        self.updateEntry(value)
-        if self.dialAngle:
-            self.updateIndicatorRadians(self.dialAngle)
-            self.dialAngle = None
-        else:
-            self.updateIndicator(value)
-        if fCommand and (self['command'] != None):
-            apply(self['command'], [value] + self['commandData'])
+        return self._dial.get()
 
-    def updateIndicator(self, value):
-        # compute new indicator angle
-        delta = self.delta
-        factors = divmod(value - self['min'], delta)
-        self.baseVal = factors[0] * delta
-        self.updateIndicatorRadians( (factors[1]/delta) * TWO_PI )
-
-    def updateIndicatorDegrees(self, degAngle):
-        self.updateIndicatorRadians(degAngle * (math.pi/180.0))
-        
-    def updateIndicatorRadians(self,dialAngle):
-        rawAngle = dialAngle - POINTFIVE_PI
-        # Compute end points
-        endx = math.cos(rawAngle) * self.radius
-        endy = math.sin(rawAngle) * self.radius
-        # Draw new indicator
-        self._canvas.coords('indicator', endx * INNER_SF, endy * INNER_SF,
-                            endx, endy)
-        
-    def updateEntry(self, value):
+    def setEntry(self, value, fCommand = 1):
         self._entryVal.set(self.entryFormat % value)
+        # Execute command
+        if fCommand and (self['command'] != None):
+            apply(self['command'], [value] + self['commandData'])
 
-    def updateEntryFormat(self):
+    def setEntryFormat(self):
         self.entryFormat = "%." + "%df" % self['numDigits']
-        self.updateEntry(self.value)
+        self.setEntry(self.get())
 
     def validateEntryInput(self, event):
         input = self._entryVal.get()
         try:
+            self._onReturnPress()
             self._entry.configure(background = self._entryBackground)
             newValue = string.atof(input)
-            apply(self.onReturn, self['callbackData'])
             self.set(newValue)
-            apply(self.onReturnRelease, self['callbackData'])
+            self._onReturnRelease()
         except ValueError:
             self._entry.configure(background = 'Pink')
 
-    def sfMouseDown(self, event):
-        # Record marker starting position
-        self.starty = self.sfy
-        # Record mouse starting position (convert to canvas coords)
-        self.lasty = self._canvas.canvasy(event.y)
-
-    def sfMouseMotion(self, event):
-        # How far did the mouse move?
-        dy = self._canvas.canvasy(event.y) - self.lasty
-        # Apply this delta to the marker
-        newy = self.starty + dy
-        # Compute new exponent based upon current position
-        exp = self.sfComputeExp(newy)
-        # Set resulting scale factor
-        self.setScaleFactorExp(exp)
-
-    def sfMouseUp(self, event):
-        self._canvas.delete('sfText')
-
-    # Compute exponent based on current marker position
-    def sfComputeExp(self, y, fSnap = 1):
-        # Force marker to stay visible
-        newy = max( -self.half, min( self.half, y ) )
-        # Snap it
-        gridDelta = self.sfGridDelta
-        if fSnap:
-            newy = round( newy / gridDelta ) * gridDelta
-        # Compute resulting exponent
-        return (-(newy / gridDelta))
-                                       
-    def setScaleFactorExp(self, exp, showText = 1, fUpdateIndicator = 1):
-        self.exp = exp
-        # Update popup scale factor menu to nearest exponent
-        self.expVar.set(int(round(exp)))
-        # Compute new scale factor
-        self.scaleFactor = math.pow(10, exp)
-        # Compute resulting delta
-        self.delta = self.scaleFactor * (self['max'] - self['min'])
-        # Update indicator to reflect new scale factor
-        if fUpdateIndicator:
-            self.updateIndicator(self.value)
-        # Move marker to correct position
-        self.updateScaleFactorMarker(-exp*self.sfGridDelta, showText)
-
-    def expUp(self,event):
-        self.setScaleFactorExp(min(MAX_EXP, self.exp + 1), 0)
-
-    def expDown(self,event):
-        self.setScaleFactorExp(max(-MAX_EXP, self.exp - 1), 0)
-
-    def ringMouseDown(self,event):
-        apply(self.onPress, self['callbackData'])
-        self.startRingAngle = self.computeRingAngle(event)
-        self.deltaRingAngle = 0.0
-        self.velocityTask = self.after(100, self.ringComputeVelocity)
-
-    def ringMouseMotion(self, event):
-        # What is the current ring angle
-        ringAngle = self.computeRingAngle(event)
-        self.deltaRingAngle = ringAngle - self.startRingAngle
-
-    def ringComputeVelocity(self):
-        # Compute new exponent based upon current ring position
-        exp = self.deltaRingAngle/POINTFIVE_PI
-        # Set resulting scale factor
-        self.setScaleFactorExp(exp, fUpdateIndicator = 1)
-        # Update value and entry
-        delta = self.delta
-        self.value = newValue = self.value + delta * self.deltaRingAngle
-        self.set(newValue)
-        self.updateIndicator(self.value)
-        self.velocityTask = self.after(100, self.ringComputeVelocity)
-
-    def computeRingAngle(self, event):
-        x = self._canvas.canvasx(event.x)
-        y = self._canvas.canvasy(event.y)
-        rawAngle = math.atan2(y,x)
-        # Convert to dial coords
-        dialAngle = rawAngle + TWO_PI
-        return dialAngle
-
-    def ringMouseUp(self, event):
-        self.after_cancel(self.velocityTask)
-        # reset indicator
-        self.updateIndicator(self.value)
-        apply(self.onRelease, self['callbackData'])
-
-    def knobMouseDown(self,event):
-        apply(self.onPress, self['callbackData'])
-        self.lasty = self._canvas.canvasy(event.y)
-        self.updateIndicatorRadians(0.0)
-        self.velocityTask = self.after(100, self.computeVelocity)
-        
-    def knobMouseMotion(self, event):
-        # How far is the mouse from the origin?
-        dx = self._canvas.canvasx(event.x)
-        self.lasty = self._canvas.canvasy(event.y)
-        exp = -5 + dx/20.0
-        exp = max( -5, min( 5, exp ) )
-        # Set resulting scale factor
-        self.setScaleFactorExp(exp, 0, fUpdateIndicator = 0)
-
-    def knobMouseUp(self, event):
-        self.after_cancel(self.velocityTask)
-        # reset indicator
-        self.updateIndicator(self.value)
-        apply(self.onRelease, self['callbackData'])
-
-    def computeVelocity(self):
-        if self.lasty < 0:
-            sign = -1.0
-        else:
-            sign = 1.0
-        lasty = abs(self.lasty)
-        if lasty > 5:
-            lasty = lasty - 5
-            sf = min(100, lasty)/100.0
-            sf = pow(sf, 3.0)
-            newVal = self.value - sign * sf * self.delta
-            self.dialAngle = - sign * sf * POINTFIVE_PI
-            self.set(newVal)
-        self.velocityTask = self.after(100, self.computeVelocity)
-
-    def updateScaleFactorMarker(self, newy, showText = 1):
-        # Move marker
-        self._canvas.move('sfMarker', 0, newy - self.sfy)
-        self.sfy = newy
-
-        # Show current scaling factor
-        if showText:
-            sfText = '%g' % (self.delta / 10.0,)
-            self._canvas.delete('sfText')
-            self._canvas.create_rectangle( self.half - 40, newy - 6,
-                                           self.half, newy + 7,
-                                           fill = 'white',
-                                           tags = ('sfText',))
-            self._canvas.create_text( self.half, newy,
-                                      justify = RIGHT,
-                                      anchor = E,
-                                      text = sfText,
-                                      fill = 'Red',
-                                      tags = ('sfText',))
-
-    # The following routines are used to handle the popup menu
-    def popupDialMenu(self,event):
-        self._popupMenu.post(event.widget.winfo_pointerx(),
-                             event.widget.winfo_pointery())
-
-    # This is called by the scale factor popup menu and when the user
-    # changes the dial 'delta' value
-    def setScaleFactor(self):
-        exp = self.expVar.get()
-        self.setScaleFactorExp(exp, showText = 0)
-
-    # This handles the popup scale factor dialog
-    def getScaleFactor(self):
-        sf = askfloat('Dial Scale Factor', 'Scale Factor:',
-                      parent = self.interior())
-        if sf:
-            self.setScaleFactorExp(math.log10(sf), showText = 0)
-
-    # Turn angle snap on/off
-    def setAngleSnap(self):
-        self['fSnap'] = self._fAngleSnap.get()
-
-    # Turn rollover (accumulation of a sum) on/off
-    def setRollover(self):
-        self['fRollover'] = self._fRollover.get()
-
-    def highlightSFMarker(self, event):
-        self._canvas.itemconfigure('sfMarker', fill = '#252525')
-
-    def restoreSFMarker(self, event):
-        self._canvas.itemconfigure('sfMarker', fill = '#A0A0A0')
+    def _onReturnPress(self, *args):
+        """ User redefinable callback executed on <Return> in entry """
+        if self['onReturnPress']:
+            apply(self['onReturnPress'], self['callbackData'])
 
-    def highlightRing(self, event):
-        self._canvas.itemconfigure('ring', fill = '#A0A0A0')
+    def _onReturnRelease(self, *args):
+        """ User redefinable callback executed on <Return> release in entry """
+        if self['onReturnRelease']:
+            apply(self['onReturnRelease'], self['callbackData'])
 
-    def restoreRing(self, event):
-        self._canvas.itemconfigure('ring', fill = 'white')
+    # Pass settings down to dial
+    def setCallbackData(self):
+        # Pass callback data down to dial
+        self._dial['callbackData'] = self['callbackData']
 
-    def highlightKnob(self, event):
-        self._canvas.itemconfigure('velocityKnob', fill = '#252525')
+    def setResetValue(self):
+        self._dial['resetValue'] = self['resetValue']
 
-    def restoreKnob(self, event):
-        self._canvas.itemconfigure('velocityKnob', fill = '#A0A0A0')
+    def setMin(self):
+        self._dial['min'] = self['min']
 
-    # Reset dial to zero
-    def mouseReset(self,event):
-        if not self._canvas.find_withtag(CURRENT):
-            self.reset()
+    def setMax(self):
+        self._dial['max'] = self['max']
         
-    def reset(self):
-        self.set(self['initialValue'])
-        # Should we do this?
-        self.setScaleFactorExp(0, showText = 0)
-
-    def onReturn(self, *args):
-        """ User redefinable callback executed on <Return> in entry """
-        pass
+    def setLabel(self):
+        self._label['text'] = self['text']
 
-    def onReturnRelease(self, *args):
-        """ User redefinable callback executed on <Return> release in entry """
-        pass
+    def setButtonPressCmd(self):
+        self._dial['onButtonPress'] = self['onButtonPress']
 
-    def onPress(self, *args):
-        """ User redefinable callback executed on button press """
-        pass
-
-    def onRelease(self, *args):
-        """ User redefinable callback executed on button release """
-        pass
+    def setButtonReleaseCmd(self):
+        self._dial['onButtonRelease'] = self['onButtonRelease']
 
 class AngleDial(Dial):
     def __init__(self, parent = None, **kw):
         # Set the typical defaults for a 360 degree angle dial
         optiondefs = (
-            ('fRollover',       0,              None),
-            ('numTicks',        12,             None),
-            ('max',             360.0,          None),
+            ('max',               360.0,          None),
+            ('dial_fRollover',    0,              None),
+            ('dial_numSegments',  12,             None),
             )
         self.defineoptions(kw, optiondefs)
         # Initialize the superclass
@@ -539,7 +164,7 @@ class MiniDial(Pmw.MegaWidget):
         optiondefs = (
             ## Appearance
             # Edge size of the dial
-            ('size',            50,             INITOPT),
+            ('size',            40,             INITOPT),
             # Widget relief
             ('relief',          GROOVE,         self.setRelief),
             # Widget borderwidth
@@ -566,6 +191,8 @@ class MiniDial(Pmw.MegaWidget):
             ('commandData',     [],             None),
             # Extra data to be passed to callback function
             ('callbackData',    [],             None),
+            ('onButtonPress',   None,           None),
+            ('onButtonRelease', None,           None),
             )
         self.defineoptions(kw, optiondefs)
         
@@ -693,12 +320,12 @@ class MiniDial(Pmw.MegaWidget):
     ## Canvas callback functions
     # Dial
     def mouseDown(self,event):
-        apply(self.onPress, self['callbackData'])
+        self._onButtonPress()
         self.lastAngle = dialAngle = self.computeDialAngle(event)
         self.computeValueFromAngle(dialAngle)
 
     def mouseUp(self,event):
-        apply(self.onRelease, self['callbackData'])
+        self._onButtonRelease()
 
     def shiftMouseMotion(self,event):
         self.mouseMotion(event, 1)
@@ -753,7 +380,7 @@ class MiniDial(Pmw.MegaWidget):
 
     # Knob velocity controller
     def knobMouseDown(self,event):
-        apply(self.onPress, self['callbackData'])
+        self._onButtonPress()
         self.knobSF = 0.0
         t = taskMgr.spawnMethodNamed(self.knobComputeVelocity, 'cv')
         t.lastTime = globalClock.getFrameTime()
@@ -782,7 +409,7 @@ class MiniDial(Pmw.MegaWidget):
     def knobMouseUp(self, event):
         taskMgr.removeTasksNamed('cv')
         self.knobSF = 0.0
-        apply(self.onRelease, self['callbackData'])
+        self._onButtonRelease()
 
     def highlightKnob(self, event):
         self._canvas.itemconfigure('knob', fill = 'black')
@@ -864,13 +491,15 @@ class MiniDial(Pmw.MegaWidget):
             self['resetValue'] = newResetValue
 
     # User callbacks
-    def onPress(self, *args):
+    def _onButtonPress(self, *args):
         """ User redefinable callback executed on button press """
-        pass
+        if self['onButtonPress']:
+            apply(self['onButtonPress'], self['callbackData'])
 
-    def onRelease(self, *args):
+    def _onButtonRelease(self, *args):
         """ User redefinable callback executed on button release """
-        pass
+        if self['onButtonRelease']:
+            apply(self['onButtonRelease'], self['callbackData'])
         
   
 if __name__ == '__main__':