def bind(self, event, command, extraArgs=[]): gEvent = event + self.guiId if get_config_showbase().GetBool('debug-directgui-msgs', False): from direct.showbase.PythonUtil import StackTrace print gEvent print StackTrace() self.accept(gEvent, command, extraArgs=extraArgs)
def bind(self, event, command, extraArgs = []): """ Bind the command (which should expect one arg) to the specified event (such as ENTER, EXIT, B1PRESS, B1CLICK, etc.) See DirectGuiGlobals for possible events """ # Need to tack on gui item specific id gEvent = event + self.guiId if get_config_showbase().GetBool('debug-directgui-msgs', False): from direct.showbase.PythonUtil import StackTrace print(gEvent) print(StackTrace()) self.accept(gEvent, command, extraArgs = extraArgs)
def bind(self, event, command, extraArgs=[]): """ Bind the command (which should expect one arg) to the specified event (such as ENTER, EXIT, B1PRESS, B1CLICK, etc.) See DirectGuiGlobals for possible events """ # Need to tack on gui item specific id gEvent = event + self.guiId if get_config_showbase().GetBool('debug-directgui-msgs', False): from direct.showbase.PythonUtil import StackTrace print gEvent print StackTrace() self.accept(gEvent, command, extraArgs=extraArgs)
an alternative to using the builtin scope. Note that you cannot directly import `base` from this module since ShowBase may not have been created yet; instead, ShowBase dynamically adds itself to this module's scope when instantiated.""" __all__ = [] from .ShowBase import ShowBase, WindowControls from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem from panda3d.core import ConfigPageManager, ConfigVariableManager from panda3d.core import NodePath, PGTop from panda3d.direct import get_config_showbase config = get_config_showbase() __dev__ = config.GetBool('want-dev', __debug__) vfs = VirtualFileSystem.getGlobalPtr() ostream = Notify.out() globalClock = ClockObject.getGlobalClock() cpMgr = ConfigPageManager.getGlobalPtr() cvMgr = ConfigVariableManager.getGlobalPtr() pandaSystem = PandaSystem.getGlobalPtr() # This is defined here so GUI elements can be instantiated before ShowBase. aspect2d = NodePath(PGTop("aspect2d")) # Set direct notify categories now that we have config directNotify.setDconfigLevels()
* Licensing information can found in 'LICENSE', which is part of this source code package. """ import __builtin__ import os from panda3d.core import loadPrcFile if os.path.exists('config/general.prc'): loadPrcFile('config/general.prc') from panda3d.direct import get_config_showbase from direct.directnotify.DirectNotifyGlobal import directNotify from direct.task.TaskManagerGlobal import taskMgr as task_mgr __builtin__.config = get_config_showbase() __builtin__.task_mgr = task_mgr __builtin__.task_chain = task_mgr.setupTaskChain('mainloop-taskchain', numThreads=4, frameSync=False) from realtime import io, types, clientagent, messagedirector, \ stateserver, database notify = directNotify.newCategory('Main') notify.setInfo(True) def setup_component(cls, *args, **kwargs): notify.info('Starting component: %s...' % (cls.__name__))
class DirectGuiWidget(DirectGuiBase, NodePath): # Toggle if you wish widget's to snap to grid when draggin snapToGrid = 0 gridSpacing = 0.05 # Determine the default initial state for inactive (or # unclickable) components. If we are in edit mode, these are # actually clickable by default. guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0) if guiEdit: inactiveInitState = DGG.NORMAL else: inactiveInitState = DGG.DISABLED guiDict = {} def __init__(self, parent=None, **kw): # Direct gui widgets are node paths # Direct gui widgets have: # - stateNodePaths (to hold visible representation of widget) # State node paths can have: # - a frame of type (None, FLAT, RAISED, GROOVE, RIDGE) # - arbitrary geometry for each state # They inherit from DirectGuiWidget # - Can create components (with aliases and groups) # - Can bind to mouse events # They inherit from NodePath # - Can position/scale them optiondefs = ( # Widget's constructor ('pgFunc', PGItem, None), ('numStates', 1, None), ('invertedFrames', (), None), ('sortOrder', 0, None), # Widget's initial state ('state', DGG.NORMAL, self.setState), # Widget's frame characteristics ('relief', DGG.FLAT, self.setRelief), ('borderWidth', (.1, .1), self.setBorderWidth), ('borderUvWidth', (.1, .1), self.setBorderUvWidth), ('frameSize', None, self.setFrameSize), ('frameColor', (.8, .8, .8, 1), self.setFrameColor), ('frameTexture', None, self.setFrameTexture), ('frameVisibleScale', (1, 1), self.setFrameVisibleScale), ('pad', (0, 0), self.resetFrameSize), # Override button id (beware! your name may not be unique!) ('guiId', None, DGG.INITOPT), # Initial pos/scale of the widget ('pos', None, DGG.INITOPT), ('hpr', None, DGG.INITOPT), ('scale', None, DGG.INITOPT), ('color', None, DGG.INITOPT), # Do events pass through this widget? ('suppressMouse', 1, DGG.INITOPT), ('suppressKeys', 0, DGG.INITOPT), ('enableEdit', 1, DGG.INITOPT), ) # Merge keyword options with default options self.defineoptions(kw, optiondefs) # Initialize the base classes (after defining the options). DirectGuiBase.__init__(self) NodePath.__init__(self) # Create a button self.guiItem = self['pgFunc']('') # Override automatically generated guiId if self['guiId']: self.guiItem.setId(self['guiId']) self.guiId = self.guiItem.getId() if __dev__: guiObjectCollector.addLevel(1) guiObjectCollector.flushLevel() # track gui items by guiId for tracking down leaks if hasattr(base, 'guiItems'): if self.guiId in base.guiItems: base.notify.warning( 'duplicate guiId: %s (%s stomping %s)' % (self.guiId, self, base.guiItems[self.guiId])) base.guiItems[self.guiId] = self if hasattr(base, 'printGuiCreates'): printStack() # Attach button to parent and make that self if (parent == None): parent = aspect2d self.assign(parent.attachNewNode(self.guiItem, self['sortOrder'])) # Update pose to initial values if self['pos']: self.setPos(self['pos']) if self['hpr']: self.setHpr(self['hpr']) if self['scale']: self.setScale(self['scale']) if self['color']: try: self.setColor(self['color']) except: # wow an't this legit. try: self.setColor(self['color'][0]) except: self.setColor(self['color'][0], self['color'][1], self['color'][2]) # Initialize names # Putting the class name in helps with debugging. self.setName("%s-%s" % (self.__class__.__name__, self.guiId)) # Create self.stateNodePath = [] for i in range(self['numStates']): self.stateNodePath.append(NodePath(self.guiItem.getStateDef(i))) # Initialize frame style self.frameStyle = [] for i in range(self['numStates']): self.frameStyle.append(PGFrameStyle()) # For holding bounds info self.ll = Point3(0) self.ur = Point3(0) # Is drag and drop enabled? if self['enableEdit'] and self.guiEdit: self.enableEdit() # Set up event handling suppressFlags = 0 if self['suppressMouse']: suppressFlags |= MouseWatcherRegion.SFMouseButton suppressFlags |= MouseWatcherRegion.SFMousePosition if self['suppressKeys']: suppressFlags |= MouseWatcherRegion.SFOtherButton self.guiItem.setSuppressFlags(suppressFlags) # Bind destroy hook self.guiDict[self.guiId] = self # self.bind(DGG.DESTROY, self.destroy) # Update frame when everything has been initialized self.postInitialiseFuncList.append(self.frameInitialiseFunc) # Call option initialization functions self.initialiseoptions(DirectGuiWidget) def frameInitialiseFunc(self): # Now allow changes to take effect self.updateFrameStyle() if not self['frameSize']: self.resetFrameSize() def enableEdit(self): self.bind(DGG.B2PRESS, self.editStart) self.bind(DGG.B2RELEASE, self.editStop) self.bind(DGG.PRINT, self.printConfig) # Can we move this to showbase # Certainly we don't need to do this for every button! #mb = base.mouseWatcherNode.getModifierButtons() #mb.addButton(KeyboardButton.control()) #base.mouseWatcherNode.setModifierButtons(mb) def disableEdit(self): self.unbind(DGG.B2PRESS) self.unbind(DGG.B2RELEASE) self.unbind(DGG.PRINT) #mb = base.mouseWatcherNode.getModifierButtons() #mb.removeButton(KeyboardButton.control()) #base.mouseWatcherNode.setModifierButtons(mb) def editStart(self, event): taskMgr.remove('guiEditTask') vWidget2render2d = self.getPos(render2d) vMouse2render2d = Point3(event.getMouse()[0], 0, event.getMouse()[1]) editVec = Vec3(vWidget2render2d - vMouse2render2d) if base.mouseWatcherNode.getModifierButtons().isDown( KeyboardButton.control()): t = taskMgr.add(self.guiScaleTask, 'guiEditTask') t.refPos = vWidget2render2d t.editVecLen = editVec.length() t.initScale = self.getScale() else: t = taskMgr.add(self.guiDragTask, 'guiEditTask') t.editVec = editVec def guiScaleTask(self, state): mwn = base.mouseWatcherNode if mwn.hasMouse(): vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) newEditVecLen = Vec3(state.refPos - vMouse2render2d).length() self.setScale(state.initScale * (newEditVecLen / state.editVecLen)) return Task.cont def guiDragTask(self, state): mwn = base.mouseWatcherNode if mwn.hasMouse(): vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) newPos = vMouse2render2d + state.editVec self.setPos(render2d, newPos) if DirectGuiWidget.snapToGrid: newPos = self.getPos() newPos.set(ROUND_TO(newPos[0], DirectGuiWidget.gridSpacing), ROUND_TO(newPos[1], DirectGuiWidget.gridSpacing), ROUND_TO(newPos[2], DirectGuiWidget.gridSpacing)) self.setPos(newPos) return Task.cont def editStop(self, event): taskMgr.remove('guiEditTask') def setState(self): if type(self['state']) == type(0): self.guiItem.setActive(self['state']) elif (self['state'] == DGG.NORMAL) or (self['state'] == 'normal'): self.guiItem.setActive(1) else: self.guiItem.setActive(0) def resetFrameSize(self): if not self.fInit: self.setFrameSize(fClearFrame=1) def setFrameSize(self, fClearFrame=0): # Use ready state to determine frame Type frameType = self.getFrameType() if self['frameSize']: # Use user specified bounds self.bounds = self['frameSize'] #print "%s bounds = %s" % (self.getName(), self.bounds) bw = (0, 0) else: if fClearFrame and (frameType != PGFrameStyle.TNone): self.frameStyle[0].setType(PGFrameStyle.TNone) self.guiItem.setFrameStyle(0, self.frameStyle[0]) # To force an update of the button self.guiItem.getStateDef(0) # Clear out frame before computing bounds self.getBounds() # Restore frame style if necessary if (frameType != PGFrameStyle.TNone): self.frameStyle[0].setType(frameType) self.guiItem.setFrameStyle(0, self.frameStyle[0]) if ((frameType != PGFrameStyle.TNone) and (frameType != PGFrameStyle.TFlat)): bw = self['borderWidth'] else: bw = (0, 0) # Set frame to new dimensions self.guiItem.setFrame(self.bounds[0] - bw[0], self.bounds[1] + bw[0], self.bounds[2] - bw[1], self.bounds[3] + bw[1]) def getBounds(self, state=0): self.stateNodePath[state].calcTightBounds(self.ll, self.ur) # Scale bounds to give a pad around graphics vec_right = Vec3.right() vec_up = Vec3.up() left = (vec_right[0] * self.ll[0] + vec_right[1] * self.ll[1] + vec_right[2] * self.ll[2]) right = (vec_right[0] * self.ur[0] + vec_right[1] * self.ur[1] + vec_right[2] * self.ur[2]) bottom = (vec_up[0] * self.ll[0] + vec_up[1] * self.ll[1] + vec_up[2] * self.ll[2]) top = (vec_up[0] * self.ur[0] + vec_up[1] * self.ur[1] + vec_up[2] * self.ur[2]) self.ll = Point3(left, 0.0, bottom) self.ur = Point3(right, 0.0, top) self.bounds = [ self.ll[0] - self['pad'][0], self.ur[0] + self['pad'][0], self.ll[2] - self['pad'][1], self.ur[2] + self['pad'][1] ] return self.bounds def getWidth(self): return self.bounds[1] - self.bounds[0] def getHeight(self): return self.bounds[3] - self.bounds[2] def getCenter(self): x = self.bounds[0] + (self.bounds[1] - self.bounds[0]) / 2.0 y = self.bounds[2] + (self.bounds[3] - self.bounds[2]) / 2.0 return (x, y) def getFrameType(self, state=0): return self.frameStyle[state].getType() def updateFrameStyle(self): if not self.fInit: for i in range(self['numStates']): self.guiItem.setFrameStyle(i, self.frameStyle[i]) def setRelief(self, fSetStyle=1): relief = self['relief'] # Convert None, and string arguments if relief == None: relief = PGFrameStyle.TNone elif isinstance(relief, types.StringTypes): # Convert string to frame style int relief = DGG.FrameStyleDict[relief] # Set style if relief == DGG.RAISED: for i in range(self['numStates']): if i in self['invertedFrames']: self.frameStyle[1].setType(DGG.SUNKEN) else: self.frameStyle[i].setType(DGG.RAISED) elif relief == DGG.SUNKEN: for i in range(self['numStates']): if i in self['invertedFrames']: self.frameStyle[1].setType(DGG.RAISED) else: self.frameStyle[i].setType(DGG.SUNKEN) else: for i in range(self['numStates']): self.frameStyle[i].setType(relief) # Apply styles self.updateFrameStyle() def setFrameColor(self): # this might be a single color or a list of colors colors = self['frameColor'] if type(colors[0]) == types.IntType or \ type(colors[0]) == types.FloatType: colors = (colors, ) for i in range(self['numStates']): if i >= len(colors): color = colors[-1] else: color = colors[i] self.frameStyle[i].setColor(color[0], color[1], color[2], color[3]) self.updateFrameStyle() def setFrameTexture(self): # this might be a single texture or a list of textures textures = self['frameTexture'] if textures == None or \ isinstance(textures, Texture) or \ isinstance(textures, types.StringTypes): textures = (textures, ) * self['numStates'] for i in range(self['numStates']): if i >= len(textures): texture = textures[-1] else: texture = textures[i] if isinstance(texture, types.StringTypes): texture = loader.loadTexture(texture) if texture: self.frameStyle[i].setTexture(texture) else: self.frameStyle[i].clearTexture() self.updateFrameStyle() def setFrameVisibleScale(self): scale = self['frameVisibleScale'] for i in range(self['numStates']): self.frameStyle[i].setVisibleScale(scale[0], scale[1]) self.updateFrameStyle() def setBorderWidth(self): width = self['borderWidth'] for i in range(self['numStates']): self.frameStyle[i].setWidth(width[0], width[1]) self.updateFrameStyle() def setBorderUvWidth(self): uvWidth = self['borderUvWidth'] for i in range(self['numStates']): self.frameStyle[i].setUvWidth(uvWidth[0], uvWidth[1]) self.updateFrameStyle() def destroy(self): if hasattr(self, "frameStyle"): if __dev__: guiObjectCollector.subLevel(1) guiObjectCollector.flushLevel() try: if hasattr(base, 'guiItems'): if self.guiId in base.guiItems: del base.guiItems[self.guiId] else: base.notify.warning( 'DirectGuiWidget.destroy(): ' 'gui item %s not in base.guiItems' % self.guiId) except: pass # Destroy children for child in self.getChildren(): childGui = self.guiDict.get(child.getName()) if childGui: childGui.destroy() else: # RAU since we added the class to the name, try # it with the original name parts = child.getName().split('-') simpleChildGui = self.guiDict.get(parts[-1]) if simpleChildGui: simpleChildGui.destroy() # messenger.send(DESTROY + child.getName()) del self.guiDict[self.guiId] del self.frameStyle # Get rid of node path self.removeNode() for nodePath in self.stateNodePath: nodePath.removeNode() del self.stateNodePath del self.guiItem # Call superclass destruction method (clears out hooks) DirectGuiBase.destroy(self) def printConfig(self, indent=0): space = ' ' * indent print space + self.guiId, '-', self.__class__.__name__ print space + 'Pos: %s' % tuple(self.getPos()) print space + 'Scale: %s' % tuple(self.getScale()) # Print out children info for child in self.getChildren(): messenger.send(DGG.PRINT + child.getName(), [indent + 2]) def copyOptions(self, other): """ Copy other's options into our self so we look and feel like other """ for key, value in other._optionInfo.items(): self[key] = value[1] def taskName(self, idString): return (idString + "-" + str(self.guiId)) def uniqueName(self, idString): return (idString + "-" + str(self.guiId)) def setProp(self, propString, value): """ Allows you to set a property like frame['text'] = 'Joe' in a function instead of an assignment. This is useful for setting properties inside function intervals where must input a function and extraArgs, not an assignment. """ self[propString] = value
gEvent = event + self.guiId self.ignore(gEvent) def toggleGuiGridSnap(): DirectGuiWidget.snapToGrid = 1 - DirectGuiWidget.snapToGrid def setGuiGridSpacing(spacing): DirectGuiWidget.gridSpacing = spacing # this should trigger off of __dev__, but it's not available at this point. # __debug__ works because the production client is not __debug__ and the # production AI doesn't create any GUI. if get_config_showbase().GetBool('record-gui-creation-stack', __debug__): # this will help track down the code that created DirectGui objects # call obj.printCreationStackTrace() to figure out what code created it DirectGuiBase = recordCreationStackStr(DirectGuiBase) class DirectGuiWidget(DirectGuiBase, NodePath): # Toggle if you wish widget's to snap to grid when draggin snapToGrid = 0 gridSpacing = 0.05 # Determine the default initial state for inactive (or # unclickable) components. If we are in edit mode, these are # actually clickable by default. guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0) if guiEdit:
# uncompyle6 version 3.2.4 # Python bytecode 2.7 (62211) # Decompiled from: Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] # Embedded file name: direct.showbase.ExceptionVarDump from panda3d.direct import get_config_showbase from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.PythonUtil import fastRepr import sys, types, traceback notify = directNotify.newCategory('ExceptionVarDump') config = get_config_showbase() reentry = 0 def _varDump__init__(self, *args, **kArgs): global reentry if reentry > 0: return reentry += 1 f = 1 self._savedExcString = None self._savedStackFrames = [] while True: try: frame = sys._getframe(f) except ValueError as e: break else: f += 1 self._savedStackFrames.append(frame) self._moved__init__(*args, **kArgs)
class DirectGuiWidget(DirectGuiBase, NodePath): snapToGrid = 0 gridSpacing = 0.05 guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0) if guiEdit: inactiveInitState = DGG.NORMAL else: inactiveInitState = DGG.DISABLED guiDict = {} def __init__(self, parent=None, **kw): optiondefs = (('pgFunc', PGItem, None), ('numStates', 1, None), ('invertedFrames', (), None), ('sortOrder', 0, None), ('state', DGG.NORMAL, self.setState), ('relief', DGG.FLAT, self.setRelief), ('borderWidth', (0.1, 0.1), self.setBorderWidth), ('borderUvWidth', (0.1, 0.1), self.setBorderUvWidth), ('frameSize', None, self.setFrameSize), ('frameColor', (0.8, 0.8, 0.8, 1), self.setFrameColor), ('frameTexture', None, self.setFrameTexture), ('frameVisibleScale', (1, 1), self.setFrameVisibleScale), ('pad', (0, 0), self.resetFrameSize), ('guiId', None, DGG.INITOPT), ('pos', None, DGG.INITOPT), ('hpr', None, DGG.INITOPT), ('scale', None, DGG.INITOPT), ('color', None, DGG.INITOPT), ('suppressMouse', 1, DGG.INITOPT), ('suppressKeys', 0, DGG.INITOPT), ('enableEdit', 1, DGG.INITOPT)) self.defineoptions(kw, optiondefs) DirectGuiBase.__init__(self) NodePath.__init__(self) self.guiItem = self['pgFunc']('') if self['guiId']: self.guiItem.setId(self['guiId']) self.guiId = self.guiItem.getId() if __dev__: guiObjectCollector.addLevel(1) guiObjectCollector.flushLevel() if hasattr(base, 'guiItems'): if self.guiId in base.guiItems: base.notify.warning( 'duplicate guiId: %s (%s stomping %s)' % (self.guiId, self, base.guiItems[self.guiId])) base.guiItems[self.guiId] = self if hasattr(base, 'printGuiCreates'): printStack() if parent == None: parent = aspect2d self.assign(parent.attachNewNode(self.guiItem, self['sortOrder'])) if self['pos']: self.setPos(self['pos']) if self['hpr']: self.setHpr(self['hpr']) if self['scale']: self.setScale(self['scale']) if self['color']: self.setColor(self['color']) self.setName('%s-%s' % (self.__class__.__name__, self.guiId)) self.stateNodePath = [] for i in range(self['numStates']): self.stateNodePath.append(NodePath(self.guiItem.getStateDef(i))) self.frameStyle = [] for i in range(self['numStates']): self.frameStyle.append(PGFrameStyle()) self.ll = Point3(0) self.ur = Point3(0) if self['enableEdit'] and self.guiEdit: self.enableEdit() suppressFlags = 0 if self['suppressMouse']: suppressFlags |= MouseWatcherRegion.SFMouseButton suppressFlags |= MouseWatcherRegion.SFMousePosition if self['suppressKeys']: suppressFlags |= MouseWatcherRegion.SFOtherButton self.guiItem.setSuppressFlags(suppressFlags) self.guiDict[self.guiId] = self self.postInitialiseFuncList.append(self.frameInitialiseFunc) self.initialiseoptions(DirectGuiWidget) return def frameInitialiseFunc(self): self.updateFrameStyle() if not self['frameSize']: self.resetFrameSize() def enableEdit(self): self.bind(DGG.B2PRESS, self.editStart) self.bind(DGG.B2RELEASE, self.editStop) self.bind(DGG.PRINT, self.printConfig) def disableEdit(self): self.unbind(DGG.B2PRESS) self.unbind(DGG.B2RELEASE) self.unbind(DGG.PRINT) def editStart(self, event): taskMgr.remove('guiEditTask') vWidget2render2d = self.getPos(render2d) vMouse2render2d = Point3(event.getMouse()[0], 0, event.getMouse()[1]) editVec = Vec3(vWidget2render2d - vMouse2render2d) if base.mouseWatcherNode.getModifierButtons().isDown( KeyboardButton.control()): t = taskMgr.add(self.guiScaleTask, 'guiEditTask') t.refPos = vWidget2render2d t.editVecLen = editVec.length() t.initScale = self.getScale() else: t = taskMgr.add(self.guiDragTask, 'guiEditTask') t.editVec = editVec def guiScaleTask(self, state): mwn = base.mouseWatcherNode if mwn.hasMouse(): vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) newEditVecLen = Vec3(state.refPos - vMouse2render2d).length() self.setScale(state.initScale * (newEditVecLen / state.editVecLen)) return Task.cont def guiDragTask(self, state): mwn = base.mouseWatcherNode if mwn.hasMouse(): vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) newPos = vMouse2render2d + state.editVec self.setPos(render2d, newPos) if DirectGuiWidget.snapToGrid: newPos = self.getPos() newPos.set(ROUND_TO(newPos[0], DirectGuiWidget.gridSpacing), ROUND_TO(newPos[1], DirectGuiWidget.gridSpacing), ROUND_TO(newPos[2], DirectGuiWidget.gridSpacing)) self.setPos(newPos) return Task.cont def editStop(self, event): taskMgr.remove('guiEditTask') def setState(self): if type(self['state']) == type(0): self.guiItem.setActive(self['state']) else: if self['state'] == DGG.NORMAL or self['state'] == 'normal': self.guiItem.setActive(1) else: self.guiItem.setActive(0) def resetFrameSize(self): if not self.fInit: self.setFrameSize(fClearFrame=1) def setFrameSize(self, fClearFrame=0): frameType = self.getFrameType() if self['frameSize']: self.bounds = self['frameSize'] bw = (0, 0) else: if fClearFrame and frameType != PGFrameStyle.TNone: self.frameStyle[0].setType(PGFrameStyle.TNone) self.guiItem.setFrameStyle(0, self.frameStyle[0]) self.guiItem.getStateDef(0) self.getBounds() if frameType != PGFrameStyle.TNone: self.frameStyle[0].setType(frameType) self.guiItem.setFrameStyle(0, self.frameStyle[0]) if frameType != PGFrameStyle.TNone and frameType != PGFrameStyle.TFlat: bw = self['borderWidth'] else: bw = (0, 0) self.guiItem.setFrame(self.bounds[0] - bw[0], self.bounds[1] + bw[0], self.bounds[2] - bw[1], self.bounds[3] + bw[1]) def getBounds(self, state=0): self.stateNodePath[state].calcTightBounds(self.ll, self.ur) vec_right = Vec3.right() vec_up = Vec3.up() left = vec_right[0] * self.ll[0] + vec_right[1] * self.ll[ 1] + vec_right[2] * self.ll[2] right = vec_right[0] * self.ur[0] + vec_right[1] * self.ur[ 1] + vec_right[2] * self.ur[2] bottom = vec_up[0] * self.ll[0] + vec_up[1] * self.ll[1] + vec_up[ 2] * self.ll[2] top = vec_up[0] * self.ur[0] + vec_up[1] * self.ur[1] + vec_up[ 2] * self.ur[2] self.ll = Point3(left, 0.0, bottom) self.ur = Point3(right, 0.0, top) self.bounds = [ self.ll[0] - self['pad'][0], self.ur[0] + self['pad'][0], self.ll[2] - self['pad'][1], self.ur[2] + self['pad'][1] ] return self.bounds def getWidth(self): return self.bounds[1] - self.bounds[0] def getHeight(self): return self.bounds[3] - self.bounds[2] def getCenter(self): x = self.bounds[0] + (self.bounds[1] - self.bounds[0]) / 2.0 y = self.bounds[2] + (self.bounds[3] - self.bounds[2]) / 2.0 return (x, y) def getFrameType(self, state=0): return self.frameStyle[state].getType() def updateFrameStyle(self): if not self.fInit: for i in range(self['numStates']): self.guiItem.setFrameStyle(i, self.frameStyle[i]) def setRelief(self, fSetStyle=1): relief = self['relief'] if relief == None: relief = PGFrameStyle.TNone else: if isinstance(relief, types.StringTypes): relief = DGG.FrameStyleDict[relief] if relief == DGG.RAISED: for i in range(self['numStates']): if i in self['invertedFrames']: self.frameStyle[1].setType(DGG.SUNKEN) else: self.frameStyle[i].setType(DGG.RAISED) else: if relief == DGG.SUNKEN: for i in range(self['numStates']): if i in self['invertedFrames']: self.frameStyle[1].setType(DGG.RAISED) else: self.frameStyle[i].setType(DGG.SUNKEN) else: for i in range(self['numStates']): self.frameStyle[i].setType(relief) self.updateFrameStyle() return def setFrameColor(self): colors = self['frameColor'] if type(colors[0]) == types.IntType or type( colors[0]) == types.FloatType: colors = (colors, ) for i in range(self['numStates']): if i >= len(colors): color = colors[-1] else: color = colors[i] self.frameStyle[i].setColor(color[0], color[1], color[2], color[3]) self.updateFrameStyle() def setFrameTexture(self): textures = self['frameTexture'] if textures == None or isinstance(textures, Texture) or isinstance( textures, types.StringTypes): textures = (textures, ) * self['numStates'] for i in range(self['numStates']): if i >= len(textures): texture = textures[-1] else: texture = textures[i] if isinstance(texture, types.StringTypes): texture = loader.loadTexture(texture) if texture: self.frameStyle[i].setTexture(texture) else: self.frameStyle[i].clearTexture() self.updateFrameStyle() return def setFrameVisibleScale(self): scale = self['frameVisibleScale'] for i in range(self['numStates']): self.frameStyle[i].setVisibleScale(scale[0], scale[1]) self.updateFrameStyle() def setBorderWidth(self): width = self['borderWidth'] for i in range(self['numStates']): self.frameStyle[i].setWidth(width[0], width[1]) self.updateFrameStyle() def setBorderUvWidth(self): uvWidth = self['borderUvWidth'] for i in range(self['numStates']): self.frameStyle[i].setUvWidth(uvWidth[0], uvWidth[1]) self.updateFrameStyle() def destroy(self): if hasattr(self, 'frameStyle'): if __dev__: guiObjectCollector.subLevel(1) guiObjectCollector.flushLevel() if hasattr(base, 'guiItems'): if self.guiId in base.guiItems: del base.guiItems[self.guiId] else: base.notify.warning( 'DirectGuiWidget.destroy(): gui item %s not in base.guiItems' % self.guiId) for child in self.getChildren(): childGui = self.guiDict.get(child.getName()) if childGui: childGui.destroy() else: parts = child.getName().split('-') simpleChildGui = self.guiDict.get(parts[-1]) if simpleChildGui: simpleChildGui.destroy() del self.guiDict[self.guiId] del self.frameStyle self.removeNode() for nodePath in self.stateNodePath: nodePath.removeNode() del self.stateNodePath del self.guiItem DirectGuiBase.destroy(self) def printConfig(self, indent=0): space = ' ' * indent print space + self.guiId, '-', self.__class__.__name__ print space + 'Pos: %s' % tuple(self.getPos()) print space + 'Scale: %s' % tuple(self.getScale()) for child in self.getChildren(): messenger.send(DGG.PRINT + child.getName(), [indent + 2]) def copyOptions(self, other): for key, value in other._optionInfo.items(): self[key] = value[1] def taskName(self, idString): return idString + '-' + str(self.guiId) def uniqueName(self, idString): return idString + '-' + str(self.guiId) def setProp(self, propString, value): self[propString] = value
Unbind the specified event """ # Need to tack on gui item specific id gEvent = event + self.guiId self.ignore(gEvent) def toggleGuiGridSnap(): DirectGuiWidget.snapToGrid = 1 - DirectGuiWidget.snapToGrid def setGuiGridSpacing(spacing): DirectGuiWidget.gridSpacing = spacing # this should trigger off of __dev__, but it's not available at this point. # __debug__ works because the production client is not __debug__ and the # production AI doesn't create any GUI. if get_config_showbase().GetBool('record-gui-creation-stack', __debug__): # this will help track down the code that created DirectGui objects # call obj.printCreationStackTrace() to figure out what code created it DirectGuiBase = recordCreationStackStr(DirectGuiBase) class DirectGuiWidget(DirectGuiBase, NodePath): # Toggle if you wish widget's to snap to grid when draggin snapToGrid = 0 gridSpacing = 0.05 # Determine the default initial state for inactive (or # unclickable) components. If we are in edit mode, these are # actually clickable by default. guiEdit = get_config_showbase().GetBool('direct-gui-edit', 0) if guiEdit: inactiveInitState = DGG.NORMAL