*** empty log message ***

This commit is contained in:
Mark Mine 2001-10-11 17:46:21 +00:00
parent bd800263e8
commit dba1abc3a4
6 changed files with 310 additions and 61 deletions

View File

@ -4,61 +4,152 @@ from DirectButton import *
class DirectDialog(DirectFrame):
def __init__(self, parent = guiTop, **kw):
"""
DirectDialog(kw)
Creates a popup dialog to alert and/or interact with user.
Some of the main keywords that can be used to customize the dialog:
Keyword Definition
------- ----------
text Text message/query displayed to user
geom Geometry to be displayed in dialog
buttonTextList List of text to show on each button
buttonGeomList List of geometry to show on each button
buttonImageList List of images to show on each button
buttonValueList List of values sent to dialog command for
each button. If value is [] then the
ordinal rank of the button is used as
its value
buttonSize 4-tuple used to specify custom size for
each button (to make bigger then geom/text
for example)
pad Space between border and interior graphics
topPad Extra space added above text/geom/image
midPad Extra space added between text/buttons
buttonPadSF Scale factor used to expand/contract
button horizontal spacing
command Callback command used when a button is
pressed. Value supplied to command
depends on values in buttonValueList
Note: Number of buttons on the dialog depends upon the maximum
length of any button[Text|Geom|Image|Value]List specified.
Values of None are substituted for lists that are shorter
than the max length
"""
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('pad', (0.4, 0.4), None),
('text', '', None),
('text_align', TMALIGNCENTER, None),
('geom', getDefaultDialogGeom(), None),
('relief', None, None),
('buttons', [], INITOPT),
('buttonOffset', 0.2, None),
('button_pad', (.1,.1), None),
('button_relief', RAISED, None),
('button_frameSize', (-1,1,-.2,.9), None),
('command', None, None),
('extraArgs', [], None),
('pad', (0.1, 0.1), None),
('text', '', None),
('text_align', TMALIGNLEFT, None),
('text_scale', 0.06, None),
('image', getDefaultDialogGeom(), None),
('relief', None, None),
('buttonTextList', [], INITOPT),
('buttonGeomList', [], INITOPT),
('buttonImageList', [], INITOPT),
('buttonValueList', [], INITOPT),
('button_borderWidth',(.01,.01), None),
('button_pad', (.01,.01), None),
('button_relief', RAISED, None),
('button_text_scale' , 0.06, None),
('buttonSize', None, INITOPT),
('topPad', 0.06, INITOPT),
('midPad', 0.12, INITOPT),
('buttonPadSF', 1.05, INITOPT),
('command', None, None),
('extraArgs', [], None),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs, dynamicGroups = ("button",))
# Initialize superclasses
DirectFrame.__init__(self, parent)
self.numButtons = len(self['buttons'])
# Determine number of buttons
self.numButtons = max(len(self['buttonTextList']),
len(self['buttonGeomList']),
len(self['buttonImageList']),
len(self['buttonValueList']))
# Create buttons
self.buttonList = []
for button in self['buttons']:
name = button + 'Button'
index = 0
for i in range(self.numButtons):
name = 'Button' + `i`
try:
text = self['buttonTextList'][i]
except IndexError:
text = None
try:
geom = self['buttonGeomList'][i]
except IndexError:
geom = None
try:
image = self['buttonImageList'][i]
except IndexError:
image = None
try:
value = self['buttonValueList'][i]
except IndexError:
value = i
button = self.createcomponent(
name, (), "button",
DirectButton, (self,),
text = button,
command = lambda s = self, b = button: s.__buttonCommand(b)
text = text,
geom = geom,
image = image,
frameSize = self['buttonSize'],
command = lambda s = self, v = value: s.buttonCommand(v)
)
self.buttonList.append(button)
self.numButtons += 1
# Update dialog when everything has been initialised
self.postInitialiseFuncList.append(self.configureDialog)
self.initialiseoptions(DirectDialog)
def configureDialog(self):
# Position buttons and text
# Get size of text
text = self.component('text0')
bounds = text.getTightBounds()
pad = self['pad']
l = bounds[0][0] - pad[0]
r = bounds[1][0] + pad[0]
b = bounds[0][2] - pad[1]
t = bounds[1][2] + pad[1]
text.setPos((l+r)/2.0, (b+t)/2.0)
# Move buttons
if self['button_frameSize']:
frameSize = self['button_frameSize']
bl = frameSize[0]
br = frameSize[1]
bb = frameSize[2]
bt = frameSize[3]
bpad = self['button_pad']
image = self.component('image0')
# Get size of text/geom without image (for state 0)
if image:
image.reparentTo(hidden)
bounds = self.stateNodePath[0].getTightBounds()
if image:
image.reparentTo(self.stateNodePath[0])
l = bounds[0][0]
r = bounds[1][0]
b = bounds[0][2]
t = bounds[1][2]
# Center text and geom around origin
# How far is center of text from origin?
xOffset = -(l+r)/2.0
zOffset = -(b+t)/2.0
# Update bounds to reflect text movement
l += xOffset
r += xOffset
b += zOffset
t += zOffset
# Offset text and geom to center
if self['text']:
self['text_pos'] = (self['text_pos'][0] + xOffset,
self['text_pos'][1] + zOffset)
if self['geom']:
self['geom_pos'] = Point3(self['geom_pos'][0] + xOffset,
self['geom_pos'][1],
self['geom_pos'][2] + zOffset)
# Get button size
if self['buttonSize']:
# Either use given size
buttonSize = self['buttonSize']
bl = buttonSize[0]
br = buttonSize[1]
bb = buttonSize[2]
bt = buttonSize[3]
else:
# Get bounds of union of buttons
# Or get bounds of union of buttons
bl = br = bb = bt = 0
for button in self.buttonList:
bounds = button.stateNodePath[0].getTightBounds()
@ -66,41 +157,156 @@ class DirectDialog(DirectFrame):
br = max(br, bounds[1][0])
bb = min(bb, bounds[0][2])
bt = max(bt, bounds[1][2])
bWidth = br - bl
bSpacing = 1.1 * bWidth
bl -= bpad[0]
br += bpad[0]
bb -= bpad[1]
bt += bpad[1]
# Now resize buttons to match largest
for button in self.buttonList:
button['frameSize'] = (bl,br,bb,bt)
# Must compensate for scale
scale = self['button_scale']
# Can either be a Vec3 or a tuple of 3 values
if (isinstance(scale, Vec3) or
(type(scale) == types.ListType) or
(type(scale) == types.TupleType)):
sx = scale[0]
sz = scale[2]
elif ((type(scale) == types.IntType) or
(type(scale) == types.FloatType)):
sx = sz = scale
else:
sx = sz = 1
bl *= sx
br *= sx
bb *= sz
bt *= sz
# Position buttons
# Calc button width and height
bHeight = bt - bb
index = 0
if self.numButtons == 0:
return
bPos = bSpacing * (self.numButtons - 1)/2.0
for button in self.buttonList:
button.setPos(bPos + index * bSpacing, 0,
b - self['buttonOffset'] - bt)
index += 1
# Resize frame
b = b - self['buttonOffset'] - bHeight - pad[1]
frame = self.component('geom0')
frame.setScale(r - l, 1, t - b)
frame.setPos((l+r)/2.0, 0.0, (b+t)/2.0)
bWidth = br - bl
# Add pad between buttons
bSpacing = self['buttonPadSF'] * bWidth
if self.numButtons != 0:
bPos = -bSpacing * (self.numButtons - 1)/2.0
index = 0
for button in self.buttonList:
button.setPos(bPos + index * bSpacing, 0,
b - self['midPad'] - bpad[1] - bt)
index += 1
bMax = bPos + bSpacing * (self.numButtons - 1)
else:
bPos = 0
bMax = 0
# Resize frame to fit text and buttons
l = min(bPos + bl, l) - pad[0]
r = max(bMax + br, r) + pad[0]
# reduce bottom by pad, button height and 2*button pad
b = min(b - self['midPad'] - bpad[1] - bHeight - bpad[1], b) - pad[1]
t = t + self['topPad'] + pad[1]
self['image_scale'] = (r - l, 1, t - b)
# Center frame about text and buttons
self['image_pos'] = ((l+r)/2.0, 0.0,(b+t)/2.0)
self.resetFrameSize()
def __buttonCommand(self, button):
def buttonCommand(self, value):
if self['command']:
self['command'](button)
self['command'](value)
def destroy(self):
DirectFrame.destroy(self)
class OKDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['OK'], INITOPT),
('buttonValueList', [1], INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(OKDialog)
class OKCancelDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['OK','Cancel'], INITOPT),
('buttonValueList', [1,-1], INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(OKCancelDialog)
class YesNoDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttons', ['Yes', 'No'], INITOPT),
('text', 'Yes or No?', None),
('buttonTextList', ['Yes', 'No'], INITOPT),
('buttonValueList', [1,0], INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
apply(DirectDialog.__init__, (self, parent), kw)
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoDialog)
class YesNoCancelDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['Yes', 'No', 'Cancel'], INITOPT),
('buttonValueList', [1,0,-1], INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoCancelDialog)
class RetryCancelDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['Retry','Cancel'], INITOPT),
('buttonValueList', [1,-1], INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(RetryCancelDialog)
class TTOkCancelDialog(DirectDialog):
def __init__(self, parent = guiTop, **kw):
# Inherits from DirectDialog
buttons = loader.loadModelOnce(
'phase_3/models/gui/dialog_box_buttons_gui')
okImageList = (buttons.find('**/ChtBx_OKBtn_UP'),
buttons.find('**/ChtBx_OKBtn_DN'),
buttons.find('**/ChtBx_OKBtn_Rllvr'))
okTextList = ('', 'OK', 'OK')
cancelImageList = (buttons.find('**/CloseBtn_UP'),
buttons.find('**/CloseBtn_DN'),
buttons.find('**/CloseBtn_Rllvr'))
cancelTextList = ('', 'Cancel', 'Cancel')
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', [okTextList, cancelTextList], INITOPT),
('buttonImageList', [okImageList, cancelImageList], INITOPT),
('buttonValueList', [1,-1], INITOPT),
('button_pad', (0,0), None),
('button_relief', None, None),
('button_text_pos', (0,-0.1), None),
('buttonSize', (-.05,.05,-.05,.05), None),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(TTOkCancelDialog)

View File

@ -15,3 +15,4 @@ from DirectButton import *
from DirectEntry import *
from DirectLabel import *
from DirectScrolledList import *
from DirectDialog import *

View File

@ -95,6 +95,8 @@ class DirectGuiBase(PandaObject.PandaObject):
self.guiId = 'guiObject'
# List of all active hooks
self._hookDict = {}
# List of all post initialization functions
self.postInitialiseFuncList = []
# To avoid doing things redundantly during initialisation
self.fInit = 1
# Mapping from each megawidget option to a list of information
@ -261,7 +263,8 @@ class DirectGuiBase(PandaObject.PandaObject):
self.postInitialiseFunc()
def postInitialiseFunc(self):
pass
for func in self.postInitialiseFuncList:
func()
def isinitoption(self, option):
"""
@ -758,11 +761,14 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
# Bind destroy hook
self.bind(DESTROY, self.destroy)
# Update frame when everything has been initialized
self.postInitialiseFuncList.append(self.frameInitialiseFunc)
# Call option initialization functions
self.initialiseoptions(DirectGuiWidget)
def postInitialiseFunc(self):
def frameInitialiseFunc(self):
# Now allow changes to take effect
self.updateFrameStyle()
if not self['frameSize']:

View File

@ -96,7 +96,8 @@ def setDefaultFont(newFont):
def getDefaultDialogGeom():
global defaultDialogGeom
if defaultDialogGeom == None:
defaultDialogGeom = loader.loadModelOnce('phase_3/models/props/panel')
defaultDialogGeom = loader.loadModelOnce(
'phase_3/models/gui/dialog_box_gui')
return defaultDialogGeom
def setDefaultDialogGeom(newDialogGeom):

View File

@ -96,6 +96,34 @@ de1 = DirectEntry(initialText = 'Hello, how are you?',
scale = 0.0707855,
)
# DIRECT DIALOG EXAMPLE
def printDialogValue(value):
print 'Value:', value
simpleDialog = YesNoDialog(text = 'Simple',
command = printDialogValue)
customValues = YesNoDialog(text = 'Simple',
buttonValueList = ['Yes', 'No'],
command = printDialogValue)
fancyDialog = YesNoDialog(text = 'Testing Direct Dialog',
geom = smiley,
geom_scale = .1,
geom_pos = (-0.3,0,0),
command = printDialogValue)
toontownDialog = TTOkCancelDialog(text = 'Exit Toontown?',
command = printDialogValue)
customDialog = DirectDialog(text = 'Pick a number',
buttonTextList = map(str, range(10)),
buttonValueList = range(10),
command = printDialogValue)
# NOTE: There are some utility functions which help you get size
# of a direct gui widget. These can be used to position and scale an
# image after you've created the entry. scale = (width/2, 1, height/2)

View File

@ -179,7 +179,8 @@ class OnscreenText(PandaObject, NodePath):
# We'd rather do it here, on the text itself, rather than on
# our NodePath, so we have one fewer transforms in the scene
# graph.
mat = Mat4.scaleMat(scale[0], 1, scale[1]) * Mat4.translateMat(pos[0], 0, pos[1])
mat = Mat4.scaleMat(
scale[0], 1, scale[1]) * Mat4.translateMat(pos[0], 0, pos[1])
textNode.setTransform(mat)
textNode.setBin('fixed')
@ -259,7 +260,10 @@ class OnscreenText(PandaObject, NodePath):
Position the onscreen text in 2d screen space
"""
self.pos = (x, y)
mat = Mat4.scaleMat(self.scale[0], 1, self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
mat = Mat4.scaleMat(
self.scale[0],
1,
self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
self.textNode.setTransform(mat)
def getPos(self):
@ -278,7 +282,10 @@ class OnscreenText(PandaObject, NodePath):
self.scale = (sx, sx)
else:
self.scale = (sx, sy)
mat = Mat4.scaleMat(self.scale[0], 1, self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
mat = Mat4.scaleMat(
self.scale[0],
1,
self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
self.textNode.setTransform(mat)
def getScale(self):