Ejemplo n.º 1
0
    def generateOtherPlayerGui(self):
        for avId in self.doId2Frame.keys():
            self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId] = {}
            headNumber = -1
            frame = self.doId2Frame[avId][0]
            otherPlayerHeadsFrame = DirectFrame(relief=None,
                                                scale=0.85,
                                                parent=frame)
            otherPlayerHeadsFrame['image'] = frame['image']
            otherPlayerHeadsFrame['image_color'] = frame['image_color']
            otherPlayerHeadsFrame[
                'image_scale'] = self.otherPlayerHeadHolderTransforms['scale']
            otherPlayerHeadsFrame.setPos(
                self.otherPlayerHeadHolderTransforms['pos'])
            otherPlayerHeadsFrame.setBin('gui-popup', 70)
            self.frameList.append(otherPlayerHeadsFrame)
            for otherAvId in self.doId2Frame.keys():
                if otherAvId != avId:
                    headNumber += 1
                    otherAv = base.cr.doId2do.get(otherAvId)

                    headFrame = otherPlayerHeadsFrame.attachNewNode(
                        'otherPlayerHeadFrame')
                    headFrame.setPosHprScale(
                        self.otherPlayerHeadXValues[headNumber], 5, -0.1, 180,
                        0, 0, 0.2, 0.2, 0.2)
                    headFrame.setColorScale(self.state2Color[0])

                    head = ToonGlobals.generateGuiHead(otherAv)
                    head.reparentTo(headFrame)

                    self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId][
                        otherAvId] = headFrame
Ejemplo n.º 2
0
 def generate(self, gender, head, headtype, color, doId, name, valueLabel = 1):
     gui = loader.loadModel("phase_3/models/gui/pick_a_toon_gui.bam")
     bg = gui.find('**/av-chooser_Square_UP')
     container = DirectFrame(relief=None, scale=0.3, parent=base.a2dTopLeft)
     container['image'] = bg
     container['image_color'] = self.frameColors[len(self.frameList)]
     container.setBin('gui-popup', 60)
     container.setPos(self.framePositions[len(self.frameList)])
     headframe = container.attachNewNode('head')
     headframe.setPosHprScale(0, 5, -0.1, 180, 0, 0, 0.24, 0.24, 0.24)
     toon = ToonHead(None)
     toon.generateHead(gender, head, headtype)
     r, g, b = color
     color = (r, g, b, 1.0)
     toon.setHeadColor(color)
     toon.setDepthWrite(1)
     toon.setDepthTest(1)
     toon.reparentTo(headframe)
     nameLbl = DirectLabel(text=name, text_wordwrap=7.0, parent=container, text_scale=0.13,
                     text_fg=(1,1,1,1), text_shadow=(0,0,0,1), relief=None, pos=(0, 0, 0.25))
     if valueLabel:
         someValueToBroadcast = DirectLabel(text="0", parent=container, text_scale=0.15, text_fg=(1,1,1,1),
                             text_shadow=(0,0,0,1), relief=None, pos=(0.26, 0, -0.28))
     self.frameList.append(container)
     if valueLabel:
         self.doId2Frame[doId] = tuple((container, headframe, toon, nameLbl, someValueToBroadcast))
     else:
         self.doId2Frame[doId] = tuple((container, headframe, toon, nameLbl))
Ejemplo n.º 3
0
class LoadingScreen():
    """Show a directWaitbar to display the current loading state of the
    application"""
    def __init__(self):
        # a fill panel so the player doesn't see how everything
        # gets loaded in the background
        self.frameMain = DirectFrame(
            image="gui/MenuBackground.png",
            image_scale=(1.7778, 1, 1),
            #image_pos=(0, 0, 0.25),
            frameSize=(
                base.a2dLeft, base.a2dRight,
                base.a2dTop, base.a2dBottom),
            frameColor=(0,0,0,0))
        self.frameMain.setTransparency(True)
        self.frameMain.setBin("fixed", 6000)
        self.frameMain.setDepthWrite(False)

        self.logo = DirectFrame(
            image="Logo.png",
            image_scale=0.25,
            image_pos=(0, 0, 0.55),
            frameSize=(
                base.a2dLeft, base.a2dRight,
                base.a2dTop, base.a2dBottom),
            frameColor=(0,0,0,0))
        self.logo.reparentTo(self.frameMain)


        # the text Loading...
        self.lblLoading = DirectLabel(
            scale=0.10,
            pos=(0, 0, -0.15),
            frameColor=(0, 0, 0, 0),
            text=_("Loading..."),
            text_align=TextNode.ACenter,
            text_fg=(1, 1, 1, 1))
        self.lblLoading.reparentTo(self.frameMain)

        self.stop()

    def start(self):
        self.frameMain.show()
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()

    def stop(self):
        self.frameMain.hide()
    def generateOtherPlayerGui(self):
        for avId in self.doId2Frame.keys():
            self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId] = {}
            headNumber = -1
            frame = self.doId2Frame[avId][0]
            otherPlayerHeadsFrame = DirectFrame(relief=None,
                                                scale=0.85,
                                                parent=frame)
            otherPlayerHeadsFrame['image'] = frame['image']
            otherPlayerHeadsFrame['image_color'] = frame['image_color']
            otherPlayerHeadsFrame[
                'image_scale'] = self.otherPlayerHeadHolderTransforms['scale']
            otherPlayerHeadsFrame.setPos(
                self.otherPlayerHeadHolderTransforms['pos'])
            otherPlayerHeadsFrame.setBin('gui-popup', 70)
            self.frameList.append(otherPlayerHeadsFrame)
            for otherAvId in self.doId2Frame.keys():
                if otherAvId != avId:
                    headNumber += 1
                    otherAv = base.cr.doId2do.get(otherAvId)
                    gender = otherAv.getGender()
                    head, color = otherAv.getHeadStyle()
                    animal = otherAv.getAnimal()

                    headFrame = otherPlayerHeadsFrame.attachNewNode(
                        'otherPlayerHeadFrame')
                    headFrame.setPosHprScale(
                        self.otherPlayerHeadXValues[headNumber], 5, -0.1, 180,
                        0, 0, 0.2, 0.2, 0.2)
                    headFrame.setColorScale(self.state2Color[0])
                    toon = ToonHead(None)
                    toon.generateHead(gender, animal, head)
                    r, g, b, _ = color
                    color = (r, g, b, 1.0)
                    toon.setHeadColor(color)
                    toon.setDepthWrite(1)
                    toon.setDepthTest(1)
                    toon.reparentTo(headFrame)

                    self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId][
                        otherAvId] = headFrame
Ejemplo n.º 5
0
 def generate(self, gender, head, headtype, color, doId, name, valueLabel = 1):
     gui = loader.loadModel('phase_3/models/gui/pick_a_toon_gui.bam')
     bg = gui.find('**/av-chooser_Square_UP')
     container = DirectFrame(relief=None, scale=0.3, parent=base.a2dTopLeft)
     container['image'] = bg
     container['image_color'] = self.frameColors[len(self.frameList)]
     container.setBin('gui-popup', 60)
     container.setPos(self.framePositions[len(self.frameList)])
     headframe = container.attachNewNode('head')
     headframe.setPosHprScale(0, 5, -0.1, 180, 0, 0, 0.24, 0.24, 0.24)
     toon = ToonHead(None)
     toon.generateHead(gender, head, headtype)
     r, g, b = color
     color = (r,
      g,
      b,
      1.0)
     toon.setHeadColor(color)
     toon.setDepthWrite(1)
     toon.setDepthTest(1)
     toon.reparentTo(headframe)
     nameLbl = DirectLabel(text=name, text_wordwrap=7.0, parent=container, text_scale=0.13, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), relief=None, pos=(0, 0, 0.25))
     if valueLabel:
         someValueToBroadcast = DirectLabel(text='0', parent=container, text_scale=0.15, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), relief=None, pos=(0.26, 0, -0.28))
     self.frameList.append(container)
     if valueLabel:
         self.doId2Frame[doId] = tuple((container,
          headframe,
          toon,
          nameLbl,
          someValueToBroadcast))
     else:
         self.doId2Frame[doId] = tuple((container,
          headframe,
          toon,
          nameLbl))
     return
Ejemplo n.º 6
0
    def generateOtherPlayerGui(self):
        for avId in self.doId2Frame.keys():
            self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId] = {}
            headNumber = -1
            frame = self.doId2Frame[avId][0]
            otherPlayerHeadsFrame = DirectFrame(relief=None, scale=0.85, parent=frame)
            otherPlayerHeadsFrame['image'] = frame['image']
            otherPlayerHeadsFrame['image_color'] = frame['image_color']
            otherPlayerHeadsFrame['image_scale'] = self.otherPlayerHeadHolderTransforms['scale']
            otherPlayerHeadsFrame.setPos(self.otherPlayerHeadHolderTransforms['pos'])
            otherPlayerHeadsFrame.setBin('gui-popup', 70)
            self.frameList.append(otherPlayerHeadsFrame)
            for otherAvId in self.doId2Frame.keys():
                if otherAvId != avId:
                    headNumber += 1
                    otherAv = base.cr.doId2do.get(otherAvId)
                    gender = otherAv.getGender()
                    head, color = otherAv.getHeadStyle()
                    animal = otherAv.getAnimal()
                    headFrame = otherPlayerHeadsFrame.attachNewNode('otherPlayerHeadFrame')
                    headFrame.setPosHprScale(self.otherPlayerHeadXValues[headNumber], 5, -0.1, 180, 0, 0, 0.2, 0.2, 0.2)
                    headFrame.setColorScale(self.state2Color[0])
                    toon = ToonHead(None)
                    toon.generateHead(gender, animal, head)
                    r, g, b, _ = color
                    color = (r,
                     g,
                     b,
                     1.0)
                    toon.setHeadColor(color)
                    toon.setDepthWrite(1)
                    toon.setDepthTest(1)
                    toon.reparentTo(headFrame)
                    self.avId2otherPlayerAvIds2otherPlayerHeadsFrame[avId][otherAvId] = headFrame

        return
class FinalScoreGUI:
    notify = directNotify.newCategory('FinalScoreGUI')

    def __init__(self):
        self.finalScoreBg = None
        self.finalScoreTitle = None
        self.finalScoreNameLbl = None
        self.finalScorePointLbl = None
        self.finalScoreContainer = None
        self.finalScores = []
        return

    def load(self):
        font = CIGlobals.getToonFont()
        box = DGG.getDefaultDialogGeom()
        self.finalScoreContainer = DirectFrame()
        self.finalScoreBg = OnscreenImage(image=box, color=(1, 1, 0.75, 1), scale=(1.9,
                                                                                   1.4,
                                                                                   1.4), parent=self.finalScoreContainer)
        self.finalScoreTitle = OnscreenText(text='Waiting for final scores...', pos=(0,
                                                                                     0.5,
                                                                                     0), font=font, scale=0.12, parent=self.finalScoreContainer)
        self.finalScoreNameLbl = OnscreenText(text='', scale=0.095, pos=(-0.85, 0.3,
                                                                         0), font=font, align=TextNode.ALeft, parent=self.finalScoreContainer)
        self.finalScorePointLbl = OnscreenText(text='', scale=0.095, pos=(0.85, 0.3,
                                                                          0), font=font, align=TextNode.ARight, parent=self.finalScoreContainer)
        self.finalScoreContainer.hide()
        self.finalScoreContainer.setBin('gui-popup', 60)
        del font
        del box

    def unload(self):
        if self.finalScoreContainer:
            self.finalScoreContainer.destroy()
            self.finalScoreContainer = None
        if self.finalScoreBg:
            self.finalScoreBg.destroy()
            self.finalScoreBg = None
        if self.finalScoreTitle:
            self.finalScoreTitle.destroy()
            self.finalScoreTitle = None
        if self.finalScoreNameLbl:
            self.finalScoreNameLbl.destroy()
            self.finalScoreNameLbl = None
        if self.finalScorePointLbl:
            self.finalScorePointLbl.destroy()
            self.finalScorePointLbl = None
        return

    def showFinalScores(self):
        self.finalScoreContainer.show()
        base.transitions.fadeScreen(0.5)

    def hideFinalScores(self):
        base.transitions.noTransitions()
        self.finalScoreContainer.hide()

    def handleFinalScores(self, avIdList, scoreList):
        for avId in avIdList:
            score = scoreList[avIdList.index(avId)]
            scoreObj = FinalScore(avId, score)
            self.finalScores.append(scoreObj)

        self.finalScores.sort(key=lambda x: x.score, reverse=True)
        for scoreObj in self.finalScores:
            name = base.cr.doId2do.get(scoreObj.avId).getName()
            self.finalScoreNameLbl['text'] += name + '\n'
            self.finalScorePointLbl['text'] += str(scoreObj.score) + ' Points\n'

        self.finalScoreTitle['text'] = 'Final Scores'
Ejemplo n.º 8
0
class Transitions:

    # These may be reassigned before the fade or iris transitions are
    # actually invoked to change the models that will be used.
    IrisModelName = "models/misc/iris"
    FadeModelName = "models/misc/fade"

    def __init__(self, loader, model=None, scale=3.0, pos=Vec3(0, 0, 0)):
        self.transitionIval = None
        self.letterboxIval = None
        self.iris = None
        self.fade = None
        self.letterbox = None
        self.fadeModel = model
        self.imagePos = pos
        if model:
            self.alphaOff = Vec4(1, 1, 1, 0)
            self.alphaOn = Vec4(1, 1, 1, 1)
            model.setTransparency(1)
            self.lerpFunc = LerpColorScaleInterval
        else:
            self.alphaOff = Vec4(0, 0, 0, 0)
            self.alphaOn = Vec4(0, 0, 0, 1)
            self.lerpFunc = LerpColorInterval

        self.irisTaskName = "irisTask"
        self.fadeTaskName = "fadeTask"
        self.letterboxTaskName = "letterboxTask"

    def __del__(self):
        if self.fadeModel:
            self.fadeModel.removeNode()
            self.fadeModel = None

    ##################################################
    # Fade
    ##################################################

    # We can set a custom model for the fade before using it for the first time
    def setFadeModel(self, model, scale=1.0):
        self.fadeModel = model
        # We have to change some default parameters for a custom fadeModel
        self.alphaOn = Vec4(1, 1, 1, 1)

        # Reload fade if its already been created
        if self.fade:
            self.fade.destroy()
            self.fade = None
            self.loadFade()

    def loadFade(self):
        if self.fade is None:
            # We create a DirectFrame for the fade polygon, instead of
            # simply loading the polygon model and using it directly,
            # so that it will also obscure mouse events for objects
            # positioned behind it.
            self.fade = DirectFrame(
                parent=hidden,
                guiId='fade',
                relief=None,
                image=self.fadeModel,
                image_scale=(4, 2, 2),
                state=DGG.NORMAL,
            )
            if not self.fadeModel:
                # No fade model was given, so we make this the fade model.
                self.fade["relief"] = DGG.FLAT
                self.fade["frameSize"] = (-2, 2, -1, 1)
                self.fade["frameColor"] = (0, 0, 0, 1)
                self.fade.setTransparency(TransparencyAttrib.MAlpha)
            self.fade.setBin('unsorted', 0)
            self.fade.setColor(0, 0, 0, 0)

    def getFadeInIval(self, t=0.5, finishIval=None):
        """
        Returns an interval without starting it.  This is particularly useful in
        cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately
        """
        #self.noTransitions() masad: this creates a one frame pop, is it necessary?
        self.loadFade()
        transitionIval = Sequence(
            Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
            Func(self.fade.showThrough
                 ),  # in case aspect2d is hidden for some reason
            self.lerpFunc(
                self.fade,
                t,
                self.alphaOff,
                # self.alphaOn,
            ),
            Func(self.fade.detachNode),
            name=self.fadeTaskName,
        )
        if finishIval:
            transitionIval.append(finishIval)
        return transitionIval

    def getFadeOutIval(self, t=0.5, finishIval=None):
        """
        Create a sequence that lerps the color out, then
        parents the fade to hidden
        """
        self.noTransitions()
        self.loadFade()

        transitionIval = Sequence(
            Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
            Func(self.fade.showThrough
                 ),  # in case aspect2d is hidden for some reason
            self.lerpFunc(
                self.fade,
                t,
                self.alphaOn,
                # self.alphaOff,
            ),
            name=self.fadeTaskName,
        )
        if finishIval:
            transitionIval.append(finishIval)
        return transitionIval

    def fadeIn(self, t=0.5, finishIval=None):
        """
        Play a fade in transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the color
        from black to transparent. When the color lerp is finished, it
        parents the fade polygon to hidden.
        """
        gsg = base.win.getGsg()
        if gsg:
            # If we're about to fade in from black, go ahead and
            # preload all the textures etc.
            base.graphicsEngine.renderFrame()
            render.prepareScene(gsg)
            render2d.prepareScene(gsg)

        if (t == 0):
            # Fade in immediately with no lerp
            #print "transitiosn: fadeIn 0.0"
            self.noTransitions()
            self.loadFade()
            self.fade.detachNode()
        else:
            # Create a sequence that lerps the color out, then
            # parents the fade to hidden
            self.transitionIval = self.getFadeInIval(t, finishIval)
            self.transitionIval.start()

    def fadeOut(self, t=0.5, finishIval=None):
        """
        Play a fade out transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the color
        from transparent to full black. When the color lerp is finished,
        it leaves the fade polygon covering the aspect2d plane until you
        fadeIn or call noFade.
        lerp
        """
        if (t == 0):
            # Fade out immediately with no lerp
            self.noTransitions()
            self.loadFade()
            self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
            self.fade.setColor(self.alphaOn)
        elif ConfigVariableBool('no-loading-screen', False):
            if finishIval:
                self.transitionIval = finishIval
                self.transitionIval.start()
        else:
            # Create a sequence that lerps the color out, then
            # parents the fade to hidden
            self.transitionIval = self.getFadeOutIval(t, finishIval)
            self.transitionIval.start()

    def fadeOutActive(self):
        return self.fade and self.fade.getColor()[3] > 0

    def fadeScreen(self, alpha=0.5):
        """
        Put a semitransparent screen over the camera plane
        to darken out the world. Useful for drawing attention to
        a dialog box for instance
        """
        #print "transitiosn: fadeScreen"
        self.noTransitions()
        self.loadFade()
        self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
        self.fade.setColor(self.alphaOn[0], self.alphaOn[1], self.alphaOn[2],
                           alpha)

    def fadeScreenColor(self, color):
        """
        Put a semitransparent screen over the camera plane
        to darken out the world. Useful for drawing attention to
        a dialog box for instance
        """
        #print "transitiosn: fadeScreenColor"
        self.noTransitions()
        self.loadFade()
        self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
        self.fade.setColor(color)

    def noFade(self):
        """
        Removes any current fade tasks and parents the fade polygon away
        """
        #print "transitiosn: noFade"
        if self.transitionIval:
            self.transitionIval.pause()
            self.transitionIval = None
        if self.fade:
            # Make sure to reset the color, since fadeOutActive() is looking at it
            self.fade.setColor(self.alphaOff)
            self.fade.detachNode()

    def setFadeColor(self, r, g, b):
        self.alphaOn.set(r, g, b, 1)
        self.alphaOff.set(r, g, b, 0)

    ##################################################
    # Iris
    ##################################################

    def loadIris(self):
        if self.iris == None:
            self.iris = loader.loadModel(self.IrisModelName)
            self.iris.setPos(0, 0, 0)

    def irisIn(self, t=0.5, finishIval=None):
        """
        Play an iris in transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the scale
        of the iris polygon up so it looks like we iris in. When the
        scale lerp is finished, it parents the iris polygon to hidden.
        """
        self.noTransitions()
        self.loadIris()
        if (t == 0):
            self.iris.detachNode()
        else:
            self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)

            self.transitionIval = Sequence(
                LerpScaleInterval(self.iris, t, scale=0.18, startScale=0.01),
                Func(self.iris.detachNode),
                name=self.irisTaskName,
            )
            if finishIval:
                self.transitionIval.append(finishIval)
            self.transitionIval.start()

    def irisOut(self, t=0.5, finishIval=None):
        """
        Play an iris out transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the scale
        of the iris down so it looks like we iris out. When the scale
        lerp is finished, it leaves the iris polygon covering the
        aspect2d plane until you irisIn or call noIris.
        """
        self.noTransitions()
        self.loadIris()
        self.loadFade()  # we need this to cover up the hole.
        if (t == 0):
            self.iris.detachNode()
            self.fadeOut(0)
        else:
            self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)

            self.transitionIval = Sequence(
                LerpScaleInterval(self.iris, t, scale=0.01, startScale=0.18),
                Func(self.iris.detachNode),
                # Use the fade to cover up the hole that the iris would leave
                Func(self.fadeOut, 0),
                name=self.irisTaskName,
            )
            if finishIval:
                self.transitionIval.append(finishIval)
            self.transitionIval.start()

    def noIris(self):
        """
        Removes any current iris tasks and parents the iris polygon away
        """
        if self.transitionIval:
            self.transitionIval.pause()
            self.transitionIval = None
        if self.iris != None:
            self.iris.detachNode()
        # Actually we need to remove the fade too,
        # because the iris effect uses it.
        self.noFade()

    def noTransitions(self):
        """
        This call should immediately remove any and all transitions running
        """
        self.noFade()
        self.noIris()
        # Letterbox is not really a transition, it is a screen overlay
        # self.noLetterbox()

    ##################################################
    # Letterbox
    ##################################################

    def loadLetterbox(self):
        if not self.letterbox:
            # We create a DirectFrame for the fade polygon, instead of
            # simply loading the polygon model and using it directly,
            # so that it will also obscure mouse events for objects
            # positioned behind it.
            self.letterbox = NodePath("letterbox")
            # Allow fade in and out of the bars
            self.letterbox.setTransparency(1)

            # Allow DirectLabels to be parented to the letterbox sensibly
            self.letterbox.setBin('unsorted', 0)

            # Allow a custom look to the letterbox graphic.

            # TODO: This model isn't available everywhere.  We should
            # pass it in as a parameter.
            button = loader.loadModel('models/gui/toplevel_gui',
                                      okMissing=True)

            barImage = None
            if button:
                barImage = button.find('**/generic_button')

            self.letterboxTop = DirectFrame(
                parent=self.letterbox,
                guiId='letterboxTop',
                relief=DGG.FLAT,
                state=DGG.NORMAL,
                frameColor=(0, 0, 0, 1),
                borderWidth=(0, 0),
                frameSize=(-1, 1, 0, 0.2),
                pos=(0, 0, 0.8),
                image=barImage,
                image_scale=(2.25, 1, .5),
                image_pos=(0, 0, .1),
                image_color=(0.3, 0.3, 0.3, 1),
                sortOrder=0,
            )
            self.letterboxBottom = DirectFrame(
                parent=self.letterbox,
                guiId='letterboxBottom',
                relief=DGG.FLAT,
                state=DGG.NORMAL,
                frameColor=(0, 0, 0, 1),
                borderWidth=(0, 0),
                frameSize=(-1, 1, 0, 0.2),
                pos=(0, 0, -1),
                image=barImage,
                image_scale=(2.25, 1, .5),
                image_pos=(0, 0, .1),
                image_color=(0.3, 0.3, 0.3, 1),
                sortOrder=0,
            )

            # masad: always place these at the bottom of render
            self.letterboxTop.setBin('sorted', 0)
            self.letterboxBottom.setBin('sorted', 0)
            self.letterbox.reparentTo(render2d, -1)
            self.letterboxOff(0)

    def noLetterbox(self):
        """
        Removes any current letterbox tasks and parents the letterbox polygon away
        """
        if self.letterboxIval:
            self.letterboxIval.pause()
            self.letterboxIval = None
        if self.letterbox:
            self.letterbox.stash()

    def letterboxOn(self, t=0.25, finishIval=None):
        """
        Move black bars in over t seconds.
        """
        self.noLetterbox()
        self.loadLetterbox()
        self.letterbox.unstash()
        if (t == 0):
            self.letterboxBottom.setPos(0, 0, -1)
            self.letterboxTop.setPos(0, 0, 0.8)
        else:
            self.letterboxIval = Sequence(
                Parallel(
                    LerpPosInterval(
                        self.letterboxBottom,
                        t,
                        pos=Vec3(0, 0, -1),
                        #startPos = Vec3(0, 0, -1.2),
                    ),
                    LerpPosInterval(
                        self.letterboxTop,
                        t,
                        pos=Vec3(0, 0, 0.8),
                        # startPos = Vec3(0, 0, 1),
                    ),
                ),
                name=self.letterboxTaskName,
            )
            if finishIval:
                self.letterboxIval.append(finishIval)
            self.letterboxIval.start()

    def letterboxOff(self, t=0.25, finishIval=None):
        """
        Move black bars away over t seconds.
        """
        self.noLetterbox()
        self.loadLetterbox()
        self.letterbox.unstash()
        if (t == 0):
            self.letterbox.stash()
        else:
            self.letterboxIval = Sequence(
                Parallel(
                    LerpPosInterval(
                        self.letterboxBottom,
                        t,
                        pos=Vec3(0, 0, -1.2),
                        # startPos = Vec3(0, 0, -1),
                    ),
                    LerpPosInterval(
                        self.letterboxTop,
                        t,
                        pos=Vec3(0, 0, 1),
                        # startPos = Vec3(0, 0, 0.8),
                    ),
                ),
                Func(self.letterbox.stash),
                Func(messenger.send, 'letterboxOff'),
                name=self.letterboxTaskName,
            )
            if finishIval:
                self.letterboxIval.append(finishIval)
            self.letterboxIval.start()
Ejemplo n.º 9
0
class panda3dIOClass( DirectObject.DirectObject ):
  # set gui key to None if you want to call toggleConsole from outside this class
  gui_key = PANDA3D_CONSOLE_TOGGLE_KEY
  autocomplete_key = PANDA3D_CONSOLE_AUTOCOMPLETE_KEY
  autohelp_key = PANDA3d_CONSOLE_AUTOHELP_KEY
  # change size of text and number of characters on one line
  # scale of frame ( must be small (0.0x)
  scale = PANDA3D_CONSOLE_SCALE
  # to define a special font, if loading fails the default font is used (without warning)
  font = PANDA3D_CONSOLE_FONT
  fontWidth = PANDA3D_CONSOLE_FONT_WIDTH
  # frame position and size (vertical & horizontal)
  h_pos   = PANDA3D_CONSOLE_HORIZONTAL_POS
  h_size  = PANDA3D_CONSOLE_HORIZONTAL_SIZE
  # v_size + v_pos should not exceed 2.0, else parts of the interface will not be visible
  # space above the frame ( must be below 2.0, best between 0.0 and 1.0 )
  v_pos   = PANDA3D_CONSOLE_VERTICAL_POS
  # vertical size of the frame ( must be at max 2.0, best between 0.5 and 2.0 )
  v_size  = PANDA3D_CONSOLE_VERTICAL_SIZE
  linelength = int((h_size/scale - 5) / fontWidth)
  print "max number of characters on a length:", linelength
  numlines = int(v_size/scale - 5)
  defaultTextColor  = (0.0,0.0,0.0,1.0)
  autoCompleteColor = (0.9,0.4,0.2,1.0)
  def __init__( self, parent ):
    self.parent = parent
    
    # line wrapper
    self.linewrap = textwrap.TextWrapper()
    self.linewrap.width = self.linelength
    
    # calculate window size
    left   = (self.h_pos) / self.scale
    right  = (self.h_pos + self.h_size) / self.scale
    bottom = (self.v_pos) / self.scale
    top    = (self.v_pos + self.v_size) /self.scale
    
    # panda3d interface
    self.consoleFrame = DirectFrame ( relief = DGG.GROOVE
                                    , frameColor = (200, 200, 200, 0.5)
                                    , scale=self.scale
                                    , frameSize = (0, self.h_size / self.scale, 0, self.v_size / self.scale) )
    
    # vardis 27-02-2009: Added special cull bin in order to render on top of everything
    CullBinManager.getGlobalPtr().addBin(PanoConstants.CONSOLE_CULL_BIN_NAME, CullBinManager.BTUnsorted, PanoConstants.CONSOLE_CULL_BIN_VAL)
    self.consoleFrame.setBin("fixed", PanoConstants.RENDER_ORDER_CONSOLE)
    
    self.windowEvent( base.win )
    
    # try to load the defined font
    fixedWidthFont = loader.loadFont(parent.game.getResources().getResourceFullPath(PanoConstants.RES_TYPE_FONTS, self.font))
    # if font is not valid use default font
    if not fixedWidthFont.isValid():
      if self.font is None:
        print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(self.font)
      fixedWidthFont = DGG.getDefaultFont()
    
    # text entry line
    self.consoleEntry = DirectEntry ( self.consoleFrame
                                    , text        = ""
                                    , command     = self.onEnterPress
                                    , width       = self.h_size/self.scale - 2
                                    , pos         = (1, 0, 1.5)
                                    , initialText = ""
                                    , numLines    = 1
                                    , focus       = 1
                                    , entryFont   = fixedWidthFont)
    
    # output lines
    self.consoleOutputList = list()
    for i in xrange( self.numlines ):
      label = OnscreenText( parent = self.consoleFrame
                          , text = ""
                          , pos = (1, -i+3+self.numlines)
                          , align=TextNode.ALeft
                          , mayChange=1
                          , scale=1.0
                          , fg = self.defaultTextColor )
      label.setFont( fixedWidthFont )
      self.consoleOutputList.append( label )
    
    # list of the last commands of the user
    self.userCommandList = list()
    self.userCommandListLength = 100
    for i in xrange(self.userCommandListLength):
      self.userCommandList.append('')
    self.userCommandPos = 0
    
    # buffer for data
    self.textBuffer = list()
    self.textBufferLength = 1000
    for i in xrange(self.textBufferLength):
      self.textBuffer.append(['', DEFAULT_COLOR])
    self.textBufferPos = self.textBufferLength-self.numlines
    
    # toggle the window at least once to activate the events
    self.toggleConsole()
    self.toggleConsole()
    
    self.help()
  
  def help( self ):
    # output some info text about this module
    infoTxt = """ ------ Panda3dConsole ------
- press F1 to toggle it on/off
- use the usual copy, cut & paste keys
- page_up    : scrolls up
- page_down  : scrolls down
- arrow_up   : previous command
- arrow_down : next command
- BUGS       : if you paste a to long text, the entry blocks
         FIX : use cut to remove the whole line"""
    #for line in infoTxt.split('\n'):
    #  self.write( line, color=DEFAULT_COLOR )
    return infoTxt
  
  # write a string to the panda3d console
  def write( self, printString, color=defaultTextColor ):
    # remove not printable characters (which can be input by console input)
    printString = re.sub( r'[^%s]' % re.escape(string.printable[:95]), "", printString)
    
    splitLines = self.linewrap.wrap(printString)
    for line in splitLines:
      self.textBuffer.append( [line, color] )
      self.textBuffer.pop(0)
    
    self.updateOutput()
  
  def updateOutput( self ):
    for lineNumber in xrange(self.numlines):
      lineText, color = self.textBuffer[lineNumber + self.textBufferPos]
      self.consoleOutputList[lineNumber].setText( lineText )
      self.consoleOutputList[lineNumber]['fg'] = color
  
  # toggle the gui console
  def toggleConsole( self ):
    self.consoleFrame.toggleVis()
    hidden = self.consoleFrame.isHidden()
    self.consoleEntry['focus'] != hidden
    if hidden:
      self.ignoreAll()
#      self.accept( self.gui_key, self.toggleConsole )
    else:
      self.ignoreAll()
      self.accept( 'page_up', self.scroll, [-5] )
      self.accept( 'page_up-repeat', self.scroll, [-5] )
      self.accept( 'page_down', self.scroll, [5] )
      self.accept( 'page_down-repeat', self.scroll, [5] )
      self.accept( 'window-event', self.windowEvent)
      
      self.accept( 'arrow_up'  , self.scrollCmd, [ 1] )
      self.accept( 'arrow_down', self.scrollCmd, [-1] )
      
#      self.accept( self.gui_key, self.toggleConsole )
      self.accept( self.autocomplete_key, self.autocomplete )
      self.accept( self.autohelp_key, self.autohelp )
      
      # accept v, c and x, where c & x copy's the whole console text
      #messenger.toggleVerbose()
      #for osx use ('meta')
      if sys.platform == 'darwin':
        self.accept( 'meta', self.unfocus )
        self.accept( 'meta-up', self.focus )
        self.accept( 'meta-c', self.copy )
        self.accept( 'meta-x', self.cut )
        self.accept( 'meta-v', self.paste )
      #for windows use ('control')
      if sys.platform == 'win32' or sys.platform == 'linux2':
        self.accept( 'control', self.unfocus )
        self.accept( 'control-up', self.focus )
        self.accept( 'control-c', self.copy )
        self.accept( 'control-x', self.cut )
        self.accept( 'control-v', self.paste )
  
  def autocomplete( self ):
    currentText = self.consoleEntry.get()
    currentPos = self.consoleEntry.guiItem.getCursorPosition()
    newText = self.parent.autocomplete( currentText, currentPos )
    if newText != currentText:
      self.consoleEntry.set( newText )
      self.consoleEntry.setCursorPosition( len(newText) )
  
  def autohelp( self ):
    currentText = self.consoleEntry.get()
    currentPos = self.consoleEntry.guiItem.getCursorPosition()
    self.parent.autohelp( currentText, currentPos )
  
  def focus( self ):
    self.consoleEntry['focus'] = 1
  
  def unfocus( self ):
    self.consoleEntry['focus'] = 0
  
  def copy( self ):
    copy = self.consoleEntry.get()
    clipboard.setText( copy )
  
  def paste( self ):
    oldCursorPos = self.consoleEntry.guiItem.getCursorPosition()
    clipboardText = clipboard.getText()
    
    # compose new text line
    oldText = self.consoleEntry.get()
    newText = oldText[0:oldCursorPos] + clipboardText + oldText[oldCursorPos:]
    
    clipboardTextLines = newText.split(os.linesep)
    
    for i in xrange( len(clipboardTextLines)-1 ):
      currentLine = clipboardTextLines[i]
      # we only want printable characters
      currentLine = re.sub( r'[^' + re.escape(string.printable[:95]) + ']', "", currentLine)
      
      # set new text and position
      self.consoleEntry.set( currentLine )
      self.onEnterPress( currentLine )
    currentLine = clipboardTextLines[-1]
    currentLine = re.sub( r'[^' + re.escape(string.printable[:95]) + ']', "", currentLine)
    self.consoleEntry.set( currentLine )
    self.consoleEntry.setCursorPosition( len(self.consoleEntry.get()) )
    self.focus()
  
  def cut( self ):
    clipboard.setText( self.consoleEntry.get() )
    self.consoleEntry.enterText('')
    self.focus()
  
  def scroll( self, step ):
    self.textBufferPos += step
    self.textBufferPos = min( self.textBufferLength-self.numlines, max( 0, self.textBufferPos ) )
    self.updateOutput()
  
  def scrollCmd( self, step ):
    oldCmdPos = self.userCommandPos
    self.userCommandPos += step
    self.userCommandPos = min( self.userCommandListLength-1, max( 0, self.userCommandPos ) )
    self.userCommandList[oldCmdPos] = self.consoleEntry.get()
    newCmd = self.userCommandList[self.userCommandPos]
    self.consoleEntry.set( newCmd )
    self.consoleEntry.setCursorPosition( len(newCmd) )
  
  def onEnterPress( self, textEntered ):
    # set to last message
    self.textBufferPos = self.textBufferLength-self.numlines
    # clear line
    self.consoleEntry.enterText('')
    self.focus()
    # add text entered to user command list & remove oldest entry
    self.userCommandList.insert( 1, textEntered )
    self.userCommandList[0] = ''
    self.userCommandList.pop( -1 )
    self.userCommandPos = 0
    # call our parent
    self.parent.push( textEntered )
  
  def windowEvent( self, window ):
    """
    This is a special callback.
    It is called when the panda window is modified.
    """
    wp = window.getProperties()
    width = wp.getXSize() / float(wp.getYSize())
    height = wp.getYSize() / float(wp.getXSize())
    if width > height:
      height = 1.0
    else:
      width = 1.0
    # aligned to center
    consolePos = Vec3(-self.h_size/2, 0, -self.v_size/2)
    # aligned to left bottom
    #consolePos = Vec3(-width+self.h_pos, 0, -height+self.v_pos)
    # aligned to right top
    #consolePos = Vec3(width-self.h_size, 0, height-self.v_size)
    # set position
    self.consoleFrame.setPos( consolePos )
Ejemplo n.º 10
0
class DeathNotifications(DirectObject):
    
    MESSAGE_LIFE = 5
    MAX_NUM_MESSAGES = 10
    
    def __init__(self):
        self.textNodes = []
        
        self.rootFrame = DirectFrame(pos = (-0.05, 0, -0.25),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 1),
                                 parent = base.a2dTopRight)
        self.rootFrame.setBin('fixed', GUIOrder.ORDER[GUIOrder.CHAT])
        
        self.displayFrame = DirectFrame(pos = (0, 0, 0),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 0.42),
                                 parent = self.rootFrame)   
        
        self.accept(PlayerDeathEvent.EventName, self.OnPlayerDeathEvent)
        
    def OnPlayerDeathEvent(self, event):
        player = event.GetPlayer()
        attacker = event.GetAttacker()
        wasHS = event.WasHeadshot() 
        
        if(not attacker.currentItem):
            itemName = '???'
        else:
            itemName = attacker.currentItem.GetName()
        
        self.AddMessage(victimName = player.GetPlayerState().GetValue(PlayerState.NAME), 
                        attackerName = attacker.GetPlayerState().GetValue(PlayerState.NAME), 
                        itemName = itemName, 
                        attackerColor = Globals.TEAM_COLORS[attacker.GetPlayerState().GetValue(PlayerState.TEAM)], 
                        victimColor = Globals.TEAM_COLORS[player.GetPlayerState().GetValue(PlayerState.TEAM)])
        
    def AddMessage(self, victimName, attackerName, itemName, attackerColor = Globals.COLOR_WHITE, victimColor = Globals.COLOR_WHITE):
        parent = self.displayFrame.attachNewNode('messageParent')
        
        attackerTextNode = TextNode('attackerTextNode')
        attackerTextNode.setText(attackerName)
        attackerTextNode.setTextColor(attackerColor)
        attackerTextNode.setShadow(0.05, 0.05)
        attackerTextNode.setShadowColor(Globals.COLOR_BLACK)
        attackerTextNodePath = parent.attachNewNode(attackerTextNode)
        attackerTextNodePath.setScale(Settings.CHAT_HEIGHT)
        attackerTextNodePath.setPos(Vec3(-attackerTextNode.calcWidth('%s [%s] %s' % (attackerName, itemName, victimName)) * Settings.CHAT_HEIGHT, 0, 0))
        
        itemNameTextNode = TextNode('itemNameTextNode')
        itemNameTextNode.setText('[%s]' % (itemName))
        itemNameTextNode.setTextColor(Globals.COLOR_WHITE)
        itemNameTextNode.setShadow(0.05, 0.05)
        itemNameTextNode.setShadowColor(Globals.COLOR_BLACK)
        itemNameTextNodePath = parent.attachNewNode(itemNameTextNode)
        itemNameTextNodePath.setScale(Settings.CHAT_HEIGHT)
        itemNameTextNodePath.setPos(Vec3(-attackerTextNode.calcWidth('[%s] %s' % (itemName, victimName)) * Settings.CHAT_HEIGHT, 0, 0))
        
        victimTextNode = TextNode('prefixMessage')
        victimTextNode.setText(victimName)
        victimTextNode.setTextColor(victimColor)
        victimTextNode.setShadow(0.05, 0.05)
        victimTextNode.setShadowColor(Globals.COLOR_BLACK)
        victimTextNodePath = parent.attachNewNode(victimTextNode)
        victimTextNodePath.setScale(Settings.CHAT_HEIGHT)
        victimTextNodePath.setPos(Vec3(-attackerTextNode.calcWidth(victimName) * Settings.CHAT_HEIGHT, 0, 0))
        
        taskMgr.remove('HideMessageLog')
        taskMgr.doMethodLater(DeathNotifications.MESSAGE_LIFE, self.RemoveMessage, 'RemoveMessage', extraArgs = [parent]) 
                
        self.textNodes.append(parent)
        
        if(len(self.textNodes) > DeathNotifications.MAX_NUM_MESSAGES):
            self.RemoveMessage(self.textNodes[0])
            
        self.RedrawMessages()
        
    def RedrawMessages(self):
        n = len(self.textNodes)
        for i, textNode in enumerate(self.textNodes):
            LerpPosInterval(textNode, 0.5, (0, 0, -(n-i) * (Settings.CHAT_HEIGHT + 0.01))).start()
            
    def RemoveMessage(self, textNode):
        if(textNode in self.textNodes):
            self.textNodes.remove(textNode)
            textNode.removeNode()
    
    def Destroy(self):
        taskMgr.remove('HideMessageLog')
        self.rootFrame.destroy()
        self.entryFrame.destroy()
        self.chatarea.destroy()
        self.typeText.destroy()
        self.displayFrame.destroy()
        self.ignoreAll()
        
Ejemplo n.º 11
0
class LaffOMeter(DirectFrame):

    deathColor = Vec4(0.58039216, 0.80392157, 0.34117647, 1.0)

    def __init__(self, forRender=False):
        DirectFrame.__init__(self,
                             relief=None,
                             sortOrder=50,
                             parent=base.a2dBottomLeft)
        self.initialiseoptions(LaffOMeter)
        self.container = DirectFrame(parent=self, relief=None)
        self.container.setBin('gui-popup', 60)

        if forRender:
            self.container.setY(0)
            self.setLightOff()
            self.setFogOff()
            self.setMaterialOff()
            self.hide(CIGlobals.ShadowCameraBitmask)
        self.forRender = forRender

    def generate(self, r, g, b, animal, maxHP=50, initialHP=50):
        self.maxHP = maxHP
        self.initialHP = initialHP
        self.color = (r, g, b, 1)

        gui = loader.loadModel("phase_3/models/gui/laff_o_meter.bam")
        if animal == "rabbit":
            animal = "bunny"
        headmodel = gui.find('**/' + animal + 'head')
        self.container['image'] = headmodel
        self.container['image_color'] = self.color
        if animal == 'monkey':
            self.setPos(0.153, 0.0, 0.13)
        else:
            self.setPos(0.133, 0, 0.13)
        self.resetFrameSize()
        self.setScale(0.075)
        self.frown = DirectFrame(parent=self.container,
                                 relief=None,
                                 image=gui.find('**/frown'))
        self.smile = DirectFrame(parent=self.container,
                                 relief=None,
                                 image=gui.find('**/smile'))
        self.eyes = DirectFrame(parent=self.container,
                                relief=None,
                                image=gui.find('**/eyes'))
        self.openSmile = DirectFrame(parent=self.container,
                                     relief=None,
                                     image=gui.find('**/open_smile'))
        self.tooth1 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_1'))
        self.tooth2 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_2'))
        self.tooth3 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_3'))
        self.tooth4 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_4'))
        self.tooth5 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_5'))
        self.tooth6 = DirectFrame(parent=self.openSmile,
                                  relief=None,
                                  image=gui.find('**/tooth_6'))

        self.teethList = [
            self.tooth6, self.tooth5, self.tooth4, self.tooth3, self.tooth2,
            self.tooth1
        ]
        if self.forRender:
            self.container['image_pos'] = (0, 0.01, 0)
            for tooth in self.teethList:
                tooth.setDepthWrite(False)
            self.eyes.setDepthWrite(False)
            self.smile.setDepthWrite(False)
            self.openSmile.setDepthWrite(False)
            self.frown.setDepthWrite(False)
        self.fractions = [0.0, 0.166666, 0.333333, 0.5, 0.666666, 0.833333]

        self.currentHealthLbl = DirectLabel(text=str(self.initialHP),
                                            parent=self.eyes,
                                            pos=(-0.425, 0, 0.05),
                                            scale=0.4,
                                            relief=None)
        self.maxHealthLbl = DirectLabel(text=str(self.maxHP),
                                        parent=self.eyes,
                                        pos=(0.425, 0, 0.05),
                                        scale=0.4,
                                        relief=None)
        if self.forRender:
            self.currentHealthLbl.setY(-0.01)
            self.maxHealthLbl.setY(-0.01)

        self.updateMeter(self.initialHP)
        gui.removeNode()
        return

    def start(self):
        taskMgr.add(self.updateMeterTask, "updateMeterTask")

    def updateMeterTask(self, task):
        if hasattr(base, 'localAvatar'):
            if str(base.localAvatar.getHealth()
                   ) != self.currentHealthLbl['text']:
                self.updateMeter(base.localAvatar.getHealth())
        else:
            return task.done
        return task.cont

    def updateMeter(self, health):
        self.adjustFace(health)

    def adjustFace(self, health):
        self.frown.hide()
        self.smile.hide()
        self.openSmile.hide()
        self.eyes.hide()
        for tooth in self.teethList:
            tooth.hide()
        if health <= 0:
            self.frown.show()
            self.container['image_color'] = self.deathColor
        elif health >= self.maxHP:
            self.smile.show()
            self.eyes.show()
            self.container['image_color'] = self.color
        else:
            self.openSmile.show()
            self.eyes.show()
            self.maxHealthLbl.show()
            self.currentHealthLbl.show()
            self.container['image_color'] = self.color
            self.adjustTeeth(health)
        self.animatedEffect(health - self.initialHP)
        self.adjustText(health)

    def animatedEffect(self, delta):
        if delta == 0:
            return
        name = 'effect'
        if delta > 0:
            ToontownIntervals.start(
                ToontownIntervals.getPulseLargerIval(self.container, name))
        else:
            ToontownIntervals.start(
                ToontownIntervals.getPulseSmallerIval(self.container, name))

    def adjustTeeth(self, health):
        for i in xrange(len(self.teethList)):
            if health > self.maxHP * self.fractions[i]:
                self.teethList[i].show()
            else:
                self.teethList[i].hide()

    def adjustText(self, health):
        if self.maxHealthLbl['text'] != str(
                self.maxHP) or self.currentHealthLbl['text'] != str(health):
            self.currentHealthLbl['text'] = str(health)

    def stop(self):
        taskMgr.remove("updateMeterTask")

    def disable(self):
        if not hasattr(self, 'frown'):
            notify.warning("Won't disable LaffOMeter, no var named frown.")
            return
        self.frown.destroy()
        self.smile.destroy()
        self.eyes.destroy()
        self.openSmile.destroy()
        self.tooth1.destroy()
        self.tooth2.destroy()
        self.tooth3.destroy()
        self.tooth4.destroy()
        self.tooth5.destroy()
        self.tooth6.destroy()
        del self.frown
        del self.smile
        del self.eyes
        del self.openSmile
        del self.tooth1
        del self.tooth2
        del self.tooth3
        del self.tooth4
        del self.tooth5
        del self.tooth6
        self.container["image"] = None
        return

    def delete(self):
        self.container.destroy()
        del self.container
        return
Ejemplo n.º 12
0
class OptionsMenu(DirectObject):
    def __init__(self):
        """Default constructor"""
        # create a main frame as big as the window
        self.frameMain = DirectFrame(
            # set framesize the same size as the window
            frameSize=(base.a2dLeft, base.a2dRight, base.a2dTop,
                       base.a2dBottom),
            image="LogoTextGlow.png",
            image_scale=(1.06 / 2.0, 1, 0.7 / 2.0),
            image_pos=(0, 0, 0.7),
            # position center
            pos=(0, 0, 0),
            # set tramsparent background color
            frameColor=(0, 0, 0, 0))
        self.frameMain.setTransparency(1)
        self.frameMain.setBin("fixed", 100)

        sliderscale = 0.5
        buttonScale = 0.25
        textscale = 0.1
        checkboxscale = 0.05
        left = -0.5
        right = 0.5

        self.sliderTextspeed = DirectSlider(
            scale=sliderscale,
            pos=(left, 0, 0.2),
            range=(0.2, 0.01),
            scrollSize=0.01,
            text=_("Textspeed %0.1f%%") % (base.textWriteSpeed * 10),
            text_scale=textscale,
            text_align=TextNode.ACenter,
            text_pos=(0.0, 0.15),
            text_fg=(1, 1, 1, 1),
            thumb_frameColor=(0.65, 0.65, 0.0, 1),
            thumb_relief=DGG.FLAT,
            frameColor=(0.15, 0.15, 0.15, 1),
            value=base.textWriteSpeed,
            command=self.sliderTextspeed_ValueChanged)
        self.sliderTextspeed.reparentTo(self.frameMain)

        self.cbParticles = DirectCheckButton(
            text=_(" Enable Particles"),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 0.35),
            pos=(left, 0, -0.0),
            scale=checkboxscale,
            frameColor=(0, 0, 0, 0),
            command=self.cbParticles_CheckedChanged,
            rolloverSound=None,
            clickSound=None,
            pressEffect=False,
            boxPlacement="below",
            boxBorder=0.8,
            boxRelief=DGG.FLAT,
            indicator_scale=1.5,
            indicator_text_fg=(0.65, 0.65, 0.0, 1),
            indicator_text_shadow=(0, 0, 0, 0.35),
            indicator_frameColor=(0.15, 0.15, 0.15, 1),
            indicatorValue=base.particleMgrEnabled)
        self.cbParticles.indicator['text'] = (' ', 'x')
        self.cbParticles.indicator['text_pos'] = (0, 0.1)
        #self.cbParticles.indicator.setX(self.cbParticles.indicator, -0.5)
        #self.cbParticles.indicator.setZ(self.cbParticles.indicator, -0.1)
        #self.cbParticles.setFrameSize()
        self.cbParticles.setTransparency(1)
        self.cbParticles.reparentTo(self.frameMain)

        volume = base.musicManager.getVolume()
        self.sliderVolume = DirectSlider(
            scale=sliderscale,
            pos=(left, 0, -0.35),
            range=(0, 1),
            scrollSize=0.01,
            text=_("Volume %d%%") % volume * 100,
            text_scale=textscale,
            text_align=TextNode.ACenter,
            text_pos=(.0, 0.15),
            text_fg=(1, 1, 1, 1),
            thumb_frameColor=(0.65, 0.65, 0.0, 1),
            thumb_relief=DGG.FLAT,
            frameColor=(0.15, 0.15, 0.15, 1),
            value=volume,
            command=self.sliderVolume_ValueChanged)
        self.sliderVolume.reparentTo(self.frameMain)

        self.lblControltype = DirectLabel(text=_("Control type"),
                                          text_fg=(1, 1, 1, 1),
                                          text_shadow=(0, 0, 0, 0.35),
                                          frameColor=(0, 0, 0, 0),
                                          scale=textscale / 2,
                                          pos=(right, 0, 0.27))
        self.lblControltype.setTransparency(1)
        self.lblControltype.reparentTo(self.frameMain)
        selectedControlType = 0
        if base.controlType == "MouseAndKeyboard":
            selectedControlType = 1
        self.controltype = DirectOptionMenu(
            pos=(right, 0, 0.18),
            text_fg=(1, 1, 1, 1),
            scale=0.1,
            items=[_("Keyboard"), _("Keyboard + Mouse")],
            initialitem=selectedControlType,
            frameColor=(0.15, 0.15, 0.15, 1),
            popupMarker_frameColor=(0.65, 0.65, 0.0, 1),
            popupMarker_relief=DGG.FLAT,
            highlightColor=(0.65, 0.65, 0.0, 1),
            relief=DGG.FLAT,
            command=self.controlType_Changed)
        self.controltype.reparentTo(self.frameMain)
        b = self.controltype.getBounds()
        xPos = right - ((b[1] - b[0]) / 2.0 * 0.1)
        self.controltype.setX(xPos)
        setItems(self.controltype)
        self.controltype.setItems = setItems
        self.controltype.showPopupMenu = showPopupMenu
        self.controltype.popupMarker.unbind(DGG.B1PRESS)
        self.controltype.popupMarker.bind(DGG.B1PRESS, showPopupMenu)
        self.controltype.unbind(DGG.B1PRESS)
        self.controltype.bind(DGG.B1PRESS, showPopupMenuExtra,
                              [self.controltype])

        isChecked = not base.AppHasAudioFocus
        img = None
        if base.AppHasAudioFocus:
            img = "AudioSwitch_on.png"
        else:
            img = "AudioSwitch_off.png"
        self.cbVolumeMute = DirectCheckBox(
            text=_("Mute Audio"),
            text_scale=0.5,
            text_align=TextNode.ACenter,
            text_pos=(0.0, 0.65),
            text_fg=(1, 1, 1, 1),
            pos=(right, 0, -0.35),
            scale=0.21 / 2.0,
            command=self.cbVolumeMute_CheckedChanged,
            rolloverSound=None,
            clickSound=None,
            relief=None,
            pressEffect=False,
            isChecked=isChecked,
            image=img,
            image_scale=0.5,
            checkedImage="AudioSwitch_off.png",
            uncheckedImage="AudioSwitch_on.png")
        self.cbVolumeMute.setTransparency(1)
        self.cbVolumeMute.setImage()
        self.cbVolumeMute.reparentTo(self.frameMain)

        sensitivity = base.mouseSensitivity
        self.sliderSensitivity = DirectSlider(
            scale=sliderscale,
            pos=(right, 0, -0.075),
            range=(0.5, 2),
            scrollSize=0.01,
            text=_("Mouse Sensitivity %0.1fx") % sensitivity,
            text_scale=textscale,
            text_align=TextNode.ACenter,
            text_pos=(.0, 0.15),
            text_fg=(1, 1, 1, 1),
            thumb_frameColor=(0.65, 0.65, 0.0, 1),
            thumb_relief=DGG.FLAT,
            frameColor=(0.15, 0.15, 0.15, 1),
            value=sensitivity,
            command=self.sliderSensitivity_ValueChanged)
        self.sliderSensitivity.reparentTo(self.frameMain)
        if base.controlType == "Gamepad":
            self.sliderSensitivity.hide()

        # create the back button
        self.btnBack = DirectButton(
            scale=buttonScale,
            # position on the window
            pos=(0, 0, base.a2dBottom + 0.15),
            frameColor=(0, 0, 0, 0),
            # text properties
            text=_("Back"),
            text_scale=0.5,
            text_fg=(1, 1, 1, 1),
            text_pos=(0.0, -0.15),
            text_shadow=(0, 0, 0, 0.35),
            text_shadowOffset=(-0.05, -0.05),
            # sounds that should be played
            rolloverSound=None,
            clickSound=None,
            pressEffect=False,
            relief=None,
            # the event which is thrown on clickSound
            command=lambda: base.messenger.send("options_back"))
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(self.frameMain)

        self.hide()

    def show(self, enableResume=False):
        self.frameMain.show()

    def hide(self):
        self.frameMain.hide()

    def cbVolumeMute_CheckedChanged(self, checked):
        if checked:
            base.disableAllAudio()
        else:
            base.enableAllAudio()

    def sliderVolume_ValueChanged(self):
        volume = round(self.sliderVolume["value"], 2)
        self.sliderVolume["text"] = _("Volume %d%%") % int(volume * 100)
        base.sfxManagerList[0].setVolume(volume)
        base.musicManager.setVolume(volume)

    def sliderSensitivity_ValueChanged(self):
        sensitivity = round(self.sliderSensitivity["value"], 2)
        self.sliderSensitivity["text"] = _(
            "Mouse Sensitivity %0.1fx") % sensitivity
        base.mouseSensitivity = sensitivity

    def sliderTextspeed_ValueChanged(self):
        newSpeed = round(self.sliderTextspeed["value"], 2)
        displaySpeed = 1.0 / newSpeed
        self.sliderTextspeed["text"] = _("Textspeed %0.1f%%") % displaySpeed
        base.textWriteSpeed = newSpeed

    def cbParticles_CheckedChanged(self, unchecked):
        if unchecked:
            base.enableParticles()
        else:
            base.disableParticles()

    def controlType_Changed(self, arg):
        if arg == _("Keyboard"):
            self.sliderSensitivity.hide()
            base.controlType = "Gamepad"
        elif arg == _("Keyboard + Mouse"):
            self.sliderSensitivity.show()
            base.controlType = "MouseAndKeyboard"
Ejemplo n.º 13
0
class RewardPanel(DirectFrame):
    notify = directNotify.newCategory('RewardPanel')

    def __init__(self, panelData):
        dialogBox = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
        DirectFrame.__init__(self,
                             relief=None,
                             geom=dialogBox,
                             geom_color=CIGlobals.DialogColor,
                             geom_scale=(1.75, 1, 0.75 * 1.1),
                             geom_pos=Point3(0, 0, -0.05),
                             pos=(0, 0, 0.661))
        self.initialiseoptions(RewardPanel)
        self.setScale(0.8)

        # The data for the reward panel inside of a RPToonData object.
        self.panelData = panelData

        # Top wood panel saying Reward Panel
        gagShopNodes = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        # Original pos: (-0.02, 0, 0.3) scale = (1.55, 1, 1)
        self.titlePanel = OnscreenImage(
            parent=self,
            image=gagShopNodes.find('**/Goofys_Sign'),
            pos=(0, 0, 0.3),
            hpr=(1, 0, 0),
            scale=(1.3, 1, 0.9))

        self.avatarNamePanel = DirectFrame(parent=self.titlePanel,
                                           pos=(0, 0.005, 0))
        self.avatarText = OnscreenText(parent=self.avatarNamePanel,
                                       text='',
                                       font=CIGlobals.getMickeyFont(),
                                       fg=(0.698, 0.13, 0.13, 1),
                                       mayChange=1,
                                       scale=(0.1, 0.13, 0.1))

        self.panelContentsTitle = OnscreenText(parent=self,
                                               text=GagPanelName,
                                               font=CIGlobals.getMickeyFont(),
                                               pos=(0, 0.24, 0),
                                               fg=(0.3725, 0.619, 0.627, 1),
                                               mayChange=1)

        self.playerInfo = DirectFrame(parent=self,
                                      relief=None,
                                      pos=(-0.5, 0, 0))
        self.playerInfo.setBin('gui-popup', 0)

        self.bonusText = OnscreenText(parent=self.playerInfo,
                                      text='2X Cog Office Bonus!',
                                      font=CIGlobals.getToonFont(),
                                      pos=(0, 0.15, 0),
                                      scale=(0.055, 0.055, 0.055),
                                      align=TextNode.ACenter)
        self.bonusText.hide()

        ##################################################################################
        # GUI Elements relating to the Favorite Gag/Gag Popup Used for showing Gag Unlock#
        ##################################################################################
        self.favoriteGagText = OnscreenText(parent=self.playerInfo,
                                            text=FavoriteGag,
                                            font=CIGlobals.getMickeyFont(),
                                            pos=FavoriteGagTitlePos,
                                            fg=(1, 0.2, 0.2, 1),
                                            sort=0)

        glow = loader.loadModel('phase_4/models/minigames/particleGlow.bam')
        self.favoriteGagGlow = OnscreenImage(parent=self.playerInfo,
                                             image=glow,
                                             pos=FavoriteGagPos,
                                             color=GagGlowColor,
                                             scale=(0.8, 0.8, 0.8))
        self.favoriteGagGlow.setBin('gui-popup', 10)
        # particleGlow.bam uses a material since it's normally part of render, not render2d.
        # Since render2d is still fixed-function, we have to explicitly enable shader generation
        # to correctly display the glow in render2d.
        self.favoriteGagGlow.setShaderAuto()

        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(
            GagGlobals.InventoryIconByName.get(GagGlobals.Foghorn))
        self.favoriteGag = OnscreenImage(parent=self.playerInfo,
                                         image=gag,
                                         pos=FavoriteGagPos,
                                         scale=(1.65, 1.65, 1.65))
        self.favoriteGag.setBin('gui-popup', 20)

        self.favoriteGagName = OnscreenText(parent=self.playerInfo,
                                            text=GagGlobals.Foghorn,
                                            font=CIGlobals.getToonFont(),
                                            pos=FavoriteGagNamePos,
                                            mayChange=1)

        ################################################################################
        # GUI elements showing gag experience on the right-side of the gag exp panel   #
        ################################################################################

        self.gagExpFrame = DirectFrame(parent=self,
                                       relief=None,
                                       pos=(0.085, 0, 0.15))
        self.trackLabels = []
        self.trackIncLabels = []
        self.trackBars = []
        self.trackBarsOffset = 0

        for i in range(len(GagGlobals.TrackNameById.values())):
            track = GagGlobals.TrackNameById.values()[i]
            color = GagGlobals.TrackColorByName.get(track)
            label = DirectLabel(parent=self.gagExpFrame,
                                relief=None,
                                text=track.upper(),
                                text_scale=0.05,
                                text_align=TextNode.ARight,
                                pos=(0.13, 0, -0.09 * i),
                                text_pos=(0, -0.02))
            incrementLabel = DirectLabel(parent=self.gagExpFrame,
                                         relief=None,
                                         text='',
                                         text_scale=0.05,
                                         text_align=TextNode.ALeft,
                                         pos=(0.65, 0, -0.09 * i),
                                         text_pos=(0, -0.02))
            progressBar = DirectWaitBar(
                parent=self.gagExpFrame,
                relief=DGG.SUNKEN,
                frameSize=(-1, 1, -0.15, 0.15),
                borderWidth=(0.02, 0.02),
                scale=0.25,
                frameColor=(color[0] * 0.7, color[1] * 0.7, color[2] * 0.7, 1),
                barColor=(color[0], color[1], color[2], 1),
                text='0/0',
                text_scale=0.18,
                text_fg=(0, 0, 0, 1),
                text_align=TextNode.ACenter,
                text_pos=(0, -0.05),
                pos=(0.4, 0, -0.09 * i))
            self.trackLabels.append(label)
            self.trackIncLabels.append(incrementLabel)
            self.trackBars.append(progressBar)

        ################################################################################
        # GUI elements showing progress updates on quests                              #
        ################################################################################

        self.questFrame = DirectFrame(parent=self, relief=None)
        self.questPosters = []

        self.congratsLeft = OnscreenText(parent=self.playerInfo,
                                         pos=(-0.1, 0.125, -0.1),
                                         text='',
                                         scale=0.06,
                                         align=TextNode.ARight)
        self.congratsLeft.setR(-30)
        self.congratsRight = OnscreenText(parent=self.playerInfo,
                                          pos=(0.1, 0.125, 0.1),
                                          text='',
                                          scale=0.06,
                                          align=TextNode.ALeft)
        self.congratsRight.setR(30)

        glow.removeNode()
        invIcons.removeNode()
        gagShopNodes.removeNode()
        dialogBox.removeNode()

    def __getAvatarTextScale(self):
        totalWidth = self.avatarText.node().getWidth()
        panelWidth = 9.2
        defaultTextScale = 1.0

        scale = min(defaultTextScale,
                    defaultTextScale / (totalWidth / panelWidth))
        return (scale, scale, scale)

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def setPanelData(self, panelData):
        self.panelData = panelData
        self.avatarText['text'] = self.panelData.avatarName
        self.avatarNamePanel.setScale(self.__getAvatarTextScale())

        # Let's set the data for our gag experience here.
        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            bar = self.trackBars[i]
            bar['text'] = '%d/%d' % (track.exp, track.maxExp)

            # When the maximum experience of a track isn't 0, we know it isn't unlocked.
            if track.maxExp == -1:
                bar.hide()

            self.trackIncLabels[i]['text'] = ''
            self.trackIncLabels[i].show()

    def __chooseRewardShot(self, av):
        shotChoices = [(0, 8, av.getHeight() * 0.66, 179, 15, 0),
                       (5.2, 5.45, av.getHeight() * 0.66, 131.5, 3.6, 0)]
        shot = random.choice(shotChoices)
        return shot

    def getQuestsProgressInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        def toggleFavoriteGagItems(visible):
            for item in [
                    self.favoriteGag, self.favoriteGagGlow,
                    self.favoriteGagText, self.favoriteGagName
            ]:
                if not visible:
                    item.hide()
                else:
                    item.show()

        def setupQuestPosters():
            questManager = avatar.questManager
            numQuests = len(questManager.quests.values())

            yPos = 0.47

            displayData = {
                1: [[Point3(0.0, 0.0, yPos)], 0.88],
                2: [[Point3(-0.42, 0.0, yPos),
                     Point3(0.45, 0.0, yPos)], 0.88],
                3: [[
                    Point3(-0.57, 0.0, yPos),
                    Point3(0.0, 0.0, yPos),
                    Point3(0.57, 0.0, yPos)
                ], 0.70],
                4: [[
                    Point3(-0.32, 0.0, 0.62),
                    Point3(-0.32, 0.0, 0.30),
                    Point3(0.32, 0.0, 0.62),
                    Point3(0.32, 0.0, 0.30)
                ], 0.52]
            }

            # A full frame is a frame showing two quests at once.
            howManyFullFrames = math.ceil(numQuests / 2.0)
            howManyRemainderFrames = (numQuests - howManyFullFrames)

            for i, quest in enumerate(questManager.quests.values()):
                poster = QuestGlobals.generatePoster(quest,
                                                     parent=self.questFrame)
                poster.setScale(displayData.get(numQuests)[1])
                poster.setPos(displayData.get(numQuests)[0][i])
                poster.show()
                self.questPosters.append(poster)

        intervals.append(Func(self.gagExpFrame.hide))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Func(self.panelContentsTitle.setText,
                              QuestsPanelName))
        intervals.append(Func(toggleFavoriteGagItems, False))
        intervals.append(Func(setupQuestPosters))
        #intervals.append(Func(self.playerInfo.initialiseoptions, DirectFrame))

        return intervals

    def getGagExperienceInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        shot = self.__chooseRewardShot(avatar)

        intervals.append(Func(base.camera.reparentTo, avatar))
        intervals.append(Func(base.camera.setPosHpr, *shot))
        intervals.append(Func(self.congratsLeft.hide))
        intervals.append(Func(self.congratsRight.hide))
        intervals.append(Func(self.panelContentsTitle.setText, GagPanelName))
        intervals.append(Func(self.setFavoriteGag, self.panelData.favoriteGag))
        intervals.append(Func(self.gagExpFrame.show))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Wait(1.0))

        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            intervals.extend(self.getTrackIntervalList(track, i))

        return intervals

    def getNextExpValue(self, newValue, track):
        if newValue < track.maxExp or track.maxExp == 0:
            return track.maxExp
        else:
            levels = GagGlobals.TrackExperienceAmounts[track.name]
            index = levels.index(track.maxExp)

            if index + 1 < len(levels):
                return levels[index + 1]
            return -1

    def incrementExp(self, trackIndex, track, newValue):
        bar = self.trackBars[trackIndex]
        nextExp = GagGlobals.getMaxExperienceValue(newValue, track.name)
        oldValue = bar['value']
        color = GagGlobals.TrackColorByName.get(track.name)

        bar['text'] = '%d/%d' % (newValue, nextExp)
        bar['range'] = nextExp if not nextExp == -1 else newValue
        bar['value'] = newValue
        bar['barColor'] = (color[0], color[1], color[2], 1)

    def resetBarColor(self, trackIndex):
        color = GagGlobals.TrackColorByName.get(
            GagGlobals.TrackNameById.values()[trackIndex])
        self.trackBars[trackIndex]['barColor'] = (color[0] * 0.8,
                                                  color[1] * 0.8,
                                                  color[2] * 0.8, 1)

    def showTrackIncLabel(self, trackIndex, track, increment):
        label = self.trackIncLabels[trackIndex]

        # Only show increments when that track is unlocked.
        if track.exp != -1:
            label['text'] = '+%d' % increment
        label.show()

    def getTrackIntervalList(self, track, trackIndex):
        tickDelay = 1.0 / 60
        intervalList = []

        intervalList.append(
            Func(self.showTrackIncLabel, trackIndex, track, track.increment))

        barTime = 2.0 if track.exp > 0 else 0.25
        numTicks = int(math.ceil(barTime / tickDelay))
        for i in range(numTicks):
            t = (i + 1) / float(numTicks)
            newValue = int(track.exp + t * track.increment + 0.5)
            intervalList.append(
                Func(self.incrementExp, trackIndex, track, newValue))
            intervalList.append(Wait(tickDelay))

        intervalList.append(Func(self.resetBarColor, trackIndex))
        intervalList.append(Wait(0.2))

        if track.maxExp > 0 and (track.maxExp != GagGlobals.MaxedTrackExperiences.get(track.name) \
                    and (track.exp + track.increment) >= track.maxExp):
            gagIndex = GagGlobals.TrackExperienceAmounts.get(track.name).index(
                track.maxExp) + 1
            newGag = GagGlobals.TrackGagNamesByTrackName.get(
                track.name)[gagIndex]
            intervalList.append(
                self.getShowGagUnlockedInterval(track.name, newGag))

        return intervalList

    def getShowGagUnlockedInterval(self, track, gagName):
        seq = Sequence(
            Func(self.gagExpFrame.hide),
            Func(self.panelContentsTitle.setText, 'Gag Unlocked!'),
            Func(self.playerInfo.show), Func(self.setFavoriteGag, gagName),
            Func(self.favoriteGagName.setY, -0.35),
            Func(self.favoriteGagText.setY, 0.105),
            Func(self.favoriteGagText.setText, 'New %s Gag' % track),
            Func(self.bonusText.hide), Func(self.playerInfo.setPos, 0, 0, 0),
            Func(self.playerInfo.initialiseoptions, DirectFrame))
        seq.append(self.getCongratsInterval())
        seq.append(Wait(1.0))
        seq.append(self.getHideGagUnlockedInterval())
        seq.append(Func(self.gagExpFrame.show))
        seq.append(Wait(0.5))
        return seq

    def getHideGagUnlockedInterval(self):
        def correctPositioning(guiElement, pos):
            guiElement['pos'] = pos

        seq = Sequence(
            Func(self.panelContentsTitle.setText, GagPanelName),
            Func(self.setFavoriteGag, self.panelData.favoriteGag),
            Func(self.playerInfo.setX, -0.5),
            Func(correctPositioning, self.favoriteGagName, FavoriteGagNamePos),
            Func(self.favoriteGagText.setText, FavoriteGag),
            Func(correctPositioning, self.favoriteGagText,
                 FavoriteGagTitlePos), Func(self.congratsLeft.hide),
            Func(self.congratsRight.hide))

        return seq

    def __getRandomCongratsPair(self):
        msgs = list(NewGagCongratsMessages)

        msg = msgs[random.randint(0, len(msgs) - 1)]
        msgs.remove(msg)

        return (msg, msgs[random.randint(0, len(msgs) - 1)])

    def getCongratsInterval(self):
        msgs = self.__getRandomCongratsPair()
        self.congratsLeft['text'] = msgs[0]
        self.congratsRight['text'] = msgs[1]

        sfx = loader.loadSfx('phase_3/audio/sfx/GUI_balloon_popup.ogg')
        sfx.setLoop(False)
        sfx.setVolume(1.0)

        def makeSequence(text):
            seq = Sequence(Wait(1.0), Func(text.show))
            seq.append(Func(sfx.play))
            seq.append(
                CIGlobals.makePulseEffectInterval(text, 1.0, 0.01, 1.05, 0.5,
                                                  0.25))
            seq.append(Func(sfx.stop))
            return seq

        return Sequence(makeSequence(self.congratsLeft),
                        makeSequence(self.congratsRight))

    def setFavoriteGag(self, gagName):
        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(GagGlobals.InventoryIconByName.get(gagName))
        self.favoriteGagName.setText(gagName)
        self.favoriteGag['image'] = gag
        invIcons.removeNode()

    def destroy(self):
        if self.titlePanel:
            self.titlePanel.destroy()
        if self.avatarText:
            self.avatarText.destroy()
        if self.avatarNamePanel:
            self.avatarNamePanel.destroy()
        if self.panelContentsTitle:
            self.panelContentsTitle.destroy()
        if self.favoriteGag:
            self.favoriteGag.destroy()
        if self.favoriteGagGlow:
            self.favoriteGagGlow.destroy()
        if self.favoriteGagName:
            self.favoriteGagName.destroy()
        if self.playerInfo:
            self.playerInfo.destroy()
        if self.trackLabels:
            for label in self.trackLabels:
                label.destroy()
        if self.trackIncLabels:
            for label in self.trackIncLabels:
                label.destroy()
        if self.trackBars:
            for bar in self.trackBars:
                bar.destroy()
        if self.congratsLeft:
            self.congratsLeft.destroy()
        if self.congratsRight:
            self.congratsRight.destroy()
        if self.gagExpFrame:
            self.gagExpFrame.destroy()
        if self.panelData:
            self.panelData = None
        del self.titlePanel
        del self.avatarText
        del self.avatarNamePanel
        del self.panelContentsTitle
        del self.favoriteGag
        del self.favoriteGagGlow
        del self.favoriteGagName
        del self.playerInfo
        del self.trackLabels
        del self.trackIncLabels
        del self.trackBars
        del self.gagExpFrame
        del self.congratsLeft
        del self.congratsRight
        del self.panelData
        DirectFrame.destroy(self)
Ejemplo n.º 14
0
Archivo: ui.py Proyecto: tgbugs/desc
class GuiFrame(DirectObject, HasKeybinds):
    #should be able to show/hide, do conditional show hide
    #position where you want
    #parent to other frames
    TEXT_MAGIC_NUMBER = .833333333334  #5/6 ?!?
    DRAW_ORDER={
        'frame':('unsorted',0),
        'frame_bg':('unsorted', 0),
        'items':('unsorted', 0),
        'title':('unsorted', 0),
        'border':('unsorted', 0),
    }

    def __init__(self, title,
                 shortcut = None,  # XXX obsolete, but needs a non deco replacement
                 x = 0,
                 y = .1,
                 width = .2,
                 height = .8,
                 #scale = .05,  # there is some black magic here :/
                 bdr_thickness = 2,
                 bdr_color = (.1, .1, .1, 1),
                 bg_color = (.7, .7, .7, .5),
                 text_color = (0, 0, 0, 1),
                 text_font = TextNode.getDefaultFont(),
                 #text_h = .05,  # do not use directly
                 text_height_mm = 4,
                 items = tuple(),
                ):
        #item_w_pad = 1
        #item_h_pad = 1

        self.title = title
        self.do_xywh(x, y, width, height)
        self.bdr_thickness = bdr_thickness  # FIXME ??
        self.bdr_color = bdr_color
        self.bg_color = bg_color
        self.text_color = text_color
        self.text_font = text_font
        self.text_height_mm = text_height_mm

        #set up variables
        self.__winx__ = base.win.getXSize() 
        self.__winy__ = base.win.getYSize()
        self.__ar__ = base.camLens.getAspectRatio()
        self.__was_dragging__ = False
        self.__first_item__ = None
        self.__add_head__ = None
        self.items = OrderedDict()  # ordered dict to allow sequential addition

        #self.BT = buttonThrower if buttonThrower else base.buttonThrowers[0].node()
        self.BT = base.buttonThrowers[0].node()

        # get our aspect ratio, and pixels per mm
        self.pixels_per_mm = render.getPythonTag('system_data')['max_ppmm']
        self.getWindowData()
        self.accept('window-event', self.getWindowData)

        #set the text height using the above data
        self.setTextHeight()

        # get the root for all frames in the scene
        self.frameRoot = aspect2d.find('frameRoot')
        if not self.frameRoot:
            self.frameRoot = aspect2d.attachNewNode('frameRoot')

        # create the parent node for this frame
        #parent = self.frameRoot.find('frame-*')
        #if not parent:
            #parent = self.frameRoot
        self.frame = self.frameRoot.attachNewNode('frame-%s-%s'%(title, id(self)))
        self.frame.setBin(*self.DRAW_ORDER['frame'])

        # background
        l,r,b,t = 0, self.width, 0, self.height
        self.frame_bg = DirectFrame(parent=self.frame,
                                    frameColor=self.bg_color,
                                    pos=LVecBase3f(self.x, 0, self.y),
                                    frameSize=(l,r,b,t),
                                    state=DGG.NORMAL,  # FIXME framesize is >_<
                                    suppressMouse=1)
        self.frame_bg.setBin(*self.DRAW_ORDER['frame_bg'])

        # border
        self.__make_border__(self.frame_bg, self.bdr_thickness, self.bdr_color, l, r, b, t)

        # setup for items
        self.itemsParent = self.frame_bg.attachNewNode('items parent')

        # title
        self.title_button = self.__create_item__(title, self.title_toggle_vis)
        
        # add any items that we got
        for item in items:
            self.__create_item__(*item)  # FIXME when we call frame adjust we will loose the record of any data items

        # dragging
        self.title_button.bind(DGG.B1PRESS, self.__startDrag)
        self.title_button.bind(DGG.B1RELEASE, self.__stopDrag)

        # raise if we click the frame background
        self.frame_bg.bind(DGG.B1PRESS, self.raise_)
        #self.frame_bg.bind(DGG.B1RELEASE, self.__stopDrag)  # this can cause problems w/ was dragging


        # toggle vis
        if shortcut:
            self.accept(shortcut, self.toggle_vis)

        # adjust the frame
        self.frame_adjust()

    @property
    def text_s(self):
        return self.text_h * self.TEXT_MAGIC_NUMBER

    def setTextHeight(self):
        h_units = 2 * base.a2dTop
        units_per_pixel = h_units / self.__winy__
        text_h = self.text_height_mm * self.pixels_per_mm * units_per_pixel
        self.text_h = text_h

    def do_xywh(self, x, y, w, h):
        """ makes negative wneg xidths and heights work
            as well as negative x and y (bottom right is 0)
        """
        if x < 0:
            x = 1 + x
        if y < 0:
            y = 1 + y
        if w < 0:
            x, w = x + w, -w
        if h < 0:
            y, h = y + h, -h

        self.x = self.fix_x(x)  # for top left
        self.y = self.fix_y(y)  # for top left
        self.width = self.fix_w(w)
        self.height = self.fix_h(h)

    def getWindowData(self, window=None):
        x = base.win.getXSize() 
        y = base.win.getYSize()
        if x != self.__winx__ or y != self.__winy__:
            self.__ar__ = base.camLens.getAspectRatio()  # w/h
            self.__winx__ = x
            self.__winy__ = y
            self.frame_adjust()

    def raise_(self, *args):
        """ function that raises windows
            call FIRST inside any function that should raise
        """
        self.frame.reparentTo(self.frameRoot)  # self.frame doesn't move so no wrt

    def frame_adjust(self):  # FIXME sometimes this fails to call, also calls too often at startup
        self.setTextHeight()
        MI = self.getMaxItems()  # does not count title >_<
        LI = len(self.items)
        DI = MI - LI
        if DI >= 0:
            for i in range(DI+1):
                self.__create_item__(' blank')
        else:
            for i in range(-(DI+1)):
                k,v = self.items.popitem()  # remove the last nodes in order
                v.removeNode()  # FIXME consider keeping these around?

        for k,b in self.items.items():
            if k == 'title':
                if self.frame_bg.isHidden():
                    x, y, z = self.frame_bg.getPos()
                    self.title_button.setPos(LVecBase3f(x, y , z-self.text_h))
                else:
                    self.title_button.setPos(LVecBase3f(0, 0, -self.text_h))
            elif k == self.__first_item__:
                b.setPos(LVecBase3f(0, 0, -(self.text_h * 2)))
            else:
                b.setPos(LVecBase3f(0, 0, -self.text_h))
            b['frameSize'] = 0, self.width, 0, self.text_h
            b['text_scale'] = self.text_s, self.text_s
            b['text_pos'] = 0, self.text_h - self.TEXT_MAGIC_NUMBER * self.text_s
        
    def getWindowSize(self, event=None):  # TODO see if we really need this
        self.__winx__ = base.win.getXSize()
        self.__winy__ = base.win.getYSize()
        m = max(self.__winx__, self.__winy__)
        self.__xscale__ = self.__winx__ / m
        self.__yscale__ = self.__winy__ / m

    # put origin in top left and positive down and right
    @staticmethod
    def fix_x(x): return (x - .5) *  2  # TODO * base.a2dLeft?
    @staticmethod
    def fix_y(y): return (y - .5) * -2  # TODO * base.a2dTop?
    @staticmethod
    def fix_w(n): return  n * 2
    @staticmethod
    def fix_h(n): return -n * 2

    def add_item(self, text, command = None, args = tuple()): 
        args = list(args)
        if text[0] != ' ':
            text = ' '+text
        items = list(self.items)
        last_slot = len(self.items)
        if self.__add_head__ == last_slot:
            print('all slots are full, cannot add item to %s'%self)
            return None
        button = self.items[items[self.__add_head__]]
        button['text'] = text
        button['command'] = command
        button['extraArgs'] = args + button['extraArgs']  # blank buttons always have [self,id]
        self.__add_head__ += 1


    def __create_item__(self, text, command = None, args = tuple()): 
        args = list(args)

        #if not len(self.items):
            #parent = self.frame
        if len(self.items) <= 1:
            parent = self.itemsParent  #everyone else parents off 2nd text
        else:
            parent = list(self.items.values())[-1]

        if command != None:
            def cmd(*args):
                """ any item should raise
                """
                self.raise_()
                command(*args)
        else:
            cmd = self.raise_


        b = DirectButton(
            parent=parent,
            frameColor=(1,1,1,.0),  # a = 0 => no border overlap
            frameSize=(0, self.width, 0, self.text_h),
            text=' '+text,  # hack to keep spacing from border
            text_font=self.text_font,
            text_fg=self.text_color,
            text_scale=self.text_s,
            text_pos=(0, self.text_h - self.TEXT_MAGIC_NUMBER * self.text_s),
            command=cmd,
            relief=DGG.FLAT,
            text_align=TextNode.ALeft,
        )

        b.setPos(LVecBase3f(0, 0, -self.text_h))
        b.setName('DirectButton-'+text)
        if not len(self.items):
            self.items['title'] = b
            b.setBin(*self.DRAW_ORDER['title'])
        else:
            b['extraArgs'] = args+[self, id(b)]
            b.node().setPythonTag('id', id(b))
            b.setBin(*self.DRAW_ORDER['items'])
            if len(self.items) is 1:  # the first item that is not the title
                b.setPos(LVecBase3f(0, 0, -(self.text_h * 2)))
                self.__first_item__ = id(b)

            self.items[id(b)] = b

        if text == ' blank':
            if self.__add_head__ is None:
                self.__add_head__ = 1

        return b

    def del_all(self):
        if self.__first_item__ != None:
            for id_, button in self.items.items():
                if id_ != 'title':
                    button['text'] = ' blank'
                    button['command'] = None
                    button['extraArgs'] = [self, id_]
            self.__add_head__ = 1

    def del_item(self, text):  # FIXME uniqueness problems
        #d = self.itemsParent.find('*%s*'%text)
        if text[0] != ' ':
            text = ' '+text
        d = [i for i in self.items.values() if i.getName().count(text)]
        try:
            self.__del_item__(d[0].getPythonTag('id'))
        except IndexError:
            print('that item does not seem to exist')
            # if we have a name then there shouldn't be key errors

    def __del_item__(self, index):
        """ I have no idea how this is going to work """
        out = self.items[index]
        p = out.getParent()
        if out.getNumChildren():  # avoid the printing of the AssertionError :/
            c = out.getChild(0)
            c.reparentTo(p)
            if index == self.__first_item__:  # XXX is fails, ints from id !=
                c.setPos(LVecBase3f(out.getPos()))
                id_ = c.getPythonTag('id')
                self.__first_item__ = id_
                out.setPos(LVecBase3f(0, 0, -self.text_h))
        self.items.pop(index)
        parent = list(self.items.values())[-1]
        out['text'] = ' del blank'
        #out['command'] = None
        out['extraArgs'] = [self, index]
        out.reparentTo(parent)
        self.items[index] = out
        if self.__add_head__ > 1:  # title is always at 0
            self.__add_head__ -= 1

    @classmethod
    def __make_border__(cls, parent, thickness, color, l, r , b, t):
        moveto_drawto = (
           ((l,0,t), (l,0,b)),
           ((r,0,t), (r,0,b)),
           ((l,0,b), (r,0,b)),
           ((l,0,t), (r,0,t)),
        )
        for moveto, drawto in moveto_drawto:
            Border = LineSegs()
            Border.setThickness(thickness)
            Border.setColor(*color)
            Border.moveTo(*moveto)
            Border.drawTo(*drawto)
            b = parent.attachNewNode(Border.create())
            b.setBin(*cls.DRAW_ORDER['border'])

    def getMaxItems(self):
        return int(abs(self.height / self.text_h) - 1)

    @event_callback
    def toggle_vis(self):
        if self.frame_bg.isHidden():
            self.frame_bg.show()
            self.raise_()
        else:
            self.frame_bg.hide()

    def title_toggle_vis(self):
        if not self.__was_dragging__:
            self.toggle_vis()
            if self.frame_bg.isHidden():
                self.title_button.wrtReparentTo(self.frame)
                self.title_button['frameColor'] = (1, 1, 1, .5)  # TODO
            else:
                self.title_button.wrtReparentTo(self.frame_bg)
                self.title_button['frameColor'] = (1, 1, 1, 0)  # TODO
        else:
            self.__was_dragging__ = False

    def __startDrag(self, crap):
        self.raise_()
        self._ox, self._oy = base.mouseWatcherNode.getMouse()
        taskMgr.add(self.__drag,'dragging %s'%self.title)
        self.origBTprefix=self.BT.getPrefix()
        self.BT.setPrefix('dragging frame')

    def __drag(self, task):
        if base.mouseWatcherNode.hasMouse():
            x, y = base.mouseWatcherNode.getMouse()
            if x != self._ox or y != self._oy:
                m_old = aspect2d.getRelativePoint(render2d, Point3(self._ox, self._oy, 0))
                m_new = aspect2d.getRelativePoint(render2d, Point3(x, y, 0))
                dx, dy, _ = m_new - m_old
                self.setPos(self.x + dx, self.y + dy)
                self._ox = x
                self._oy = y
                self.__was_dragging__ = True
        return task.cont

    def __stopDrag(self,crap):
        taskMgr.remove('dragging %s'%self.title)
        self.BT.setPrefix(self.origBTprefix)

    def setPos(self, x, y):
        """ actually sets the title button position
            since it is really the parent node
        """
        self.x = x
        self.y = y #- self.text_h  # FIXME is hard :/
        self.frame_bg.setPos(LVecBase3f(x, 0, y))
        if self.frame_bg.isHidden():
            self.title_button.setPos(LVecBase3f(x, 0, y - self.text_h))


    def __enter__(self):
        #load the position
        #load other saved state
        pass

    def __exit__(self):
        #save the position!
        #save other state
        pass
Ejemplo n.º 15
0
class GuiUnitInfo:
    def __init__(self, offset, parent, unit_type, default_hp, hp, default_ap, ap):
            
        self.offset = offset
        self.frame = DirectFrame(   relief = DGG.FLAT
                                  , scale = 1
                                  , frameSize = (-0.5, 0.5, 0, -0.5)
                                  , parent = parent )
        self.frame.setBillboardPointEye()
        self.frame.setLightOff()
        self.frame.setBin("fixed", 40)
        self.frame.setDepthTest(False)
        self.frame.setDepthWrite(False)
        
        fixedWidthFont = loader.loadFont(GUI_FONT)#@UndefinedVariable        
        #fixedWidthFont.setPixelsPerUnit(60)
        #fixedWidthFont.setRenderMode(fontt.RMSolid)
        if not fixedWidthFont.isValid():
            print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(self.font)
            fixedWidthFont = DGG.getDefaultFont()
        
        self.label = OnscreenText( parent = self.frame
                              , text = ""
                              , pos = (offset.getX(),offset.getZ()+0.1)
                              , align=TextNode.ACenter
                              , mayChange=True
                              , scale=0.1
                              , fg = (1,0,0,1)
                              #, shadow = (0, 0, 0, 1)
                              #, frame = (200,0,0,1) 
                              )
        self.label.setFont( fixedWidthFont )
        #self.label.setLightOff()

        self.all_icons = {}
        self.visible_icons = {}
        self.addIcon("overwatch")
        self.addIcon("set_up")
        
        self.ap_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_ap
                                  , value = ap
                                  , pos = (offset.getX()+0.08,0,offset.getZ()-0.27)
                                  , barColor = (0,0,1,1)
                                  , frameColor = (0,0,0.5,0.2)
                                  , scale = (0.3,0.5,0.3))
        
        self.hp_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_hp
                                  , value = hp
                                  , pos = (offset.getX()+0.08,0,offset.getZ()-0.2)
                                  , barColor = (0,1,0,1)
                                  , frameColor = (1,0,0,0.9)
                                  , scale = (0.3,0.5,0.3))
        
        self.insignia = OnscreenImage(parent = self.frame
                                            ,image = "unit_" + unit_type + "_big_transparent_32.png"
                                            #,pos = (offset.getX(),0,offset.getZ()+0.14)
                                            , pos = (offset.getX() - 0.31,0,offset.getZ()-0.23)
                                            ,scale = 0.09)
        self.insignia.setTransparency(TransparencyAttrib.MAlpha)

    def addIcon(self, name):
        self.all_icons[name] = OnscreenImage(parent = self.frame
                                            ,image = name + "_icon.png"
                                           #,pos = offset + (0,0,-0.1)
                                            ,scale = 0.08)
        
        self.all_icons[name].setTransparency(TransparencyAttrib.MAlpha)
        self.all_icons[name].hide()
        
    def write(self, text):
        text = ""
        self.label.setText(text)
        
    def redraw(self):
        return

    def remove(self):
        self.frame.remove()
        
    def reparentTo(self, parent):
        self.frame.reparentTo(parent)
        
    def hide(self):
        self.label.hide()
        
    def show(self):
        self.label.show()
    
    def refreshBars(self, hp, ap):
        self.ap_bar['value'] = ap
        self.hp_bar['value'] = hp
        self.ap_bar.setValue()
        self.hp_bar.setValue()
        
    def refreshIcons(self):
        count = len(self.visible_icons)
        start_pos =  (1 - count) * 0.25 / 2
        for icon in self.all_icons:
            if icon in self.visible_icons:
                self.visible_icons[icon].setPos(self.offset + (start_pos, 0, -0.08))
                self.visible_icons[icon].show()
                start_pos += 0.21
            else:
                self.all_icons[icon].hide()
            
    def hideOverwatch(self):
        if "overwatch" in self.visible_icons:
            self.visible_icons.pop("overwatch")
        self.refreshIcons()

    def showOverwatch(self):
        self.visible_icons["overwatch"] = self.all_icons["overwatch"]
        self.refreshIcons()
    
    def hideSetUp(self):
        if "set_up" in self.visible_icons:
            self.visible_icons.pop("set_up")
        self.refreshIcons()

    def showSetUp(self):
        self.visible_icons["set_up"] = self.all_icons["set_up"]
        self.refreshIcons()
Ejemplo n.º 16
0
class FinalScoreGUI:
    notify = directNotify.newCategory('FinalScoreGUI')

    def __init__(self):
        self.finalScoreBg = None
        self.finalScoreTitle = None
        self.finalScoreNameLbl = None
        self.finalScorePointLbl = None
        self.finalScoreContainer = None
        self.finalScores = []
        return

    def load(self):
        font = CIGlobals.getToonFont()
        box = DGG.getDefaultDialogGeom()
        self.finalScoreContainer = DirectFrame()
        self.finalScoreBg = OnscreenImage(image=box, color=(1, 1, 0.75, 1), scale=(1.9, 1.4, 1.4), parent=self.finalScoreContainer)
        self.finalScoreTitle = OnscreenText(text='Waiting for final scores...', pos=(0, 0.5, 0), font=font, scale=0.12, parent=self.finalScoreContainer)
        self.finalScoreNameLbl = OnscreenText(text='', scale=0.095, pos=(-0.85, 0.3, 0), font=font, align=TextNode.ALeft, parent=self.finalScoreContainer)
        self.finalScorePointLbl = OnscreenText(text='', scale=0.095, pos=(0.85, 0.3, 0), font=font, align=TextNode.ARight, parent=self.finalScoreContainer)
        self.finalScoreContainer.hide()
        self.finalScoreContainer.setBin('gui-popup', 60)
        del font
        del box

    def unload(self):
        if self.finalScoreContainer:
            self.finalScoreContainer.destroy()
            self.finalScoreContainer = None
        if self.finalScoreBg:
            self.finalScoreBg.destroy()
            self.finalScoreBg = None
        if self.finalScoreTitle:
            self.finalScoreTitle.destroy()
            self.finalScoreTitle = None
        if self.finalScoreNameLbl:
            self.finalScoreNameLbl.destroy()
            self.finalScoreNameLbl = None
        if self.finalScorePointLbl:
            self.finalScorePointLbl.destroy()
            self.finalScorePointLbl = None
        return

    def showFinalScores(self):
        self.finalScoreContainer.show()
        base.transitions.fadeScreen(0.5)

    def hideFinalScores(self):
        base.transitions.noTransitions()
        self.finalScoreContainer.hide()

    def handleFinalScores(self, avIdList, scoreList):
        for avId in avIdList:
            score = scoreList[avIdList.index(avId)]
            scoreObj = FinalScore(avId, score)
            self.finalScores.append(scoreObj)

        self.finalScores.sort(key=lambda x: x.score, reverse=True)
        for scoreObj in self.finalScores:
            name = base.cr.doId2do.get(scoreObj.avId).getName()
            self.finalScoreNameLbl['text'] += name + '\n'
            self.finalScorePointLbl['text'] += str(scoreObj.score) + ' Points\n'

        self.finalScoreTitle['text'] = 'Final Scores'
Ejemplo n.º 17
0
class ChatBox(DirectObject):
    
    MESSAGE_LIFE = 10
    MAX_NUM_MESSAGES = 15
    
    (TYPE_GLOBAL,
     TYPE_TEAM,
     TYPE_CONSOLE) = range(3)
     
    messageTypeToPrefix = { TYPE_GLOBAL : 'Global:', 
                            TYPE_TEAM : 'Team:',
                            TYPE_CONSOLE : 'Console' }
    
    def __init__(self):
        self.textNodes = []
        self.messageType = None
        
        self.rootFrame = DirectFrame(pos = (0.03, 0, 0.2),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 1),
                                 parent = base.a2dBottomLeft)
        self.rootFrame.setBin('fixed', GUIOrder.ORDER[GUIOrder.CHAT])
        
        self.entryFrame = DirectFrame(pos = (0, 0, 0),
                                 frameColor = (0, 0, 0, 0.1),
                                 frameSize = (0, 1, 0, 0.1),
                                 parent = self.rootFrame)
        
        self.chatarea = DirectEntry(width = 27,
                                    scale = Settings.CHAT_HEIGHT,
                                    pos = (0, 0, 0),
                                    frameColor = (0, 0, 0, 0),
                                    text_fg = (1, 1, 1, 1),
                                    numLines = 1,
                                    cursorKeys = 1,
                                    rolloverSound = None,
                                    clickSound = None,
                                    focus = 0,
                                    command = self.OnChatEntered,
                                    parent = self.entryFrame)
        
        self.typeText = OnscreenText(text = '', 
                                     pos = (0, Settings.CHAT_HEIGHT + 0.01), 
                                     scale = Settings.CHAT_HEIGHT,
                                     fg = (1, 1, 1, 1),
                                     mayChange = True,
                                     align = TextNode.ALeft,
                                     parent = self.entryFrame)
        
        self.displayFrame = DirectFrame(pos = (0, 0, 0.1),
                                 frameColor = (0, 0, 0, 0),
                                 frameSize = (0, 1, 0, 0.42),
                                 parent = self.rootFrame)
        
        self.chatarea.enterText('')
        self.entryFrame.hide()
        self.chatarea['focus'] = 0
        self.chatarea.setFocus()    
        
    def OnChatEntered(self, enteredText):
        enteredText = enteredText.strip()
        self.Hide()
        if(len(enteredText) > 0):
            ChatEnteredEvent(self.messageType, enteredText).Fire()
        
    def AddMessage(self, prefix, prefixColor, message):
        parent = self.displayFrame.attachNewNode('messageParent')
        
        prefixTextNode = TextNode('prefixMessage')
        prefixTextNode.setText(prefix)
        prefixTextNode.setTextColor(prefixColor)
        prefixTextNode.setShadow(0.05, 0.05)
        prefixTextNode.setShadowColor(Globals.COLOR_BLACK)
        prefixTextNodePath = parent.attachNewNode(prefixTextNode)
        prefixTextNodePath.setScale(Settings.CHAT_HEIGHT)
        
        messageTextNode = TextNode('prefixMessage')
        messageTextNode.setText(message)
        messageTextNode.setTextColor(1, 1, 1, 1)
        messageTextNode.setShadow(0.05, 0.05)
        messageTextNode.setShadowColor(Globals.COLOR_BLACK)
        messageTextNodePath = parent.attachNewNode(messageTextNode)
        messageTextNodePath.setScale(Settings.CHAT_HEIGHT)
        messageTextNodePath.setPos(Vec3(prefixTextNode.calcWidth(prefix) * Settings.CHAT_HEIGHT, 0, 0))
        
        taskMgr.remove('HideMessageLog')
        taskMgr.doMethodLater(ChatBox.MESSAGE_LIFE, self.HideMessageLog, 'HideMessageLog') 
        self.ShowMessageLog()
        
        self.textNodes.append(parent)
        
        if(len(self.textNodes) > ChatBox.MAX_NUM_MESSAGES):
            self.RemoveMessage(self.textNodes[0])
            
        self.RedrawMessages()
        
    def RedrawMessages(self):
        n = len(self.textNodes)
        for i, textNode in enumerate(self.textNodes):
            LerpPosInterval(textNode, 0.5, (0, 0, (n-i) * (Settings.CHAT_HEIGHT + 0.01))).start()
            
    def RemoveMessage(self, textNode):
        self.textNodes.remove(textNode)
        textNode.removeNode()
        
    def HideMessageLog(self, task = None):
        self.displayFrame.hide()
        
    def ShowMessageLog(self):
        self.displayFrame.show()
        
    def Hide(self):
        self.chatarea.enterText('')
        self.entryFrame.hide()
        self.chatarea['focus'] = 0
        self.chatarea.setFocus()
        self.HideMessageLog()
        ChatCloseEvent().Fire()
        
    def Show(self, messageType):
        self.messageType = messageType
        self.entryFrame.show()
        self.chatarea['focus'] = 1
        self.chatarea.setFocus()
        self.typeText.setText(ChatBox.GetPrefix(self.messageType))
        self.ShowMessageLog()
        ChatOpenEvent().Fire()
        
    def EnableKeyboardListening(self):
        self.acceptOnce('escape', self.Hide)
        
    def DisableKeyboardListening(self):
        self.ignoreAll()
        
    @staticmethod
    def GetPrefix(messageType):
        return ChatBox.messageTypeToPrefix[messageType]
    
    def Destroy(self):
        taskMgr.remove('HideMessageLog')
        self.rootFrame.destroy()
        self.entryFrame.destroy()
        self.chatarea.destroy()
        self.typeText.destroy()
        self.displayFrame.destroy()
        self.ignoreAll()
        
Ejemplo n.º 18
0
class GuiFrame(DirectObject, HasKeybinds):
    #should be able to show/hide, do conditional show hide
    #position where you want
    #parent to other frames
    TEXT_MAGIC_NUMBER = .833333333334  #5/6 ?!?
    DRAW_ORDER = {
        'frame': ('unsorted', 0),
        'frame_bg': ('unsorted', 0),
        'items': ('unsorted', 0),
        'title': ('unsorted', 0),
        'border': ('unsorted', 0),
    }

    def __init__(
            self,
            title,
            shortcut=None,  # XXX obsolete, but needs a non deco replacement
            x=0,
            y=.1,
            width=.2,
            height=.8,
            #scale = .05,  # there is some black magic here :/
            bdr_thickness=2,
            bdr_color=(.1, .1, .1, 1),
            bg_color=(.7, .7, .7, .5),
            text_color=(0, 0, 0, 1),
            text_font=TextNode.getDefaultFont(),
            #text_h = .05,  # do not use directly
            text_height_mm=4,
            items=tuple(),
    ):
        #item_w_pad = 1
        #item_h_pad = 1

        self.title = title
        self.do_xywh(x, y, width, height)
        self.bdr_thickness = bdr_thickness  # FIXME ??
        self.bdr_color = bdr_color
        self.bg_color = bg_color
        self.text_color = text_color
        self.text_font = text_font
        self.text_height_mm = text_height_mm

        #set up variables
        self.__winx__ = base.win.getXSize()
        self.__winy__ = base.win.getYSize()
        self.__ar__ = base.camLens.getAspectRatio()
        self.__was_dragging__ = False
        self.__first_item__ = None
        self.__add_head__ = None
        self.items = OrderedDict()  # ordered dict to allow sequential addition

        #self.BT = buttonThrower if buttonThrower else base.buttonThrowers[0].node()
        self.BT = base.buttonThrowers[0].node()

        # get our aspect ratio, and pixels per mm
        self.pixels_per_mm = render.getPythonTag('system_data')['max_ppmm']
        self.getWindowData()
        self.accept('window-event', self.getWindowData)

        #set the text height using the above data
        self.setTextHeight()

        # get the root for all frames in the scene
        self.frameRoot = aspect2d.find('frameRoot')
        if not self.frameRoot:
            self.frameRoot = aspect2d.attachNewNode('frameRoot')

        # create the parent node for this frame
        #parent = self.frameRoot.find('frame-*')
        #if not parent:
        #parent = self.frameRoot
        self.frame = self.frameRoot.attachNewNode('frame-%s-%s' %
                                                  (title, id(self)))
        self.frame.setBin(*self.DRAW_ORDER['frame'])

        # background
        l, r, b, t = 0, self.width, 0, self.height
        self.frame_bg = DirectFrame(
            parent=self.frame,
            frameColor=self.bg_color,
            pos=LVecBase3f(self.x, 0, self.y),
            frameSize=(l, r, b, t),
            state=DGG.NORMAL,  # FIXME framesize is >_<
            suppressMouse=1)
        self.frame_bg.setBin(*self.DRAW_ORDER['frame_bg'])

        # border
        self.__make_border__(self.frame_bg, self.bdr_thickness, self.bdr_color,
                             l, r, b, t)

        # setup for items
        self.itemsParent = self.frame_bg.attachNewNode('items parent')

        # title
        self.title_button = self.__create_item__(title, self.title_toggle_vis)

        # add any items that we got
        for item in items:
            self.__create_item__(
                *item
            )  # FIXME when we call frame adjust we will loose the record of any data items

        # dragging
        self.title_button.bind(DGG.B1PRESS, self.__startDrag)
        self.title_button.bind(DGG.B1RELEASE, self.__stopDrag)

        # raise if we click the frame background
        self.frame_bg.bind(DGG.B1PRESS, self.raise_)
        #self.frame_bg.bind(DGG.B1RELEASE, self.__stopDrag)  # this can cause problems w/ was dragging

        # toggle vis
        if shortcut:
            self.accept(shortcut, self.toggle_vis)

        # adjust the frame
        self.frame_adjust()

    @property
    def text_s(self):
        return self.text_h * self.TEXT_MAGIC_NUMBER

    def setTextHeight(self):
        h_units = 2 * base.a2dTop
        units_per_pixel = h_units / self.__winy__
        text_h = self.text_height_mm * self.pixels_per_mm * units_per_pixel
        self.text_h = text_h

    def do_xywh(self, x, y, w, h):
        """ makes negative wneg xidths and heights work
            as well as negative x and y (bottom right is 0)
        """
        if x < 0:
            x = 1 + x
        if y < 0:
            y = 1 + y
        if w < 0:
            x, w = x + w, -w
        if h < 0:
            y, h = y + h, -h

        self.x = self.fix_x(x)  # for top left
        self.y = self.fix_y(y)  # for top left
        self.width = self.fix_w(w)
        self.height = self.fix_h(h)

    def getWindowData(self, window=None):
        x = base.win.getXSize()
        y = base.win.getYSize()
        if x != self.__winx__ or y != self.__winy__:
            self.__ar__ = base.camLens.getAspectRatio()  # w/h
            self.__winx__ = x
            self.__winy__ = y
            self.frame_adjust()

    def raise_(self, *args):
        """ function that raises windows
            call FIRST inside any function that should raise
        """
        self.frame.reparentTo(
            self.frameRoot)  # self.frame doesn't move so no wrt

    def frame_adjust(
        self
    ):  # FIXME sometimes this fails to call, also calls too often at startup
        self.setTextHeight()
        MI = self.getMaxItems()  # does not count title >_<
        LI = len(self.items)
        DI = MI - LI
        if DI >= 0:
            for i in range(DI + 1):
                self.__create_item__(' blank')
        else:
            for i in range(-(DI + 1)):
                k, v = self.items.popitem()  # remove the last nodes in order
                v.removeNode()  # FIXME consider keeping these around?

        for k, b in self.items.items():
            if k == 'title':
                if self.frame_bg.isHidden():
                    x, y, z = self.frame_bg.getPos()
                    self.title_button.setPos(LVecBase3f(x, y, z - self.text_h))
                else:
                    self.title_button.setPos(LVecBase3f(0, 0, -self.text_h))
            elif k == self.__first_item__:
                b.setPos(LVecBase3f(0, 0, -(self.text_h * 2)))
            else:
                b.setPos(LVecBase3f(0, 0, -self.text_h))
            b['frameSize'] = 0, self.width, 0, self.text_h
            b['text_scale'] = self.text_s, self.text_s
            b['text_pos'] = 0, self.text_h - self.TEXT_MAGIC_NUMBER * self.text_s

    def getWindowSize(self, event=None):  # TODO see if we really need this
        self.__winx__ = base.win.getXSize()
        self.__winy__ = base.win.getYSize()
        m = max(self.__winx__, self.__winy__)
        self.__xscale__ = self.__winx__ / m
        self.__yscale__ = self.__winy__ / m

    # put origin in top left and positive down and right
    @staticmethod
    def fix_x(x):
        return (x - .5) * 2  # TODO * base.a2dLeft?

    @staticmethod
    def fix_y(y):
        return (y - .5) * -2  # TODO * base.a2dTop?

    @staticmethod
    def fix_w(n):
        return n * 2

    @staticmethod
    def fix_h(n):
        return -n * 2

    def add_item(self, text, command=None, args=tuple()):
        args = list(args)
        if text[0] != ' ':
            text = ' ' + text
        items = list(self.items)
        last_slot = len(self.items)
        if self.__add_head__ == last_slot:
            print('all slots are full, cannot add item to %s' % self)
            return None
        button = self.items[items[self.__add_head__]]
        button['text'] = text
        button['command'] = command
        button['extraArgs'] = args + button[
            'extraArgs']  # blank buttons always have [self,id]
        self.__add_head__ += 1

    def __create_item__(self, text, command=None, args=tuple()):
        args = list(args)

        #if not len(self.items):
        #parent = self.frame
        if len(self.items) <= 1:
            parent = self.itemsParent  #everyone else parents off 2nd text
        else:
            parent = list(self.items.values())[-1]

        if command != None:

            def cmd(*args):
                """ any item should raise
                """
                self.raise_()
                command(*args)
        else:
            cmd = self.raise_

        b = DirectButton(
            parent=parent,
            frameColor=(1, 1, 1, .0),  # a = 0 => no border overlap
            frameSize=(0, self.width, 0, self.text_h),
            text=' ' + text,  # hack to keep spacing from border
            text_font=self.text_font,
            text_fg=self.text_color,
            text_scale=self.text_s,
            text_pos=(0, self.text_h - self.TEXT_MAGIC_NUMBER * self.text_s),
            command=cmd,
            relief=DGG.FLAT,
            text_align=TextNode.ALeft,
        )

        b.setPos(LVecBase3f(0, 0, -self.text_h))
        b.setName('DirectButton-' + text)
        if not len(self.items):
            self.items['title'] = b
            b.setBin(*self.DRAW_ORDER['title'])
        else:
            b['extraArgs'] = args + [self, id(b)]
            b.node().setPythonTag('id', id(b))
            b.setBin(*self.DRAW_ORDER['items'])
            if len(self.items) is 1:  # the first item that is not the title
                b.setPos(LVecBase3f(0, 0, -(self.text_h * 2)))
                self.__first_item__ = id(b)

            self.items[id(b)] = b

        if text == ' blank':
            if self.__add_head__ is None:
                self.__add_head__ = 1

        return b

    def del_all(self):
        if self.__first_item__ != None:
            for id_, button in self.items.items():
                if id_ != 'title':
                    button['text'] = ' blank'
                    button['command'] = None
                    button['extraArgs'] = [self, id_]
            self.__add_head__ = 1

    def del_item(self, text):  # FIXME uniqueness problems
        #d = self.itemsParent.find('*%s*'%text)
        if text[0] != ' ':
            text = ' ' + text
        d = [i for i in self.items.values() if i.getName().count(text)]
        try:
            self.__del_item__(d[0].getPythonTag('id'))
        except IndexError:
            print('that item does not seem to exist')
            # if we have a name then there shouldn't be key errors

    def __del_item__(self, index):
        """ I have no idea how this is going to work """
        out = self.items[index]
        p = out.getParent()
        if out.getNumChildren():  # avoid the printing of the AssertionError :/
            c = out.getChild(0)
            c.reparentTo(p)
            if index == self.__first_item__:  # XXX is fails, ints from id !=
                c.setPos(LVecBase3f(out.getPos()))
                id_ = c.getPythonTag('id')
                self.__first_item__ = id_
                out.setPos(LVecBase3f(0, 0, -self.text_h))
        self.items.pop(index)
        parent = list(self.items.values())[-1]
        out['text'] = ' del blank'
        #out['command'] = None
        out['extraArgs'] = [self, index]
        out.reparentTo(parent)
        self.items[index] = out
        if self.__add_head__ > 1:  # title is always at 0
            self.__add_head__ -= 1

    @classmethod
    def __make_border__(cls, parent, thickness, color, l, r, b, t):
        moveto_drawto = (
            ((l, 0, t), (l, 0, b)),
            ((r, 0, t), (r, 0, b)),
            ((l, 0, b), (r, 0, b)),
            ((l, 0, t), (r, 0, t)),
        )
        for moveto, drawto in moveto_drawto:
            Border = LineSegs()
            Border.setThickness(thickness)
            Border.setColor(*color)
            Border.moveTo(*moveto)
            Border.drawTo(*drawto)
            b = parent.attachNewNode(Border.create())
            b.setBin(*cls.DRAW_ORDER['border'])

    def getMaxItems(self):
        return int(abs(self.height / self.text_h) - 1)

    @event_callback
    def toggle_vis(self):
        if self.frame_bg.isHidden():
            self.frame_bg.show()
            self.raise_()
        else:
            self.frame_bg.hide()

    def title_toggle_vis(self):
        if not self.__was_dragging__:
            self.toggle_vis()
            if self.frame_bg.isHidden():
                self.title_button.wrtReparentTo(self.frame)
                self.title_button['frameColor'] = (1, 1, 1, .5)  # TODO
            else:
                self.title_button.wrtReparentTo(self.frame_bg)
                self.title_button['frameColor'] = (1, 1, 1, 0)  # TODO
        else:
            self.__was_dragging__ = False

    def __startDrag(self, crap):
        self.raise_()
        self._ox, self._oy = base.mouseWatcherNode.getMouse()
        taskMgr.add(self.__drag, 'dragging %s' % self.title)
        self.origBTprefix = self.BT.getPrefix()
        self.BT.setPrefix('dragging frame')

    def __drag(self, task):
        if base.mouseWatcherNode.hasMouse():
            x, y = base.mouseWatcherNode.getMouse()
            if x != self._ox or y != self._oy:
                m_old = aspect2d.getRelativePoint(
                    render2d, Point3(self._ox, self._oy, 0))
                m_new = aspect2d.getRelativePoint(render2d, Point3(x, y, 0))
                dx, dy, _ = m_new - m_old
                self.setPos(self.x + dx, self.y + dy)
                self._ox = x
                self._oy = y
                self.__was_dragging__ = True
        return task.cont

    def __stopDrag(self, crap):
        taskMgr.remove('dragging %s' % self.title)
        self.BT.setPrefix(self.origBTprefix)

    def setPos(self, x, y):
        """ actually sets the title button position
            since it is really the parent node
        """
        self.x = x
        self.y = y  #- self.text_h  # FIXME is hard :/
        self.frame_bg.setPos(LVecBase3f(x, 0, y))
        if self.frame_bg.isHidden():
            self.title_button.setPos(LVecBase3f(x, 0, y - self.text_h))

    def __enter__(self):
        #load the position
        #load other saved state
        pass

    def __exit__(self):
        #save the position!
        #save other state
        pass
Ejemplo n.º 19
0
class PlacerTool3D(DirectFrame):
    ORIGINAL_SCALE = (1.0, 1.0, 1.0)
    MINIMIZED_SCALE = (0.85, 1.0, 0.15)
    ORIG_DRAG_BUTTON_POS = (0.37, 0.0, 0.37)
    MINI_DRAG_BUTTON_POS = (0.37, 0.0, 0.03)
    ORIG_MINI_BUTTON_POS = (0.29, 0.0, 0.37)
    MINI_MINI_BUTTON_POS = (0.29, 0.0, 0.03)
    ORIG_NAME_POS = (-0.39, 0.0, 0.27)
    MINI_NAME_POS = (-0.39, 0.0, 0.0)

    def __init__(self,
                 target,
                 increment=0.01,
                 hprIncrement=1.0,
                 parent=aspect2d,
                 pos=(0.0, 0.0, 0.0)):
        DirectFrame.__init__(self, parent)
        self.target = target
        self.increment = increment
        self.minimized = False
        self.mainFrame = DirectFrame(
            parent=self,
            relief=None,
            geom=DGG.getDefaultDialogGeom(),
            geom_color=(1, 1, 0.75, 1),
            geom_scale=self.ORIGINAL_SCALE,
            pos=pos,
        )
        # Arrow gui (preload)
        gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui.bam')
        # Set Bins
        self.mainFrame.setBin('gui-popup', 0)
        # Name
        name = self.target.getName()
        self.nameLabel = TTLabel(self.mainFrame,
                                 text='Target: %s' % name,
                                 pos=self.ORIG_NAME_POS,
                                 text_align=TextNode.ALeft,
                                 text_wordwrap=13)
        # Pos
        pos = self.target.getPos()
        self.posLabel = TTLabel(self.mainFrame,
                                text='Position: ',
                                pos=(-0.39, 0.0, 0.055),
                                text_align=TextNode.ALeft)
        self.xPosSpinner = PlacerToolSpinner(self.mainFrame,
                                             value=pos[0],
                                             pos=(-0.085, 0.0, 0.06),
                                             increment=increment,
                                             callback=self.handleXChange)
        self.yPosSpinner = PlacerToolSpinner(self.mainFrame,
                                             value=pos[1],
                                             pos=(0.1, 0.0, 0.06),
                                             increment=increment,
                                             callback=self.handleYChange)
        self.zPosSpinner = PlacerToolSpinner(self.mainFrame,
                                             value=pos[2],
                                             pos=(0.28, 0.0, 0.06),
                                             increment=increment,
                                             callback=self.handleZChange)
        # hpr
        hpr = self.target.getHpr()
        self.hprLabel = TTLabel(self.mainFrame,
                                text='HPR: ',
                                pos=(-0.39, 0.0, -0.19),
                                text_align=TextNode.ALeft)
        self.hSpinner = PlacerToolSpinner(self.mainFrame,
                                          value=hpr[0],
                                          pos=(-0.085, 0.0, -0.195),
                                          increment=hprIncrement,
                                          callback=self.handleHChange)
        self.pSpinner = PlacerToolSpinner(self.mainFrame,
                                          value=hpr[1],
                                          pos=(0.1, 0.0, -0.195),
                                          increment=hprIncrement,
                                          callback=self.handlePChange)
        self.rSpinner = PlacerToolSpinner(self.mainFrame,
                                          value=hpr[2],
                                          pos=(0.28, 0.0, -0.195),
                                          increment=hprIncrement,
                                          callback=self.handleRChange)
        # scale
        scale = [round(s, 3) for s in self.target.getScale()]
        self.scaleLabel = TTLabel(self.mainFrame,
                                  text='Scale: ',
                                  pos=(-0.39, 0.0, -0.4),
                                  text_align=TextNode.ALeft)

        self.sxSpinner = PlacerToolSpinner(self.mainFrame,
                                           value=hpr[0],
                                           pos=(-0.085, 0.0, -0.4),
                                           increment=increment,
                                           callback=self.handleSxChange)
        self.sySpinner = PlacerToolSpinner(self.mainFrame,
                                           value=hpr[1],
                                           pos=(0.1, 0.0, -0.4),
                                           increment=increment,
                                           callback=self.handleSyChange)
        self.szSpinner = PlacerToolSpinner(self.mainFrame,
                                           value=hpr[2],
                                           pos=(0.28, 0.0, -0.4),
                                           increment=increment,
                                           callback=self.handleSzChange)

        gui.removeNode()
        gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_nameShop')
        thumb = gui.find('**/tt_t_gui_mat_namePanelCircle')
        self.dragButton = DirectButton(self.mainFrame,
                                       relief=None,
                                       image=thumb,
                                       image_scale=(0.5, 0.5, 0.5),
                                       pos=self.ORIG_DRAG_BUTTON_POS)
        self.minimizeButton = DirectButton(self.mainFrame,
                                           relief=None,
                                           image=thumb,
                                           image_scale=(0.5, 0.5, 0.5),
                                           image_color=(0.0, 0.0, 0.65, 1.0),
                                           pos=self.ORIG_MINI_BUTTON_POS,
                                           command=self.toggleMinimize,
                                           extraArgs=[])
        self.dragButton.bind(DGG.B1PRESS, self.onPress)
        if target is not None:
            self.setTarget(target)

    def destroy(self):
        self.target = None
        messenger.send('placer-destroyed', [self])
        DirectFrame.destroy(self)

    def setTarget(self, target):
        self.target = target
        name = self.target.getName()
        scale = [round(s, 3) for s in self.target.getScale()]
        x, y, z = self.target.getPos()
        h, p, r = self.target.getHpr()
        sx, sy, sz = self.target.getScale()
        self.nameLabel['text'] = 'Target: %s' % name
        self.xPosSpinner.setValue(x)
        self.yPosSpinner.setValue(y)
        self.zPosSpinner.setValue(z)
        self.hSpinner.setValue(h)
        self.pSpinner.setValue(p)
        self.rSpinner.setValue(r)
        self.sxSpinner.setValue(sx)
        self.sySpinner.setValue(sy)
        self.szSpinner.setValue(sz)

    def handleXChange(self, value):
        self.changeTargetPos(0, value)

    def handleYChange(self, value):
        self.changeTargetPos(1, value)

    def handleZChange(self, value):
        self.changeTargetPos(2, value)

    def handleHChange(self, value):
        self.changeTargetHpr(0, value)

    def handlePChange(self, value):
        self.changeTargetHpr(1, value)

    def handleRChange(self, value):
        self.changeTargetHpr(2, value)

    def handleSxChange(self, value):
        self.changeTargetScale(0, value)

    def handleSyChange(self, value):
        self.changeTargetScale(1, value)

    def handleSzChange(self, value):
        self.changeTargetScale(2, value)

    def changeTargetPos(self, index, value):
        pos = self.target.getPos()
        pos[index] = float(value)
        self.target.setPos(pos)

    def changeTargetHpr(self, index, value):
        hpr = self.target.getHpr()
        hpr[index] = float(value)
        self.target.setHpr(hpr)

    def changeTargetScale(self, index, value):
        pos = self.target.getScale()
        pos[index] = float(value)
        self.target.setScale(pos)

    def toggleMinimize(self):
        if self.minimized:
            self.maximize()
        else:
            self.minimize()

    def minimize(self):
        self.minimized = True
        self.mainFrame['geom_scale'] = self.MINIMIZED_SCALE
        self.nameLabel.setPos(self.MINI_NAME_POS)
        self.dragButton.setPos(self.MINI_DRAG_BUTTON_POS)
        self.minimizeButton.setPos(self.MINI_MINI_BUTTON_POS)
        self.posLabel.hide()
        self.xPosSpinner.hide()
        self.yPosSpinner.hide()
        self.zPosSpinner.hide()
        self.hprLabel.hide()
        self.hSpinner.hide()
        self.pSpinner.hide()
        self.rSpinner.hide()
        self.scaleLabel.hide()
        self.setPos(0, 0, 0)

    def maximize(self):
        self.minimized = False
        self.mainFrame['geom_scale'] = self.ORIGINAL_SCALE
        self.nameLabel.setPos(self.ORIG_NAME_POS)
        self.dragButton.setPos(self.ORIG_DRAG_BUTTON_POS)
        self.minimizeButton.setPos(self.ORIG_MINI_BUTTON_POS)
        self.posLabel.show()
        self.xPosSpinner.show()
        self.yPosSpinner.show()
        self.zPosSpinner.show()
        self.hprLabel.show()
        self.hSpinner.show()
        self.pSpinner.show()
        self.rSpinner.show()
        self.scaleLabel.show()
        self.setPos(0, 0, 0)

    def onPress(self, e=None):
        self.accept('mouse1-up', self.onRelease)
        taskMgr.add(self.mouseMoverTask, '%s-mouseMoverTask' % self.id)

    def onRelease(self, e=None):
        self.ignore('mouse1-up')
        taskMgr.remove('%s-mouseMoverTask' % self.id)

    def mouseMoverTask(self, task):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            buttonPos = self.dragButton.getPos()
            newPos = (mpos[0] - buttonPos[0] / 2 - 0.02, 0,
                      mpos[1] - buttonPos[2])
            self.setPos(render2d, newPos)
        return task.cont
class QuestPoster(DirectFrame):
    notify = directNotify.newCategory('QuestPoster')

    def __init__(self, quest, parent = aspect2d, **kw):
        self.quest = quest

        # Let's begin building the quest poster.
        bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam')
        questCard = bookModel.find('**/questCard')
        optiondefs = (('relief', None, None),
         ('image', questCard, None),
         ('image_scale', (0.8, 1.0, 0.58), None),
         ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)
        DirectFrame.__init__(self, relief = None)
        self.initialiseoptions(QuestPoster)

        self.questFrame = DirectFrame(parent = self, relief = None)

        # Quest title text
        self.headline = DirectLabel(parent = self.questFrame, relief = None,
            text = self.quest.getName(),
            text_font = CIGlobals.getMinnieFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.05,
            text_align = TextNode.ACenter,
            text_wordwrap = 25.0, textMayChange = 1,
        pos = (0, 0, 0.23))

        # Quest information
        self.questInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.04,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_INFO_POS))
        self.questInfo.hide()

        self.questInfo02 = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.04,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_INFO2_POS))
        self.questInfo02.hide()

        self.locationInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = 'N/A',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (0, 0, -0.115))
        self.locationInfo.hide()

        # C'mon Brian this one is obvious
        self.rewardText = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_fg = QuestGlobals.REWARD_RED,
            text_scale = 0.0425,
            text_align = TextNode.ALeft,
            text_wordwrap = 17.0,
            textMayChange = 1,
        pos = (-0.36, 0, -0.26))
        self.rewardText.hide()

        self.lPictureFrame = DirectFrame(parent = self.questFrame, relief = None,
            image = bookModel.find('**/questPictureFrame'),
            image_scale = QuestGlobals.IMAGE_SCALE_SMALL,
            text = '',
            text_pos = (0, -0.11),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = 11.0,
            pos = (QuestGlobals.DEFAULT_LEFT_PICTURE_POS),
        textMayChange = 1)
        self.lPictureFrame.hide()

        self.rPictureFrame = DirectFrame(parent = self.questFrame, relief = None,
            image = bookModel.find('**/questPictureFrame'),
            image_scale = QuestGlobals.IMAGE_SCALE_SMALL,
            text = '', text_pos = (0, -0.11),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = 11.0,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_RIGHT_PICTURE_POS))
        self.rPictureFrame['image_color'] = Vec4(*QuestGlobals.GREEN)
        self.rPictureFrame.hide()

        self.lQuestIcon = DirectFrame(parent = self.lPictureFrame, relief = None,
            text = ' ', text_font = CIGlobals.getSuitFont(),
            text_pos = (0, -0.03),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.13,
            text_align = TextNode.ACenter,
            text_wordwrap = 13.0,
        textMayChange = 1)
        self.lQuestIcon.setColorOff(-1)

        self.rQuestIcon = DirectFrame(parent = self.rPictureFrame, relief = None,
            text = ' ',
            text_font = CIGlobals.getSuitFont(),
            text_pos = (0, -0.03),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.13,
            text_align = TextNode.ACenter,
            text_wordwrap = 13.0,
        textMayChange = 1)
        self.rQuestIcon.setColorOff(-1)

        head = SuitBank.PennyPincher.getHead().generate()
        head.setDepthTest(True)
        head.setDepthWrite(True)
        head.setScale(0.25)
        for part in head.getChildren():
            part.setDepthTest(True)
            part.setDepthWrite(True)
        self.fitGeometry(head, fFlip = 1)
        self.rQuestIcon['geom'] = head
        self.rQuestIcon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL
        self.rQuestIcon['geom_pos'] = Point3(0, 10, -0.05)
        self.rQuestIcon['geom_hpr'] = Point3(180, 0, 0)
        self.rQuestIcon.initialiseoptions(DirectFrame)

        self.auxText = DirectLabel(parent = self.questFrame, relief = None,
            text = 'Recover',
            text_font = CIGlobals.getToonFont(),
            text_scale = QuestGlobals.QPauxText,
            text_fg = QuestGlobals.TEXT_COLOR,
            text_align = TextNode.ACenter,
            pos = (QuestGlobals.DEFAULT_AUX_POS),
        textMayChange=1)
        self.auxText.hide()

        self.middleText = DirectLabel(parent = self.questFrame, relief = None,
            text = 'from:',
            text_font = CIGlobals.getToonFont(),
            text_scale = QuestGlobals.QPauxText,
            text_fg = QuestGlobals.TEXT_COLOR,
            text_align = TextNode.ACenter,
            pos = (QuestGlobals.DEFAULT_MIDDLE_POS),
        textMayChange=1)
        self.middleText.hide()

        self.questProgress = DirectWaitBar(parent = self.questFrame, relief = DGG.SUNKEN,
            frameSize=(-0.95, 0.95, -0.1, 0.12),
            borderWidth = (0.025, 0.025),
            scale = 0.2,
            frameColor = (0.945, 0.875, 0.706, 1.0),
            barColor=(0.5, 0.7, 0.5, 1),
            text='0/0',
            text_font = CIGlobals.getToonFont(),
            text_scale = 0.19,
            text_fg = (0.05, 0.14, 0.4, 1),
            text_align = TextNode.ACenter,
            text_pos = (0, -0.05), #-0.02
        pos = (0, 0, -0.2425))
        self.questProgress.hide()

        rewardFrameGeom = loader.loadModel('phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.rewardFrame = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Goofys_Sign'),
            geom_scale = (0.615, 0, 0.4),
            pos = (-0.01, 0, -0.25)
        )

        jellybeanJar = QuestGlobals.getFilmIcon()
        self.lRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None,
            geom = jellybeanJar,
            geom_scale = QuestGlobals.TP_ACCESS_SCALE,
            sortOrder = 1,
        pos = (QuestGlobals.LEFT_TP_ACCESS_POS))
        self.lRewardFrame.setBin('gui-popup', 30)

        self.lRewardAmt = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Char_Pnl'),
            geom_scale = (0.15, 0, 0.1275),
            text = '#1',
            text_font = CIGlobals.getToonFont(),
            text_scale = 0.04,
            text_fg = (0, 0, 0, 1),
            text_align = TextNode.ACenter,
            text_pos = (0, -0.01),
            sortOrder = 2,
        pos = (-0.285, 0, -0.255))
        self.lRewardAmt.setBin('gui-popup', 40)

        self.rRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None,
            geom = QuestGlobals.getJBIcon(),
            geom_scale = QuestGlobals.JB_JAR_SCALE,
        pos = QuestGlobals.RIGHT_JB_JAR_POS)

        self.rRewardAmt = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Char_Pnl'),
            geom_scale = (0.15, 0, 0.1275),
            text = '25',
            text_font = CIGlobals.getToonFont(),
            text_scale = 0.04,
            text_fg = (0, 0, 0, 1),
            text_align = TextNode.ACenter,
            text_pos = (0, -0.01),
        pos = (0.2725, 0, -0.255))
        self.rRewardAmt.setBin('gui-popup', 40)

        rewardFrameGeom.removeNode()

        # This is the rotated text on the side.
        self.sideInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = QuestGlobals.JUST_FOR_FUN,
            text_fg = (0.0, 0.439, 1.0, 1.0),
            text_shadow = (0, 0, 0, 1),
            pos = (-0.2825, 0, 0.2),
        scale = 0.03)
        self.sideInfo.setR(-30)
        self.sideInfo.hide()

        bookModel.removeNode()
        self.laffMeter = None
        
        self.hide()
        return
    
    def handleIcon(self, objective, geom, scale, icon):
        isHead = True if type(geom) == ToonHead else geom.getName() == ('%sHead' % CIGlobals.Suit)

        if isHead:
            geom.setDepthWrite(1)
            geom.setDepthTest(1)
            self.fitGeometry(geom, fFlip = 1)
            
            if isinstance(objective, VisitNPCObjective) and icon == self.rQuestIcon:
                icon.setPos(icon.getX(), icon.getY(), icon.getZ() + 0.05)
                icon.setH(180)
            elif isinstance(objective, CogObjective):
                icon.setScale(QuestGlobals.IMAGE_SCALE_SMALL)
                icon.setPos(icon.getX(), icon.getY(), icon.getZ() - 0.04)
                if icon == self.lQuestIcon:
                    icon.setH(180)
            
            icon['geom'] = geom
            icon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL
        else:
            icon['geom'] = geom
            icon['geom_scale'] = scale

    def update(self):
        objective = self.quest.getCurrentObjective()
        objective.updateInfo()

        # Let's setup the quest info.
        self.questInfo.setPos(self.quest.getInfoPos())
        self.questInfo['text'] = self.quest.getInfoText()
        self.questInfo02.setPos(self.quest.getInfo02Pos())
        self.questInfo02['text'] = self.quest.getInfo02Text()
        
        # Let's move the picture frames to the positions we want them in.
        self.lPictureFrame.setPos(self.quest.getLeftPicturePos())
        self.rPictureFrame.setPos(self.quest.getRightPicturePos())
        
        editLeftAtr = isinstance(objective, VisitNPCObjective) or isinstance(objective, CogObjective)
        if editLeftAtr and objective.getDidEditLeft() or not editLeftAtr:
            geom = self.quest.getLeftIconGeom()
            scale = self.quest.getLeftIconScale()
            icon = self.lQuestIcon
            self.handleIcon(objective, geom, scale, icon)
            self.handleIcon(objective, self.quest.getRightIconGeom(), self.quest.getRightIconScale(), self.rQuestIcon)
        else:
            geom = self.quest.getRightIconGeom()
            scale = self.quest.getRightIconScale()
            icon = self.rQuestIcon
            self.handleIcon(objective, geom, scale, icon)
            self.handleIcon(objective, self.quest.getLeftIconGeom(), self.quest.getLeftIconScale(), self.lQuestIcon)

        if self.questInfo02['text'] == '':
            self.rPictureFrame.hide()
            self.questInfo02.hide()
        else:
            self.rPictureFrame.show()
            self.questInfo02.show()

        self.middleText['text'] = self.quest.getMiddleText()
        if not self.middleText['text'] == '':
            self.middleText.show()

        self.questInfo.show()
        self.lPictureFrame.show()

        # Let's set the location text.
        self.locationInfo['text'] = self.quest.getLocationText()
        self.locationInfo['text_pos'] = (0, self.quest.getLocationY())
        self.locationInfo.show()

        # Let's set the progress bar up.
        self.questProgress['text'] = self.quest.getProgressText()
        if len(self.questProgress['text']) > 0 and not objective.finished():
            self.questProgress.show()
            self.questProgress['range'] = objective.getNeededAmount()
            self.questProgress['value'] = objective.getProgress() & pow(2, 16) - 1
        else:
            self.questProgress.hide()

        # Let's setup the aux text.
        self.auxText.setPos(self.quest.getAuxPos())
        self.auxText['text'] = self.quest.getAuxText()
        self.auxText.show()

        maxHP = base.localAvatar.getMaxHealth()
        
        # Let's setup the rewards.
        for i in xrange(0, len(self.quest.getRewards())):
            reward = self.quest.getRewards()[i]
            frame = self.lRewardFrame if (i == 0) else self.rRewardFrame
            info = self.lRewardAmt if (i == 0) else self.rRewardAmt
            rType = reward.getType()
            if(rType == RewardType.JELLYBEANS):
                frame['pos'] = QuestGlobals.LEFT_JB_JAR_POS if (i == 0) else QuestGlobals.RIGHT_JB_JAR_POS
                frame['geom'] = QuestGlobals.getJBIcon()
                frame['geom_scale'] = QuestGlobals.JB_JAR_SCALE
                info['text'] = str(reward.getModifier())
            elif(rType == RewardType.TELEPORT_ACCESS or rType == RewardType.GAG_FRAME):
                frame['pos'] = QuestGlobals.LEFT_TP_ACCESS_POS if(i == 0) else QuestGlobals.RIGHT_TP_ACCESS_POS
                frame['geom'] = QuestGlobals.getTPAccessIcon() if(rType == RewardType.TELEPORT_ACCESS) else QuestGlobals.getFilmIcon()
                frame['geom_scale'] = QuestGlobals.TP_ACCESS_SCALE
                info['text'] = 'N/A' if(rType == RewardType.TELEPORT_ACCESS) else '#%s' % (str(reward.getModifier()))
            elif(rType == RewardType.LAFF_POINTS):
                frame.initialiseoptions(DirectFrame)
                r, g, b, _ = base.localAvatar.getHeadColor()
                pos = QuestGlobals.LEFT_LAFF_METER_POS if(i == 0) else QuestGlobals.RIGHT_LAFF_METER_POS

                # Create the laff meter with the new health.
                hp = maxHP + reward.getModifier()
                laffMeter = LaffOMeter()
                laffMeter.generate(r, g, b, base.localAvatar.getAnimal(), maxHP = hp, initialHP = hp)

                # Let's position the laff meter.
                frame['geom'] = laffMeter
                frame['geom_scale'] = QuestGlobals.LAFF_METER_SCALE
                frame.setPos(pos)
                info['text'] = '+%s' % (str(reward.getModifier()))
                laffMeter.destroy()
                laffMeter = None

        # Hide or show the other reward depending on if there's 2 rewards.
        if(len(self.quest.getRewards()) == 1):
            self.rRewardFrame.hide()
            self.rRewardAmt.hide()
        else:
            self.rRewardFrame.show()
            self.rRewardAmt.show()

        if objective.finished():
            self.setColor(Vec4(*QuestGlobals.LIGHT_GREEN))
            self.sideInfo['text'] = 'Completed!'
            self.sideInfo.show()
            
        self.questInfo.initialiseoptions(DirectLabel)
        self.questInfo02.initialiseoptions(DirectLabel)
        self.locationInfo.initialiseoptions(DirectLabel)
        self.lPictureFrame.initialiseoptions(DirectFrame)
        self.rPictureFrame.initialiseoptions(DirectFrame)
        self.lQuestIcon.initialiseoptions(DirectFrame)
        self.rQuestIcon.initialiseoptions(DirectFrame)
        self.auxText.initialiseoptions(DirectLabel)
        self.middleText.initialiseoptions(DirectLabel)
        self.sideInfo.initialiseoptions(DirectLabel)
        self.lPictureFrame['image_color'] = self.quest.getPictureFrameColor()
        self.rPictureFrame['image_color'] = self.quest.getPictureFrameColor()

    def fitGeometry(self, geom, fFlip = 0, dimension = 0.8):
        p1 = Point3()
        p2 = Point3()
        geom.calcTightBounds(p1, p2)
        if fFlip:
            t = p1[0]
            p1.setX(-p2[0])
            p2.setX(-t)
        d = p2 - p1
        biggest = max(d[0], d[2])
        s = dimension / biggest
        mid = (p1 + d / 2.0) * s
        geomXform = hidden.attachNewNode('geomXform')
        for child in geom.getChildren():
            child.reparentTo(geomXform)

        geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s)
        geomXform.reparentTo(geom)

    def destroy(self):
        self._deleteGeoms()
        DirectFrame.destroy(self)

    def _deleteGeoms(self):
        for icon in (self.lQuestIcon, self.rQuestIcon):
            geom = icon['geom']
            if geom and hasattr(geom, 'delete'):
                geom.delete()
                
    def getQuest(self):
        return self.quest
Ejemplo n.º 21
0
class OptionsMenu(DirectObject):
    def __init__(self):
        """Default constructor"""
        # create a main frame as big as the window
        self.frameMain = DirectFrame(
            # set framesize the same size as the window
            frameSize = (base.a2dLeft, base.a2dRight,
                         base.a2dTop, base.a2dBottom),
            image = "LogoTextGlow.png",
            image_scale = (1.06/2.0, 1, 0.7/2.0),
            image_pos = (0, 0, 0.7),
            # position center
            pos = (0, 0, 0),
            # set tramsparent background color
            frameColor = (0, 0, 0, 0))
        self.frameMain.setTransparency(1)
        self.frameMain.setBin("fixed", 100)

        sliderscale = 0.5
        buttonScale = 0.25
        textscale = 0.1
        checkboxscale = 0.05
        left = -0.5
        right = 0.5

        self.sliderTextspeed = DirectSlider(
            scale = sliderscale,
            pos = (left, 0, 0.2),
            range = (0.2,0.01),
            scrollSize = 0.01,
            text = _("Textspeed %0.1f%%")%(base.textWriteSpeed * 10),
            text_scale = textscale,
            text_align = TextNode.ACenter,
            text_pos = (0.0, 0.15),
            text_fg = (1,1,1,1),
            thumb_frameColor = (0.65, 0.65, 0.0, 1),
            thumb_relief = DGG.FLAT,
            frameColor = (0.15, 0.15, 0.15, 1),
            value = base.textWriteSpeed,
            command = self.sliderTextspeed_ValueChanged)
        self.sliderTextspeed.reparentTo(self.frameMain)

        self.cbParticles = DirectCheckButton(
            text = _(" Enable Particles"),
            text_fg = (1, 1, 1, 1),
            text_shadow = (0, 0, 0, 0.35),
            pos = (left, 0, -0.0),
            scale = checkboxscale,
            frameColor = (0,0,0,0),
            command = self.cbParticles_CheckedChanged,
            rolloverSound = None,
            clickSound = None,
            pressEffect = False,
            boxPlacement = "below",
            boxBorder = 0.8,
            boxRelief = DGG.FLAT,
            indicator_scale = 1.5,
            indicator_text_fg = (0.65, 0.65, 0.0, 1),
            indicator_text_shadow = (0, 0, 0, 0.35),
            indicator_frameColor = (0.15, 0.15, 0.15, 1),
            indicatorValue = base.particleMgrEnabled
            )
        self.cbParticles.indicator['text'] = (' ', 'x')
        self.cbParticles.indicator['text_pos'] = (0, 0.1)
        #self.cbParticles.indicator.setX(self.cbParticles.indicator, -0.5)
        #self.cbParticles.indicator.setZ(self.cbParticles.indicator, -0.1)
        #self.cbParticles.setFrameSize()
        self.cbParticles.setTransparency(1)
        self.cbParticles.reparentTo(self.frameMain)

        volume = base.musicManager.getVolume()
        self.sliderVolume = DirectSlider(
            scale = sliderscale,
            pos = (left, 0, -0.35),
            range = (0,1),
            scrollSize = 0.01,
            text = _("Volume %d%%")%volume*100,
            text_scale = textscale,
            text_align = TextNode.ACenter,
            text_pos = (.0, 0.15),
            text_fg = (1,1,1,1),
            thumb_frameColor = (0.65, 0.65, 0.0, 1),
            thumb_relief = DGG.FLAT,
            frameColor = (0.15, 0.15, 0.15, 1),
            value = volume,
            command = self.sliderVolume_ValueChanged)
        self.sliderVolume.reparentTo(self.frameMain)

        self.lblControltype = DirectLabel(
            text = _("Control type"),
            text_fg = (1, 1, 1, 1),
            text_shadow = (0, 0, 0, 0.35),
            frameColor = (0, 0, 0, 0),
            scale = textscale/2,
            pos = (right, 0, 0.27))
        self.lblControltype.setTransparency(1)
        self.lblControltype.reparentTo(self.frameMain)
        selectedControlType = 0
        if base.controlType == "MouseAndKeyboard":
            selectedControlType = 1
        self.controltype = DirectOptionMenu(
            pos = (right, 0, 0.18),
            text_fg = (1, 1, 1, 1),
            scale = 0.1,
            items = [_("Keyboard"),_("Keyboard + Mouse")],
            initialitem = selectedControlType,
            frameColor = (0.15, 0.15, 0.15, 1),
            popupMarker_frameColor = (0.65, 0.65, 0.0, 1),
            popupMarker_relief = DGG.FLAT,
            highlightColor = (0.65, 0.65, 0.0, 1),
            relief = DGG.FLAT,
            command=self.controlType_Changed)
        self.controltype.reparentTo(self.frameMain)
        b = self.controltype.getBounds()
        xPos = right - ((b[1] - b[0]) / 2.0 * 0.1)
        self.controltype.setX(xPos)
        setItems(self.controltype)
        self.controltype.setItems = setItems
        self.controltype.showPopupMenu = showPopupMenu
        self.controltype.popupMarker.unbind(DGG.B1PRESS)
        self.controltype.popupMarker.bind(DGG.B1PRESS, showPopupMenu)
        self.controltype.unbind(DGG.B1PRESS)
        self.controltype.bind(DGG.B1PRESS, showPopupMenuExtra, [self.controltype])

        isChecked = not base.AppHasAudioFocus
        img = None
        if base.AppHasAudioFocus:
            img = "AudioSwitch_on.png"
        else:
            img = "AudioSwitch_off.png"
        self.cbVolumeMute = DirectCheckBox(
            text = _("Mute Audio"),
            text_scale = 0.5,
            text_align = TextNode.ACenter,
            text_pos = (0.0, 0.65),
            text_fg = (1,1,1,1),
            pos = (right, 0, -0.35),
            scale = 0.21/2.0,
            command = self.cbVolumeMute_CheckedChanged,
            rolloverSound = None,
            clickSound = None,
            relief = None,
            pressEffect = False,
            isChecked = isChecked,
            image = img,
            image_scale = 0.5,
            checkedImage = "AudioSwitch_off.png",
            uncheckedImage = "AudioSwitch_on.png")
        self.cbVolumeMute.setTransparency(1)
        self.cbVolumeMute.setImage()
        self.cbVolumeMute.reparentTo(self.frameMain)

        sensitivity = base.mouseSensitivity
        self.sliderSensitivity = DirectSlider(
            scale = sliderscale,
            pos = (right, 0, -0.075),
            range = (0.5,2),
            scrollSize = 0.01,
            text = _("Mouse Sensitivity %0.1fx")%sensitivity,
            text_scale = textscale,
            text_align = TextNode.ACenter,
            text_pos = (.0, 0.15),
            text_fg = (1,1,1,1),
            thumb_frameColor = (0.65, 0.65, 0.0, 1),
            thumb_relief = DGG.FLAT,
            frameColor = (0.15, 0.15, 0.15, 1),
            value = sensitivity,
            command = self.sliderSensitivity_ValueChanged)
        self.sliderSensitivity.reparentTo(self.frameMain)
        if base.controlType == "Gamepad":
            self.sliderSensitivity.hide()

        # create the back button
        self.btnBack = DirectButton(
            scale = buttonScale,
            # position on the window
            pos = (0, 0, base.a2dBottom + 0.15),
            frameColor = (0,0,0,0),
            # text properties
            text = _("Back"),
            text_scale = 0.5,
            text_fg = (1,1,1,1),
            text_pos = (0.0, -0.15),
            text_shadow = (0, 0, 0, 0.35),
            text_shadowOffset = (-0.05, -0.05),
            # sounds that should be played
            rolloverSound = None,
            clickSound = None,
            pressEffect = False,
            relief = None,
            # the event which is thrown on clickSound
            command = lambda: base.messenger.send("options_back"))
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(self.frameMain)

        self.hide()


    def show(self, enableResume=False):
        self.frameMain.show()

    def hide(self):
        self.frameMain.hide()

    def cbVolumeMute_CheckedChanged(self, checked):
        if checked:
            base.disableAllAudio()
        else:
            base.enableAllAudio()

    def sliderVolume_ValueChanged(self):
        volume = round(self.sliderVolume["value"], 2)
        self.sliderVolume["text"] = _("Volume %d%%") % int(volume * 100)
        base.sfxManagerList[0].setVolume(volume)
        base.musicManager.setVolume(volume)

    def sliderSensitivity_ValueChanged(self):
        sensitivity = round(self.sliderSensitivity["value"], 2)
        self.sliderSensitivity["text"] = _("Mouse Sensitivity %0.1fx") % sensitivity
        base.mouseSensitivity = sensitivity

    def sliderTextspeed_ValueChanged(self):
        newSpeed = round(self.sliderTextspeed["value"], 2)
        displaySpeed = 1.0 / newSpeed
        self.sliderTextspeed["text"] = _("Textspeed %0.1f%%")%displaySpeed
        base.textWriteSpeed = newSpeed

    def cbParticles_CheckedChanged(self, unchecked):
        if unchecked:
            base.enableParticles()
        else:
            base.disableParticles()

    def controlType_Changed(self, arg):
        if arg == _("Keyboard"):
            self.sliderSensitivity.hide()
            base.controlType = "Gamepad"
        elif arg == _("Keyboard + Mouse"):
            self.sliderSensitivity.show()
            base.controlType = "MouseAndKeyboard"
Ejemplo n.º 22
0
class Menu(DirectObject):
    def __init__(self):
        self.accept("window-event", self.recalcAspectRatio)

        self.frameMain = DirectFrame(
            # size of the frame
            frameSize = (base.a2dLeft, base.a2dRight,
                         base.a2dTop, base.a2dBottom),
            # position of the frame
            image = "LogoTextGlow.png",
            image_scale = (1.06, 1, 0.7),
            image_pos = (0, 0, 0.25),
            pos = (0, 0, 0),
            # tramsparent bg color
            frameColor = (0, 0, 0, 0),
            sortOrder = 0)
        self.frameMain.setTransparency(1)
        self.frameMain.setBin("fixed", 100)

        btnGeom = None

        self.btnStart = self.createButton(_("Start"), btnGeom, -0.6, self.btnStart_Click)
        self.btnStart.reparentTo(self.frameMain)

        self.btnOptions = self.createButton(_("Options"), btnGeom, 0, self.btnOptions_Click)
        self.btnOptions.reparentTo(self.frameMain)

        self.btnQuit = self.createButton(_("Quit"), btnGeom, 0.6, self.btnQuit_Click)
        self.btnQuit.reparentTo(self.frameMain)

        self.recalcAspectRatio(base.win)

        # hide all buttons at startup
        self.hide()

    def show(self):
        self.frameMain.show()
        self.recalcAspectRatio(base.win)

    def hide(self):
        self.frameMain.hide()

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        screenResMultiplier = window.getXSize() / window.getYSize()
        self.frameMain["frameSize"] = (
            base.a2dLeft, base.a2dRight,
            base.a2dTop, base.a2dBottom)
        self.btnQuit["text_scale"] = (0.5*screenResMultiplier, 0.5, 0.5)
        self.btnStart["text_scale"] = (0.5*screenResMultiplier, 0.5, 0.5)


    def createButton(self, text, btnGeom, xPos, command):
        btn = DirectButton(
            scale = (0.25, 0.25, 0.25),
            # some temp text
            text = text,
            text_scale = (0.5, 0.5, 0.5),
            # set the alignment to right
            text_align = TextNode.ACenter,
            # put the text on the right side of the button
            text_pos = (0, -0.15),
            # set the text color to black
            text_fg = (1,1,1,1),
            text_shadow = (0.3, 0.3, 0.1, 1),
            text_shadowOffset = (0.05, 0.05),
            # set the buttons images
            #geom = btnGeom,
            relief = 1,
            frameColor = (0,0,0,0),
            pressEffect = False,
            pos = (xPos, 0, -0.65),
            command = command,
            rolloverSound = None,
            clickSound = None)
        btn.setTransparency(1)
        return btn

    def btnStart_Click(self):
        base.messenger.send("menu_start")

    def btnOptions_Click(self):
        base.messenger.send("menu_options")

    def btnQuit_Click(self):
        base.messenger.send("menu_quit")
Ejemplo n.º 23
0
class Transitions:

    # These may be reassigned before the fade or iris transitions are
    # actually invoked to change the models that will be used.
    IrisModelName = "models/misc/iris"
    FadeModelName = "models/misc/fade"

    def __init__(self, loader,
                 model=None,
                 scale=3.0,
                 pos=Vec3(0, 0, 0)):
        self.transitionIval = None
        self.letterboxIval = None
        self.iris = None
        self.fade = None
        self.letterbox = None
        self.fadeModel = model
        self.imagePos = pos
        if model:
            self.alphaOff = Vec4(1, 1, 1, 0)
            self.alphaOn = Vec4(1, 1, 1, 1)
            model.setTransparency(1)
            self.lerpFunc = LerpColorScaleInterval
        else:
            self.alphaOff = Vec4(0, 0, 0, 0)
            self.alphaOn = Vec4(0, 0, 0, 1)
            self.lerpFunc = LerpColorInterval

        self.irisTaskName = "irisTask"
        self.fadeTaskName = "fadeTask"
        self.letterboxTaskName = "letterboxTask"

    def __del__(self):
        if self.fadeModel:
            self.fadeModel.removeNode()
            self.fadeModel = None

    ##################################################
    # Fade
    ##################################################

    # We can set a custom model for the fade before using it for the first time
    def setFadeModel(self, model, scale=1.0):
        self.fadeModel = model
        # We have to change some default parameters for a custom fadeModel
        self.alphaOn = Vec4(1, 1, 1, 1)

        # Reload fade if its already been created
        if self.fade:
            self.fade.destroy()
            self.fade = None
            self.loadFade()

    def loadFade(self):
        if self.fade is None:
            # We create a DirectFrame for the fade polygon, instead of
            # simply loading the polygon model and using it directly,
            # so that it will also obscure mouse events for objects
            # positioned behind it.
            self.fade = DirectFrame(
                parent = hidden,
                guiId = 'fade',
                relief = None,
                image = self.fadeModel,
                image_scale = (4, 2, 2),
                state = DGG.NORMAL,
                )
            if not self.fadeModel:
                # No fade model was given, so we make this the fade model.
                self.fade["relief"] = DGG.FLAT
                self.fade["frameSize"] = (-2, 2, -1, 1)
                self.fade["frameColor"] = (0, 0, 0, 1)
                self.fade.setTransparency(TransparencyAttrib.MAlpha)
            self.fade.setBin('unsorted', 0)
            self.fade.setColor(0,0,0,0)

    def getFadeInIval(self, t=0.5, finishIval=None):
        """
        Returns an interval without starting it.  This is particularly useful in
        cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately
        """
        #self.noTransitions() masad: this creates a one frame pop, is it necessary?
        self.loadFade()
        transitionIval = Sequence(Func(self.fade.reparentTo, aspect2d, DGG.FADE_SORT_INDEX),
                                  Func(self.fade.showThrough),  # in case aspect2d is hidden for some reason
                                  self.lerpFunc(self.fade, t,
                                                self.alphaOff,
                                                # self.alphaOn,
                                                ),
                                  Func(self.fade.detachNode),
                                  name = self.fadeTaskName,
                                  )
        if finishIval:
            transitionIval.append(finishIval)
        return transitionIval

    def getFadeOutIval(self, t=0.5, finishIval=None):
        """
        Create a sequence that lerps the color out, then
        parents the fade to hidden
        """
        self.noTransitions()
        self.loadFade()

        transitionIval = Sequence(Func(self.fade.reparentTo,aspect2d,DGG.FADE_SORT_INDEX),
                                  Func(self.fade.showThrough),  # in case aspect2d is hidden for some reason
                                  self.lerpFunc(self.fade, t,
                                                self.alphaOn,
                                                # self.alphaOff,
                                                ),
                                  name = self.fadeTaskName,
                                  )
        if finishIval:
            transitionIval.append(finishIval)
        return transitionIval

    def fadeIn(self, t=0.5, finishIval=None):
        """
        Play a fade in transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the color
        from black to transparent. When the color lerp is finished, it
        parents the fade polygon to hidden.
        """
        gsg = base.win.getGsg()
        if gsg:
            # If we're about to fade in from black, go ahead and
            # preload all the textures etc.
            base.graphicsEngine.renderFrame()
            render.prepareScene(gsg)
            render2d.prepareScene(gsg)

        if (t == 0):
            # Fade in immediately with no lerp
            #print "transitiosn: fadeIn 0.0"
            self.noTransitions()
            self.loadFade()
            self.fade.detachNode()
        else:
            # Create a sequence that lerps the color out, then
            # parents the fade to hidden
            self.transitionIval = self.getFadeInIval(t, finishIval)
            self.transitionIval.start()

    def fadeOut(self, t=0.5, finishIval=None):
        """
        Play a fade out transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the color
        from transparent to full black. When the color lerp is finished,
        it leaves the fade polygon covering the aspect2d plane until you
        fadeIn or call noFade.
        lerp
        """
        if (t == 0):
            # Fade out immediately with no lerp
            self.noTransitions()
            self.loadFade()
            self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
            self.fade.setColor(self.alphaOn)
        elif ConfigVariableBool('no-loading-screen', False):
            if finishIval:
                self.transitionIval = finishIval
                self.transitionIval.start()
        else:
            # Create a sequence that lerps the color out, then
            # parents the fade to hidden
            self.transitionIval = self.getFadeOutIval(t,finishIval)
            self.transitionIval.start()

    def fadeOutActive(self):
        return self.fade and self.fade.getColor()[3] > 0

    def fadeScreen(self, alpha=0.5):
        """
        Put a semitransparent screen over the camera plane
        to darken out the world. Useful for drawing attention to
        a dialog box for instance
        """
        #print "transitiosn: fadeScreen"
        self.noTransitions()
        self.loadFade()
        self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
        self.fade.setColor(self.alphaOn[0],
                           self.alphaOn[1],
                           self.alphaOn[2],
                           alpha)

    def fadeScreenColor(self, color):
        """
        Put a semitransparent screen over the camera plane
        to darken out the world. Useful for drawing attention to
        a dialog box for instance
        """
        #print "transitiosn: fadeScreenColor"
        self.noTransitions()
        self.loadFade()
        self.fade.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)
        self.fade.setColor(color)

    def noFade(self):
        """
        Removes any current fade tasks and parents the fade polygon away
        """
        #print "transitiosn: noFade"
        if self.transitionIval:
            self.transitionIval.pause()
            self.transitionIval = None
        if self.fade:
            # Make sure to reset the color, since fadeOutActive() is looking at it
            self.fade.setColor(self.alphaOff)
            self.fade.detachNode()

    def setFadeColor(self, r, g, b):
        self.alphaOn.set(r, g, b, 1)
        self.alphaOff.set(r, g, b, 0)


    ##################################################
    # Iris
    ##################################################

    def loadIris(self):
        if self.iris == None:
            self.iris = loader.loadModel(self.IrisModelName)
            self.iris.setPos(0, 0, 0)

    def irisIn(self, t=0.5, finishIval=None):
        """
        Play an iris in transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the scale
        of the iris polygon up so it looks like we iris in. When the
        scale lerp is finished, it parents the iris polygon to hidden.
        """
        self.noTransitions()
        self.loadIris()
        if (t == 0):
            self.iris.detachNode()
        else:
            self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)

            self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
                                                   scale = 0.18,
                                                   startScale = 0.01),
                                 Func(self.iris.detachNode),
                                 name = self.irisTaskName,
                                 )
            if finishIval:
                self.transitionIval.append(finishIval)
            self.transitionIval.start()

    def irisOut(self, t=0.5, finishIval=None):
        """
        Play an iris out transition over t seconds.
        Places a polygon on the aspect2d plane then lerps the scale
        of the iris down so it looks like we iris out. When the scale
        lerp is finished, it leaves the iris polygon covering the
        aspect2d plane until you irisIn or call noIris.
        """
        self.noTransitions()
        self.loadIris()
        self.loadFade()  # we need this to cover up the hole.
        if (t == 0):
            self.iris.detachNode()
            self.fadeOut(0)
        else:
            self.iris.reparentTo(aspect2d, DGG.FADE_SORT_INDEX)

            self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
                                                   scale = 0.01,
                                                   startScale = 0.18),
                                 Func(self.iris.detachNode),
                                 # Use the fade to cover up the hole that the iris would leave
                                 Func(self.fadeOut, 0),
                                 name = self.irisTaskName,
                                 )
            if finishIval:
                self.transitionIval.append(finishIval)
            self.transitionIval.start()

    def noIris(self):
        """
        Removes any current iris tasks and parents the iris polygon away
        """
        if self.transitionIval:
            self.transitionIval.pause()
            self.transitionIval = None
        if self.iris != None:
            self.iris.detachNode()
        # Actually we need to remove the fade too,
        # because the iris effect uses it.
        self.noFade()

    def noTransitions(self):
        """
        This call should immediately remove any and all transitions running
        """
        self.noFade()
        self.noIris()
        # Letterbox is not really a transition, it is a screen overlay
        # self.noLetterbox()

    ##################################################
    # Letterbox
    ##################################################

    def loadLetterbox(self):
        if not self.letterbox:
            # We create a DirectFrame for the fade polygon, instead of
            # simply loading the polygon model and using it directly,
            # so that it will also obscure mouse events for objects
            # positioned behind it.
            self.letterbox = NodePath("letterbox")
            # Allow fade in and out of the bars
            self.letterbox.setTransparency(1)

            # Allow DirectLabels to be parented to the letterbox sensibly
            self.letterbox.setBin('unsorted', 0)

            # Allow a custom look to the letterbox graphic.

            # TODO: This model isn't available everywhere.  We should
            # pass it in as a parameter.
            button = loader.loadModel('models/gui/toplevel_gui',
                                      okMissing = True)

            barImage = None
            if button:
                barImage = button.find('**/generic_button')

            self.letterboxTop = DirectFrame(
                parent = self.letterbox,
                guiId = 'letterboxTop',
                relief = DGG.FLAT,
                state = DGG.NORMAL,
                frameColor = (0, 0, 0, 1),
                borderWidth = (0, 0),
                frameSize = (-1, 1, 0, 0.2),
                pos = (0, 0, 0.8),
                image = barImage,
                image_scale = (2.25,1,.5),
                image_pos = (0,0,.1),
                image_color = (0.3,0.3,0.3,1),
                sortOrder = 0,
                )
            self.letterboxBottom = DirectFrame(
                parent = self.letterbox,
                guiId = 'letterboxBottom',
                relief = DGG.FLAT,
                state = DGG.NORMAL,
                frameColor = (0, 0, 0, 1),
                borderWidth = (0, 0),
                frameSize = (-1, 1, 0, 0.2),
                pos = (0, 0, -1),
                image = barImage,
                image_scale = (2.25,1,.5),
                image_pos = (0,0,.1),
                image_color = (0.3,0.3,0.3,1),
                sortOrder = 0,
                )

            # masad: always place these at the bottom of render
            self.letterboxTop.setBin('sorted',0)
            self.letterboxBottom.setBin('sorted',0)
            self.letterbox.reparentTo(render2d, -1)
            self.letterboxOff(0)

    def noLetterbox(self):
        """
        Removes any current letterbox tasks and parents the letterbox polygon away
        """
        if self.letterboxIval:
            self.letterboxIval.pause()
            self.letterboxIval = None
        if self.letterbox:
            self.letterbox.stash()

    def letterboxOn(self, t=0.25, finishIval=None):
        """
        Move black bars in over t seconds.
        """
        self.noLetterbox()
        self.loadLetterbox()
        self.letterbox.unstash()
        if (t == 0):
            self.letterboxBottom.setPos(0, 0, -1)
            self.letterboxTop.setPos(0, 0, 0.8)
        else:
            self.letterboxIval = Sequence(Parallel(
                LerpPosInterval(self.letterboxBottom,
                                t,
                                pos = Vec3(0, 0, -1),
                                #startPos = Vec3(0, 0, -1.2),
                                ),
                LerpPosInterval(self.letterboxTop,
                                t,
                                pos = Vec3(0, 0, 0.8),
                                # startPos = Vec3(0, 0, 1),
                                ),
                ),
                                          name = self.letterboxTaskName,
                                          )
            if finishIval:
                self.letterboxIval.append(finishIval)
            self.letterboxIval.start()

    def letterboxOff(self, t=0.25, finishIval=None):
        """
        Move black bars away over t seconds.
        """
        self.noLetterbox()
        self.loadLetterbox()
        self.letterbox.unstash()
        if (t == 0):
            self.letterbox.stash()
        else:
            self.letterboxIval = Sequence(Parallel(
                LerpPosInterval(self.letterboxBottom,
                                t,
                                pos = Vec3(0, 0, -1.2),
                                # startPos = Vec3(0, 0, -1),
                                ),
                LerpPosInterval(self.letterboxTop,
                                t,
                                pos = Vec3(0, 0, 1),
                                # startPos = Vec3(0, 0, 0.8),
                                ),
                ),
                                          Func(self.letterbox.stash),
                                          Func(messenger.send,'letterboxOff'),
                                          name = self.letterboxTaskName,
                                          )
            if finishIval:
                self.letterboxIval.append(finishIval)
            self.letterboxIval.start()
Ejemplo n.º 24
0
class Menu(DirectObject):
    def __init__(self):
        self.accept("window-event", self.recalcAspectRatio)

        self.frameMain = DirectFrame(
            # size of the frame
            frameSize=(base.a2dLeft, base.a2dRight, base.a2dTop, base.a2dBottom),
            # position of the frame
            image="LogoTextGlow.png",
            image_scale=(1.06, 1, 0.7),
            image_pos=(0, 0, 0.25),
            pos=(0, 0, 0),
            # tramsparent bg color
            frameColor=(0, 0, 0, 0),
            sortOrder=0,
        )
        self.frameMain.setTransparency(1)
        self.frameMain.setBin("fixed", 100)

        btnGeom = None

        self.btnStart = self.createButton(_("Start"), btnGeom, -0.6, self.btnStart_Click)
        self.btnStart.reparentTo(self.frameMain)

        self.btnOptions = self.createButton(_("Options"), btnGeom, 0, self.btnOptions_Click)
        self.btnOptions.reparentTo(self.frameMain)

        self.btnQuit = self.createButton(_("Quit"), btnGeom, 0.6, self.btnQuit_Click)
        self.btnQuit.reparentTo(self.frameMain)

        self.recalcAspectRatio(base.win)

        # hide all buttons at startup
        self.hide()

    def show(self):
        self.frameMain.show()
        self.recalcAspectRatio(base.win)

    def hide(self):
        self.frameMain.hide()

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        screenResMultiplier = window.getXSize() / window.getYSize()
        self.frameMain["frameSize"] = (base.a2dLeft, base.a2dRight, base.a2dTop, base.a2dBottom)
        self.btnQuit["text_scale"] = (0.5 * screenResMultiplier, 0.5, 0.5)
        self.btnStart["text_scale"] = (0.5 * screenResMultiplier, 0.5, 0.5)

    def createButton(self, text, btnGeom, xPos, command):
        btn = DirectButton(
            scale=(0.25, 0.25, 0.25),
            # some temp text
            text=text,
            text_scale=(0.5, 0.5, 0.5),
            # set the alignment to right
            text_align=TextNode.ACenter,
            # put the text on the right side of the button
            text_pos=(0, -0.15),
            # set the text color to black
            text_fg=(1, 1, 1, 1),
            text_shadow=(0.3, 0.3, 0.1, 1),
            text_shadowOffset=(0.05, 0.05),
            # set the buttons images
            # geom = btnGeom,
            relief=1,
            frameColor=(0, 0, 0, 0),
            pressEffect=False,
            pos=(xPos, 0, -0.65),
            command=command,
            rolloverSound=None,
            clickSound=None,
        )
        btn.setTransparency(1)
        return btn

    def btnStart_Click(self):
        base.messenger.send("menu_start")

    def btnOptions_Click(self):
        base.messenger.send("menu_options")

    def btnQuit_Click(self):
        base.messenger.send("menu_quit")