From 60313b33fa22b71f08797297dbce510f5cc85588 Mon Sep 17 00:00:00 2001 From: Mark Mine Date: Sun, 27 Jan 2002 05:09:10 +0000 Subject: [PATCH] *** empty log message *** --- direct/src/cluster/ClusterConfig.py | 3 +- direct/src/tkpanels/DirectSessionPanel.py | 7 +- direct/src/tkpanels/ParticlePanel.py | 8 +- direct/src/tkpanels/Placer.py | 75 ++- direct/src/tkwidgets/Dial.py | 533 ++++------------------ 5 files changed, 125 insertions(+), 501 deletions(-) diff --git a/direct/src/cluster/ClusterConfig.py b/direct/src/cluster/ClusterConfig.py index 1c1d5682db..f953d7507a 100644 --- a/direct/src/cluster/ClusterConfig.py +++ b/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)], diff --git a/direct/src/tkpanels/DirectSessionPanel.py b/direct/src/tkpanels/DirectSessionPanel.py index 46a09adbf5..82ba7f78d9 100644 --- a/direct/src/tkpanels/DirectSessionPanel.py +++ b/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) diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index 7509fb507f..2c806644e8 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/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') diff --git a/direct/src/tkpanels/Placer.py b/direct/src/tkpanels/Placer.py index aea3174b6a..fdf6c5a6d6 100644 --- a/direct/src/tkpanels/Placer.py +++ b/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 diff --git a/direct/src/tkwidgets/Dial.py b/direct/src/tkwidgets/Dial.py index 7707a810d1..431a511a19 100644 --- a/direct/src/tkwidgets/Dial.py +++ b/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 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 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 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', '', self.highlightRing) - self._canvas.tag_bind('ring', '', self.restoreRing) - self._canvas.tag_bind('ring', '', self.ringMouseDown) - self._canvas.tag_bind('ring', '', self.ringMouseMotion) - self._canvas.tag_bind('ring', '', self.ringMouseUp) - self._canvas.tag_bind('dial', '', self.mouseDown) - self._canvas.tag_bind('dial', '', self.mouseMotion) - self._canvas.tag_bind('dial', '', self.shiftMouseMotion) - self._canvas.tag_bind('dial', '', self.mouseUp) - self._canvas.tag_bind('sfMarker', '', self.highlightSFMarker) - self._canvas.tag_bind('sfMarker', '', self.restoreSFMarker) - self._canvas.tag_bind('velocityKnob', '', self.highlightKnob) - self._canvas.tag_bind('velocityKnob', '', self.restoreKnob) - self._canvas.tag_bind('sfMarker', '', self.sfMouseDown) - self._canvas.tag_bind('sfMarker', '', self.sfMouseMotion) - self._canvas.tag_bind('sfMarker', '', self.sfMouseUp) - self._canvas.tag_bind('velocityKnob', '', self.knobMouseDown) - self._canvas.tag_bind('velocityKnob', '', self.knobMouseMotion) - self._canvas.tag_bind('velocityKnob', '', self.knobMouseUp) - self._canvas.bind('', self.popupDialMenu) - self._canvas.bind('', self.mouseReset) - self._canvas.bind('', self.expUp) - self._canvas.bind('', 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 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) + # Pass fCommand to dial which will return it to self.setEntry + self._dial['commandData'] = [fCommand] + self._dial.set(value) + + def get(self): + return self._dial.get() + + 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 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): - self._entryVal.set(self.entryFormat % value) - - 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 highlightRing(self, event): - self._canvas.itemconfigure('ring', fill = '#A0A0A0') - - def restoreRing(self, event): - self._canvas.itemconfigure('ring', fill = 'white') - - def highlightKnob(self, event): - self._canvas.itemconfigure('velocityKnob', fill = '#252525') - - def restoreKnob(self, event): - self._canvas.itemconfigure('velocityKnob', fill = '#A0A0A0') - - # Reset dial to zero - def mouseReset(self,event): - if not self._canvas.find_withtag(CURRENT): - self.reset() - - def reset(self): - self.set(self['initialValue']) - # Should we do this? - self.setScaleFactorExp(0, showText = 0) - - def onReturn(self, *args): + def _onReturnPress(self, *args): """ User redefinable callback executed on in entry """ - pass + if self['onReturnPress']: + apply(self['onReturnPress'], self['callbackData']) - def onReturnRelease(self, *args): + def _onReturnRelease(self, *args): """ User redefinable callback executed on release in entry """ - pass + if self['onReturnRelease']: + apply(self['onReturnRelease'], self['callbackData']) - def onPress(self, *args): - """ User redefinable callback executed on button press """ - pass + # Pass settings down to dial + def setCallbackData(self): + # Pass callback data down to dial + self._dial['callbackData'] = self['callbackData'] - def onRelease(self, *args): - """ User redefinable callback executed on button release """ - pass + def setResetValue(self): + self._dial['resetValue'] = self['resetValue'] + + def setMin(self): + self._dial['min'] = self['min'] + + def setMax(self): + self._dial['max'] = self['max'] + + def setLabel(self): + self._label['text'] = self['text'] + + def setButtonPressCmd(self): + self._dial['onButtonPress'] = self['onButtonPress'] + + 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__':