Пример #1
0
 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)
Пример #2
0
 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)
Пример #4
0
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()
Пример #5
0
 * 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)
Пример #9
0
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
Пример #10
0
        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