"""This module defines various dialog windows for the DirectGUI system.
See the :ref:`directdialog` page in the programming manual for a more
in-depth explanation and an example of how to use this class.
"""
__all__ = [
'findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog',
'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog',
]
from panda3d.core import *
from direct.showbase import ShowBaseGlobal
from . import DirectGuiGlobals as DGG
from .DirectFrame import *
from .DirectButton import *
import types
[docs]def findDialog(uniqueName):
"""
Returns the panel whose uniqueName is given. This is mainly
useful for debugging, to get a pointer to the current onscreen
panel of a particular type.
"""
if uniqueName in DirectDialog.AllDialogs:
return DirectDialog.AllDialogs[uniqueName]
return None
[docs]def cleanupDialog(uniqueName):
"""cleanupPanel(string uniqueName)
Cleans up (removes) the panel with the given uniqueName. This
may be useful when some panels know about each other and know
that opening panel A should automatically close panel B, for
instance.
"""
if uniqueName in DirectDialog.AllDialogs:
# calling cleanup() will remove it out of the AllDialogs dict
# This way it will get removed from the dict even it we did
# not clean it up using this interface (ie somebody called
# self.cleanup() directly
DirectDialog.AllDialogs[uniqueName].cleanup()
[docs]class DirectDialog(DirectFrame):
AllDialogs = {}
PanelIndex = 0
[docs] def __init__(self, parent=None, **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:
Parameters:
text (str): 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.
buttonHotKeyList: List of hotkeys to bind to each button.
Typing the hotkey is equivalent to pressing the
corresponding button.
suppressKeys: Set to true if you wish to suppress keys
(i.e. Dialog eats key event), false if you wish Dialog
to pass along key event.
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
sidePad: Extra space added to either side of 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:
The number of buttons on the dialog depends on 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
('dialogName', 'DirectDialog_' + repr(DirectDialog.PanelIndex), DGG.INITOPT),
# Default position is slightly forward in Y, so as not to
# intersect the near plane, which is incorrectly set to 0
# in DX for some reason.
('pos', (0, 0.1, 0), None),
('pad', (0.1, 0.1), None),
('text', '', None),
('text_align', TextNode.ALeft, None),
('text_scale', 0.06, None),
('image', DGG.getDefaultDialogGeom(), None),
('relief', DGG.getDefaultDialogRelief(), None),
('borderWidth', (0.01, 0.01), None),
('buttonTextList', [], DGG.INITOPT),
('buttonGeomList', [], DGG.INITOPT),
('buttonImageList', [], DGG.INITOPT),
('buttonValueList', [], DGG.INITOPT),
('buttonHotKeyList', [], DGG.INITOPT),
('button_borderWidth', (.01, .01), None),
('button_pad', (.01, .01), None),
('button_relief', DGG.RAISED, None),
('button_text_scale', 0.06, None),
('buttonSize', None, DGG.INITOPT),
('topPad', 0.06, DGG.INITOPT),
('midPad', 0.12, DGG.INITOPT),
('sidePad', 0., DGG.INITOPT),
('buttonPadSF', 1.1, DGG.INITOPT),
# Alpha of fade screen behind dialog
('fadeScreen', 0, None),
('command', None, None),
('extraArgs', [], None),
('sortOrder', DGG.NO_FADE_SORT_INDEX, None),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs, dynamicGroups = ("button",))
# Initialize superclasses
DirectFrame.__init__(self, parent)
#if not self['dialogName']:
# self['dialogName'] = 'DirectDialog_' + repr(DirectDialog.PanelIndex)
# Clean up any previously existing panel with the same unique
# name. We don't allow any two panels with the same name to
# coexist.
cleanupDialog(self['dialogName'])
# Store this panel in our map of all open panels.
DirectDialog.AllDialogs[self['dialogName']] = self
DirectDialog.PanelIndex += 1
# Determine number of buttons
self.numButtons = max(len(self['buttonTextList']),
len(self['buttonGeomList']),
len(self['buttonImageList']),
len(self['buttonValueList']))
# Create buttons
self.buttonList = []
index = 0
for i in range(self.numButtons):
name = 'Button' + repr(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
self['buttonValueList'].append(i)
try:
hotKey = self['buttonHotKeyList'][i]
except IndexError:
hotKey = None
button = self.createcomponent(
name, (), "button",
DirectButton, (self,),
text = text,
geom = geom,
image = image,
suppressKeys = self['suppressKeys'],
frameSize = self['buttonSize'],
command = lambda s = self, v = value: s.buttonCommand(v)
)
self.buttonList.append(button)
# Update dialog when everything has been initialised
self.postInitialiseFuncList.append(self.configureDialog)
self.initialiseoptions(DirectDialog)
[docs] def show(self):
if self['fadeScreen']:
base.transitions.fadeScreen(self['fadeScreen'])
self.setBin('gui-popup', 0)
NodePath.show(self)
[docs] def hide(self):
if self['fadeScreen']:
base.transitions.noTransitions()
NodePath.hide(self)
[docs] def setMessage(self, message):
self['text'] = message
self.configureDialog()
[docs] def cleanup(self):
# Remove this panel out of the AllDialogs list
uniqueName = self['dialogName']
if uniqueName in DirectDialog.AllDialogs:
del DirectDialog.AllDialogs[uniqueName]
self.destroy()
[docs] def destroy(self):
if self['fadeScreen']:
base.transitions.noTransitions()
for button in self.buttonList:
button.destroy()
DirectFrame.destroy(self)
[docs]class OkDialog(DirectDialog):
[docs] def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['OK'], DGG.INITOPT),
('buttonValueList', [DGG.DIALOG_OK], DGG.INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(OkDialog)
[docs]class OkCancelDialog(DirectDialog):
[docs] def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['OK','Cancel'], DGG.INITOPT),
('buttonValueList', [DGG.DIALOG_OK, DGG.DIALOG_CANCEL], DGG.INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(OkCancelDialog)
[docs]class YesNoDialog(DirectDialog):
[docs] def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['Yes', 'No'], DGG.INITOPT),
('buttonValueList', [DGG.DIALOG_YES, DGG.DIALOG_NO], DGG.INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoDialog)
[docs]class YesNoCancelDialog(DirectDialog):
[docs] def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['Yes', 'No', 'Cancel'], DGG.INITOPT),
('buttonValueList', [DGG.DIALOG_YES, DGG.DIALOG_NO, DGG.DIALOG_CANCEL],
DGG.INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(YesNoCancelDialog)
[docs]class RetryCancelDialog(DirectDialog):
[docs] def __init__(self, parent = None, **kw):
# Inherits from DirectFrame
optiondefs = (
# Define type of DirectGuiWidget
('buttonTextList', ['Retry','Cancel'], DGG.INITOPT),
('buttonValueList', [DGG.DIALOG_RETRY, DGG.DIALOG_CANCEL], DGG.INITOPT),
)
# Merge keyword options with default options
self.defineoptions(kw, optiondefs)
DirectDialog.__init__(self, parent)
self.initialiseoptions(RetryCancelDialog)