*** empty log message ***

This commit is contained in:
Mark Mine 2002-01-27 05:09:10 +00:00
parent 9b5a3a0eb0
commit 60313b33fa
5 changed files with 125 additions and 501 deletions

View File

@ -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)],

View File

@ -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)

View File

@ -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')

View File

@ -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

View File

@ -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', '<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 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 <Return> in entry """
pass
if self['onReturnPress']:
apply(self['onReturnPress'], self['callbackData'])
def onReturnRelease(self, *args):
def _onReturnRelease(self, *args):
""" User redefinable callback executed on <Return> 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__':