diff --git a/direct/src/gui/DialogBox.py b/direct/src/gui/DialogBox.py index 34dfc997ce..6d80b971e1 100644 --- a/direct/src/gui/DialogBox.py +++ b/direct/src/gui/DialogBox.py @@ -1,122 +1,2 @@ -from DirectObject import * -from ShowBaseGlobal import * -from GuiGlobals import * +from ToontownDialog import * -import DirectNotifyGlobal -import string -import OnscreenText -import Button -import StateData -import OnscreenPanel - -# No buttons at all -NoButtons = 0 - -# just an OK button -Acknowledge = 1 - -# OK and CANCEL buttons -TwoChoice = 2 - -class DialogBox(OnscreenPanel.OnscreenPanel): - - notify = DirectNotifyGlobal.directNotify.newCategory("DialogBox") - - def __init__(self, message = "", doneEvent = None, style = NoButtons, - font = getDefaultFont(), wordwrap = 12, okButtonText = "OK", - cancelButtonText = "Cancel"): - """___init___(self, Event, string="", int, model, int=12)""" - - # Sanity check - if (doneEvent == None) and (style != NoButtons): - self.notify.error("Boxes with buttons must specify a doneEvent.") - - self.__doneEvent = doneEvent - self.message = message - self.style = style - self.font = font - self.wordwrap = wordwrap - self.okButtonText = okButtonText - self.cancelButtonText = cancelButtonText - - # initialize our OnscreenPanel essence - # NOTE: all db's have the same name so we can kill them easily - OnscreenPanel.OnscreenPanel.__init__(self, "globalDialog") - - # make the panel - self.makePanel(rect = (-0.5, 0.5, -0.4, 0.4), - drawOrder = 32000, font = self.font, - bg = (0.8, 0.8, 0.8, 1.0)) - - # create a message - self.makeText(self.message, wordwrap = self.wordwrap, scale = 0.08, - pos = (0.0, 0.25)) - - if (self.style == TwoChoice): - # create OK and CANCEL buttons - self.makeButton(self.okButtonText, - pos = (-0.325, -0.25), - func = self.handleOk, - event = "ok") - self.makeButton(self.cancelButtonText, - pos = (0.2, -0.25), - func = self.handleCancel, - event = "cancel") - elif (self.style == Acknowledge): - # create a centered OK button - self.makeButton(self.okButtonText, - pos = (0.0, -0.25), - func = self.handleOk, - event = "ok") - elif (self.style == NoButtons): - # No buttons at all - pass - else: - "Sanity check" - self.notify.error("No such style as: " + str(self.style)) - - return None - - def show(self): - """show(self) - """ - base.transitions.fadeScreen() - OnscreenPanel.OnscreenPanel.show(self) - - return None - - def hide(self): - """hide(self) - """ - base.transitions.noTransitions() - OnscreenPanel.OnscreenPanel.hide(self) - - return None - - def cleanup(self): - """unload(self) - """ - self.hide() - OnscreenPanel.OnscreenPanel.cleanup(self) - - return None - - # def handleRollover(self): - # return None - - def handleOk(self, okButton, item): - assert(self.style != NoButtons) - if (okButton == item): - self.doneStatus = "ok" - messenger.send(self.__doneEvent) - - def handleCancel(self, cancelButton, item): - assert(self.style == TwoChoice) - if (cancelButton == item): - self.doneStatus = "cancel" - messenger.send(self.__doneEvent) - - def setMessage(self, message): - """setMessage(self, string) - """ - self.panelText[0].setText(message) diff --git a/direct/src/gui/DirectDialog.py b/direct/src/gui/DirectDialog.py deleted file mode 100644 index 6348d1cdca..0000000000 --- a/direct/src/gui/DirectDialog.py +++ /dev/null @@ -1,341 +0,0 @@ -from DirectGuiGlobals import * -from DirectFrame import * -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 - buttonHotKeyList List of hotkeys to bind to each button. - Typing hotkey is equivalent to pressing - the corresponding button. - supressKeys Set to true if you wish to supress 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 - 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.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), - ('buttonHotKeyList', [], 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) - # 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' + `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) - - def configureDialog(self): - # Set up hot key bindings - bindList = zip(self.buttonList, self['buttonHotKeyList'], - self['buttonValueList']) - for button, hotKey, value in bindList: - if ((type(hotKey) == types.ListType) or - (type(hotKey) == types.TupleType)): - for key in hotKey: - button.bind('press-' + key + '-', self.buttonCommand, - extraArgs = [value]) - self.bind('press-' + key + '-', self.buttonCommand, - extraArgs = [value]) - - else: - button.bind('press-' + hotKey + '-',self.buttonCommand, - extraArgs = [value]) - self.bind('press-' + hotKey + '-', self.buttonCommand, - extraArgs = [value]) - # Position buttons and text - pad = self['pad'] - 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: - # Or get bounds of union of buttons - bl = br = bb = bt = 0 - for button in self.buttonList: - bounds = button.stateNodePath[0].getTightBounds() - bl = min(bl, bounds[0][0]) - br = max(br, bounds[1][0]) - bb = min(bb, bounds[0][2]) - bt = max(bt, bounds[1][2]) - 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 - 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, value, event = None): - if self['command']: - 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 - ('buttonTextList', ['Yes', 'No'], INITOPT), - ('buttonValueList', [1,0], INITOPT), - ) - # Merge keyword options with default options - self.defineoptions(kw, optiondefs) - 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) - buttons.removeNode() diff --git a/direct/src/gui/DirectGuiGlobals.py b/direct/src/gui/DirectGuiGlobals.py index 388f0ae823..08b5ac48e9 100644 --- a/direct/src/gui/DirectGuiGlobals.py +++ b/direct/src/gui/DirectGuiGlobals.py @@ -34,6 +34,11 @@ FrameStyleDict = {'flat' : FLAT, 'raised' : RAISED, 'sunken': SUNKEN, 'groove' : GROOVE, 'ridge' : RIDGE } +# Dialog button values +DIALOG_NO = 0 +DIALOG_OK = DIALOG_YES = DIALOG_RETRY = 1 +DIALOG_CANCEL = -1 + # User can bind commands to these gui events DESTROY = 'destroy-' PRINT = 'print-' @@ -59,6 +64,8 @@ ERASE = PGEntry.getErasePrefix() IMAGE_SORT_INDEX = 10 GEOM_SORT_INDEX = 20 TEXT_SORT_INDEX = 30 +FADE_SORT_INDEX = 100 +DIALOG_SORT_INDEX = 200 defaultFont = None defaultClickSound = None diff --git a/direct/src/gui/DirectGuiTest.py b/direct/src/gui/DirectGuiTest.py index 35633b30f9..95de8f1375 100644 --- a/direct/src/gui/DirectGuiTest.py +++ b/direct/src/gui/DirectGuiTest.py @@ -114,9 +114,6 @@ fancyDialog = YesNoDialog(text = 'Testing Direct Dialog', 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),