コード例 #1
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))
コード例 #2
0
ファイル: actor.py プロジェクト: NanoDano/cookbook
    def __init__(self):
        ShowBase.__init__(self)
 
        # Load the environment model.
        self.environ = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.environ.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, 0)
 
        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
 
        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.reparentTo(self.render)
        # Loop its animation.
        self.pandaActor.loop("walk")
        
        
 
        myFrame = DirectFrame(frameColor=(0, 0, 0, 1),
            frameSize=(-1, 1, -1, 1))
        myFrame.setPos(-0.5, 0, -0.5)
コード例 #3
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
コード例 #4
0
    def __init__(self):
        ShowBase.__init__(self)

        # Load the environment model.
        self.environ = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.environ.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, 0)

        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.reparentTo(self.render)
        # Loop its animation.
        self.pandaActor.loop("walk")

        myFrame = DirectFrame(frameColor=(0, 0, 0, 1),
                              frameSize=(-1, 1, -1, 1))
        myFrame.setPos(-0.5, 0, -0.5)
コード例 #5
0
ファイル: layout.py プロジェクト: cosmonium/cosmonium
class Layout(object):
    def __init__(self, width, height, parent=None, frameColor=(1, 1, 1, 1), frameSize=(0, 0.5, -0.5, 0)):
        self.width = width
        self.height = height
        if parent is None:
            parent = aspect2d
        self.parent = parent
        self.frame = DirectFrame(parent=parent, frameColor=frameColor, frameSize=frameSize, state=DGG.DISABLED)
        self.frame.setPos(0, 0, 0)
        self.children = [[None for y in range(self.height)] for x in range(self.width)]
        self.children_width = [[0.0 for y in range(self.height)] for x in range(self.width)]
        self.children_height = [[0.0 for y in range(self.height)] for x in range(self.width)]

    def set_child(self, x, y, child):
        if x >= self.width or y >= self.height: return
        child.reparent_to(self.frame)
        self.children[x][y] = child
        bounds = child.getBounds()
        if bounds is not None:
            width = bounds[1] - bounds[0]
            height = bounds[3] - bounds[2]
            self.children_width[x][y] = width
            self.children_height[x][y] = height
        else:
            self.children_width[x][y] = 0
            self.children_height[x][y] = 0

    def recalc_positions(self):
        max_widths = []
        for x in range(self.width):
            max_width = 0.0
            for y in range(self.height):
                max_width = max(max_width, self.children_width[x][y])
            max_widths.append(max_width)
        max_heights = []
        for y in range(self.height):
            max_height = 0.0
            for x in range(self.width):
                max_height = max(max_height, self.children_height[x][y])
            max_heights.append(max_height)
        pos_x = 0.0
        for x in range(self.width):
            pos_y = 0.0
            for y in range(self.height):
                pos_y -= max_heights[y]
                child = self.children[x][y]
                if child is not None:
                    child.setPos(pos_x, 0, pos_y)
            pos_x += max_widths[x]
        self.frame['frameSize']= [0, pos_x, 0, pos_y]

    def destroy(self):
        self.frame.destroy()

    def reparent_to(self, parent):
        self.frame.reparent_to(parent)
    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
コード例 #7
0
ファイル: HeadPanels.py プロジェクト: coginvasion/src
 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
コード例 #8
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
コード例 #9
0
class MainMenu():
    def __init__(self):
        print("MainMenu object created")
        self.bk_text = "This is my Demo"
        self.textObject = OnscreenText(text=self.bk_text,
                                       pos=(0.95, -0.95),
                                       scale=0.07,
                                       fg=(1, 0.5, 0.5, 1),
                                       align=TextNode.ACenter,
                                       mayChange=1)

        self.f = DirectFrame(frameColor=(1, 0, 0, 1), frameSize=(-1, 1, -1, 1))
        self.f.setPos(-0.5, 0, -0.5)

        self.t = DirectLabel(self.f,
                             text="Glorious title",
                             scale=0.1,
                             pos=(0, 0, 0.9))

        self.b = DirectButton(self.f,
                              text=("Exit", "click!", "rolling over",
                                    "disabled"),
                              scale=.15,
                              pos=(0, 0, 0.1),
                              text_scale=0.5,
                              command=self.setText)

        self.ttb = DirectButton(self.f,
                                text=("Terrain Test"),
                                scale=.15,
                                pos=(0, 0, 0.2),
                                text_scale=0.5,
                                command=self.request_state,
                                extraArgs=["TerrainTest"])

        self.ccb = DirectButton(self.f,
                                text=("CharGen Test"),
                                scale=.15,
                                pos=(0, 0, 0.3),
                                text_scale=0.5,
                                command=self.request_state,
                                extraArgs=["CharGen"])

        self.nt = DirectButton(self.f,
                               text=("Network Test"),
                               scale=.15,
                               pos=(0, 0, 0.4),
                               text_scale=0.5,
                               command=self.request_state,
                               extraArgs=["NetworkTest"])

        #self.nt

    def setText(self):
        self.bk_text = "Button Clicked"
        self.textObject.setText(self.bk_text)
        self.f.destroy()
        Globals.game_states.request("None")
        sys.exit()

    def request_state(self, name):
        self.f.destroy()
        self.textObject.destroy()
        #Globals.game_states.request("TerrainTest")
        Globals.game_states.request(name)
コード例 #10
0
ファイル: uielements.py プロジェクト: Compy/DemolitionMan2000
class Menu(UIItem):
    def __init__(self, list=[]):
        self.__menuContainer = DirectFrame(
            #text_pos=(0,1),
            pos=(0, 0, 0),
            text_scale=1.5,
            text_fg=(0, 0, 0, 0),
            relief=DGG.FLAT,
            frameColor=(1, 1, 1, 0.5))
        self.__menuContainer.hide()
        self.__menuItems = []
        self.selectedItem = 0
        self.addItems(list)

    def addItem(self, text, action):
        self.__menuItems.append(
            DirectButton(
                text=text,
                command=self.pressEnter,
                extraArgs=[len(self.__menuItems)],
                text_align=TextNode.ALeft,
                scale=0.1,
                #left/right, forward/back, up/down
                pos=Vec3(-0.38, 0, 0.5 - (len(self.__menuItems) * 0.15)),
                text_fg=(1, 1, 1, 1),
                rolloverSound=None,
                clickSound=None,
                pressEffect=0,
                relief=None,
                textMayChange=True
                #text_font=base.fontLoader.load('Arial Bold.ttf')
            ))
        self.__menuItems[-1].reparentTo(self.__menuContainer)
        self.__menuItems[-1].setPythonTag('action', action)
        self.__menuItems[-1].setPythonTag('text', text)

    def addItems(self, list):
        for k, v in list:
            self.addItem(k, v)

    def hasItem(self, text):
        for i in self.__menuItems:
            if (i['text'] == text): return True
        return False

    def __del__(self):
        self.ignoreAll()

    def pressEnter(self, item=None):
        if (item != None):
            self.selectedItem = item

        logging.info("pressEnter:: selectedItem = %s" % str(self.selectedItem))

        action = self.__menuItems[self.selectedItem].getPythonTag('action')
        text = self.__menuItems[self.selectedItem].getPythonTag('text')

        logging.info("pressEnter:: action = %s" % str(action))

        if (action != None):  #function
            #self.hide()
            action(text)  #call the function in 'action'

    def enter(self):
        """ Press the enter key to select the current menu item. """
        self.pressEnter()
        UIItem.enter(self)

    def up(self):
        """Move one item up in the menu."""
        newItem = self.selectedItem - 1
        if (newItem < 0):
            newItem = len(self.__menuItems) - 1
        self.select(newItem)

        UIItem.up(self)

    def down(self):
        """Move one item down in the menu."""
        newItem = self.selectedItem + 1
        if (newItem >= len(self.__menuItems)):
            newItem = 0
        self.select(newItem)

        UIItem.down(self)

    def select(self, item):
        self.__menuItems[self.selectedItem]['text_fg'] = (1, 1, 1, 1)
        self.__menuItems[self.selectedItem]['text_bg'] = (0, 0, 0, 0)
        self.selectedItem = item
        self.__menuItems[self.selectedItem]['text_fg'] = (0, 0, 0.5, 1)
        self.__menuItems[self.selectedItem]['text_bg'] = (1, 1, 1, 1)

    def show(self):
        assert len(self.__menuItems) > 0
        self.select(0)  #make the first item selected
        if (self.__menuContainer.isHidden()):
            Sequence(
                Func(self.__menuContainer.setAlphaScale, 0.0),
                Func(self.__menuContainer.show),
                LerpFunctionInterval(self.__menuContainer.setAlphaScale,
                                     toData=1.0,
                                     fromData=0.0,
                                     duration=1.0)).start()

    def hide(self):
        self.ignoreAll()
        if (not self.__menuContainer.isHidden()):
            Sequence(
                LerpFunctionInterval(self.__menuContainer.setAlphaScale,
                                     toData=0.0,
                                     fromData=1.0,
                                     duration=1.0),
                Func(self.__menuContainer.hide),
                Func(self.__menuContainer.setAlphaScale, 1.0)).start()
        #now, hide all dialogs referred to:
        for i in self.__menuItems:
            a = i.getPythonTag('action')
            if (isinstance(a, Menu)):
                a.hide()

    def setParent(self, parent):
        self.__menuContainer.reparentTo(parent)

    def setPos(self, x, y, z):
        self.__menuContainer.setPos(x, y, z)
コード例 #11
0
class QuestMap(DirectFrame):
    def __init__(self, av, **kw):
        DirectFrame.__init__(self, relief=None, sortOrder=50)
        self.initialiseoptions(QuestMap)
        self.container = DirectFrame(parent=self, relief=None)
        self.marker = DirectFrame(parent=self.container, relief=None)
        self.cogInfoFrame = DirectFrame(parent=self.container, relief=None)
        cm = CardMaker('bg')
        cm.setFrame(-0.5, 0.5, -0.5, 0.5)
        bg = self.cogInfoFrame.attachNewNode(cm.generate())
        bg.setTransparency(1)
        bg.setColor(0.5, 0.5, 0.5, 0.5)
        bg.setBin('fixed', 0)
        self.cogInfoFrame['geom'] = bg
        self.cogInfoFrame['geom_pos'] = (0, 0, 0)
        self.cogInfoFrame['geom_scale'] = (6, 1, 2)
        self.cogInfoFrame.setScale(0.05)
        self.cogInfoFrame.setPos(0, 0, 0.6)
        self.buildingMarkers = []
        self.av = av
        self.wantToggle = False
        if base.config.GetBool('want-toggle-quest-map', True):
            self.wantToggle = True
        self.updateMarker = True
        self.cornerPosInfo = None
        self.hqPosInfo = None
        self.fishingSpotInfo = None
        self.load()
        self.setScale(1.5)
        bg.removeNode()
        self.hoodId = None
        self.zoneId = None
        self.suitPercentage = {}
        for currHoodInfo in SuitPlannerBase.SuitPlannerBase.SuitHoodInfo:
            tracks = currHoodInfo[
                SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
            self.suitPercentage[currHoodInfo[
                SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks

        return

    def load(self):
        gui = loader.loadModel('phase_4/models/questmap/questmap_gui')
        icon = gui.find('**/tt_t_gui_qst_arrow')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setR(90)
        self.marker['geom'] = iconNP
        self.marker['image'] = iconNP
        self.marker.setScale(0.05)
        iconNP.removeNode()
        self.mapOpenButton = DirectButton(
            image=(gui.find('**/tt_t_gui_qst_mapClose'),
                   gui.find('**/tt_t_gui_qst_mapClose'),
                   gui.find('**/tt_t_gui_qst_mapTryToOpen')),
            relief=None,
            pos=(-0.084, 0, 0.37),
            parent=base.a2dBottomRight,
            scale=0.205,
            command=self.show)
        self.mapCloseButton = DirectButton(
            image=(gui.find('**/tt_t_gui_qst_mapOpen'),
                   gui.find('**/tt_t_gui_qst_mapOpen'),
                   gui.find('**/tt_t_gui_qst_mapTryToClose')),
            relief=None,
            pos=(-0.084, 0, 0.37),
            parent=base.a2dBottomRight,
            scale=0.205,
            command=self.hide)
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()
        gui.removeNode()
        icons = loader.loadModel('phase_3/models/gui/cog_icons')
        cIcon = icons.find('**/CorpIcon')
        lIcon = icons.find('**/LegalIcon')
        mIcon = icons.find('**/MoneyIcon')
        sIcon = icons.find('**/SalesIcon')
        cogInfoTextColor = (0.2, 0.2, 0.2, 1)
        textPos = (1.2, -0.2)
        textScale = 0.8
        self.cInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text='',
                                 text_fg=cogInfoTextColor,
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=cIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.cInfo.setPos(-2.2, 0, 0.5)
        self.lInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=lIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.lInfo.setPos(-2.2, 0, -0.5)
        self.mInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=mIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.mInfo.setPos(0.8, 0, 0.5)
        self.sInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=sIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.sInfo.setPos(0.8, 0, -0.5)
        icons.removeNode()
        return

    def updateCogInfo(self):
        currPercentage = self.suitPercentage.get(self.zoneId)
        if currPercentage is None:
            return
        self.cInfo['text'] = '%s%%' % currPercentage[0]
        self.lInfo['text'] = '%s%%' % currPercentage[1]
        self.mInfo['text'] = '%s%%' % currPercentage[2]
        self.sInfo['text'] = '%s%%' % currPercentage[3]
        return

    def destroy(self):
        self.ignore('questPageUpdated')
        self.mapOpenButton.destroy()
        self.mapCloseButton.destroy()
        del self.mapOpenButton
        del self.mapCloseButton
        DirectFrame.destroy(self)

    def putBuildingMarker(self, pos, hpr=(0, 0, 0), mapIndex=None):
        marker = DirectLabel(parent=self.container,
                             text='',
                             text_pos=(-0.05, -0.15),
                             text_fg=(1, 1, 1, 1),
                             relief=None)
        gui = loader.loadModel(
            'phase_4/models/parties/schtickerbookHostingGUI')
        icon = gui.find('**/startPartyButton_inactive')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setX(-12.0792 / 30.48)
        icon.setZ(-9.7404 / 30.48)
        marker['text'] = '%s' % mapIndex
        marker['text_scale'] = 0.7
        marker['image'] = iconNP
        marker['image_color'] = (1, 0, 0, 1)
        marker['image_scale'] = 6
        marker.setScale(0.05)
        relX, relY = self.transformAvPos(pos)
        marker.setPos(relX, 0, relY)
        self.buildingMarkers.append(marker)
        iconNP.removeNode()
        gui.removeNode()
        return

    def updateQuestInfo(self):
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        dnaStore = base.cr.playGame.dnaStore
        for questIndex in self.av.questPage.quests.keys():
            questDesc = self.av.questPage.quests.get(questIndex)
            if questDesc is None:
                continue
            mapIndex = questIndex + 1
            questId, fromNpcId, toNpcId, rewardId, toonProgress = questDesc
            quest = Quests.getQuest(questId)
            fComplete = quest.getCompletionStatus(self.av,
                                                  questDesc) == Quests.COMPLETE
            if not fComplete:
                if quest.getType() == Quests.RecoverItemQuest:
                    if quest.getHolder() == Quests.AnyFish:
                        self.putBuildingMarker(self.fishingSpotInfo,
                                               mapIndex=mapIndex)
                    continue
                elif quest.getType(
                ) != Quests.DeliverGagQuest and quest.getType(
                ) != Quests.DeliverItemQuest and quest.getType(
                ) != Quests.VisitQuest and quest.getType(
                ) != Quests.TrackChoiceQuest:
                    continue
            if toNpcId == Quests.ToonHQ:
                self.putBuildingMarker(self.hqPosInfo, mapIndex=mapIndex)
            else:
                npcZone = NPCToons.getNPCZone(toNpcId)
                hoodId = ZoneUtil.getCanonicalHoodId(npcZone)
                branchId = ZoneUtil.getCanonicalBranchZone(npcZone)
                if self.hoodId == hoodId and self.zoneId == branchId:
                    for blockIndex in xrange(dnaStore.getNumBlockTitles()):
                        blockNumber = dnaStore.getTitleBlockAt(blockIndex)
                        zone = dnaStore.getZoneFromBlockNumber(blockNumber)
                        branchZone = zone - zone % 100
                        finalZone = branchZone + 500 + blockNumber
                        buildingType = dnaStore.getBlockBuildingType(
                            blockNumber)
                        if npcZone == finalZone:
                            self.putBuildingMarker(
                                dnaStore.getDoorPosHprFromBlockNumber(
                                    blockNumber).getPos(),
                                dnaStore.getDoorPosHprFromBlockNumber(
                                    blockNumber).getHpr(),
                                mapIndex=mapIndex)

        return

    def transformAvPos(self, pos):
        if self.cornerPosInfo is None:
            return (0, 0)
        topRight = self.cornerPosInfo[0]
        bottomLeft = self.cornerPosInfo[1]
        relativeX = (pos.getX() - bottomLeft.getX()) / (
            topRight.getX() - bottomLeft.getX()) - 0.5
        relativeY = (pos.getY() - bottomLeft.getY()) / (
            topRight.getY() - bottomLeft.getY()) - 0.5
        return (relativeX, relativeY)

    def update(self, task):
        if self.av:
            if self.updateMarker:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
        i = 0
        for buildingMarker in self.buildingMarkers:
            buildingMarker.setScale(
                (math.sin(task.time * 16.0 + i * math.pi / 3.0) + 1) * 0.005 +
                0.04)
            i = i + 1

        return Task.cont

    def updateMap(self):
        if self.av:
            try:
                hoodId = ZoneUtil.getCanonicalHoodId(self.av.getLocation()[1])
                zoneId = ZoneUtil.getCanonicalBranchZone(
                    self.av.getLocation()[1])
                mapsGeom = loader.loadModel('phase_4/models/questmap/%s_maps' %
                                            ToontownGlobals.dnaMap[hoodId])
                mapImage = mapsGeom.find(
                    '**/%s_%s_english' %
                    (ToontownGlobals.dnaMap[hoodId], zoneId))
                if not mapImage.isEmpty():
                    self.container['image'] = mapImage
                    self.resetFrameSize()
                    self.cornerPosInfo = QuestMapGlobals.CornerPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.hqPosInfo = QuestMapGlobals.HQPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.fishingSpotInfo = QuestMapGlobals.FishingSpotPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.cogInfoPos = QuestMapGlobals.CogInfoPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.cogInfoFrame.setPos(self.cogInfoPos)
                    self.hide()
                    self.hoodId = hoodId
                    self.zoneId = zoneId
                    self.updateQuestInfo()
                    self.updateCogInfo()
                    taskMgr.add(self.update, 'questMapUpdate')
                else:
                    self.stop()
                mapsGeom.removeNode()
            except:
                self.stop()

    def start(self):
        self.container.show()
        self.accept('questPageUpdated', self.updateMap)
        self.handleMarker()
        self.updateMap()

    def initMarker(self, task):
        if self.av:
            if not hasattr(base.cr.playGame.getPlace(), 'isInterior'
                           ) or not base.cr.playGame.getPlace().isInterior:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
            self.marker['geom_scale'] = 1.4 * task.time % 0.5 * 10 + 1
            self.marker['geom_color'] = (1, 1, 1, 0.8 -
                                         1.4 * task.time % 0.5 * 2 / 0.8 + 0.2)
        if task.time < 1:
            return Task.cont
        else:
            self.marker['geom_color'] = (1, 1, 1, 0)
            return Task.done

    def show(self):
        taskMgr.add(self.initMarker, 'questMapInit')
        DirectFrame.show(self)
        self.mapOpenButton.hide()
        if self.container['image']:
            self.mapCloseButton.show()

    def hide(self):
        taskMgr.remove('questMapInit')
        DirectFrame.hide(self)
        if self.container['image']:
            self.mapOpenButton.show()
        self.mapCloseButton.hide()

    def toggle(self):
        if self.isHidden():
            self.show()
        else:
            self.hide()

    def obscureButton(self):
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()

    def stop(self):
        self.container['image'] = None
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        self.container.hide()
        self.hide()
        self.obscureButton()
        self.ignore('questPageUpdated')
        taskMgr.remove('questMapUpdate')
        return

    def handleMarker(self):
        if hasattr(base.cr.playGame.getPlace(),
                   'isInterior') and base.cr.playGame.getPlace().isInterior:
            self.updateMarker = False
        else:
            self.updateMarker = True

    def acceptOnscreenHooks(self):
        if self.wantToggle:
            self.accept(ToontownGlobals.MapHotkey, self.toggle)
        else:
            self.accept(ToontownGlobals.MapHotkeyOn, self.show)
            self.accept(ToontownGlobals.MapHotkeyOff, self.hide)
        self.updateMap()

    def ignoreOnscreenHooks(self):
        self.ignore(ToontownGlobals.MapHotkey)
        self.ignore(ToontownGlobals.MapHotkeyOn)
        self.ignore(ToontownGlobals.MapHotkeyOff)
        self.obscureButton()
コード例 #12
0
class IssueFrameV2(IssueFrame.IssueFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('IssueFrameV2')
    SectionIdents = ['hom', 'new', 'evt', 'tot', 'att', 'tnr', 'ext']

    def __init__(self, parent, newsDir, dateStr, myIssueIndex, numIssues,
                 strFilenames, newsIndexEntries):
        self.newsIndexEntries = newsIndexEntries
        self.dateStr = dateStr
        self.calcActualSectionsInThisIssue()
        IssueFrame.IssueFrame.__init__(self, parent, newsDir, dateStr,
                                       myIssueIndex, numIssues, strFilenames)
        self.notify.debug('version2 %s' % dateStr)

    def load(self):
        self.guiNavV2 = loader.loadModel(
            'phase_3.5/models/gui/tt_m_gui_ign_directNewsGuiNavV2')
        IssueFrame.IssueFrame.load(self)

    def calcActualSectionsInThisIssue(self):
        self.actualSectionIdents = []
        for ident in self.SectionIdents:
            identTest = self.dateStr + '_' + ident + '1'
            if self.isSectionInIndex(identTest):
                self.actualSectionIdents.append(ident)
                continue

    def isSectionInIndex(self, sectionIdent):
        for name in self.newsIndexEntries:
            if sectionIdent in name and self.dateStr in name:
                return True
                continue

        return False

    def parseNewsContent(self):
        existingSectionIndex = 0
        for (section, ident) in enumerate(self.SectionIdents):
            subSectionList = []
            curSubSection = 0
            endSearch = False
            while not endSearch:
                justName = self.ContentPattern % (self.dateStr, ident,
                                                  curSubSection + 1)
                fullName = Filename(self.newsDir + '/' + justName)
                if self.strFilenames:
                    if justName in self.strFilenames:
                        subSectionList.append(fullName)
                        self.flatSubsectionList.append(
                            (existingSectionIndex, curSubSection))
                        curSubSection += 1
                    else:
                        endSearch = True
                justName in self.strFilenames
                theFile = vfs.getFile(Filename(fullName), status_only=1)
                if theFile:
                    subSectionList.append(fullName)
                    self.flatSubsectionList.append(
                        (existingSectionIndex, curSubSection))
                    curSubSection += 1
                    continue
                if curSubSection == 0 and self.isSectionInIndex(ident):
                    self.notify.warning('could not find %s' % fullName)
                    subSectionList.append(fullName)
                    self.flatSubsectionList.append(
                        (existingSectionIndex, curSubSection))

                endSearch = True
            if not subSectionList:
                continue
            self.sectionList.append(subSectionList)
            existingSectionIndex += 1

        self.notify.debug('IssueFrameV2 self.sectionList=%s' %
                          self.sectionList)

    def loadHomePageButtons(self, section, subsection, pageFrame):
        self.notify.debug('Doing nothing for loadNavButtons')
        if section == 0 and subsection == 0:
            self.loadNavButtons(pageFrame)
            self.parentOfWeekNav = DirectFrame(frameColor=(1, 1, 1, 0),
                                               relief=DGG.FLAT,
                                               parent=pageFrame)
            self.loadWeekNavButtons(self.parentOfWeekNav)
            self.parentOfWeekNav.setPos(-1.9399999999999999, 0, 0)

    def loadNavButtons(self, pageFrame):
        identToButtonNames = {
            'hom': 'tt_i_art_btn_NavHom2',
            'new': 'tt_i_art_btn_NavNew2',
            'evt': 'tt_i_art_btn_NavEvt2',
            'tot': 'tt_i_art_btn_NavTot2',
            'att': 'tt_i_art_btn_NavAtt2',
            'tnr': 'tt_i_art_btn_NavTnr2',
            'ext': 'tt_i_art_btn_NavExt2'
        }
        identToRolloverButtonNames = {
            'hom': 'tt_i_art_btn_NavHomRo2',
            'new': 'tt_i_art_btn_NavNewRo2',
            'evt': 'tt_i_art_btn_NavEvtRo2',
            'tot': 'tt_i_art_btn_NavTotRo2',
            'att': 'tt_i_art_btn_NavAttRo2',
            'tnr': 'tt_i_art_btn_NavTnrRo2',
            'ext': 'tt_i_art_btn_NavExtRo2'
        }
        xPos = 1.2466699999999999
        positions = [(xPos, 0, 0.62333300000000003), (xPos, 0, 0.536663),
                     (xPos, 0, 0.45000000000000001),
                     (xPos, 0, 0.36332999999999999), (xPos, 0, 0.276667),
                     (xPos, 0, 0.19), (xPos, 0, 0.080000000000000002)]
        xSize1 = 177
        desiredXSize1 = 90
        image_scale1 = float(desiredXSize1) / xSize1
        image_scale = 1
        xSize2 = 300
        desiredXSize2 = 152
        image_scale2 = float(desiredXSize2) / xSize2
        image_scale2 *= 30.0 / 30.0
        rolloverPositions = [(1.0449999999999999, 0, 0.62333300000000003),
                             (1.0449999999999999, 0, 0.53333299999999995),
                             (1.0449999999999999, 0, 0.44333299999999998),
                             (1.0449999999999999, 0, 0.35333300000000001),
                             (1.0449999999999999, 0, 0.26333400000000001),
                             (1.0449999999999999, 0, 0.17333299999999999),
                             (1.0449999999999999, 0, 0.089999999999999997)]
        imageScales = [
            image_scale2, image_scale2, image_scale2, image_scale2,
            image_scale2, image_scale2, image_scale2
        ]
        frameSizeAdj1 = 0.10000000000000001
        frameSize1 = (-0.040000000000000001 + frameSizeAdj1,
                      0.040000000000000001 + frameSizeAdj1,
                      -0.040000000000000001, 0.040000000000000001)
        frameSizeAdj2 = 0.20999999999999999
        frameSize2 = (-0.040000000000000001 + frameSizeAdj2,
                      0.040000000000000001 + frameSizeAdj2,
                      -0.040000000000000001, 0.040000000000000001)
        frameSizes = (frameSize2, frameSize2, frameSize2, frameSize2,
                      frameSize2, frameSize2, frameSize2)
        self.sectionBtns = []
        for (section, ident) in enumerate(self.actualSectionIdents):
            image = self.guiNavV2.find('**/%s' % identToButtonNames[ident])
            rolloverImage = self.guiNavV2.find(
                '**/%s' % identToRolloverButtonNames[ident])
            if image.isEmpty():
                self.notify.error('cant find %s' % identToButtonNames[ident])

            sectionBtn = DirectButton(relief=None,
                                      parent=pageFrame,
                                      frameSize=frameSizes[section],
                                      image=(image, rolloverImage,
                                             rolloverImage, image),
                                      image_scale=imageScales[section],
                                      command=self.gotoPage,
                                      extraArgs=(section, 0),
                                      enableEdit=1,
                                      pos=rolloverPositions[section])
コード例 #13
0
class GuiConsole(DirectObject.DirectObject):
    def __init__(self, class_parent, parent, h_size, v_size, aspect, hugpos):
        self.h_size = h_size
        self.v_size = v_size
        self.scale = 0.04
        self.parent = class_parent
        self.numlines = int(v_size / self.scale - 2)

        self.pos_min_x = 0
        self.pos_min_y = 0
        self.pos_max_x = self.h_size
        self.pos_max_y = 0.7

        if aspect > 0:
            self.pos_max_x /= aspect
        else:
            self.pos_max_y *= aspect

        self.consoleFrame = DirectFrame(relief=DGG.RIDGE,
                                        frameColor=(0, 0, 0, 0),
                                        scale=self.scale,
                                        frameSize=(0, self.h_size / self.scale,
                                                   0,
                                                   self.v_size / self.scale))

        if parent == base.a2dBottomLeft:  #@UndefinedVariable
            self.pos_min_x -= 1
            self.pos_min_y -= 1
            self.pos_max_x -= 1
            self.pos_max_y -= 1

        if hugpos == "bottom":
            self.consoleFrame.setPos(0, 0, GUI_BOTTOM_OFFSET - 0.085)
            self.pos_min_x = 0
            self.pos_min_y = GUI_BOTTOM_OFFSET - 0.085 - 0.07
            self.pos_max_x = self.h_size
            self.pos_max_y = GUI_BOTTOM_OFFSET - 0.085

        fixedWidthFont = loader.loadFont(GUI_FONT)  #@UndefinedVariable
        #fixedWidthFont.setPixelsPerUnit(60)
        #fixedWidthFont.setRenderMode(fixedWidthFont.RMSolid)
        if not fixedWidthFont.isValid():
            print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(
                self.font)
            fixedWidthFont = DGG.getDefaultFont()

        #fixedWidthFont.setPageSize(512,512)
        #fixedWidthFont.setPixelsPerUnit(60)

        self.consoleEntry = DirectEntry(
            self.consoleFrame,
            text="",
            command=self.onEnterPress
            #, width       = self.h_size/self.scale -2
            ,
            pos=(0.01, 0, 0.02),
            initialText="Enter text...",
            numLines=1,
            focus=0,
            entryFont=fixedWidthFont,
            scale=1,
            frameColor=(0, 0, 0, 0.2),
            text_fg=(0, 1, 0, 1),
            text_shadow=(0, 0, 0, 1))

        #self.consoleEntry = DirectEntry(self.consoleFrame)

        self.consoleEntry["frameSize"] = (0, self.h_size / self.scale, 0, 1)
        self.consoleEntry["width"] = self.h_size / self.scale
        self.consoleEntry["focusInCommand"] = self.focusInCallback
        self.consoleEntry["focusOutCommand"] = self.focusOutCallback

        self.consoleFrame.reparentTo(parent)

        self.textBuffer = list()
        self.textBufferLength = 100
        for i in xrange(self.textBufferLength):
            self.textBuffer.append(['', (100, 100, 100, 1)])
        self.textBufferPos = self.textBufferLength - self.numlines

        # output lines
        self.consoleOutputList = list()
        for i in xrange(self.numlines):
            label = OnscreenText(parent=self.consoleFrame,
                                 text="",
                                 pos=(0, i + 1.5),
                                 align=TextNode.ALeft,
                                 mayChange=1,
                                 scale=1.0,
                                 fg=(100, 100, 100, 1),
                                 shadow=(0, 0, 0, 1))
            # , frame = (200,0,0,1) )
            label.setFont(fixedWidthFont)
            self.consoleOutputList.append(label)

        self.linelength = 57
        self.linewrap = textwrap.TextWrapper()
        self.linewrap.width = self.linelength
        self.toggleConsole()

    def focusInCallback(self):
        self.parent.parent.camera_manager.disableKeyMovement()

    def focusOutCallback(self):
        self.parent.parent.camera_manager.enableKeyMovement()

    def show(self):
        if self.consoleFrame.isHidden():
            self.consoleFrame.toggleVis()

    def hide(self):
        pass
        #if not self.consoleFrame.isHidden():
        #    self.consoleFrame.toggleVis()

    def toggleConsole(self):
        self.consoleFrame.toggleVis()
        hidden = self.consoleFrame.isHidden()
        #self.consoleEntry['focus'] != hidden
        if hidden:
            #self.ignoreAll()
            self.accept('control', self.toggleConsole)
            self.accept('enter', self.manageFocus)
            self.accept('escape', self.unfocus)
        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('control', self.toggleConsole)
            self.accept('enter', self.manageFocus)
            self.accept('escape', self.unfocus)
            #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 onEnterPress(self, textEntered):
        # set to last message
        self.textBufferPos = self.textBufferLength - self.numlines
        # clear line
        self.consoleEntry.enterText('')
        self.consoleOutput(textEntered, utils.CONSOLE_PLAYER1_TEXT)
        ClientMsg.chat(textEntered)
        self.focus()

    def manageFocus(self):
        if self.consoleFrame.isHidden():
            self.consoleFrame.toggleVis()

        if self.consoleEntry["focus"] == 0:
            self.focus()

    def consoleOutput(self, printString, msgType):
        if msgType == utils.CONSOLE_SYSTEM_ERROR:
            self.write(printString, utils.CONSOLE_SYSTEM_ERROR_TEXT_COLOR)
        elif msgType == utils.CONSOLE_SYSTEM_MESSAGE:
            self.write(printString, utils.CONSOLE_SYSTEM_MESSAGE_TEXT_COLOR)
        elif msgType == utils.CONSOLE_PLAYER1_TEXT:
            self.write(printString, utils.CONSOLE_PLAYER1_TEXT_COLOR)
        else:
            self.write(printString, utils.CONSOLE_PLAYER2_TEXT_COLOR)

    def write(self, printString, color=(100, 100, 100, 0.5)):
        # 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[self.numlines - lineNumber -
                                   1].setText(lineText)
            self.consoleOutputList[self.numlines - lineNumber -
                                   1]['fg'] = color

    def focus(self):
        self.consoleEntry['focus'] = 1

    def unfocus(self):
        self.consoleEntry['focus'] = 0

    def getTightBounds(self):
        l, r, b, t = self.consoleFrame.getBounds()
        print l, r, b, t
        bottom_left = Point3(l, 0, b)
        top_right = Point3(r, 0, t)
        return (bottom_left, top_right)
コード例 #14
0
class IssueFrameV2(IssueFrame.IssueFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('IssueFrameV2')
    SectionIdents = ['hom',
     'new',
     'evt',
     'tot',
     'att',
     'tnr',
     'ext']

    def __init__(self, parent, newsDir, dateStr, myIssueIndex, numIssues, strFilenames, newsIndexEntries):
        self.newsIndexEntries = newsIndexEntries
        self.dateStr = dateStr
        self.calcActualSectionsInThisIssue()
        IssueFrame.IssueFrame.__init__(self, parent, newsDir, dateStr, myIssueIndex, numIssues, strFilenames)
        self.notify.debug('version2 %s' % dateStr)

    def load(self):
        self.guiNavV2 = loader.loadModel('phase_3.5/models/gui/tt_m_gui_ign_directNewsGuiNavV2')
        IssueFrame.IssueFrame.load(self)

    def calcActualSectionsInThisIssue(self):
        self.actualSectionIdents = []
        for ident in self.SectionIdents:
            identTest = self.dateStr + '_' + ident + '1'
            if self.isSectionInIndex(identTest):
                self.actualSectionIdents.append(ident)

    def isSectionInIndex(self, sectionIdent):
        for name in self.newsIndexEntries:
            if sectionIdent in name and self.dateStr in name:
                return True

        return False

    def parseNewsContent(self):
        existingSectionIndex = 0
        for section, ident in enumerate(self.SectionIdents):
            subSectionList = []
            curSubSection = 0
            endSearch = False
            while not endSearch:
                justName = self.ContentPattern % (self.dateStr, ident, curSubSection + 1)
                fullName = Filename(self.newsDir + '/' + justName)
                if self.strFilenames:
                    if justName in self.strFilenames:
                        subSectionList.append(fullName)
                        self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        curSubSection += 1
                    else:
                        endSearch = True
                else:
                    theFile = vfs.getFile(Filename(fullName), status_only=1)
                    if theFile:
                        subSectionList.append(fullName)
                        self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        curSubSection += 1
                    else:
                        if curSubSection == 0 and self.isSectionInIndex(ident):
                            self.notify.warning('could not find %s' % fullName)
                            subSectionList.append(fullName)
                            self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        endSearch = True

            if not subSectionList:
                pass
            else:
                self.sectionList.append(subSectionList)
                existingSectionIndex += 1

        self.notify.debug('IssueFrameV2 self.sectionList=%s' % self.sectionList)

    def loadHomePageButtons(self, section, subsection, pageFrame):
        self.notify.debug('Doing nothing for loadNavButtons')
        if section == 0 and subsection == 0:
            self.loadNavButtons(pageFrame)
            self.parentOfWeekNav = DirectFrame(frameColor=(1, 1, 1, 0), relief=DGG.FLAT, parent=pageFrame)
            self.loadWeekNavButtons(self.parentOfWeekNav)
            self.parentOfWeekNav.setPos(-1.94, 0, 0)

    def loadNavButtons(self, pageFrame):
        identToButtonNames = {'hom': 'tt_i_art_btn_NavHom2',
         'new': 'tt_i_art_btn_NavNew2',
         'evt': 'tt_i_art_btn_NavEvt2',
         'tot': 'tt_i_art_btn_NavTot2',
         'att': 'tt_i_art_btn_NavAtt2',
         'tnr': 'tt_i_art_btn_NavTnr2',
         'ext': 'tt_i_art_btn_NavExt2'}
        identToRolloverButtonNames = {'hom': 'tt_i_art_btn_NavHomRo2',
         'new': 'tt_i_art_btn_NavNewRo2',
         'evt': 'tt_i_art_btn_NavEvtRo2',
         'tot': 'tt_i_art_btn_NavTotRo2',
         'att': 'tt_i_art_btn_NavAttRo2',
         'tnr': 'tt_i_art_btn_NavTnrRo2',
         'ext': 'tt_i_art_btn_NavExtRo2'}
        xPos = 1.24667
        positions = [(xPos, 0, 0.623333),
         (xPos, 0, 0.536663),
         (xPos, 0, 0.45),
         (xPos, 0, 0.36333),
         (xPos, 0, 0.276667),
         (xPos, 0, 0.19),
         (xPos, 0, 0.08)]
        xSize1 = 177
        desiredXSize1 = 90
        image_scale1 = float(desiredXSize1) / xSize1
        image_scale = 1
        xSize2 = 300
        desiredXSize2 = 152
        image_scale2 = float(desiredXSize2) / xSize2
        image_scale2 *= 30.0 / 30.0
        rolloverPositions = [(1.045, 0, 0.623333),
         (1.045, 0, 0.533333),
         (1.045, 0, 0.443333),
         (1.045, 0, 0.353333),
         (1.045, 0, 0.263334),
         (1.045, 0, 0.173333),
         (1.045, 0, 0.09)]
        imageScales = [image_scale2,
         image_scale2,
         image_scale2,
         image_scale2,
         image_scale2,
         image_scale2,
         image_scale2]
        frameSizeAdj1 = 0.1
        frameSize1 = (-0.04 + frameSizeAdj1,
         0.04 + frameSizeAdj1,
         -0.04,
         0.04)
        frameSizeAdj2 = 0.21
        frameSize2 = (-0.04 + frameSizeAdj2,
         0.04 + frameSizeAdj2,
         -0.04,
         0.04)
        frameSizes = (frameSize2,
         frameSize2,
         frameSize2,
         frameSize2,
         frameSize2,
         frameSize2,
         frameSize2)
        self.sectionBtns = []
        for section, ident in enumerate(self.actualSectionIdents):
            image = self.guiNavV2.find('**/%s' % identToButtonNames[ident])
            rolloverImage = self.guiNavV2.find('**/%s' % identToRolloverButtonNames[ident])
            if image.isEmpty():
                self.notify.error('cant find %s' % identToButtonNames[ident])
            sectionBtn = DirectButton(relief=None, parent=pageFrame, frameSize=frameSizes[section], image=(image,
             rolloverImage,
             rolloverImage,
             image), image_scale=imageScales[section], command=self.gotoPage, extraArgs=(section, 0), enableEdit=1, pos=rolloverPositions[section])

        return
コード例 #15
0
class RailsScheme:
    """Rails scheme GUI.

    Represents the railways map, which can be used by
    players to choose the right way across the game world.

    Args:
        world_map (list): All the world blocks.
    """
    def __init__(self, world_map):
        self.is_shown = False
        self._temp_wids = []

        self._open_snd = loader.loadSfx("sounds/GUI/paper1.ogg")  # noqa: F821
        self._close_snd = loader.loadSfx("sounds/GUI/paper2.ogg")  # noqa: F821
        self._world_map = world_map

        self._list = DirectFrame(
            frameSize=(-1.2, 1.2, -0.6, 0.6),
            frameTexture="gui/tex/paper2.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        DirectLabel(  # Silewer Railways Scheme
            parent=self._list,
            text=base.labels.SCHEME[0],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.2, 0.2, 0.2, 0.2),
            text_scale=0.035,
            pos=(0, 0, 0.5),
        )
        self._scheme = DirectFrame(
            parent=self._list,
            frameSize=(-1.1, 1.1, -0.3, 0.3),
            frameTexture="gui/tex/world_scheme.png",
        )
        self._scheme.setTransparency(TransparencyAttrib.MAlpha)

        self._arrow = DirectFrame(
            parent=self._scheme,
            frameSize=(-0.02, 0.02, -0.02, 0.02),
            frameTexture="gui/tex/train_dir.png",
            pos=(-0.96, 0, 0.07),
        )
        self._build_legend()

    def _build_legend(self):
        """Build the scheme legend GUI."""
        lab_opts = {
            "parent": self._list,
            "text_scale": 0.033,
            "frameColor": (0, 0, 0, 0),
            "frameSize": (-0.1, 0.1, -0.1, 0.1),
        }
        DirectLabel(  # Legend
            text=base.labels.SCHEME[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_align=TextNode.ALeft,
            pos=(-1, 0, -0.35),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameTexture="gui/tex/city.png",
            frameSize=(-0.04, 0.04, -0.04, 0.04),
            pos=(-0.39, 0, -0.41),
        )
        DirectLabel(  # city
            text=base.labels.SCHEME[2],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(-0.3, 0, -0.42),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameTexture="gui/tex/dash.png",
            frameSize=(-0.004, 0.004, -0.06, 0.06),
            frameColor=(0, 0, 0, 0.2),
            pos=(0.09, 0, -0.37),
        ).setR(90)

        DirectLabel(
            text=base.labels.SCHEME[3],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(0.29, 0, -0.38),
            **lab_opts,
        )
        DirectFrame(
            parent=self._scheme,
            frameColor=(0.71, 0.25, 0.05, 0.2),
            frameSize=(-0.06, 0.06, -0.02, 0.02),
            pos=(0.09, 0, -0.45),
        )
        DirectLabel(
            text=base.labels.SCHEME[4],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            pos=(0.26, 0, -0.46),
            **lab_opts,
        )

    def _fill_branches(self):
        """Paint railway branches on the railways scheme."""
        for branch in base.world.branches:  # noqa: F821
            start = -0.96 + self._world_map[branch["start"]].id * 0.0032
            self._temp_wids.append(
                DirectFrame(
                    parent=self._scheme,
                    frameTexture="gui/tex/dash.png",
                    frameSize=(-0.004, 0.004, -0.1, 0.1),
                    frameColor=(0, 0, 0, 0.2),
                    pos=(start, 0, 0.1 if branch["side"] == "l" else -0.1),
                ))
            end = -0.96 + self._world_map[branch["end"]].id * 0.0032
            self._temp_wids.append(
                DirectFrame(
                    parent=self._scheme,
                    frameTexture="gui/tex/dash.png",
                    frameSize=(-0.004, 0.004, -0.1, 0.1),
                    frameColor=(0, 0, 0, 0.2),
                    pos=(end, 0, 0.1 if branch["side"] == "l" else -0.1),
                ))

            x_coor = (start + end) / 2

            horiz = DirectFrame(
                parent=self._scheme,
                frameTexture="gui/tex/dash.png",
                frameSize=(-0.004, 0.004, -(x_coor - start), end - x_coor),
                frameColor=(0, 0, 0, 0.2),
                pos=(x_coor, 0, 0.2 if branch["side"] == "l" else -0.2),
            )
            horiz.setR(90)
            self._temp_wids.append(horiz)

            outs = ""
            for block in branch["blocks"][1:-1]:
                if block.outing_available:
                    outs += block.outing_available[0]

                if block.is_station:
                    outs += "i"

            if outs:
                outs = outs.lower()
                self._temp_wids.append(
                    DirectLabel(
                        parent=self._scheme,
                        text=outs,
                        text_scale=0.035,
                        text_bg=(0, 0, 0, 0),
                        text_fg=(0, 0, 0, 0.5),
                        frameColor=(0, 0, 0, 0),
                        pos=(x_coor, 0,
                             0.25 if branch["side"] == "l" else -0.27),
                    ))

    def _fill_scheme(self):
        """Fill the railways scheme with the world data.

        Shows cities, outings and railway branches on the scheme.
        """
        self._fill_branches()

        outs = None
        cities = 0
        for block in self._world_map[:601]:
            if block.id % 100 == 0:
                if outs:
                    self._temp_wids.append(
                        DirectLabel(
                            parent=self._scheme,
                            text=outs,
                            text_scale=0.035,
                            text_bg=(0, 0, 0, 0),
                            frameColor=(0, 0, 0, 0),
                            pos=(-0.96 + (block.id - 50) * 0.0032, 0, -0.1),
                        ))
                outs = ""

            if block.outing_available:
                outs += block.outing_available[0].lower()

            if block.is_station:
                outs += "i"

            if block.is_city:
                self._temp_wids.append(
                    DirectFrame(
                        parent=self._scheme,
                        frameTexture="gui/tex/city.png",
                        frameSize=(-0.04, 0.04, -0.04, 0.04),
                        pos=(-0.96 + block.id * 0.0032, 0, 0),
                    ))
                self._temp_wids.append(
                    DirectLabel(
                        parent=self._scheme,
                        text=base.labels.CITY_NAMES[cities],  # noqa: F821
                        text_font=base.main_font,  # noqa: F821
                        text_scale=0.032,
                        text_bg=(0, 0, 0, 0),
                        frameColor=(0, 0, 0, 0),
                        pos=(-0.96 + block.id * 0.0032, 0, 0.1),
                    ))
                cities += 1

        self._temp_wids.append(
            DirectFrame(
                parent=self._scheme,
                frameColor=(0.71, 0.25, 0.05, 0.2),
                frameSize=(
                    0,
                    base.world.stench_step * 0.0032,  # noqa: F821
                    -0.22,
                    0.22,
                ),
                pos=(-0.96, 0, 0),
            ))

    def _update_arrow(self, task):
        """Update the Train position on the scheme."""
        blocks = base.world.current_blocks  # noqa: F821
        if blocks and blocks[0] != -1:

            z_shift = 0
            if not base.world.is_near_fork:  # noqa: F821
                if base.world.current_block.branch == "l":  # noqa: F821
                    z_shift = 0.155
                elif base.world.current_block.branch == "r":  # noqa: F821
                    z_shift = -0.295

            if blocks[0] < 600:
                x = -0.96 + blocks[0] * 0.0032
            else:
                x = self._arrow.getX()

            self._arrow.setPos(x, 0, 0.07 + z_shift)

            if blocks[0] < blocks[1]:
                self._arrow["frameTexture"] = "gui/tex/train_dir.png"
            else:
                self._arrow["frameTexture"] = "gui/tex/train_dir_op.png"

        task.delayTime = 5
        return task.again

    def show(self):
        """Show/hide railways scheme GUI."""
        if (self.is_shown or base.world.outings_mgr.gui_is_shown  # noqa: F821
                or base.traits_gui.is_shown  # noqa: F821
            ):
            self._close_snd.play()
            self._list.hide()
            taskMgr.remove("update_scheme_arrow")  # noqa: F821

            clear_wids(self._temp_wids)
        else:
            if base.world.is_on_et:  # noqa: F821
                return

            self._open_snd.play()
            taskMgr.doMethodLater(  # noqa: F821
                0.2, self._update_arrow, "update_scheme_arrow")
            self._fill_scheme()
            self._list.show()
            base.char_gui.clear_char_info(True)  # noqa: F821

        self.is_shown = not self.is_shown
コード例 #16
0
ファイル: panda3d.py プロジェクト: borgified/Hockfire
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.9, 0.9, 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),
        )
        self.windowEvent(base.win)

        # try to load the defined font
        fixedWidthFont = loader.loadFont(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 F10 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)
コード例 #17
0
ファイル: window.py プロジェクト: ondrocks/cosmonium
class Window():
    texture = None

    def __init__(self,
                 title,
                 scale,
                 parent=None,
                 child=None,
                 transparent=False,
                 owner=None):
        self.scale = scale
        self.owner = owner
        self.last_pos = None
        self.title_text = title
        self.title_color = (1, 1, 1, 1)
        self.title_pad = tuple(self.scale * 2)
        if parent is None:
            parent = aspect2d
        self.parent = parent
        if transparent:
            frameColor = (0, 0, 0, 0)
        else:
            frameColor = (0, 0, 0, 1)
        self.pad = 0
        #         if Window.texture is None:
        #             Window.texture = loader.loadTexture('textures/futureui1.png')
        #         image_scale = (scale[0] * Window.texture.get_x_size(), 1, scale[1] * Window.texture.get_y_size())
        self.frame = DirectFrame(
            parent=parent, state=DGG.NORMAL, frameColor=frameColor
        )  #, image=self.texture, image_scale=image_scale)
        self.title_frame = DirectFrame(parent=self.frame,
                                       state=DGG.NORMAL,
                                       frameColor=(.5, .5, .5, 1))
        self.title = OnscreenText(text=self.title_text,
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * 14),
                                  parent=self.title_frame,
                                  pos=(0, 0),
                                  align=TextNode.ALeft,
                                  font=None,
                                  mayChange=True)
        bounds = self.title.getTightBounds()
        self.title_frame['frameSize'] = [
            0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2, 0,
            bounds[1][2] - bounds[0][2] + self.title_pad[1] * 2
        ]
        self.title.setPos(-bounds[0][0] + self.title_pad[0],
                          -bounds[0][2] + self.title_pad[1])
        self.close_frame = DirectFrame(parent=self.frame,
                                       state=DGG.NORMAL,
                                       frameColor=(.5, .5, .5, 1))
        self.close = OnscreenText(text='X',
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * 14),
                                  parent=self.close_frame,
                                  pos=(0, 0),
                                  align=TextNode.ACenter,
                                  font=None,
                                  mayChange=True)
        bounds = self.close.getTightBounds()
        self.close_frame['frameSize'] = [
            0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
            self.title_frame['frameSize'][2], self.title_frame['frameSize'][3]
        ]
        self.close.setPos(-bounds[0][0] + self.title_pad[0],
                          -bounds[0][2] + self.title_pad[1])
        self.frame.setPos(0, 0, 0)
        self.title_frame.bind(DGG.B1PRESS, self.start_drag)
        self.title_frame.bind(DGG.B1RELEASE, self.stop_drag)
        self.close_frame.bind(DGG.B1PRESS, self.close_window)
        self.set_child(child)

    def set_child(self, child):
        if child is not None:
            self.child = child
            child.reparent_to(self.frame)
            self.update()

    def update(self):
        if self.child is not None:
            frame_size = self.child.frame['frameSize']
            if frame_size is not None:
                frame_size[0] -= self.pad
                frame_size[1] += self.pad
                frame_size[2] += self.pad
                frame_size[3] -= self.pad
            self.frame['frameSize'] = frame_size
        if self.frame['frameSize'] is not None:
            width = self.frame['frameSize'][1] - self.frame['frameSize'][0]
            title_size = self.title_frame['frameSize']
            title_size[0] = 0
            title_size[1] = width
            self.title_frame['frameSize'] = title_size
            self.close_frame.setPos(width - self.close_frame['frameSize'][1],
                                    0, 0)

    def start_drag(self, event):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            self.drag_start = self.frame.parent.get_relative_point(
                render2d, Point3(mpos.get_x(), 0,
                                 mpos.get_y())) - self.frame.getPos()
            taskMgr.add(self.drag, "drag", -1)

    def drag(self, task):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            current_pos = self.frame.parent.get_relative_point(
                render2d, Point3(mpos.get_x(), 0, mpos.get_y()))
            self.frame.set_pos(current_pos - self.drag_start)
        return task.again

    def close_window(self, event=None):
        if self.owner is not None:
            self.owner.window_closed(self)
        self.destroy()

    def stop_drag(self, event):
        taskMgr.remove("drag")
        self.last_pos = self.frame.getPos()

    def destroy(self):
        if self.frame is not None:
            self.frame.destroy()
        self.frame = None

    def getPos(self):
        return self.frame.getPos()

    def setPos(self, pos):
        self.frame.setPos(pos)
コード例 #18
0
ファイル: widgets.py プロジェクト: IlyaFaer/ForwardOnlyGame
class ItemChooser(metaclass=abc.ABCMeta):
    """The base class for choose-one-of widgets.

    Args:
        is_shadowed (bool):
            Optional. If True, a shadowed font
            color will be used for this widget.
    """

    def __init__(self, is_shadowed=False):
        font = (0, 0, 0, 0.3 if is_shadowed else 0)
        self._ind = 0
        self._items = None
        self._chosen_item = None

        self._fr = DirectFrame(frameSize=(-0.11, 0.12, -0.025, 0.024), frameColor=font)
        self._name = DirectLabel(
            parent=self._fr,
            frameColor=(0, 0, 0, 0.3),
            text_fg=SILVER_COL,
            text_font=base.main_font,  # noqa: F821
            text="",
            text_scale=0.03,
            pos=(0, 0, -0.01),
        )
        but_params = {
            "parent": self._fr,
            "text_fg": SILVER_COL,
            "frameColor": font,
            "scale": (0.075, 0, 0.075),
        }
        DirectButton(pos=(0.15, 0, -0.015), text=">", command=self._next, **but_params)
        DirectButton(pos=(-0.15, 0, -0.015), text="<", command=self._prev, **but_params)
        self._fr.hide()

    @abc.abstractmethod
    def _show_info(self):
        """Show the chosen item info."""
        raise NotImplementedError("Chooser class must have _show_info() method.")

    @property
    def chosen_item(self):
        """The item chosen with this widget.

        Returns:
            object: The chosen object.
        """
        return self._chosen_item

    def _next(self):
        """Choose the next item from the list."""
        self._ind += 1
        self._show_info()

    def _prev(self):
        """Choose the previous item from the list."""
        self._ind -= 1
        self._show_info()

    def destroy(self):
        """Clear this widget."""
        self._fr.destroy()

        self._ind = 0
        self._chosen_item = None
        self._items = None

    def prepare(self, parent, pos, items, init_ind=None):
        """Set this widget's parent and position.

        Args:
            parent (panda3d.core.NodePath): Parent widget.
            pos (tuple): New widget position.
            items (dict): Items to iterate through.
            init_ind (int): Index of the initial value.
        """
        self._items = items

        self._fr.reparentTo(parent)
        self._fr.setPos(pos)
        self._fr.show()

        if init_ind is not None:
            self._ind = init_ind

        self._show_info()
コード例 #19
0
ファイル: ToonPanel.py プロジェクト: coginvasion/src
class ToonPanel(DirectFrame):
    notify = directNotify.newCategory('ToonPanel')
    animal2HeadData = {'dog': (0.125, 0.04),
     'duck': (0.1, 0.025),
     'cat': (0.115, 0.04),
     'rabbit': (0.115, 0.04),
     'horse': (0.115, 0.06),
     'monkey': (0.115, 0.06),
     'pig': (0.115, 0.07),
     'mouse': (0.09, 0.02),
     'bear': (0.125, 0.05)}
    State2Text = {'status': ('Seeing if %s is available...', '%s is busy right now; try again later.'),
     'teleport': ('Trying to go to %s...', 'Could not go to %s.'),
     'friend': ('Asking %s to be your friend...', '%s said no, thank you.', 'You are now friends with %s!'),
     'remove': ('Are you sure you want to remove %s from your friends list?', '%s left your friends list.')}

    def __init__(self):
        DirectFrame.__init__(self, scale=1.2)
        self['image'] = DGG.getDefaultDialogGeom()
        self['image_hpr'] = (0, 0, -90)
        self['image_scale'] = (0.62, 0.9, 0.325)
        self['image_color'] = (1, 1, 0.75, 1)
        self['image_pos'] = (0, 0, -0.065)
        self['relief'] = None
        self.reparentTo(base.a2dTopRight)
        self.setPos(-0.235, 0.0, -0.325)
        self.hide()
        self.head = None
        self.laffMeter = None
        self.exitButton = None
        self.friendButton = None
        self.teleportButton = None
        self.nameText = None
        self.actionFrame = None
        self.actionFrameText = None
        self.actionFrameButton = None
        self.actionFrameButton2 = None
        self.avatarInfo = None
        self.action = None
        self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [State.State('off', self.enterOff, self.exitOff), State.State('waitOnAvatarInfoResponse', self.enterWaitOnAvatarInfoResponse, self.exitWaitOnAvatarInfoResponse, ['panel']), State.State('panel', self.enterPanel, self.exitPanel, ['off'])], 'off', 'off')
        self.fsm.enterInitialState()
        self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [State.State('off', self.enterOff, self.exitOff),
         State.State('waitOnAvatarStatusResponse', self.enterWaitOnAvatarStatusResponse, self.exitWaitOnAvatarStatusResponse, ['waitOnAvatarTeleportResponse',
          'waitOnAvatarFriendListResponse',
          'avatarBusy',
          'off']),
         State.State('avatarBusy', self.enterAvatarBusy, self.exitAvatarBusy, ['off']),
         State.State('waitOnAvatarTeleportResponse', self.enterWaitOnAvatarTeleportResponse, self.exitWaitOnAvatarTeleportResponse, ['unableToTP']),
         State.State('unableToTP', self.enterUnableToTP, self.exitUnableToTP, ['off']),
         State.State('waitOnAvatarFriendListResponse', self.enterWaitOnAvatarFriendListResponse, self.exitWaitOnAvatarFriendListResponse, ['fRequestA', 'fRequestR']),
         State.State('fRequestA', self.enterFriendRequestAccepted, self.exitFriendRequestAccepted, ['off']),
         State.State('fRequestR', self.enterFriendRequestRejected, self.exitFriendRequestRejected, ['off']),
         State.State('removeFriendConfirm', self.enterRemoveFriendConfirm, self.exitRemoveFriendConfirm, ['off', 'removedFriend']),
         State.State('removedFriend', self.enterRemovedFriend, self.exitRemovedFriend, ['off'])], 'off', 'off')
        self.actionFSM.enterInitialState()
        return

    def maybeUpdateFriendButton(self):
        if self.friendButton:
            if self.avatarInfo:
                if self.avatarInfo[0] not in base.localAvatar.friends:
                    self.friendButton['text'] = 'Add Friend'
                    self.friendButton['extraArgs'] = ['waitOnAvatarFriendListResponse']
                else:
                    self.friendButton['text'] = 'Remove Friend'
                    self.friendButton['extraArgs'] = ['removeFriendConfirm']

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterUnableToTP(self):
        pass

    def exitUnableToTP(self):
        pass

    def enterWaitOnAvatarTeleportResponse(self):
        self.setActionText(self.State2Text['teleport'][0] % self.getAvatarName())
        self.makeButtons('Cancel')
        self.acceptOnce('gotAvatarTeleportResponse', self.handleTeleportResponse)
        base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0])

    def handleTeleportResponse(self, avatarId, shardId, zoneId):
        if self.avatarInfo[0] == avatarId:
            requestStatus = {}
            whereName = ZoneUtil.getWhereName(zoneId)
            loaderName = ZoneUtil.getLoaderName(zoneId)
            requestStatus['zoneId'] = zoneId
            if base.localAvatar.parentId == shardId:
                requestStatus['shardId'] = None
            else:
                requestStatus['shardId'] = shardId
            requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1)
            requestStatus['where'] = whereName
            requestStatus['loader'] = loaderName
            requestStatus['how'] = 'teleportIn'
            requestStatus['avId'] = avatarId
            base.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])
            self.cleanup()
        return

    def exitWaitOnAvatarTeleportResponse(self):
        self.ignore('gotAvatarTeleportResponse')
        self.clearActionText()
        self.clearActionButtons()

    def setActionText(self, text):
        self.actionFrameText.setText(text)

    def clearActionText(self):
        self.actionFrameText.setText('')

    def makeButtons(self, button1, button2 = None):
        button2GeomFunc = {'Cancel': CIGlobals.getCancelBtnGeom,
         'No': CIGlobals.getCancelBtnGeom,
         'Okay': CIGlobals.getOkayBtnGeom,
         'Yes': CIGlobals.getOkayBtnGeom}
        if button1 and not button2:
            button1Pos = (0, 0, -0.1)
        elif button1 and button2:
            button1Pos = (-0.1, 0, -0.1)
        button2Pos = (0.1, 0, -0.1)
        if button1:
            self.actionFrameButton = DirectButton(text=button1, geom=button2GeomFunc[button1](), parent=self.actionFrame, pos=button1Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[1], relief=None, geom_scale=0.75)
        if button2:
            self.actionFrameButton2 = DirectButton(text=button2, geom=button2GeomFunc[button2](), parent=self.actionFrame, pos=button2Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[2], relief=None, geom_scale=0.75)
        return

    def actionButtonPressed(self, buttonNum):
        currentState = self.actionFSM.getCurrentState().getName()
        if buttonNum == 1:
            if currentState in ('waitOnAvatarStatusResponse', 'waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'unableToTP', 'fRequestA', 'fRequestR', 'removeFriendConfirm', 'removedFriend'):
                if currentState == 'waitOnAvatarFriendListResponse':
                    base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0])
                elif currentState == 'removeFriendConfirm':
                    self.actionFSM.request('removedFriend')
                    return
                self.actionFSM.request('off')
                self.removeActionPanel()
                self.action = None
        elif buttonNum == 2:
            self.actionFSM.request('off')
            self.removeActionPanel()
            self.action = None
        return

    def clearActionButtons(self):
        if self.actionFrameButton2:
            self.actionFrameButton2.destroy()
            self.actionFrameButton2 = None
        if self.actionFrameButton:
            self.actionFrameButton.destroy()
            self.actionFrameButton = None
        return

    def enterAvatarBusy(self):
        self.setActionText(self.State2Text['status'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitAvatarBusy(self):
        self.clearActionText()
        self.clearActionButtons()

    def getAvatarName(self):
        if self.avatarInfo:
            return self.avatarInfo[1]

    def enterWaitOnAvatarStatusResponse(self):
        self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)
        base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0])
        self.setActionText(self.State2Text['status'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleAvatarStatusResponse(self, avatarId, status):
        if avatarId == self.avatarInfo[0]:
            if status == 1:
                self.actionFSM.request('avatarBusy')
            else:
                self.actionFSM.request(self.action)
        else:
            self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)

    def exitWaitOnAvatarStatusResponse(self):
        self.ignore('gotAvatarStatus')
        self.clearActionText()
        self.clearActionButtons()

    def enterWaitOnAvatarFriendListResponse(self):
        self.acceptOnce('friendRequestAccepted', self.handleFriendRequestAccepted)
        self.acceptOnce('friendRequestRejected', self.handleFriendRequestRejected)
        base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0])
        self.setActionText(self.State2Text['friend'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleFriendRequestAccepted(self):
        self.actionFSM.request('fRequestA')

    def handleFriendRequestRejected(self):
        self.actionFSM.request('fRequestR')

    def exitWaitOnAvatarFriendListResponse(self):
        self.ignore('friendRequestAccepted')
        self.ignore('friendRequestRejected')
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestAccepted(self):
        self.setActionText(self.State2Text['friend'][2] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestAccepted(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestRejected(self):
        self.setActionText(self.State2Text['friend'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestRejected(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemoveFriendConfirm(self):
        self.setActionText(self.State2Text['remove'][0] % self.getAvatarName())
        self.makeButtons('Yes', 'No')

    def exitRemoveFriendConfirm(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemovedFriend(self):
        base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0])
        self.setActionText(self.State2Text['remove'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitRemovedFriend(self):
        self.clearActionText()
        self.clearActionButtons()

    def makeActionPanel(self):
        self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(), image_scale=(0.7, 0.5, 0.45), image_color=(1, 1, 0.75, 1), relief=None)
        self.actionFrame.reparentTo(base.a2dTopRight)
        self.actionFrame.setPos(-0.815, 0, -0.31)
        self.actionFrameText = OnscreenText(text='', parent=self.actionFrame, scale=0.05, wordwrap=12, pos=(0, 0.1))
        return

    def removeActionPanel(self):
        self.clearActionButtons()
        if self.actionFrameText:
            self.actionFrameText.destroy()
            self.actionFrameText = None
        if self.actionFrame:
            self.actionFrame.destroy()
            self.actionFrame = None
        return

    def doAction(self, action):
        self.action = action
        self.actionFSM.requestFinalState()
        self.removeActionPanel()
        self.makeActionPanel()
        if action != 'removeFriendConfirm':
            self.actionFSM.request('waitOnAvatarStatusResponse')
        else:
            self.actionFSM.request(action)

    def enterWaitOnAvatarInfoResponse(self):
        self.label = OnscreenText(text='Retrieving Toon\ndetails...', parent=self, scale=0.04)
        self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse)
        base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0])

    def handleAvatarInfoResponse(self, name, dna, maxHealth, health):
        if self.avatarInfo:
            self.avatarInfo.append(name)
            self.avatarInfo.append(dna)
            self.avatarInfo.append(maxHealth)
            self.avatarInfo.append(health)
            self.fsm.request('panel')

    def exitWaitOnAvatarInfoResponse(self):
        self.label.destroy()
        del self.label
        self.ignore('avatarInfoResponse')

    def makePanel(self, avId):
        if self.avatarInfo:
            if self.avatarInfo[0] == avId:
                return
        self.cleanup()
        base.localAvatar.hideFriendButton()
        self.show()
        self.avatarInfo = []
        self.avatarInfo.append(avId)
        self.fsm.request('waitOnAvatarInfoResponse')

    def exitClicked(self):
        self.cleanup()
        base.localAvatar.showFriendButton()

    def cleanup(self):
        self.actionFSM.requestFinalState()
        self.fsm.requestFinalState()
        self.avatarInfo = None
        return

    def enterPanel(self):
        self.nameText = OnscreenText(text=self.avatarInfo[1], parent=self, pos=(0, 0.2), scale=0.035, wordwrap=8)
        self.nameText.setBin('gui-popup', 60)
        dna = ToonDNA.ToonDNA()
        dna.setDNAStrand(self.avatarInfo[2])
        self.head = ToonHead.ToonHead(base.cr)
        self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
        self.head.setHeadColor(dna.headcolor)
        self.head.reparentTo(self)
        self.head.setDepthWrite(1)
        self.head.setDepthTest(1)
        self.head.setH(180)
        self.head.setScale(self.animal2HeadData[dna.animal][0])
        self.head.setZ(self.animal2HeadData[dna.animal][1])
        self.laffMeter = LaffOMeter()
        r, g, b, _ = dna.headcolor
        self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3], self.avatarInfo[4])
        self.laffMeter.reparentTo(self)
        self.laffMeter.setBin('gui-popup', 60)
        self.laffMeter.setScale(0.045)
        self.laffMeter.setPos(0, 0, -0.1)
        self.friendButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Add Friend', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarFriendListResponse'])
        self.friendButton.setPos(0, 0.0, -0.225)
        self.maybeUpdateFriendButton()
        self.teleportButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Teleport', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarTeleportResponse'])
        self.teleportButton.setPos(0, 0, -0.275)
        self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self, relief=None, scale=0.6, pos=(-0.127, 0.0, -0.3425), command=self.exitClicked)
        return

    def exitPanel(self):
        if self.actionFSM.getCurrentState().getName() == 'waitOnAvatarFriendListResponse':
            if self.avatarInfo:
                base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0])
        self.actionFSM.requestFinalState()
        self.action = None
        self.avatarInfo = None
        self.removeActionPanel()
        self.hide()
        if self.nameText:
            self.nameText.destroy()
            self.nameText = None
        if self.head:
            self.head.removeNode()
            self.head.delete()
            self.head = None
        if self.laffMeter:
            self.laffMeter.disable()
            self.laffMeter.delete()
            self.laffMeter = None
        if self.friendButton:
            self.friendButton.destroy()
            self.friendButton = None
        if self.teleportButton:
            self.teleportButton.destroy()
            self.teleportButton = None
        if self.exitButton:
            self.exitButton.destroy()
            self.exitButton = None
        return
コード例 #20
0
class GuiUnitPanel:
    def __init__(self, aspect, unit_id, panel_pos, unit_type, default_hp, hp, default_ap, ap):
        self.unit_id = unit_id
        self.frameWidth = 0.30
        self.frameHeight = 0.06
        self.frame = DirectFrame(  # relief = DGG.FLAT
                                   scale = 1
                                  , frameSize = (0, self.frameWidth, 0, -self.frameHeight)
                                  , frameColor = (0.2, 0.2, 0.2, 0.8)
                                  , parent = base.a2dTopLeft )#@UndefinedVariable
        
        self.pos = Point3(0, 0, -GUI_TOP_OFFSET-0.05 - (0.069*panel_pos))        
        self.frame.setPos(self.pos)
        
        self.ap_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_ap
                                  , value = ap
                                  , pos = (0.2,0,-0.045)
                                  , barColor = (0,0,1,1)
                                  , frameColor = (0,0,0.5,0.2)
                                  , scale = (0.1,0.5,0.1))
        
        self.hp_bar = DirectWaitBar(parent = self.frame
                                  , text = ""
                                  , range = default_hp
                                  , value = hp
                                  , pos = (0.2,0,-0.015)
                                  , barColor = (0,1,0,1)
                                  , frameColor = (1,0,0,0.9)
                                  , scale = (0.1,0.5,0.08))
        
        self.insignia = OnscreenImage(parent = self.frame
                                            ,image = "unit_" + unit_type + "_big_transparent_32.png"
                                            ,pos = (0.035,0,-0.03)
                                            ,scale = 0.025)
        self.insignia.setTransparency(TransparencyAttrib.MAlpha)
        
        self.all_icons = {}
        self.visible_icons = {}
        self.addIcon("overwatch")
        self.addIcon("set_up")
        
        self.getBounds(aspect)
        
    def addIcon(self, name):
        self.all_icons[name] = OnscreenImage(parent = self.frame
                                            ,image = name + "_icon.png"
                                           #,pos = offset + (0,0,-0.1)
                                            ,scale = 0.035)
        
        self.all_icons[name].setTransparency(TransparencyAttrib.MAlpha)
        self.all_icons[name].hide()
        
    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 =  0.34
        for icon in self.all_icons:
            if icon in self.visible_icons:
                self.visible_icons[icon].setPos((start_pos, 0, -0.032))
                self.visible_icons[icon].show()
                start_pos += 0.07
            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()
        
    def getBounds(self, aspect):
        posx, posy = self.frame.getTightBounds()
        self.pos_min_x = -1
        self.pos_min_y = self.pos.getZ() + 1 - self.frameHeight
        self.pos_max_x = -1 + self.frameWidth/aspect
        self.pos_max_y = self.pos.getZ() + 1
コード例 #21
0
class GuiTextFrame:
    def __init__(self, offset, h_size, v_size, numLines, hugpos):
        self.numLines = numLines
        #if hugpos == "statusbar":
        #    color = (0,0,0,1)
        #else:
        #    color = (0.2, 0.2, 0.2, 0.8)
        color = (0.2, 0.2, 0.2, 0.9)
        self.frame = DirectFrame(   relief = DGG.FLAT
                                  , frameColor = color
                                  , scale = 1
                                  , frameSize = (0, h_size, 0, -v_size) )
        self.v_size = v_size
        self.hugpos = hugpos
        self.offset = offset
        
        if hugpos == "top":
            self.frame.reparentTo(base.a2dTopLeft)#@UndefinedVariable
            self.frame.setPos(self.offset.getX(), 0, self.offset.getZ() - GUI_TOP_OFFSET)
        elif hugpos == "bottom":
            self.frame.reparentTo(base.a2dBottomLeft)#@UndefinedVariable
            self.frame.setPos(self.offset.getX(), 0, self.offset.getZ() + GUI_BOTTOM_OFFSET -0.085)
        elif hugpos == "statusbar":
            self.frame.reparentTo(base.a2dTopLeft)#@UndefinedVariable
            self.frame.setPos(self.offset.getX(), 0, self.offset.getZ())

        fixedWidthFont = loader.loadFont(GUI_FONT)#@UndefinedVariable
        if not fixedWidthFont.isValid():
            print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(self.font)
            fixedWidthFont = DGG.getDefaultFont()
        
        if numLines == 1:
            self.lineHeight = 0.05
        else:
            self.lineHeight = v_size*0.9 / numLines
            
        # output lines
        self.frameOutputList = list()
        for i in xrange( self.numLines ):
            label = OnscreenText( parent = self.frame
                              , text = ""
                              , pos = (0.005, -(i+1)*self.lineHeight)
                              , align=TextNode.ALeft
                              , mayChange=1
                              , scale=0.04
                              , fg = (1,1,1,1)
                              , shadow = (0, 0, 0, 1))
                              #, frame = (200,0,0,1) )
            label.setFont( fixedWidthFont )
            self.frameOutputList.append( label )

    def write(self, lineNumber, text):
        if lineNumber > self.numLines:
            return
        self.frameOutputList[lineNumber - 1].setText(text)
        
    def redraw(self, aspect):
        if self.hugpos == "top":
            p = base.a2dTopLeft.getPos()#@UndefinedVariable
            p.setX(p.getX() + self.offset.getX() + 0.05)
            p.setZ(p.getZ() + self.offset.getZ() - GUI_TOP_OFFSET - 0.05)
            self.frame.setPos(p)
        elif self.hugpos == "bottom":
            p = base.a2dBottomLeft.getPos()#@UndefinedVariable
            p.setX(p.getX() + self.offset.getX() + 0.05)
            p.setZ(p.getZ() + self.offset.getZ() + GUI_BOTTOM_OFFSET - 0.05)
            self.frame.setPos(p)
        elif self.hugpos == "statusbar":
            self.frame["frameSize"] = (0, 2*aspect, 0, -self.v_size)
            self.frame.resetFrameSize()
コード例 #22
0
class GuiButton2:
    def __init__(self, hugpos, offset, aspect, plane, name):
        self.enabled = True
        self.name = name
        
        self.frame = DirectFrame(   relief = DGG.FLAT
                                  , frameColor = (0, 0, 0, 0)
                                  , scale = 1
                                  , frameSize = (-0.3, 0.3, -0.3, 0.3) ) #32/600=0.05333
        self.frame.setScale(0.0533)
        
        self.imageObject = OnscreenImage(image = name+".png", pos = (0, 0, 0))
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)
        self.imageObject.setAlphaScale(1) 
        self.imageObject.reparentTo(self.frame)
        
        self.hugpos = hugpos
        self.offset = offset
        self.redraw(aspect)

    def redraw(self, aspect, flag="wide"):
        if self.hugpos == "top":
            p = base.a2dTopLeft.getPos()#@UndefinedVariable
            p.setX(p.getX() + self.offset.getX() + 0.05)
            p.setZ(p.getZ() + self.offset.getZ() - GUI_TOP_OFFSET - 0.05)
        elif self.hugpos == "bottom":
            p = base.a2dBottomLeft.getPos()#@UndefinedVariable
            p.setX(p.getX() + self.offset.getX() + 0.05)
            p.setZ(p.getZ() + self.offset.getZ() + GUI_BOTTOM_OFFSET - 0.05)
        elif self.hugpos == "right":
            p = base.a2dBottomRight.getPos()#@UndefinedVariable
            p.setX(p.getX() + self.offset.getX() + 0.05)
            p.setZ(p.getZ() + self.offset.getZ() + GUI_BOTTOM_OFFSET - 0.05)
        self.frame.setPos(p)
        if flag == "wide":
            posx, posy = self.frame.getTightBounds()
            self.pos_min_x = posx.getX() / aspect
            self.pos_min_y = posx.getZ()
            self.pos_max_x = posy.getX() / aspect
            self.pos_max_y = posy.getZ()
        elif flag == "tall":
            posx, posy = self.frame.getTightBounds()
            self.pos_min_x = posx.getX()
            self.pos_min_y = posx.getZ() / aspect
            self.pos_max_x = posy.getX()
            self.pos_max_y = posy.getZ() / aspect
            
    def turnOn(self):
        self.imageObject.setImage(self.name+"_on.png")#@UndefinedVariable
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)
        
    def turnOff(self):
        self.imageObject.setImage(self.name+".png")#@UndefinedVariable
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)    
            
    def enable(self):
        self.imageObject.setImage(self.name+".png")#@UndefinedVariable
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)
        self.enabled = True
        
    def disable(self):
        self.imageObject.setImage("empty.png")#@UndefinedVariable
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)
        self.enabled = False
            
    def removeNode(self):
        self.frame.removeNode()   
        
    def setAbility(self, ability):
        self.name = ability
        self.imageObject.setImage(self.name+".png")
        self.imageObject.setTransparency(TransparencyAttrib.MAlpha)
        self.imageObject.setAlphaScale(1) 
コード例 #23
0
class IssueFrameV2(IssueFrame.IssueFrame):

    notify = DirectNotifyGlobal.directNotify.newCategory("IssueFrameV2")

    # home page is considered one section, must always be first
    # home, news, events, talk of the town, ask toontown, toon resistance, extra
    SectionIdents = ['hom', 'new', 'evt', 'tot', 'att', 'tnr', 'ext']

    def __init__(self, parent, newsDir, dateStr, myIssueIndex, numIssues, strFilenames, newsIndexEntries):
        self.newsIndexEntries = newsIndexEntries
        self.dateStr = dateStr
        self.calcActualSectionsInThisIssue()
        IssueFrame.IssueFrame.__init__(self,
                                       parent,
                                       newsDir,
                                       dateStr,
                                       myIssueIndex,
                                       numIssues,
                                       strFilenames,
                                       )
        self.notify.debug("version2 %s" % dateStr)

    def load(self):
        self.guiNavV2 = loader.loadModel("phase_3.5/models/gui/tt_m_gui_ign_directNewsGuiNavV2")
        IssueFrame.IssueFrame.load(self)

    def calcActualSectionsInThisIssue(self):
        self.actualSectionIdents = []
        for ident in self.SectionIdents:
            identTest = self.dateStr + "_" + ident + "1"
            if self.isSectionInIndex(identTest):
                self.actualSectionIdents.append(ident)

    def isSectionInIndex(self, sectionIdent):
        for name in self.newsIndexEntries:
            if sectionIdent in name and self.dateStr in name:
                return True

        return False

    def parseNewsContent(self):
        """Open up the directory, read all the files, and figure out the structure."""
        existingSectionIndex = 0
        for section, ident in enumerate(self.SectionIdents):
            subSectionList = []
            curSubSection = 0
            endSearch = False
            while not endSearch:
                justName = self.ContentPattern % (self.dateStr, ident, curSubSection +1)
                fullName = Filename(self.newsDir + '/' + justName)
                if self.strFilenames:
                    # we already have a list of filenames, check if it's in there
                    if justName in self.strFilenames:
                        subSectionList.append(fullName)
                        self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        curSubSection += 1
                    else:
                        endSearch = True
                else:
                    theFile = vfs.getFile(Filename(fullName), status_only=1)
                    if theFile:
                        subSectionList.append(fullName)
                        self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        curSubSection += 1
                    else:
                        if curSubSection == 0 and self.isSectionInIndex(ident):
                            self.notify.warning('could not find %s' % fullName)
                            subSectionList.append(fullName)
                            self.flatSubsectionList.append((existingSectionIndex, curSubSection))
                        endSearch = True
            if not subSectionList:
                pass
            else:
                self.sectionList.append(subSectionList)
                existingSectionIndex += 1

        self.notify.debug("IssueFrameV2 self.sectionList=%s" % self.sectionList)

    def loadHomePageButtons(self, section, subsection, pageFrame):
        self.notify.debug('Doing nothing for loadNavButtons')
        if section == 0 and subsection == 0:
            self.loadNavButtons(pageFrame)
            self.parentOfWeekNav = DirectFrame(frameColor = (1, 1, 1, 0),
                                               relief = DGG.FLAT,
                                               parent = pageFrame,
                                               )
            self.loadWeekNavButtons(self.parentOfWeekNav)
            self.parentOfWeekNav.setPos(-1.94, 0, 0)

    def loadNavButtons(self, pageFrame):
        identToButtonNames = {'hom' : 'tt_i_art_btn_NavHom2',
                              'new' : 'tt_i_art_btn_NavNew2',
                              'evt' : 'tt_i_art_btn_NavEvt2',
                              'tot' : 'tt_i_art_btn_NavTot2',
                              'att' : 'tt_i_art_btn_NavAtt2',
                              'tnr' : 'tt_i_art_btn_NavTnr2',
                              'ext' : 'tt_i_art_btn_NavExt2',
                              }
        identToRolloverButtonNames = {'hom' : 'tt_i_art_btn_NavHomRo2',
                                      'new' : 'tt_i_art_btn_NavNewRo2',
                                      'evt' : 'tt_i_art_btn_NavEvtRo2',
                                      'tot' : 'tt_i_art_btn_NavTotRo2',
                                      'att' : 'tt_i_art_btn_NavAttRo2',
                                      'tnr' : 'tt_i_art_btn_NavTnrRo2',
                                      'ext' : 'tt_i_art_btn_NavExtRo2',
                                      }
        xPos = 1.24667
        positions = [ (xPos, 0, 0.623333),
                      (xPos, 0, 0.536663),
                      (xPos, 0, 0.45),
                      (xPos, 0, 0.36333),
                      (xPos, 0, 0.276667),
                      (xPos, 0, 0.19),
                      (xPos, 0, 0.08),
                      ]

        # values captured using direct screen captures
        xSize1 = 177
        desiredXSize1 = 90
        image_scale1 = float(desiredXSize1) / xSize1
        image_scale = 1

        xSize2 = 300
        desiredXSize2 = 152
        image_scale2 = float(desiredXSize2) / xSize2
        image_scale2 *= 30.0 / 30.0
        
        rolloverPositions = [ (1.045, 0, 0.623333),
                              (1.045, 0, 0.533333),
                              (1.045, 0, 0.443333),
                              (1.045, 0, 0.353333),
                              (1.045, 0, 0.263334),
                              (1.045, 0, 0.173333),
                              (1.045, 0, 0.09),
                              ]
                              
        imageScales = [ image_scale2,
                        image_scale2,
                        image_scale2,
                        image_scale2,
                        image_scale2,
                        image_scale2,
                        image_scale2,
                        ]
                        
        frameSizeAdj1 = 0.1
        frameSize1 = (-0.04 + frameSizeAdj1,
         0.04 + frameSizeAdj1,
         -0.04,
         0.04)
        frameSizeAdj2 = 0.21
        frameSize2 = (-0.04 + frameSizeAdj2,
                      0.04 + frameSizeAdj2,
                      -0.04,
                      0.04)
        frameSizes = ( frameSize2, frameSize2, frameSize2, frameSize2,
                       frameSize2, frameSize2, frameSize2)
        # TODO get from Teani normal state buttons same size as rollover
        self.sectionBtns = []
        for section, ident in enumerate(self.actualSectionIdents):
            image = self.guiNavV2.find('**/%s' % identToButtonNames[ident])
            rolloverImage = self.guiNavV2.find('**/%s' % identToRolloverButtonNames[ident])
            if image.isEmpty():
                self.notify.error('cant find %s' % identToButtonNames[ident])
            sectionBtn = DirectButton(
                relief = None,
                parent = pageFrame,
                frameSize = frameSizes[section],
                image = (image, rolloverImage, rolloverImage, image),
                image_scale = imageScales[section],
                command = self.gotoPage,
                extraArgs = (section, 0),
                enableEdit = 1,
                pos = rolloverPositions[section],
                )
コード例 #24
0
class ConsoleWindow(DirectObject.DirectObject):
    console_output = None
    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)
    textBuffer = list()
    MAX_BUFFER_LINES = 5000
    commandPos = 0
    _iconsole = None
    _commandBuffer = ''
    logger.debug("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.9, 0.9, 1.0)
    consoleFrame = None
    commandList = []
    maxCommandHistory = 10000
    textBufferPos = -1
    clipboardTextLines = None
    clipboardTextRaw = None

    def __init__(self, parent):
        global base
        if not logger.isEnabledFor(logging.DEBUG):
            global CONSOLE_MESSAGE
            CONSOLE_MESSAGE = '''
----------------- Ship's Interface version 3.0.9_749 -------------------
Direct Ship Interface Enabled.
Please use caution.  Irresponsible use of this console may result in the ship's AI refusing access to this interface.

type 'help' for basic commands.
-------------------------------------------------------------------------'''

        # change up from parent/IC
        self.parent = parent
        localenv = globals()
        localenv['gameroot'] = self.parent
        self._iconsole = customConsoleClass(localsEnv=localenv)

        # 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))

        self.windowEvent(base.win)
        fixedWidthFont = None
        try:
            # try to load the defined font
            fixedWidthFont = parent.loader.loadFont(self.font)
        except Exception:
            traceback.print_exc()
            # if font is not valid use default font
            logger.warn('could not load the defined font %s" % str(self.font')
            fixedWidthFont = DGG.getDefaultFont()

        # text lines
        self._visibleLines = list(
            OnscreenText(parent=self.consoleFrame,
                         text="",
                         pos=(1, -i + 3 + self.numlines),
                         align=TextNode.ALeft,
                         mayChange=1,
                         scale=1.0,
                         fg=self.defaultTextColor)
            for i in range(self.numlines))
        map(lambda x: x.setFont(fixedWidthFont), self._visibleLines)

        # text entry line
        self.consoleEntry = DirectEntry(self.consoleFrame,
                                        text="",
                                        command=self.submitTrigger,
                                        width=self.h_size / self.scale - 2,
                                        pos=(1, 0, 1.5),
                                        initialText="",
                                        numLines=1,
                                        focus=1,
                                        entryFont=fixedWidthFont)

        # self.console_output = ConsoleOutput(testme=True)
        self.echo(CONSOLE_MESSAGE)
        self.clipboard = pyperclip

    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)

    def submitTrigger(self, cmdtext):
        # set to last message
        # clear line
        self.consoleEntry.enterText('')
        self.focus()
        # add text entered to user command list & remove oldest entry
        self.commandList.append(cmdtext)
        self.commandPos += 1
        self._commandBuffer = ''
        logger.debug('CP {}'.format(self.commandPos))
        # push to interp
        for text, pre, color in self._iconsole.push(cmdtext):
            self.echo(text, pre, color)

    # set up console controls
    def mapControls(self):
        hidden = self.consoleFrame.isHidden()
        self.consoleEntry['focus'] != hidden
        if hidden:
            self.ignoreAll()
        else:
            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('escape', 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)

    # toggle the gui console
    def toggleConsole(self, hide=False):
        if hide:
            self.consoleFrame.hide()
            self.ignoreAll()
            # express hide, don't call setControls()
            return

        if self.consoleFrame.is_hidden():
            self.consoleFrame.show()
            self.parent.setControls(self)
        else:
            self.consoleFrame.hide()
            self.ignoreAll()
            self.parent.setControls()

    def scroll(self, step):
        newpos = self.textBufferPos + step
        if newpos < 0 or newpos >= len(self.textBuffer):
            # no... no... I no think so
            return
        self.textBufferPos = newpos
        self.redrawConsole()

    def redrawConsole(self):
        windowstart = max(self.textBufferPos - len(self._visibleLines) + 1, 0)
        windowend = min(
            len(self._visibleLines) + windowstart, len(self.textBuffer))
        logger.debug('windowS: {} WindowE: {}'.format(windowstart, windowend))
        for lineNumber, (lineText, color) in \
                enumerate(self.textBuffer[
                    windowstart:
                    windowend]):
            logger.debug("LN {}, LEN {}".format(lineNumber,
                                                len(self.textBuffer)))
            self._visibleLines[lineNumber].setText(lineText)
            self._visibleLines[lineNumber]['fg'] = color

    def scrollCmd(self, step):
        if not self.commandList:  # 0 or null - nothing to scroll
            return
        # should we update a temp buffer?
        if self.commandPos == len(self.commandList):
            if step > 0:
                self.consoleEntry.set(self._commandBuffer)
                return
            else:
                tmp = self.consoleEntry.get()
                if self.commandList[-1] != tmp:
                    self._commandBuffer = tmp
        self.commandPos += step
        if self.commandPos >= len(self.commandList):
            self.commandPos = len(self.commandList) - 1
            self.consoleEntry.set(self._commandBuffer)
            self.consoleEntry.setCursorPosition(
                len(self.commandList[self.commandPos]))
        elif self.commandPos < 0:
            self.commandPos = -1
            # No need to change anything, can't go past the beginning
            return
        # finally, just set it
        self.consoleEntry.set(self.commandList[self.commandPos])
        self.consoleEntry.setCursorPosition(
            len(self.commandList[self.commandPos]))

    def autocomplete(self):
        currentText = self.consoleEntry.get()
        currentPos = self.consoleEntry.guiItem.getCursorPosition()
        newText = self._iconsole.autocomplete(currentText, currentPos)
        if newText[-1] and newText[-1] != currentText:
            self.consoleEntry.set(newText[-1])
            self.consoleEntry.setCursorPosition(len(newText))

    def autohelp(self):
        currentText = self.consoleEntry.get()
        currentPos = self.consoleEntry.guiItem.getCursorPosition()
        self.parent.autohelp(currentText, currentPos)

    def unfocus(self):
        self.consoleEntry['focus'] = 0

    def focus(self):
        self.consoleEntry['focus'] = 1

    def copy(self):
        copy = self.consoleEntry.get()
        pyperclip.copy(copy)

    def paste(self):
        oldCursorPos = self.consoleEntry.guiItem.getCursorPosition()
        self.clipboardTextRaw = pyperclip.paste()

        # compose new text line
        oldText = self.consoleEntry.get()
        newText = oldText[0:oldCursorPos] + self.clipboardTextRaw + oldText[
            oldCursorPos:]

        self.clipboardTextLines = newText.split(os.linesep)

        for i in range(len(self.clipboardTextLines) - 1):
            currentLine = self.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.submitTrigger(currentLine)
        currentLine = self.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):
        pyperclip.copy(self.consoleEntry.get())
        self.consoleEntry.enterText('')
        self.focus()

    def echo(self, output, pre='*', color=defaultTextColor):
        if logger.isEnabledFor(logging.DEBUG):
            logger.debug('output: {}'.format(pprint.pformat(output)))
        for line in output.split('\n'):
            fmtline = "{}{}".format(pre, line)
            logger.debug(fmtline)
            if len(line) > 0:
                self.write_to_panel(fmtline, color)

    def write_to_panel(self, output, color=defaultTextColor):
        # remove not printable characters (which can be input by console input)
        output = re.sub(r'[^%s]' % re.escape(string.printable[:95]), "",
                        output)
        logger.debug('write_to_panel: output="{}"'.format(output))
        splitLines = self.linewrap.wrap(output)
        logger.debug('write_to_panel: splitLines="{}"'.format(splitLines))
        for line in splitLines:
            self.textBuffer.append([line, color])
            if len(self.textBuffer) > self.MAX_BUFFER_LINES:
                self.textBuffer.pop(0)
            else:
                self.textBufferPos += 1

        self.redrawConsole()
コード例 #25
0
class InventoryGui(DirectObject):
    directNotify = DirectNotify().newCategory('InventoryGui')
    HiddenPos = (0.2, 0, 0)
    VisiblePos = (-0.1725, 0, 0)
    SwitchTime = 0.3
    AutoShowTime = 1.5
    DELETED = False

    def __init__(self):
        DirectObject.__init__(self)
        self.backpack = base.localAvatar.backpack
        if not self.backpack:
            return
        self.backpack.loadoutGUI = self
        self.oneSlotPos = [(0, 0, 0)]
        self.twoSlotsPos = [(0, 0, 0.3), (0, 0, -0.2)]
        self.threeSlotsPos = [(0, 0, 0.5), (0, 0, 0), (0, 0, -0.5)]
        self.fourSlotPos = [(0, 0, 0.5), (0, 0, 0.15), (0, 0, -0.2),
                            (0, 0, -0.55)]
        self.availableSlot = 0
        self.slots = []
        self.activeSlot = None
        self.defaultSlots = 3
        self.prevSlot = None
        self.ammoLabel = None
        self.inventoryFrame = DirectFrame(parent=base.a2dRightCenter,
                                          pos=(-0.1725, 0, 0))
        self.visibilityBtn = DirectButton(text='',
                                          relief=None,
                                          text_bg=(1, 1, 1, 0),
                                          parent=base.a2dRightCenter,
                                          pos=(-0.1725, 0, 0),
                                          frameSize=(-0.2, 0.2, -0.725, 0.7),
                                          clickSound=None,
                                          rolloverSound=None)
        self.visibilityBtn.bind(DGG.WITHIN, self.__handleVisEnter)
        self.visibilityBtn.bind(DGG.WITHOUT, self.__handleVisExit)
        self.visibilityBtn.setBin('background', 10)
        self.visibilityBtn = None
        self.visibilityBtnStatus = 0
        self.switchSound = True
        self.switchSoundSfx = base.loadSfx(
            'phase_3/audio/sfx/GUI_balloon_popup.ogg')
        self.visibilityFSM = ClassicFSM('InventoryGui-VisibilityFSM', [
            State('off', self.enterOff, self.exitOff),
            State('hidden', self.enterHidden, self.exitHidden),
            State('hidden2visible', self.enterHidden2Visible,
                  self.exitHidden2Visible),
            State('visible', self.enterVisible, self.exitVisible),
            State('visible2hidden', self.enterVisible2Hidden,
                  self.exitVisible2Hidden)
        ], 'off', 'off')
        self.visibilityFSM.enterInitialState()
        self.visibilityFSM.request('hidden')
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterHidden(self):
        self.inventoryFrame.setPos(InventoryGui.HiddenPos)
        self.inventoryFrame.hide()

    def exitHidden(self):
        pass

    def enterVisible(self, autoShow=False):
        self.inventoryFrame.setPos(InventoryGui.VisiblePos)
        self.inventoryFrame.show()
        if self.visibilityBtnStatus == 0:
            if autoShow is False:
                self.visibilityFSM.request('visible2hidden')

    def exitVisible(self):
        pass

    def enterHidden2Visible(self, autoShow=False):
        self.inventoryFrame.show()
        self.moveIval = LerpPosInterval(self.inventoryFrame,
                                        duration=InventoryGui.SwitchTime,
                                        pos=InventoryGui.VisiblePos,
                                        startPos=InventoryGui.HiddenPos)
        self.moveIval.setDoneEvent('hidden2visible')
        self.acceptOnce('hidden2visible', self.visibilityFSM.request,
                        ['visible', [autoShow]])
        self.moveIval.start()

    def exitHidden2Visible(self):
        self.ignore('hidden2visible')
        self.moveIval.finish()
        del self.moveIval

    def enterVisible2Hidden(self):
        self.moveIval = LerpPosInterval(self.inventoryFrame,
                                        duration=InventoryGui.SwitchTime,
                                        pos=InventoryGui.HiddenPos,
                                        startPos=InventoryGui.VisiblePos)
        self.moveIval.setDoneEvent('visible2hidden')
        self.acceptOnce('visible2hidden', self.visibilityFSM.request,
                        ['hidden'])
        self.moveIval.start()

    def exitVisible2Hidden(self):
        self.ignore('visible2hidden')
        self.moveIval.finish()
        del self.moveIval

    def click_setWeapon(self, slot, cmd):
        self.setWeapon(slot, playSound=False)

    def setWeapon(self, slot, playSound=True, showUpIfHidden=False):
        if isinstance(slot, str):
            for iSlot in self.slots:
                if iSlot.getGag():
                    if iSlot.getGag().getID() == slot:
                        slot = iSlot

        if self.activeSlot and slot != self.activeSlot:
            self.activeSlot.setOutlineImage('idle')
            self.prevSlot = self.activeSlot
        if slot.getGag() and self.backpack.getSupply(slot.getGag().getID(
        )) > 0 and not slot.getGag().getState() == GagState.RECHARGING:
            if self.activeSlot != slot:
                gagId = slot.getGag().getID()
                base.localAvatar.needsToSwitchToGag = gagId
                if base.localAvatar.gagsTimedOut == False:
                    base.localAvatar.b_equip(gagId)
                    base.localAvatar.enableGagKeys()
                slot.setOutlineImage('selected')
                self.activeSlot = slot
            else:
                if self.activeSlot == slot and slot.getGag().getState() in [
                        GagState.LOADED, GagState.RECHARGING
                ]:
                    base.localAvatar.needsToSwitchToGag = 'unequip'
                    if base.localAvatar.gagsTimedOut == False:
                        base.localAvatar.b_unEquip()
                        base.localAvatar.enableGagKeys()
                    self.activeSlot = None
            self.update()
            if self.switchSound and playSound:
                base.playSfx(self.switchSoundSfx)
        if showUpIfHidden:
            base.taskMgr.remove('showUpIfHidden')
            self.__autoVisEnter()
            base.taskMgr.doMethodLater(InventoryGui.AutoShowTime,
                                       self.__autoVisExitTask,
                                       'showUpIfHidden')
        return

    def __autoVisExitTask(self, task):
        if self.visibilityBtnStatus == 0:
            self.__handleVisExit(None, updateBtnStatus=False)
        return task.done

    def __autoVisEnter(self):
        self.__handleVisEnter(None, True, False)
        return

    def __handleVisEnter(self, foo, autoShow=False, updateBtnStatus=True):
        if updateBtnStatus:
            self.visibilityBtnStatus = 1
        if self.visibilityFSM.getCurrentState().getName() == 'hidden':
            self.visibilityFSM.request('hidden2visible', [autoShow])
        else:
            if self.visibilityFSM.getCurrentState().getName(
            ) == 'visible2hidden':
                self.visibilityFSM.request('visible')

    def __handleVisExit(self, foo, updateBtnStatus=True):
        if updateBtnStatus:
            self.visibilityBtnStatus = 0
        base.taskMgr.remove('showUpIfHidden')
        if self.visibilityFSM.getCurrentState().getName() == 'visible':
            self.visibilityFSM.request('visible2hidden')

    def createGui(self):
        self.deleteGui()
        posGroup = self.threeSlotsPos
        if self.defaultSlots == 4:
            posGroup = self.fourSlotPos
        for slot in range(len(posGroup) + 1):
            if slot == 3:
                posGroup = self.fourSlotPos
            slotObj = Slot(self, slot + 1, posGroup[slot], self.inventoryFrame)
            self.slots.append(slotObj)
            if slot == 3:
                slotObj.hide()

        self.ammoLabel = DirectLabel(text='Ammo: 0',
                                     text_fg=(1, 1, 1, 1),
                                     relief=None,
                                     text_shadow=(0, 0, 0, 1),
                                     text_scale=0.08,
                                     pos=(0.2, 0, 0.35),
                                     parent=base.a2dBottomLeft)
        self.ammoLabel.hide()
        self.enableWeaponSwitch()
        self.resetScroll()
        self.update()
        return

    def deleteGui(self):
        self.disableWeaponSwitch()
        for slot in self.slots:
            slot.destroy()

        self.slots = []
        if self.ammoLabel:
            self.ammoLabel.destroy()
            self.ammoLabel = None
        self.DELETED = True
        return

    def resetScroll(self):
        nextGag = 0
        prevGag = -1
        curGag = -1
        if self.prevSlot:
            prevGag = self.slots.index(self.prevSlot)
        if self.activeSlot:
            curGag = self.slots.index(self.activeSlot)
        if curGag == len(self.slots) - 1:
            nextGag = 0
            prevGag = curGag - 1
        else:
            if curGag == 0:
                nextGag = 1
                prevGag = len(self.slots) - 1
            else:
                if curGag == -1:
                    prevGag = len(self.slots) - 1
                else:
                    nextGag = curGag + 1
                    prevGag = curGag - 1
        self.accept('wheel_down',
                    self.setWeapon,
                    extraArgs=[self.slots[nextGag], True, True])
        self.accept('wheel_up',
                    self.setWeapon,
                    extraArgs=[self.slots[prevGag], True, True])

    def update(self):
        if not self.backpack:
            return
        for element in [self.ammoLabel, self.inventoryFrame]:
            if not element:
                return

        updateSlots = list(self.slots)
        for slot in self.slots:
            gag = slot.getGag()
            if not gag:
                updateSlots.remove(slot)
                slot.hide()
                continue
            supply = self.backpack.getSupply(gag.getID())
            index = self.slots.index(slot)
            if not gag and len(self.backpack.getGags()) - 1 >= index:
                gag = self.backpack.getGagByIndex(index)
                slot.setGag(gag)
                if self.backpack.getSupply(gag.getID(
                )) > 0 and not gag.getState() == GagState.RECHARGING:
                    slot.setOutlineImage('idle')
                else:
                    slot.setOutlineImage('no_ammo')
            elif slot == self.activeSlot:
                self.ammoLabel['text_fg'] = (1, 1, 1, 1)
                if supply > 0 and not gag.getState() == GagState.RECHARGING:
                    slot.setOutlineImage('selected')
                else:
                    if supply <= 0:
                        self.ammoLabel['text_fg'] = (0.9, 0, 0, 1)
                    slot.setOutlineImage('no_ammo')
                    self.activeSlot = None
                self.ammoLabel.show()
                self.ammoLabel['text'] = 'Ammo: %s' % self.backpack.getSupply(
                    slot.getGag().getID())
            elif self.backpack.getSupply(slot.getGag().getID(
            )) > 0 and not gag.getState() == GagState.RECHARGING:
                slot.setOutlineImage('idle')
            else:
                slot.setOutlineImage('no_ammo')

        numSlots = len(updateSlots)
        posGroup = {
            1: self.oneSlotPos,
            2: self.twoSlotsPos,
            3: self.threeSlotsPos,
            4: self.fourSlotPos
        }.get(numSlots)
        for i in xrange(len(updateSlots)):
            updateSlots[i].setPos(posGroup[i])
            updateSlots[i].show()

        if self.activeSlot == None:
            self.ammoLabel.hide()
            self.ammoLabel['text'] = 'Ammo: 0'
        self.resetScroll()
        return

    def setBackpack(self, backpack):
        self.backpack = backpack

    def updateLoadout(self):
        if self.backpack:
            loadout = self.backpack.getLoadout()
            if len(loadout) <= 3:
                self.reseatSlots()
            else:
                if len(loadout) == 4:
                    self.reseatSlots(slots=4)
            for i in range(len(self.slots)):
                slot = self.slots[i]
                if i < len(loadout):
                    slot.setGag(loadout[i])
                else:
                    slot.setGag(None)

            self.update()
        return

    def reseatSlots(self, slots=3):
        for slot in range(len(self.slots) - 1):
            if slots == 4:
                self.slots[slot].setPos(self.fourSlotPos[slot])
            else:
                self.slots[slot].setPos(self.threeSlotsPos[slot])

    def enableWeaponSwitch(self):
        for index in range(len(self.slots)):
            self.accept(str(index + 1),
                        self.setWeapon,
                        extraArgs=[self.slots[index], True, True])

    def disableWeaponSwitch(self):
        for key in ['1', '2', '3', '4', 'wheel_down', 'wheel_up']:
            self.ignore(key)

    def getSlots(self):
        return self.slots

    def getActiveSlot(self):
        return self.activeSlot

    def isDeleted(self):
        return self.DELETED
コード例 #26
0
ファイル: window.py プロジェクト: cosmonium/cosmonium
class Window():
    texture = None
    def __init__(self, title_text, scale, parent=None, child=None, transparent=False, owner=None):
        self.title_text = title_text
        self.scale = scale
        self.title_size = settings.ui_font_size
        self.owner = owner
        self.child = None
        self.last_pos = None
        self.title_color = (1, 1, 1, 1)
        self.title_pad = tuple(self.scale * 2)
        if parent is None:
            parent = aspect2d
        self.parent = parent
        if transparent:
            frameColor = (0, 0, 0, 0)
        else:
            frameColor = (0.5, 0.5, 0.5, 1)
        self.pad = 0
        self.event_handler = DirectObject()
        self.button_thrower = base.buttonThrowers[0].node()
        self.event_handler.accept("wheel_up-up", self.mouse_wheel_event, extraArgs = [-1])
        self.event_handler.accept("wheel_down-up", self.mouse_wheel_event, extraArgs = [1])
        self.scrollers = []

#         if Window.texture is None:
#             Window.texture = loader.loadTexture('textures/futureui1.png')
#         image_scale = (scale[0] * Window.texture.get_x_size(), 1, scale[1] * Window.texture.get_y_size())
        self.frame = DirectFrame(parent=parent, state=DGG.NORMAL, frameColor=frameColor)#, image=self.texture, image_scale=image_scale)
        self.title_frame = DirectFrame(parent=self.frame, state=DGG.NORMAL, frameColor=(.5, .5, .5, 1))
        self.title = OnscreenText(text=self.title_text,
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * self.title_size),
                                  parent=self.title_frame,
                                  pos=(0, 0),
                                  align=TextNode.ALeft,
                                  font=None,
                                  mayChange=True)
        bounds = self.title.getTightBounds()
        self.title_frame['frameSize'] = [0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
                                         0, bounds[1][2] - bounds[0][2] + self.title_pad[1] * 2]
        self.title.setPos( -bounds[0][0] + self.title_pad[0],  -bounds[0][2] + self.title_pad[1])
        self.close_frame = DirectFrame(parent=self.frame, state=DGG.NORMAL, frameColor=(.5, .5, .5, 1))
        self.close = OnscreenText(text='X',
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * self.title_size),
                                  parent=self.close_frame,
                                  pos=(0, 0),
                                  align=TextNode.ACenter,
                                  font=None,
                                  mayChange=True)
        bounds = self.close.getTightBounds()
        self.close_frame['frameSize'] = [0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
                                         self.title_frame['frameSize'][2], self.title_frame['frameSize'][3]]
        self.close.setPos( -bounds[0][0] + self.title_pad[0],  -bounds[0][2] + self.title_pad[1])
        self.frame.setPos(0, 0, 0)
        self.title_frame.bind(DGG.B1PRESS, self.start_drag)
        self.title_frame.bind(DGG.B1RELEASE, self.stop_drag)
        self.close_frame.bind(DGG.B1PRESS, self.close_window)
        self.set_child(child)

    def set_child(self, child):
        if child is not None:
            self.child = child
            child.reparent_to(self.frame)
            self.update()

    def update(self):
        if self.child is not None:
            frame_size = list(self.child.frame['frameSize'])
            if frame_size is not None:
                frame_size[0] -= self.pad
                frame_size[1] += self.pad
                frame_size[2] += self.pad
                frame_size[3] -= self.pad
            self.frame['frameSize'] = frame_size
        if self.frame['frameSize'] is not None:
            width = self.frame['frameSize'][1] - self.frame['frameSize'][0]
            title_size = self.title_frame['frameSize']
            title_size[0] = 0
            title_size[1] = width
            self.title_frame['frameSize'] = title_size
            self.close_frame.setPos(width - self.close_frame['frameSize'][1], 0, 0)

    def register_scroller(self, scroller):
        self.scrollers.append(scroller)

    def mouse_wheel_event(self, dir):
        # If the user is scrolling a scroll-bar, don't try to scroll the scrolled-frame too.
        region = base.mouseWatcherNode.getOverRegion()
        if region is not None:
            widget = base.render2d.find("**/*{0}".format(region.name))
            if widget.is_empty() or isinstance(widget.node(), PGSliderBar) or isinstance(widget.getParent().node(), PGSliderBar):
                return

        # Get the mouse-position
        if not base.mouseWatcherNode.hasMouse():
            return
        mouse_pos = base.mouseWatcherNode.getMouse()

        found_scroller = None
        # Determine whether any of the scrolled-frames are under the mouse-pointer
        for scroller in self.scrollers:
            bounds = scroller['frameSize']
            pos = scroller.get_relative_point(base.render2d, Point3(mouse_pos.get_x() ,0, mouse_pos.get_y()))
            if pos.x > bounds[0] and pos.x < bounds[1] and \
                pos.z > bounds[2] and pos.z < bounds[3]:
                found_scroller = scroller
                break

        if found_scroller is not None:
            if not found_scroller.verticalScroll.isHidden():
                self.do_mouse_scroll(found_scroller.verticalScroll, dir, None)
            else:
                self.do_mouse_scroll(found_scroller.horizontalScroll, dir, None)

    def do_mouse_scroll(self, obj, dir, data):
        if isinstance(obj, DirectSlider) or isinstance(obj, DirectScrollBar):
            obj.setValue(obj.getValue() + dir * obj["pageSize"] * 0.1)

    def start_drag(self, event):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            self.drag_start = self.frame.parent.get_relative_point(render2d, Point3(mpos.get_x() ,0, mpos.get_y())) - self.frame.getPos()
            taskMgr.add(self.drag, "drag", -1)

    def drag(self, task):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            current_pos = self.frame.parent.get_relative_point(render2d, Point3(mpos.get_x() ,0, mpos.get_y()))
            self.frame.set_pos(current_pos - self.drag_start)
        return task.again

    def close_window(self, event=None):
        if self.owner is not None:
            self.owner.window_closed(self)
        self.destroy()

    def stop_drag(self, event):
        taskMgr.remove("drag")
        self.last_pos = self.frame.getPos()

    def destroy(self):
        if self.frame is not None:
            self.frame.destroy()
        self.frame = None
        self.scrollers = []
        self.event_handler.ignore_all()

    def getPos(self):
        return self.frame.getPos()

    def setPos(self, pos):
        self.frame.setPos(pos)
コード例 #27
0
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
コード例 #28
0
ファイル: panda3d_console.py プロジェクト: PlumpMath/fps_game
class panda3dIOClass( DirectObject.DirectObject ):
  # set gui key to None if you want to call toggleConsole from outside this class
  gui_key = CONSOLE_TOGGLE_KEY
  autocomplete_key = CONSOLE_AUTOCOMPLETE_KEY
  autohelp_key = CONSOLE_AUTOHELP_KEY
  
  scroll_up_repeat_key = CONSOLE_SCROLL_UP_KEY + "-repeat"
  scroll_down_repeat_key = CONSOLE_SCROLL_DOWN_KEY + "-repeat"
  
  # 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.9,0.9,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) )
    self.windowEvent( base.win )
    
    # try to load the defined font
    try:
      fixedWidthFont = loader.loadFont(self.font)
    except:
      print "pandaInteractiveConsole.py :: could not load the defined font %s" % str(self.font)
      fixedWidthFont = DGG.getDefaultFont()
    # 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()
    
    # call the help-command on start
    self.onEnterPress("help")
    
  
  
  # 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 )
      
      #playerController.enableInput()
      #unpause("v")
    else:
      self.ignoreAll()
      
      #playerController.disableInput()
      #pause("v")
      
      self.accept( CONSOLE_SCROLL_UP_KEY, self.scroll, [-5] )
      self.accept( self.scroll_up_repeat_key, self.scroll, [-5] )
      self.accept( CONSOLE_SCROLL_DOWN_KEY, self.scroll, [5] )
      self.accept( self.scroll_down_repeat_key, self.scroll, [5] )
      self.accept( 'window-event', self.windowEvent)
      
      self.accept( CONSOLE_PREVIOUS_COMMAND_KEY , self.scrollCmd, [ 1] )
      self.accept( CONSOLE_NEXT_COMMAND_KEY, 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 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 the interpreter to handle the input
    interpreter = cliClass()
    result = interpreter.interpreter(textEntered)
    # write the entered text to the output
    self.write(textEntered, (0.0, 0.0, 1, 1))
    print textEntered
    # write each line seperately to the output
    for line in result.split('\n'):
        line = "        " + line
        self.write(line, (0, 0, 0, 1))
        print line
  
  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 )
コード例 #29
0
class ToonPanel(DirectFrame):
    notify = directNotify.newCategory("ToonPanel")

    animal2HeadData = {
        'dog': (0.125, 0.04),
        'duck': (0.1, 0.025),
        'cat': (0.115, 0.04),
        'rabbit': (0.115, 0.04),
        'horse': (0.115, 0.06),
        'monkey': (0.115, 0.06),
        'pig': (0.115, 0.07),
        'mouse': (0.09, 0.02),
        'bear': (0.125, 0.05)
    }

    State2Text = {
        'status': ('Seeing if %s is available...',
                   '%s is busy right now; try again later.'),
        'teleport': ('Trying to go to %s...', 'Could not go to %s.'),
        'friend': ('Asking %s to be your friend...', '%s said no, thank you.',
                   'You are now friends with %s!'),
        'remove':
        ('Are you sure you want to remove %s from your friends list?',
         '%s left your friends list.')
    }

    def __init__(self):
        DirectFrame.__init__(self, scale=1.2)
        self['image'] = DGG.getDefaultDialogGeom()
        self['image_hpr'] = (0, 0, -90)
        self['image_scale'] = (0.67, 0.9, 0.325)
        self['image_color'] = (1, 1, 0.75, 1)
        self['image_pos'] = (0, 0, -0.09)
        self['relief'] = None
        self.reparentTo(base.a2dTopRight)
        self.setPos(-0.235, 0.0, -0.325)
        self.hide()
        self.head = None
        self.laffMeter = None
        self.exitButton = None
        self.friendButton = None
        self.teleportButton = None
        self.whisperButton = None
        self.nameText = None
        self.actionFrame = None
        self.actionFrameText = None
        self.actionFrameButton = None
        self.actionFrameButton2 = None
        self.avatarInfo = None
        self.action = None
        self.locationText = None
        self.shardText = None
        self.detailsExitBtn = None

        self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('waitOnAvatarInfoResponse',
                        self.enterWaitOnAvatarInfoResponse,
                        self.exitWaitOnAvatarInfoResponse, ['panel']),
            State.State('panel', self.enterPanel, self.exitPanel, ['off'])
        ], 'off', 'off')
        self.fsm.enterInitialState()

        self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State(
                'waitOnAvatarStatusResponse',
                self.enterWaitOnAvatarStatusResponse,
                self.exitWaitOnAvatarStatusResponse, [
                    'waitOnAvatarTeleportResponse',
                    'waitOnAvatarFriendListResponse', 'avatarBusy', 'off'
                ]),
            State.State('avatarBusy', self.enterAvatarBusy,
                        self.exitAvatarBusy, ['off']),
            State.State('waitOnAvatarTeleportResponse',
                        self.enterWaitOnAvatarTeleportResponse,
                        self.exitWaitOnAvatarTeleportResponse, ['unableToTP']),
            State.State('unableToTP', self.enterUnableToTP,
                        self.exitUnableToTP, ['off']),
            State.State('waitOnAvatarFriendListResponse',
                        self.enterWaitOnAvatarFriendListResponse,
                        self.exitWaitOnAvatarFriendListResponse,
                        ['fRequestA', 'fRequestR']),
            State.State('fRequestA', self.enterFriendRequestAccepted,
                        self.exitFriendRequestAccepted, ['off']),
            State.State('fRequestR', self.enterFriendRequestRejected,
                        self.exitFriendRequestRejected, ['off']),
            State.State('removeFriendConfirm', self.enterRemoveFriendConfirm,
                        self.exitRemoveFriendConfirm,
                        ['off', 'removedFriend']),
            State.State('removedFriend', self.enterRemovedFriend,
                        self.exitRemovedFriend, ['off'])
        ], 'off', 'off')
        self.actionFSM.enterInitialState()

    def makeMoreDetailsPanel(self):
        self.actionFSM.request('off')
        self.removeMoreDetailsPanel()
        self.removeActionPanel()
        self.makeActionPanel()
        zoneId = self.avatarInfo[5]
        shardId = self.avatarInfo[6]
        isOnline = self.avatarInfo[7]
        shardName = 'Unknown District'
        hoodName = ZoneUtil.getHoodId(zoneId, 1)
        for district in base.cr.activeDistricts.values():
            if district.doId == shardId:
                shardName = district.getDistrictName()
                break
        if not isOnline:
            hoodName = 'Offline'
            shardName = 'Offline'
        self.locationText = OnscreenText('Location: {0}'.format(hoodName),
                                         parent=self.actionFrame,
                                         pos=(-0.3, 0.05, 0),
                                         align=TextNode.ALeft,
                                         scale=0.04)
        self.shardText = OnscreenText('District: {0}'.format(shardName),
                                      parent=self.actionFrame,
                                      pos=(-0.3, 0.0, 0),
                                      align=TextNode.ALeft,
                                      scale=0.04)
        self.detailsExitBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                           parent=self.actionFrame,
                                           relief=None,
                                           scale=0.8,
                                           pos=(-0.3, 0.0, -0.175),
                                           command=self.removeMoreDetailsPanel)

    def removeMoreDetailsPanel(self):
        if self.locationText:
            self.locationText.destroy()
            self.locationText = None
        if self.shardText:
            self.shardText.destroy()
            self.shardText = None
        if self.detailsExitBtn:
            self.detailsExitBtn.destroy()
            self.detailsExitBtn = None
        self.removeActionPanel()

    def maybeUpdateFriendButton(self):
        if self.friendButton:
            if self.avatarInfo:
                if not self.avatarInfo[0] in base.localAvatar.friends:
                    self.friendButton['text'] = 'Add Friend'
                    self.friendButton['extraArgs'] = [
                        'waitOnAvatarFriendListResponse'
                    ]
                else:
                    self.friendButton['text'] = 'Remove Friend'
                    self.friendButton['extraArgs'] = ['removeFriendConfirm']

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterUnableToTP(self):
        pass

    def exitUnableToTP(self):
        pass

    def enterWaitOnAvatarTeleportResponse(self):
        self.setActionText(self.State2Text['teleport'][0] %
                           self.getAvatarName())
        self.makeButtons('Cancel')
        self.acceptOnce('gotAvatarTeleportResponse',
                        self.handleTeleportResponse)
        base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0])

    def handleTeleportResponse(self, avatarId, shardId, zoneId):
        if self.avatarInfo[0] == avatarId:
            requestStatus = {}
            whereName = ZoneUtil.getWhereName(zoneId)
            loaderName = ZoneUtil.getLoaderName(zoneId)
            requestStatus['zoneId'] = zoneId
            if base.localAvatar.parentId == shardId:
                requestStatus['shardId'] = None
            else:
                requestStatus['shardId'] = shardId
            requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1)
            requestStatus['where'] = whereName
            requestStatus['loader'] = loaderName
            requestStatus['how'] = 'teleportIn'
            requestStatus['avId'] = avatarId
            base.cr.playGame.getPlace().fsm.request('teleportOut',
                                                    [requestStatus])
            self.cleanup()

    def exitWaitOnAvatarTeleportResponse(self):
        self.ignore('gotAvatarTeleportResponse')
        self.clearActionText()
        self.clearActionButtons()

    def setActionText(self, text):
        self.actionFrameText.setText(text)

    def clearActionText(self):
        self.actionFrameText.setText("")

    def makeButtons(self, button1, button2=None):
        button2GeomFunc = {
            'Cancel': CIGlobals.getCancelBtnGeom,
            'No': CIGlobals.getCancelBtnGeom,
            'Okay': CIGlobals.getOkayBtnGeom,
            'Yes': CIGlobals.getOkayBtnGeom
        }
        if button1 and not button2:
            button1Pos = (0, 0, -0.1)
        elif button1 and button2:
            button1Pos = (-0.1, 0, -0.1)
        button2Pos = (0.1, 0, -0.1)
        if button1:
            self.actionFrameButton = DirectButton(
                text=button1,
                geom=button2GeomFunc[button1](),
                parent=self.actionFrame,
                pos=button1Pos,
                text_scale=0.045,
                text_pos=(0, -0.08),
                command=self.actionButtonPressed,
                extraArgs=[1],
                relief=None,
                geom_scale=0.75)
        if button2:
            self.actionFrameButton2 = DirectButton(
                text=button2,
                geom=button2GeomFunc[button2](),
                parent=self.actionFrame,
                pos=button2Pos,
                text_scale=0.045,
                text_pos=(0, -0.08),
                command=self.actionButtonPressed,
                extraArgs=[2],
                relief=None,
                geom_scale=0.75)

    def actionButtonPressed(self, buttonNum):
        currentState = self.actionFSM.getCurrentState().getName()
        if buttonNum == 1:
            if currentState in [
                    'waitOnAvatarStatusResponse',
                    'waitOnAvatarTeleportResponse',
                    'waitOnAvatarFriendListResponse', 'avatarBusy',
                    'unableToTP', 'fRequestA', 'fRequestR',
                    'removeFriendConfirm', 'removedFriend'
            ]:
                if currentState == 'waitOnAvatarFriendListResponse':
                    base.cr.friendsManager.d_iCancelledFriendRequest(
                        self.avatarInfo[0])
                elif currentState == 'removeFriendConfirm':
                    self.actionFSM.request('removedFriend')
                    return
                self.actionFSM.request('off')
                self.removeActionPanel()
                self.action = None
        elif buttonNum == 2:
            self.actionFSM.request('off')
            self.removeActionPanel()
            self.action = None

    def clearActionButtons(self):
        if self.actionFrameButton2:
            self.actionFrameButton2.destroy()
            self.actionFrameButton2 = None
        if self.actionFrameButton:
            self.actionFrameButton.destroy()
            self.actionFrameButton = None

    def enterAvatarBusy(self):
        self.setActionText(self.State2Text['status'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitAvatarBusy(self):
        self.clearActionText()
        self.clearActionButtons()

    def getAvatarName(self):
        if self.avatarInfo:
            return self.avatarInfo[1]

    def enterWaitOnAvatarStatusResponse(self):
        self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)
        base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0])
        self.setActionText(self.State2Text['status'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleAvatarStatusResponse(self, avatarId, status):
        if avatarId == self.avatarInfo[0]:

            # Busy
            if status == 1:
                self.actionFSM.request('avatarBusy')

            # Not busy
            else:
                self.actionFSM.request(self.action)
        else:
            self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)

    def exitWaitOnAvatarStatusResponse(self):
        self.ignore('gotAvatarStatus')
        self.clearActionText()
        self.clearActionButtons()

    def enterWaitOnAvatarFriendListResponse(self):
        self.acceptOnce('friendRequestAccepted',
                        self.handleFriendRequestAccepted)
        self.acceptOnce('friendRequestRejected',
                        self.handleFriendRequestRejected)
        base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0])
        self.setActionText(self.State2Text['friend'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleFriendRequestAccepted(self):
        self.actionFSM.request('fRequestA')

    def handleFriendRequestRejected(self):
        self.actionFSM.request('fRequestR')

    def exitWaitOnAvatarFriendListResponse(self):
        self.ignore('friendRequestAccepted')
        self.ignore('friendRequestRejected')
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestAccepted(self):
        self.setActionText(self.State2Text['friend'][2] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestAccepted(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestRejected(self):
        self.setActionText(self.State2Text['friend'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestRejected(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemoveFriendConfirm(self):
        self.setActionText(self.State2Text['remove'][0] % self.getAvatarName())
        self.makeButtons('Yes', 'No')

    def exitRemoveFriendConfirm(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemovedFriend(self):
        base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0])
        self.setActionText(self.State2Text['remove'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitRemovedFriend(self):
        self.clearActionText()
        self.clearActionButtons()

    def makeActionPanel(self):
        self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(),
                                       image_scale=(0.7, 0.5, 0.45),
                                       image_color=(1, 1, 0.75, 1),
                                       relief=None)
        self.actionFrame.reparentTo(base.a2dTopRight)
        self.actionFrame.setPos(-0.815, 0, -0.31)
        self.actionFrameText = OnscreenText(text="",
                                            parent=self.actionFrame,
                                            scale=0.05,
                                            wordwrap=12,
                                            pos=(0, 0.1))

    def removeActionPanel(self):
        self.clearActionButtons()
        if self.actionFrameText:
            self.actionFrameText.destroy()
            self.actionFrameText = None
        if self.actionFrame:
            self.actionFrame.destroy()
            self.actionFrame = None

    def doAction(self, action):
        self.action = action
        self.actionFSM.requestFinalState()
        self.removeMoreDetailsPanel()
        self.removeActionPanel()
        self.makeActionPanel()
        if action != 'removeFriendConfirm':
            self.actionFSM.request('waitOnAvatarStatusResponse')
        else:
            self.actionFSM.request(action)

    def enterWaitOnAvatarInfoResponse(self):
        self.label = OnscreenText(text='Retrieving Toon\ndetails...',
                                  parent=self,
                                  scale=0.04)
        self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse)
        base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0])

    def handleAvatarInfoResponse(self, name, dna, maxHealth, health, zoneId,
                                 shardId, isOnline, adminToken):
        if self.avatarInfo:
            self.avatarInfo.append(name)
            self.avatarInfo.append(dna)
            self.avatarInfo.append(maxHealth)
            self.avatarInfo.append(health)
            self.avatarInfo.append(zoneId)
            self.avatarInfo.append(shardId)
            self.avatarInfo.append(isOnline)
            self.avatarInfo.append(adminToken)
            self.fsm.request('panel')

    def exitWaitOnAvatarInfoResponse(self):
        self.label.destroy()
        del self.label
        self.ignore('avatarInfoResponse')

    def makePanel(self, avId):
        if self.avatarInfo:
            if self.avatarInfo[0] == avId:
                # They clicked on the same toon without closing the
                # previous panel, maybe they're spamming?
                return

        self.cleanup()

        base.localAvatar.hideFriendButton()

        self.show()
        self.avatarInfo = []
        self.avatarInfo.append(avId)
        self.fsm.request('waitOnAvatarInfoResponse')

    def exitClicked(self):
        self.cleanup()
        base.localAvatar.showFriendButton()

    def cleanup(self):
        self.actionFSM.requestFinalState()
        self.fsm.requestFinalState()
        self.avatarInfo = None

    def enterPanel(self):
        adminToken = self.avatarInfo[8]
        text_color = CIGlobals.TextColorByAdminToken[adminToken]
        self.nameText = OnscreenText(text=self.avatarInfo[1],
                                     parent=self,
                                     pos=(0, 0.2),
                                     scale=0.035,
                                     wordwrap=8,
                                     fg=text_color)
        self.nameText.setBin('gui-popup', 60)

        dna = ToonDNA.ToonDNA()
        dna.setDNAStrand(self.avatarInfo[2])

        self.head = ToonHead.ToonHead(base.cr)
        self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
        self.head.setHeadColor(dna.headcolor)
        self.head.reparentTo(self)
        self.head.setDepthWrite(1)
        self.head.setDepthTest(1)
        self.head.setH(180)
        self.head.setScale(self.animal2HeadData[dna.animal][0])
        self.head.setZ(self.animal2HeadData[dna.animal][1])

        self.laffMeter = LaffOMeter()
        r, g, b, _ = dna.headcolor
        self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3],
                                self.avatarInfo[4])
        self.laffMeter.reparentTo(self)
        self.laffMeter.setBin('gui-popup', 60)
        self.laffMeter.setScale(0.045)
        self.laffMeter.setPos(0, 0, -0.1)

        self.friendButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Add Friend",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarFriendListResponse'])
        self.friendButton.setPos(0, 0.0, -0.225)
        self.maybeUpdateFriendButton()

        self.teleportButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Teleport",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarTeleportResponse'])
        self.teleportButton.setPos(0, 0, -0.275)

        self.whisperButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Whisper",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=base.localAvatar.handleClickedWhisper,
            extraArgs=[self.avatarInfo[1], self.avatarInfo[0], 1])
        self.whisperButton.setPos(0, 0, -0.325)

        self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                       parent=self,
                                       relief=None,
                                       scale=0.6,
                                       pos=(0, 0.0, -0.39),
                                       command=self.exitClicked)
        gui = loader.loadModel("phase_3.5/models/gui/friendslist_gui.bam")
        self.moreDetailsBtn = DirectButton(
            geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'),
                  gui.find('**/Horiz_Arrow_Rllvr'),
                  gui.find('**/Horiz_Arrow_UP')),
            relief=None,
            parent=self,
            pos=(-0.127, 0.0, -0.39),
            geom_hpr=(180, 0, 0),
            command=self.makeMoreDetailsPanel,
            scale=0.77,
            text=('', 'More Details', 'More Details', ''),
            text_scale=0.045,
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_pos=(-0.08, -0.01),
            text_align=TextNode.ARight)

    def exitPanel(self):
        if self.actionFSM.getCurrentState().getName(
        ) == 'waitOnAvatarFriendListResponse':
            if self.avatarInfo:
                base.cr.friendsManager.d_iCancelledFriendRequest(
                    self.avatarInfo[0])
        self.actionFSM.requestFinalState()
        self.action = None
        self.avatarInfo = None
        self.removeActionPanel()
        self.removeMoreDetailsPanel()
        self.hide()
        if self.nameText:
            self.nameText.destroy()
            self.nameText = None
        if self.head:
            self.head.removeNode()
            self.head.delete()
            self.head = None
        if self.laffMeter:
            self.laffMeter.disable()
            self.laffMeter.delete()
            self.laffMeter = None
        if self.friendButton:
            self.friendButton.destroy()
            self.friendButton = None
        if self.teleportButton:
            self.teleportButton.destroy()
            self.teleportButton = None
        if self.whisperButton:
            self.whisperButton.destroy()
            self.whisperButton = None
        if self.exitButton:
            self.exitButton.destroy()
            self.exitButton = None
        if self.moreDetailsBtn:
            self.moreDetailsBtn.destroy()
            self.moreDetailsBtn = None
コード例 #30
0
 def setPos(self, *args, **kwargs):
     DirectFrame.setPos(self, *args, **kwargs)
     self.resetArcBall()
コード例 #31
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()
コード例 #32
0
ファイル: Transitions.py プロジェクト: frostbane/panda3d
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()
コード例 #33
0
class QuestPoster(DirectFrame):
    notify = directNotify.newCategory('QuestPoster')

    # We need to declare and initialize these variables here
    # because some methods use them as default arguments.
    auxIcon = None

    # Requires one parameter, quest, this must be a Quest instance.
    # The next argument, parent, is where to reparent the DirectFrame to.
    # The next arguments are simply additional options when setting up the DirectFrame.
    def __init__(self, quest, parent=aspect2d, **kw):
        # The quest this poster is representing.
        self.quest = quest
        self.accessibleObjectives = quest.accessibleObjectives if quest else []
        self.viewObjective = quest.accessibleObjectives.seek(
        ) if quest else None

        isObjComplete = False if not quest else (
            self.accessibleObjectives.isComplete() or quest.isComplete())

        # Let's define our options for the DirectFrame.
        bookModel = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        optiondefs = (('relief', None,
                       None), ('image', bookModel.find('**/questCard'),
                               None), ('image_scale', (0.8, 1.0, 0.58), None),
                      ('image_color', (1.0, 1.0, 1.0,
                                       1.0) if not isObjComplete else Vec4(
                                           *QuestGlobals.LIGHT_GREEN),
                       None), ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)

        # Finally, initialize the DirectFrame.
        DirectFrame.__init__(self, parent, relief=None)
        self.initialiseoptions(QuestPoster)

        # Let's declare and initialize our barebone GUI element variables.
        questTitle = '' if not self.quest else self.quest.name
        self.titleLabel = DirectLabel(parent=self,
                                      relief=None,
                                      text=questTitle,
                                      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))

        ##########################################################################
        #           THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER            #
        ##########################################################################

        # The background frame where the objective image is displayed.
        # This is the colored background frame.

        circleGui = loader.loadModel(
            'phase_4/models/gui/CircleIconBackgroundGui.bam')
        self.auxFrame = DirectFrame(
            parent=self,
            relief=None,
            image=circleGui.find('**/circle_display_interior'),
            image_scale=0.18,
            text='',
            text_pos=(0, -0.11),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=11.0,
            pos=QuestGlobals.DEFAULT_LEFT_PICTURE_POS)

        if self.quest and len(
                self.quest.accessibleObjectives) > 1 and not isObjComplete:
            # We can only use arrows when we have more than one objective available.
            arrowGui = loader.loadModel('phase_4/models/gui/QuestArrowGui.bam')
            self.prevObjArrow = DirectButton(
                parent=self.auxFrame,
                relief=None,
                geom=((arrowGui.find('**/quest_arrow_enabled'),
                       arrowGui.find('**/quest_arrow_click'),
                       arrowGui.find('**/quest_arrow_mouseover'),
                       arrowGui.find('**/quest_arrow_disabled'))),
                scale=0.08,
                command=self.switchObjective,
                extraArgs=[0],
                hpr=(180, 0, 0),
                pos=QuestGlobals.DEFAULT_LEFT_ARROW_POS)

            self.nextObjArrow = DirectButton(
                parent=self.auxFrame,
                relief=None,
                geom=((arrowGui.find('**/quest_arrow_enabled'),
                       arrowGui.find('**/quest_arrow_click'),
                       arrowGui.find('**/quest_arrow_mouseover'),
                       arrowGui.find('**/quest_arrow_disabled'))),
                scale=0.08,
                command=self.switchObjective,
                pos=QuestGlobals.DEFAULT_RIGHT_ARROW_POS)

        # The icon that goes on top of the aux frame.
        self.auxIcon = DirectFrame(parent=self.auxFrame,
                                   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.auxIcon.setColorOff(-1)

        self.auxOutline = DirectLabel(
            parent=self.auxFrame,
            relief=None,
            image=circleGui.find('**/circle_display_outline'),
            image_scale=0.18)

        # The aux text saying: DEFEAT, RECOVER, etc.
        self.auxText = DirectLabel(parent=self,
                                   relief=None,
                                   text=QuestGlobals.RECOVER,
                                   text_font=CIGlobals.getToonFont(),
                                   text_scale=QuestGlobals.QPauxText,
                                   text_fg=QuestGlobals.TEXT_COLOR,
                                   text_align=TextNode.ACenter,
                                   textMayChange=1,
                                   pos=QuestGlobals.DEFAULT_AUX_POS)
        self.auxText.hide()

        ##########################################################################

        # Information displayed about the objective.
        self.objectiveInfo = DirectLabel(
            parent=self,
            relief=None,
            text='',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=0.04,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(QuestGlobals.DEFAULT_INFO_POS))
        self.objectiveInfo.hide()

        # Information displayed showing the location.
        self.locationInfo = DirectLabel(
            parent=self,
            relief=None,
            text='N/A',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(0, 0, -0.115))
        self.locationInfo.hide()

        # The progress bar showing the objective's progress
        self.progressBar = DirectWaitBar(parent=self,
                                         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),
                                         pos=(0, 0, -0.2425))
        self.progressBar.hide()

        # The wood panel at the bottom where rewards are displayed.
        rewardFrameGeom = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.rewardFrame = DirectFrame(
            parent=self,
            relief=None,
            geom=rewardFrameGeom.find('**/Goofys_Sign'),
            geom_scale=(0.62, 0, 0.4),
            pos=(-0.015, 0, -0.25))

        # Let's setup our reward frames.
        reward = None

        if self.quest and len(self.quest.rewards) > 0:
            reward = self.quest.rewards[0]
        self.lReward = QuestRewardFrame(self, reward)

        # The text displayed on the right side of the frame with additional information, if necessary.
        self.sideInfo = DirectLabel(parent=self,
                                    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)

        # This side information is usually not needed, let's hide it.
        self.sideInfo.hide()

        # Remove the nodes of the loaded models we no longer need.
        circleGui.removeNode()
        bookModel.removeNode()
        rewardFrameGeom.removeNode()

        # We are only removing this node if we generated arrows.
        if hasattr(self, 'arrowGui'):
            arrowGui.removeNode()

        # Let's hide this until it is needed.
        self.hide()
        return

    def switchObjective(self, forward=1):
        if forward:
            self.accessibleObjectives.nextObjective()
        else:
            self.accessibleObjectives.lastObjective()
        self.viewObjective = self.accessibleObjectives.seek()
        self.setup()

    def setup(self):
        if self.quest:
            objective = self.viewObjective
            complete = self.accessibleObjectives.isComplete()

            # Let's reset our positioning of elements.
            self.auxFrame.setPos(QuestGlobals.DEFAULT_LEFT_PICTURE_POS)
            self.auxText.setPos(QuestGlobals.DEFAULT_AUX_POS)
            self.objectiveInfo.setPos(QuestGlobals.DEFAULT_INFO_POS)

            # Let's reset our icon.
            self.auxIcon.setScale(1, 1, 1)
            self.auxIcon.setPos(0, 0, 0)
            self.auxIcon.setHpr(0, 0, 0)

            self.objectiveInfo.show()
            self.auxFrame.show()

            # Let's setup the quest progress bar
            progress = objective.progress if hasattr(objective,
                                                     'progress') else None

            if objective.goal > 1:
                self.progressBar['range'] = objective.goal
                self.progressBar['value'] = progress & pow(2, 16) - 1

            if objective.HasProgress and objective.goal > 1 and not complete:
                self.progressBar.show()

            self.auxText.show()

            # Let's handle the objectives.
            if not complete:
                if objective.__class__ == CogObjective:
                    self.handleCogObjective()
                elif objective.__class__ == CogBuildingObjective:
                    self.handleCogBuildingObjective()
                elif objective.__class__ == MinigameObjective:
                    self.handleMinigameObjective()
                elif objective.__class__ == VisitNPCObjective:
                    self.handleNPCObjective()
            else:
                bgColor = QuestGlobals.RED

                if objective.type in DefeatObjectives:
                    bgColor = QuestGlobals.BLUE

                self.handleNPCObjective(auxText=QuestGlobals.RETURN + ' to',
                                        frameColor=bgColor)

            self.lReward.setup()

            newLineInObjInfo = '\n' in self.objectiveInfo['text']
            isShopLoc = QuestGlobals.isShopLocation(
                objective.area) if not complete else True

            if complete:
                locationText = QuestGlobals.getLocationText(None, objective)
            else:
                locationText = QuestGlobals.getLocationText(objective.area)

            self.locationInfo['text'] = locationText
            self.locationInfo['text_pos'] = (0.0, (0.025 if isShopLoc else (
                -0.025 if newLineInObjInfo else 0.0)))
            self.locationInfo.show()
        else:
            # We want to be able to show empty quest posters.
            self.titleLabel.hide()
            self.auxFrame.hide()
            self.auxIcon.hide()

        self.titleLabel.initialiseoptions(DirectLabel)
        self.auxIcon.initialiseoptions(DirectFrame)
        self.auxText.initialiseoptions(DirectLabel)
        self.objectiveInfo.initialiseoptions(DirectLabel)
        self.locationInfo.initialiseoptions(DirectLabel)
        self.rewardFrame.initialiseoptions(DirectFrame)
        self.sideInfo.initialiseoptions(DirectLabel)
        self.lReward.initialiseoptions(DirectFrame)

        # Handle arrow stuff if necessary.
        if hasattr(self, 'prevObjArrow'):
            index = self.accessibleObjectives.seeker
            self.prevObjArrow['state'] = DGG.NORMAL
            self.nextObjArrow['state'] = DGG.NORMAL
            self.prevObjArrow.setPos(QuestGlobals.DEFAULT_LEFT_ARROW_POS)
            self.nextObjArrow.setPos(QuestGlobals.DEFAULT_RIGHT_ARROW_POS)

            if index == 0:
                self.prevObjArrow['state'] = DGG.DISABLED
            elif index == len(self.accessibleObjectives) - 1:
                self.nextObjArrow['state'] = DGG.DISABLED

            self.prevObjArrow.initialiseoptions(DirectButton)
            self.nextObjArrow.initialiseoptions(DirectButton)

    # Changes geometry and scale of an icon.
    def handleSimpleIcon(self, geom, scale, icon):
        icon['geom'] = geom
        icon['geom_scale'] = scale

    def handleComplexIcon(self,
                          geom,
                          icon,
                          scale=QuestGlobals.IMAGE_SCALE_SMALL):
        geom.setDepthWrite(1)
        geom.setDepthTest(1)
        self.fitGeometry(geom, fFlip=1)
        self.handleSimpleIcon(geom, scale, icon)

        # We have to rotate the head and set the scale of the icon.
        if CIGlobals.Suit in geom.getName():
            cogName = geom.getPythonTag('Settings')
            data = QuestGlobals.Suit2PosterZNDScale.get(cogName)
            zOffset = data[0]
            headScale = data[1]
            icon.setScale(headScale)
            icon.setZ(icon.getZ() + zOffset)
            icon.setH(180)
        else:
            icon.setZ(icon.getZ() - 0.01)

    def handleCogObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.DEFEAT,
                           frameColor=QuestGlobals.BLUE):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if objective.__class__ == RecoverItemObjective:
            infoText = CIGlobals.makePlural(objective.cog)

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, CogObjective):
            return

        if objective.dept:
            icons = loader.loadModel('phase_3/models/gui/cog_icons.bam')
            deptIcon = None

            if objective.dept == Dept.BOSS:
                deptIcon = icons.find('**/CorpIcon')
            else:
                deptIcon = icons.find('**/%sIcon' %
                                      objective.dept.getTie().title())

            # Correct the medallion color.
            deptIcon.setColor(SuitGlobals.medallionColors[objective.dept])

            # Setup the icon and remove the icons node.
            self.handleSimpleIcon(deptIcon, 0.13, iconElement)
            icons.removeNode()
        elif objective.cog == QuestGlobals.Any:
            # We aren't fighting a Cog in particular.
            cogIcon = QuestGlobals.getCogIcon()
            self.handleSimpleIcon(cogIcon, 0.13, iconElement)

        # We're fighting a Cog in particular.
        if not objective.cog == QuestGlobals.Any:
            cogHeadInstance = SuitBank.getSuitByName(objective.cog).getHead()
            cogHead = cogHeadInstance.generate()
            cogHead.setName('%sHead' % CIGlobals.Suit)
            cogHead.setPythonTag('Settings', cogHeadInstance.head)
            cogHead.setScale(2)
            cogHead.setLightOff()
            self.handleComplexIcon(cogHead, iconElement)

            # HACK FIX: Corrects the buggy Flunky glasses.
            glasses = cogHead.find('**/glasses')
            if glasses and not glasses.isEmpty():
                glasses.setScale(1)
                glasses.reparentTo(cogHead)

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.auxText['text'] = auxText

        # Let's set the color of the poster.
        frame = self.auxFrame if iconElement is self.auxIcon else self.goalFrame
        frame['image_color'] = Vec4(*frameColor)

    def handleCogBuildingObjective(self,
                                   iconElement=auxIcon,
                                   auxText=QuestGlobals.DEFEAT,
                                   frameColor=QuestGlobals.BLUE):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogBuildingObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, CogBuildingObjective):
            return

        # If we aren't looking for any specific department of building.
        if objective.dept == QuestGlobals.Any:
            # Let's just use the good ol' generic building icon.
            self.handleSimpleIcon(QuestGlobals.getCogBuildingIcon(),
                                  QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)
        else:
            # Ah geez, we're looking for a specific department.
            # Bossbot tie names are messed up, so we need this if statement.
            dept = objective.dept.getTie(
            ) if not objective.dept == Dept.BOSS else 'corp'
            bldgMdl = loader.loadModel(
                'phase_4/models/modules/suit_landmark_%s.bam' % dept)

            # Next, we need to load the building elevator.
            elevator = loader.loadModel('phase_4/models/modules/elevator.bam')
            elevator.reparentTo(bldgMdl.find('**/*_door_origin'))

            self.handleComplexIcon(bldgMdl, iconElement)

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.objectiveInfo['text'] = infoText
        self.auxText['text'] = auxText
        self.auxFrame['image_color'] = Vec4(*frameColor)

    def handleMinigameObjective(self,
                                iconElement=auxIcon,
                                auxText=QuestGlobals.PLAY,
                                frameColor=QuestGlobals.RED):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the MinigameObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, MinigameObjective):
            return

        # Let's set the icon to the minigame icon.
        self.handleSimpleIcon(QuestGlobals.getTrolleyIcon(),
                              QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.objectiveInfo['text'] = infoText
        self.auxText['text'] = auxText
        self.auxFrame['image_color'] = Vec4(*frameColor)

    def handleNPCObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.VISIT,
                           frameColor=QuestGlobals.BROWN):
        objective = self.viewObjective
        npcId = 0

        if self.accessibleObjectives.isComplete() and not hasattr(
                objective, 'npcId'):
            npcId = objective.assigner
        elif hasattr(objective, 'npcId'):
            npcId = objective.npcId

        if npcId == 0:
            infoText = 'A %s' % NPCGlobals.lHQOfficerF
        else:
            infoText = NPCGlobals.NPCToonNames[npcId]

        if not iconElement:
            iconElement = self.auxIcon

        # Let's generate the head.
        if not npcId == 0:
            dna = ToonDNA()
            dna.setDNAStrand(NPCGlobals.NPCToonDict.get(npcId)[2])
            head = ToonGlobals.generateGuiHead(dna)
            self.handleComplexIcon(head,
                                   iconElement,
                                   scale=QuestGlobals.IMAGE_SCALE_SMALL - 0.01)
        else:
            self.handleSimpleIcon(QuestGlobals.getHQIcon(),
                                  QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)

        self.auxText['text'] = auxText

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
                self.goalFrame['image_color'] = frameColor
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText
            self.auxFrame['image_color'] = frameColor

    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):
        if hasattr(self, 'titleLabel'):
            self.titleLabel.destroy()
            self.auxFrame.destroy()
            self.auxIcon.destroy()
            self.auxOutline.destroy()
            self.auxText.destroy()
            self.objectiveInfo.destroy()
            self.locationInfo.destroy()
            self.progressBar.destroy()
            self.rewardFrame.destroy()
            self.sideInfo.destroy()
            self.lReward.destroy()

            # We need to cleanup our arrows if they were created.
            if hasattr(self, 'prevObjArrow'):
                self.prevObjArrow.destroy()
                self.nextObjArrow.destroy()
                del self.prevObjArrow
                del self.nextObjArrow

            del self.titleLabel
            del self.auxFrame
            del self.auxIcon
            del self.auxOutline
            del self.auxText
            del self.objectiveInfo
            del self.locationInfo
            del self.progressBar
            del self.rewardFrame
            del self.sideInfo
            del self.lReward
            del self.accessibleObjectives
            del self.viewObjective
            DirectFrame.destroy(self)
            self.notify.debug('Destroyed all elements.')
コード例 #34
0
ファイル: uielements.py プロジェクト: Compy/DemolitionMan2000
class NameValueList(UIItem):
    """
    A NameValueList is a list of name and value pairs. This is commonly used in the settings screen
    where the user has a list of items and can edit them at any point in time.
    This is just a generic UI element to keep all of the data and logic within the game subsystem
    """
    def __init__(self, items=[], lines_to_show=5):
        # items is a tuple consisting of (text name of item, selection values, current selection)
        self._items = []
        self._lines_to_show = lines_to_show

        self.__menuContainer = DirectFrame(
            #text_pos=(0,1),
            pos=(-0.6, 0, 0.3),
            text_scale=1.5,
            text_align=TextNode.ALeft,
            text_fg=(0, 0, 0, 0),
            relief=DGG.FLAT,
            frameColor=(1, 1, 1, 0),
            #left,right,bottom,top
            frameSize=(-0.5, 0.5, -0.5, 0.5))
        self.__menuContainer.hide()

        self.selectedItem = 0

        self.editing = False
        self.blink = False
        self.blinkTask = None

        for item in items:
            self.addItem(item[0], item[1], item[2])

    def setPos(self, x, y, z):
        self.__menuContainer.setPos(x, y, z)

    def addItem(self, text_name, selection_values, current_selection_idx=-1):
        """
        Adds an item to the list display.
        text_name - The string representation of the list item
        selection_values - A list of available values for selection in this field
        current_selection - The currently selected item
        """

        pos_name = Vec3(-0.47, 0, 0.4 - (len(self._items) * 0.15))
        pos_value = Vec3(1.0, 0, 0.4 - (len(self._items) * 0.15))

        length = len(self._items)

        selection_text = ""
        if current_selection_idx != -1:
            selection_text = str(selection_values[current_selection_idx])

        name_display = DirectButton(
            text=text_name,
            command=None,
            extraArgs=[len(self._items)],
            text_align=TextNode.ALeft,
            scale=0.1,
            #left/right, forward/back, up/down
            pos=pos_name,
            text_fg=(1, 1, 1, 1),
            rolloverSound=None,
            clickSound=None,
            pressEffect=0,
            relief=None,
            textMayChange=True
            #text_font=base.fontLoader.load('Arial Bold.ttf')
        )
        name_display.reparentTo(self.__menuContainer)

        value_display = DirectButton(
            text=str(selection_text),
            command=None,
            extraArgs=[len(self._items)],
            text_align=TextNode.ALeft,
            scale=0.1,
            #left/right, forward/back, up/down
            pos=pos_value,
            text_fg=(1, 1, 1, 1),
            rolloverSound=None,
            clickSound=None,
            pressEffect=0,
            relief=None,
            textMayChange=True
            #text_font=base.fontLoader.load('Arial Bold.ttf')
        )

        value_display.reparentTo(self.__menuContainer)

        v = {}
        v['name'] = text_name
        v['name_display'] = name_display
        v['value_display'] = value_display
        v['selection_values'] = selection_values
        v['current_selection_idx'] = current_selection_idx
        self._items.append(v)

    def up(self):
        """Move one item up in the menu."""

        if self.editing:
            current_item = self._items[self.selectedItem]
            current_item['current_selection_idx'] = (
                current_item['current_selection_idx'] + 1) % len(
                    current_item['selection_values'])
            current_item['value_display']['text'] = current_item[
                'selection_values'][current_item['current_selection_idx']]
        else:

            newItem = self.selectedItem - 1
            if (newItem < 0):
                newItem = len(self._items) - 1
            self.select(newItem)

        UIItem.up(self)

    def down(self):
        """Move one item down in the menu."""
        if self.editing:
            current_item = self._items[self.selectedItem]
            current_item['current_selection_idx'] = (
                current_item['current_selection_idx'] - 1) % len(
                    current_item['selection_values'])
            current_item['value_display']['text'] = current_item[
                'selection_values'][current_item['current_selection_idx']]
        else:

            newItem = self.selectedItem + 1
            if (newItem >= len(self._items)):
                newItem = 0
            self.select(newItem)

        UIItem.down(self)

    def show(self):
        if (self.__menuContainer.isHidden()):
            Sequence(
                Func(self.__menuContainer.setAlphaScale, 0.0),
                Func(self.__menuContainer.show),
                LerpFunctionInterval(self.__menuContainer.setAlphaScale,
                                     toData=1.0,
                                     fromData=0.0,
                                     duration=1.0)).start()

    def hide(self):
        self.ignoreAll()
        if (not self.__menuContainer.isHidden()):
            Sequence(
                LerpFunctionInterval(self.__menuContainer.setAlphaScale,
                                     toData=0.0,
                                     fromData=1.0,
                                     duration=1.0),
                Func(self.__menuContainer.hide),
                Func(self.__menuContainer.setAlphaScale, 1.0)).start()

    def setParent(self, parent):
        self.__menuContainer.reparentTo(parent)

    def select(self, item):
        self._items[self.selectedItem]['name_display']['text_fg'] = (1, 1, 1,
                                                                     1)
        self._items[self.selectedItem]['name_display']['text_bg'] = (0, 0, 0,
                                                                     0)
        self._items[self.selectedItem]['value_display']['text_fg'] = (1, 1, 1,
                                                                      1)
        self._items[self.selectedItem]['value_display']['text_bg'] = (0, 0, 0,
                                                                      0)
        self.selectedItem = item
        self._items[self.selectedItem]['name_display']['text_fg'] = (0, 0, 0.5,
                                                                     1)
        self._items[self.selectedItem]['name_display']['text_bg'] = (1, 1, 1,
                                                                     1)
        self._items[self.selectedItem]['value_display']['text_fg'] = (0, 0,
                                                                      0.5, 1)
        self._items[self.selectedItem]['value_display']['text_bg'] = (1, 1, 1,
                                                                      1)

    def toggleEdit(self):
        self.editing = not self.editing
        if self.editing:
            # Start blinking
            self.blinkTask = base.taskMgr.doMethodLater(
                0.4, self._doBlink, 'nvBlinkTask')
        else:
            # Stop blinking
            if self.blinkTask != None:
                base.taskMgr.remove(self.blinkTask)

    def _doBlink(self, task):
        self.blink = not self.blink
        if self.blink:
            self._items[self.selectedItem]['value_display']['text_fg'] = (0, 0,
                                                                          0, 1)
            self._items[self.selectedItem]['value_display']['text_bg'] = (1, 1,
                                                                          1, 1)
        else:
            self._items[self.selectedItem]['value_display']['text_fg'] = (1, 1,
                                                                          1, 1)
            self._items[self.selectedItem]['value_display']['text_bg'] = (0, 0,
                                                                          0, 0)
        return Task.again
コード例 #35
0
ファイル: QuestMap.py プロジェクト: CalebSmith376/src
class QuestMap(DirectFrame):

    def __init__(self, av, **kw):
        DirectFrame.__init__(self, relief=None, sortOrder=50)
        self.initialiseoptions(QuestMap)
        self.container = DirectFrame(parent=self, relief=None)
        self.marker = DirectFrame(parent=self.container, relief=None)
        self.cogInfoFrame = DirectFrame(parent=self.container, relief=None)
        cm = CardMaker('bg')
        cm.setFrame(-0.5, 0.5, -0.5, 0.5)
        bg = self.cogInfoFrame.attachNewNode(cm.generate())
        bg.setTransparency(1)
        bg.setColor(0.5, 0.5, 0.5, 0.5)
        bg.setBin('fixed', 0)
        self.cogInfoFrame['geom'] = bg
        self.cogInfoFrame['geom_pos'] = (0, 0, 0)
        self.cogInfoFrame['geom_scale'] = (6, 1, 2)
        self.cogInfoFrame.setScale(0.05)
        self.cogInfoFrame.setPos(0, 0, 0.6)
        self.buildingMarkers = []
        self.av = av
        self.wantToggle = False
        if base.config.GetBool('want-toggle-quest-map', True):
            self.wantToggle = True
        self.updateMarker = True
        self.cornerPosInfo = None
        self.hqPosInfo = None
        self.fishingSpotInfo = None
        self.load()
        self.setScale(1.5)
        bg.removeNode()
        self.hoodId = None
        self.zoneId = None
        self.suitPercentage = {}
        for currHoodInfo in SuitPlannerBase.SuitPlannerBase.SuitHoodInfo:
            tracks = currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
            self.suitPercentage[currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks

        return

    def load(self):
        gui = loader.loadModel('phase_4/models/questmap/questmap_gui')
        icon = gui.find('**/tt_t_gui_qst_arrow')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setR(90)
        self.marker['geom'] = iconNP
        self.marker['image'] = iconNP
        self.marker.setScale(0.05)
        iconNP.removeNode()
        self.mapOpenButton = DirectButton(image=(gui.find('**/tt_t_gui_qst_mapClose'), gui.find('**/tt_t_gui_qst_mapClose'), gui.find('**/tt_t_gui_qst_mapTryToOpen')), relief=None, pos=(-0.08, 0, 0.37), parent=base.a2dBottomRight, scale=0.205, command=self.show)
        self.mapCloseButton = DirectButton(image=(gui.find('**/tt_t_gui_qst_mapOpen'), gui.find('**/tt_t_gui_qst_mapOpen'), gui.find('**/tt_t_gui_qst_mapTryToClose')), relief=None, pos=(-0.08, 0, 0.37), parent=base.a2dBottomRight, scale=0.205, command=self.hide)
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()
        gui.removeNode()
        icons = loader.loadModel('phase_3/models/gui/cog_icons')
        cIcon = icons.find('**/CorpIcon')
        lIcon = icons.find('**/LegalIcon')
        mIcon = icons.find('**/MoneyIcon')
        sIcon = icons.find('**/SalesIcon')
        cogInfoTextColor = (0.2, 0.2, 0.2, 1)
        textPos = (1.2, -0.2)
        textScale = 0.8
        self.cInfo = DirectLabel(parent=self.cogInfoFrame, text='', text_fg=cogInfoTextColor, text_pos=textPos, text_scale=textScale, geom=cIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.cInfo.setPos(-2.2, 0, 0.5)
        self.lInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=lIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.lInfo.setPos(-2.2, 0, -0.5)
        self.mInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=mIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.mInfo.setPos(0.8, 0, 0.5)
        self.sInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=sIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.sInfo.setPos(0.8, 0, -0.5)
        icons.removeNode()
        return

    def updateCogInfo(self):
        currPercentage = self.suitPercentage.get(self.zoneId)
        if currPercentage is None:
            return
        self.cInfo['text'] = '%s%%' % currPercentage[0]
        self.lInfo['text'] = '%s%%' % currPercentage[1]
        self.mInfo['text'] = '%s%%' % currPercentage[2]
        self.sInfo['text'] = '%s%%' % currPercentage[3]
        return

    def destroy(self):
        self.ignore('questPageUpdated')
        self.mapOpenButton.destroy()
        self.mapCloseButton.destroy()
        del self.mapOpenButton
        del self.mapCloseButton
        DirectFrame.destroy(self)

    def putBuildingMarker(self, pos, hpr = (0, 0, 0), mapIndex = None):
        marker = DirectLabel(parent=self.container, text='', text_pos=(-0.05, -0.15), text_fg=(1, 1, 1, 1), relief=None)
        gui = loader.loadModel('phase_4/models/parties/schtickerbookHostingGUI')
        icon = gui.find('**/startPartyButton_inactive')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setX(-12.0792 / 30.48)
        icon.setZ(-9.7404 / 30.48)
        marker['text'] = '%s' % mapIndex
        marker['text_scale'] = 0.7
        marker['image'] = iconNP
        marker['image_color'] = (1, 0, 0, 1)
        marker['image_scale'] = 6
        marker.setScale(0.05)
        relX, relY = self.transformAvPos(pos)
        marker.setPos(relX, 0, relY)
        self.buildingMarkers.append(marker)
        iconNP.removeNode()
        gui.removeNode()
        return

    def updateQuestInfo(self):
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []

        for (i, questDesc) in enumerate(self.av.quests):
            mapIndex = i + 1
            quest = Quests.getQuest(questDesc[0])
            toNpcId = questDesc[2]

            completed = quest.getCompletionStatus(self.av, questDesc) == Quests.COMPLETE
            if not completed:
                if quest.getType() == Quests.RecoverItemQuest:
                    if quest.getHolder() == Quests.AnyFish:
                        self.putBuildingMarker(self.fishingSpotInfo, mapIndex=mapIndex)
                    continue
                elif quest.getType() not in (
                    Quests.DeliverGagQuest, Quests.DeliverItemQuest,
                    Quests.VisitQuest, Quests.TrackChoiceQuest):
                    continue

            if toNpcId == Quests.ToonHQ:
                self.putBuildingMarker(self.hqPosInfo, mapIndex=mapIndex)
                continue

            npcZoneId = NPCToons.getNPCZone(toNpcId)
            hoodId = ZoneUtil.getCanonicalHoodId(npcZoneId)
            branchId = ZoneUtil.getCanonicalBranchZone(npcZoneId)

            if (self.hoodId != hoodId) or (self.zoneId != branchId):
                continue

            for blockIndex in xrange(base.cr.playGame.dnaStore.getNumBlockNumbers()):
                blockNumber = base.cr.playGame.dnaStore.getBlockNumberAt(blockIndex)
                zoneId = base.cr.playGame.dnaStore.getZoneFromBlockNumber(blockNumber)
                interiorZoneId = (zoneId - (zoneId%100)) + 500 + blockNumber
                if npcZoneId == interiorZoneId:
                    self.putBuildingMarker(
                        base.cr.playGame.dnaStore.getDoorPosHprFromBlockNumber(blockNumber).getPos(render),
                        base.cr.playGame.dnaStore.getDoorPosHprFromBlockNumber(blockNumber).getHpr(render),
                        mapIndex=mapIndex)

    def transformAvPos(self, pos):
        if self.cornerPosInfo is None:
            return (0, 0)
        topRight = self.cornerPosInfo[0]
        bottomLeft = self.cornerPosInfo[1]
        relativeX = (pos.getX() - bottomLeft.getX()) / (topRight.getX() - bottomLeft.getX()) - 0.5
        relativeY = (pos.getY() - bottomLeft.getY()) / (topRight.getY() - bottomLeft.getY()) - 0.5
        return (relativeX, relativeY)

    def update(self, task):
        if self.av:
            if self.updateMarker:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
        i = 0
        for buildingMarker in self.buildingMarkers:
            buildingMarker.setScale((math.sin(task.time * 16.0 + i * math.pi / 3.0) + 1) * 0.005 + 0.04)
            i = i + 1

        return Task.cont

    def updateMap(self):
        if self.av:
            hoodId = ZoneUtil.getCanonicalHoodId(self.av.getLocation()[1])
            zoneId = ZoneUtil.getCanonicalBranchZone(self.av.getLocation()[1])
            try:
                mapsGeom = loader.loadModel('phase_4/models/questmap/%s_maps' % ToontownGlobals.dnaMap[hoodId])
            except:
                self.stop()
                return
            mapImage = mapsGeom.find('**/%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
            if not mapImage.isEmpty():
                self.container['image'] = mapImage
                self.resetFrameSize()
                self.cornerPosInfo = QuestMapGlobals.CornerPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.hqPosInfo = QuestMapGlobals.HQPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.fishingSpotInfo = QuestMapGlobals.FishingSpotPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.cogInfoPos = QuestMapGlobals.CogInfoPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.cogInfoFrame.setPos(self.cogInfoPos)
                self.hide()
                self.hoodId = hoodId
                self.zoneId = zoneId
                self.updateQuestInfo()
                self.updateCogInfo()
                taskMgr.add(self.update, 'questMapUpdate')
            else:
                self.stop()
                mapsGeom.removeNode()

    def start(self):
        self.container.show()
        self.accept('questPageUpdated', self.updateMap)
        self.handleMarker()
        self.updateMap()

    def initMarker(self, task):
        if self.av:
            if not hasattr(base.cr.playGame.getPlace(), 'isInterior') or not base.cr.playGame.getPlace().isInterior:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
            self.marker['geom_scale'] = 1.4 * task.time % 0.5 * 10 + 1
            self.marker['geom_color'] = (1,
             1,
             1,
             0.8 - 1.4 * task.time % 0.5 * 2 / 0.8 + 0.2)
        if task.time < 1:
            return Task.cont
        else:
            self.marker['geom_color'] = (1, 1, 1, 0)
            return Task.done

    def show(self):
        taskMgr.add(self.initMarker, 'questMapInit')
        DirectFrame.show(self)
        self.mapOpenButton.hide()
        if self.container['image']:
            self.mapCloseButton.show()

    def hide(self):
        taskMgr.remove('questMapInit')
        DirectFrame.hide(self)
        if self.container['image']:
            self.mapOpenButton.show()
        self.mapCloseButton.hide()

    def toggle(self):
        if self.isHidden():
            self.show()
        else:
            self.hide()

    def obscureButton(self):
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()

    def stop(self):
        self.container['image'] = None
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        self.container.hide()
        self.hide()
        self.obscureButton()
        self.ignore('questPageUpdated')
        taskMgr.remove('questMapUpdate')
        return

    def handleMarker(self):
        if hasattr(base.cr.playGame.getPlace(), 'isInterior') and base.cr.playGame.getPlace().isInterior:
            self.updateMarker = False
        else:
            self.updateMarker = True

    def acceptOnscreenHooks(self):
        if self.wantToggle:
            self.accept(ToontownGlobals.MapHotkey, self.toggle)
        else:
            self.accept(ToontownGlobals.MapHotkeyOn, self.show)
            self.accept(ToontownGlobals.MapHotkeyOff, self.hide)
        self.updateMap()

    def ignoreOnscreenHooks(self):
        self.ignore(ToontownGlobals.MapHotkey)
        self.ignore(ToontownGlobals.MapHotkeyOn)
        self.ignore(ToontownGlobals.MapHotkeyOff)
        self.obscureButton()
コード例 #36
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
コード例 #37
0
ファイル: directWindow.py プロジェクト: croxis/CityMania
class DirectWindow( DirectFrame ):
  def __init__( self,
                pos              = ( -.5, .5),
                title            = 'Title',
                curSize          = (1, 1),
                maxSize          = ( 1, 1 ),
                minSize          = ( .5, .5 ),
                backgroundColor = ( 0, 0, 1, .6),
                borderColor      = ( 1, 1, 1, 1 ),
                titleColor       = ( 1, 1, 1, 1 ),
                borderSize       = 0.04,
                titleSize        = 0.06,
                closeButton      = False,
                resizeButton    = True,
                windowParent     = aspect2d,
                preserve         = True,
                preserveWhole      = True, 
              ):
    self.preserve = preserve
    self.preserveWhole = preserveWhole
    self.windowParent = windowParent
    self.windowPos = pos
    DirectFrame.__init__( self,
        parent       = aspect2d,
        pos          = ( self.windowPos[0], 0, self.windowPos[1] ),
        frameColor  = ( 0, 0, 0, 0 ),
        frameTexture = loader.loadTexture( DIRECTORY+'transparent.png' )
      )
    self.setTransparency(True)
    
    # the title part of the window, drag around to move the window
    self.headerHeight = titleSize
    h = -self.headerHeight
    self.windowHeaderLeft = DirectButton(
        parent       = self,
        frameTexture = DEFAULT_TITLE_GEOM_LEFT,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
      )
    self.windowHeaderCenter = DirectButton(
        parent       = self,
        frameTexture = DEFAULT_TITLE_GEOM_CENTER,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
      )
    if closeButton:
      rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT_CLOSE
      command = self.destroy
    else:
      rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT
      command = None
    self.windowHeaderRight = DirectButton(
        parent       = self,
        frameTexture = rightTitleGeom,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
        command      = command
      )
    
    self.windowHeaderLeft.setTransparency(True)
    self.windowHeaderCenter.setTransparency(True)
    self.windowHeaderRight.setTransparency(True)
    
    self.windowHeaderLeft.bind( DGG.B1PRESS, self.startWindowDrag )
    self.windowHeaderCenter.bind( DGG.B1PRESS, self.startWindowDrag )
    self.windowHeaderRight.bind( DGG.B1PRESS, self.startWindowDrag )
    
    # this is not handled correctly, if a window is dragged which has been
    # created before another it will not be released
    # check the bugfixed startWindowDrag function
    #self.windowHeader.bind(DGG.B1RELEASE,self.stopWindowDrag)
    
    text = TextNode('WindowTitleTextNode')
    text.setText(title)
    text.setAlign(TextNode.ACenter)
    text.setTextColor( 0, 0, 0, 1 )
    text.setShadow(0.05, 0.05)
    text.setShadowColor( 1, 1, 1, 1 )
    self.textNodePath = self.attachNewNode(text)
    self.textNodePath.setScale(self.headerHeight*0.8)
    
    # the content part of the window, put stuff beneath
    # contentWindow.getCanvas() to put it into it
    self.maxVirtualSize = maxSize
    self.minVirtualSize = minSize
    self.resizeSize     = borderSize
    self.contentWindow = DirectScrolledFrame(
        parent                                  = self,
        pos                                     = ( 0, 0, -self.headerHeight ),
        canvasSize                              = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
        frameColor                              = ( 0, 0, 0, 0), # defines the background color of the resize-button
        relief                                  = DGG.FLAT,
        borderWidth                             = (0, 0),
        verticalScroll_frameSize                = [0, self.resizeSize, 0, 1],
        horizontalScroll_frameSize              = [0, 1, 0, self.resizeSize],
        
        # resize the scrollbar according to window size
        verticalScroll_resizeThumb              = False,
        horizontalScroll_resizeThumb            = False,
        # define the textures for the scrollbars
        verticalScroll_frameTexture             = VERTICALSCROLL_FRAMETEXTURE,
        verticalScroll_incButton_frameTexture   = VERTICALSCROLL_INCBUTTON_FRAMETEXTURE,
        verticalScroll_decButton_frameTexture   = VERTICALSCROLL_DECBUTTON_FRAMETEXTURE,
        verticalScroll_thumb_frameTexture       = VERTICALSCROLL_TUMB_FRAMETEXTURE,
        horizontalScroll_frameTexture           = HORIZONTALSCROLL_FRAMETEXTURE,
        horizontalScroll_incButton_frameTexture = HORIZONTALSCROLL_INCBUTTON_FRAMETEXTURE,
        horizontalScroll_decButton_frameTexture = HORIZONTALSCROLL_DECBUTTON_FRAMETEXTURE,
        horizontalScroll_thumb_frameTexture     = HORIZONTALSCROLL_TUMB_FRAMETEXTURE,
        # make all flat, so the texture is as we want it
        verticalScroll_relief                   = DGG.FLAT,
        verticalScroll_thumb_relief             = DGG.FLAT,
        verticalScroll_decButton_relief         = DGG.FLAT,
        verticalScroll_incButton_relief         = DGG.FLAT,
        horizontalScroll_relief                 = DGG.FLAT,
        horizontalScroll_thumb_relief           = DGG.FLAT,
        horizontalScroll_decButton_relief       = DGG.FLAT,
        horizontalScroll_incButton_relief       = DGG.FLAT,
        # colors
        verticalScroll_frameColor               = borderColor,
        verticalScroll_incButton_frameColor     = borderColor,
        verticalScroll_decButton_frameColor     = borderColor,
        verticalScroll_thumb_frameColor         = borderColor,
        horizontalScroll_frameColor             = borderColor,
        horizontalScroll_incButton_frameColor   = borderColor,
        horizontalScroll_decButton_frameColor   = borderColor,
        horizontalScroll_thumb_frameColor       = borderColor,
      )
    self.contentWindow.setTransparency(True)
    
    # background color
    self.backgroundColor = DirectFrame(
        parent       = self.contentWindow.getCanvas(),
        frameSize    = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
        frameColor   = backgroundColor,
        relief       = DGG.FLAT,
        borderWidth  = ( .01, .01),
      )
    self.backgroundColor.setTransparency(True)

    # Add a box
    self.box = boxes.VBox(parent = self.getCanvas())
   
    # is needed for some nicer visuals of the resize button (background)
    self.windowResizeBackground = DirectButton(
        parent       = self,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        scale        = ( self.resizeSize, 1, self.resizeSize ),
        relief       = DGG.FLAT,
        frameColor   = backgroundColor,
      )
    # the resize button of the window
    if resizeButton:
        self.windowResize = DirectButton(
            parent       = self,
            frameSize    = ( -.5, .5, -.5, .5 ),
            borderWidth  = ( 0, 0 ),
            scale        = ( self.resizeSize, 1, self.resizeSize ),
            relief       = DGG.FLAT,
            frameTexture = DEFAULT_RESIZE_GEOM,
            frameColor   = borderColor,
          )
        self.windowResize.setTransparency(True)
        self.windowResize.bind(DGG.B1PRESS,self.startResizeDrag)
        self.windowResize.bind(DGG.B1RELEASE,self.stopResizeDrag)
    else:
        self.windowResize = DirectFrame()
    
    # offset then clicking on the resize button from the mouse to the resizebutton
    # position, required to calculate the position / scaling
    self.offset = None
    self.taskName = "resizeTask-%s" % str(hash(self))
    
    # do sizing of the window (minimum)
    #self.resize( Vec3(0,0,0), Vec3(0,0,0) )
    # maximum
    #self.resize( Vec3(100,0,-100), Vec3(0,0,0) )
    self.resize( Vec3(curSize[0], 0, -curSize[1]), Vec3(0,0,0))
    self.widgets = []
  
  def getCanvas(self):
    return self.contentWindow.getCanvas()
  
  # dragging functions
  def startWindowDrag( self, param ):
    self.wrtReparentTo( aspect2dMouseNode )
    self.ignoreAll()
    self.accept( 'mouse1-up', self.stopWindowDrag )
  def stopWindowDrag( self, param=None ):
    # this is called 2 times (bug), so make sure it's not already parented to aspect2d
    if self.getParent() != self.windowParent:
      self.wrtReparentTo( self.windowParent )
    if self.preserve:
        if self.preserveWhole:
            if self.getZ() > 1:
                self.setZ(1)
            elif self.getZ() < -1 - self.getHeight():
                self.setZ(-1 - self.getHeight())
            if self.getX() > base.a2dRight - self.getWidth():
                self.setX(base.a2dRight - self.getWidth())
            elif self.getX() < base.a2dLeft:
                self.setX(base.a2dLeft)
        else:
            if self.getZ() > 1:
                self.setZ(1)
            elif self.getZ() < -1 + self.headerHeight:
                self.setZ(-1 + self.headerHeight)
            if self.getX() > base.a2dRight - self.headerHeight:
                self.setX(base.a2dRight - self.headerHeight)
            elif self.getX() < base.a2dLeft + self.headerHeight - self.getWidth():
                self.setX(base.a2dLeft + self.headerHeight - self.getWidth())
    #else: #Window moved beyond reach. Destroy window?
  # resize functions
  def resize( self, mPos, offset ):
    mXPos = max( min( mPos.getX(), self.maxVirtualSize[0] ), self.minVirtualSize[0])
    mZPos = max( min( mPos.getZ(), -self.minVirtualSize[1] ), -self.maxVirtualSize[1]-self.headerHeight)
    self.windowResize.setPos( mXPos-self.resizeSize/2., 0, mZPos+self.resizeSize/2. )
    self.windowResizeBackground.setPos( mXPos-self.resizeSize/2., 0, mZPos+self.resizeSize/2. )
    self['frameSize'] = (0, mXPos, 0, mZPos)
    self.windowHeaderLeft.setPos( self.headerHeight/2., 0, -self.headerHeight/2. )
    self.windowHeaderLeft.setScale( self.headerHeight, 1, self.headerHeight )
    self.windowHeaderCenter.setPos( mXPos/2., 0, -self.headerHeight/2. )
    self.windowHeaderCenter.setScale( mXPos - self.headerHeight*2., 1, self.headerHeight )
    self.windowHeaderRight.setPos( mXPos-self.headerHeight/2., 0, -self.headerHeight/2. )
    self.windowHeaderRight.setScale( self.headerHeight, 1, self.headerHeight )
    self.contentWindow['frameSize'] = ( 0, mXPos, mZPos+self.headerHeight, 0)
    self.textNodePath.setPos( mXPos/2., 0, -self.headerHeight/3.*2. )
    # show and hide that small background for the window sizer
    if mXPos == self.maxVirtualSize[0] and \
       mZPos == -self.maxVirtualSize[1]-self.headerHeight:
      self.windowResizeBackground.hide()
    else:
      self.windowResizeBackground.show()
  
  def resizeTask( self, task=None ):
    mPos = aspect2dMouseNode.getPos( self )+self.offset
    self.resize( mPos, self.offset )
    return task.cont
  def startResizeDrag( self, param ):
    self.offset  = self.windowResize.getPos( aspect2dMouseNode )
    taskMgr.remove( self.taskName )
    taskMgr.add( self.resizeTask, self.taskName )
  def stopResizeDrag( self, param ):
    taskMgr.remove( self.taskName )
    # get the window to the front
    self.wrtReparentTo( self.windowParent )
  def addHorizontal(self, widgets):
      """
      Accepts a list of directgui objects which are added to a horizontal box, which is then added to the vertical stack.
      """
      hbox = boxes.HBox()
      for widget in widgets:
          widget.setScale(0.05)
          hbox.pack(widget)
          self.widgets.append(widget)
      self.box.pack(hbox)
      self.updateMaxSize()
  
  def addVertical(self, widgets):
      """
      Accepts a list of directgui objects which are added to a vertical box, which is then added to the vertical stack.
      May cause funky layout results.
      """
      for widget in widgets:
          widget.setScale(0.05)
          self.box.pack(widget)
          self.widgets.append(widget)
      self.updateMaxSize()
  
  def add(self, widgets):
      """Shortcut function for addVertical"""
      self.addVertical(widgets)
  
  def updateMaxSize(self):
      """Updates the max canvas size to include all items packed.
      Window is resized to show all contents."""
      bottomLeft, topRight = self.box.getTightBounds()
      self.maxVirtualSize = (topRight[0], -bottomLeft[2])
      if self.minVirtualSize[0] > self.maxVirtualSize[0]:
          self.minVirtualSize = (self.maxVirtualSize[0], self.minVirtualSize[1])
      if self.minVirtualSize[1] > self.maxVirtualSize[1]:
          self.minVirtualSize = (self.minVirtualSize[0], self.maxVirtualSize[1]+self.headerHeight)
      self.contentWindow['canvasSize'] = ( 0, self.maxVirtualSize[0], -self.maxVirtualSize[1],  0)
      self.backgroundColor['frameSize'] = ( 0, self.maxVirtualSize[0], -self.maxVirtualSize[1], 0 )
      # For CityMania Onlue
      self.reset()
      self.center()
  
  def reset(self):
    """Poorly named function that resizes window to fit all contents"""
    self.resize( Vec3(self.maxVirtualSize[0], 0, -self.maxVirtualSize[1]-self.headerHeight), Vec3(0,0,0))

  def center(self):
      """Centers window on screen"""
      self.setPos(-self.maxVirtualSize[0]/2.0, 0, (self.maxVirtualSize[1]+self.headerHeight)/2.0)
  
  def getEntries(self):
        """Returns the fields for any entires"""
        entries = []
        for widget in self.widgets:
            if isinstance(widget, DirectEntry):
                entries.append(widget.get())
        return entries

  def addScrolledList(self, items, numItemsVisible = 4, itemHeight = 1):
        '''Adds a list of items into a scrolled list'''
        scrolled_list = DirectScrolledList(
            decButton_pos= (0.35, 0, 5),
            decButton_text = "Up",
            decButton_borderWidth = (0.005, 0.005),
            
            incButton_pos= (0.35, 0, -5),
            incButton_text = "Down",
            incButton_borderWidth = (0.005, 0.005),
            
            frameSize = (-5, 5, -5, 5),
            frameColor = (1,0,1,0.5),
            pos = (-1, 0, 0),
            items = items,
            numItemsVisible = numItemsVisible,
            forceHeight = itemHeight,
            itemFrame_frameSize = (-5, 5, -5, 5),
            itemFrame_pos = (0.35, 0, 0.4),
            scale = (0.05),
            #parent = (aspect2d),
            )
        scrolled_list.updateFrameStyle()
        self.add([scrolled_list])
コード例 #38
0
def add_button(self, text, label_id, pos_x, pos_y, width=0.0, hight=0.1):
    if width == 0.0:
        for c in range(len(text) / 2):
            width += 0.08
    ls = LineSegs("lines")
    ls.setColor(0, 1, 0, 1)
    ls.drawTo(-width / 2, 0, hight / 2)
    ls.drawTo(width / 2, 0, hight / 2)
    ls.drawTo(width / 2, 0, -hight / 2)
    ls.drawTo(-width / 2, 0, -hight / 2)
    ls.drawTo(-width / 2, 0, hight / 2)
    border = ls.create(False)
    border.setTag('back_ground', '1')

    array = GeomVertexArrayFormat()
    array.addColumn("vertex", 4, Geom.NTFloat32, Geom.CPoint)
    arr_format = GeomVertexFormat()
    arr_format.addArray(array)
    arr_format = GeomVertexFormat.registerFormat(arr_format)

    vdata = GeomVertexData('fill', arr_format, Geom.UHStatic)
    vdata.setNumRows(4)
    vertex = GeomVertexWriter(vdata, 'vertex')

    vertex.addData3f(-width / 2, 0, hight / 2)
    vertex.addData3f(width / 2, 0, hight / 2)
    vertex.addData3f(-width / 2, 0, -hight / 2)
    vertex.addData3f(width / 2, 0, -hight / 2)

    prim = GeomTristrips(Geom.UHStatic)
    prim.addVertex(0)
    prim.addVertex(1)
    prim.addVertex(2)
    prim.addVertex(3)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('gnode')
    node.addGeom(geom)
    nodePath = NodePath("button")
    nodePath.attachNewNode(node)
    nodePath.setPos(0, 0, 0)
    nodePath.setTag('button', '1')
    nodePath.setBin("unsorted", 0)
    nodePath.setDepthTest(False)
    nodePath.setColor(0, 0, 0, 1)
    nodePath.attachNewNode(border)

    nodePath1 = NodePath("button")
    nodePath1.attachNewNode(node)
    nodePath1.setPos(0, 0, 0)
    nodePath1.setTag('button1', '1')
    nodePath1.setBin("unsorted", 0)
    nodePath1.setDepthTest(False)
    nodePath1.setColor(0, 1, 0, 1)
    nodePath1.attachNewNode(border)

    button = DirectFrame(enableEdit=1,
                         text=text,
                         geom=nodePath,
                         text_scale=0.05,
                         text_fg=(0, 1, 0, 1),
                         borderWidth=(1, 1),
                         relief=None,
                         text_pos=(0, -0.01, 0),
                         textMayChange=1,
                         state=DGG.NORMAL,
                         parent=aspect2d)
    button.setPos(pos_x, 0, pos_y)
    button.bind(DGG.B1PRESS, button_click, [button])
    button.bind(DGG.WITHIN, button_hover, [button])
    button.bind(DGG.WITHOUT, button_no_hover, [button])
    # button.resetFrameSize()
    # self.button.bind(DGG.WITHIN, self.onMouseHoverInFunction, [button, some_value1])

    defines.ENTITIES[defines.ENTITY_ID] = {
        'CATEGORY': 'button',
        'BUTTON': button,
        'NODE': nodePath,
        'LABEL': label_id,
        'STATUS': 0
    }
    defines.ENTITY_ID += 1
コード例 #39
0
ファイル: WorldMap.py プロジェクト: tiideinmaar/POTCO-PS
 def setPos(self, *args, **kwargs):
     DirectFrame.setPos(self, *args, **args)
     self.resetArcBall()
コード例 #40
0
ファイル: ui.py プロジェクト: 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
コード例 #41
0
class CharGen():
    def __init__(self):
        self.text = "CharGen"
        self.textObject = OnscreenText(text=self.text,
                                       pos=(0.95, -0.95),
                                       scale=0.07,
                                       fg=(1, 0.5, 0.5, 1),
                                       align=TextNode.ACenter,
                                       mayChange=1)

        self.f = DirectFrame(frameColor=(1, 1, 1, 0.5),
                             frameSize=(-1, 1, -0.4, 0.4))
        self.f.setPos(-0.5, 0, -0.5)

        self.flavorText = OnscreenText("Primary Colour",
                                       pos=(0, 0, 0.4),
                                       scale=0.07,
                                       align=TextNode.ACenter,
                                       mayChange=1,
                                       fg=(1, 1, 1, 1))
        self.flavorText.reparent_to(self.f)
        self.flavorText.setPos(0, 0.2)
        #slider R
        self.sR = DirectSlider(self.f,
                               range=(0, 1),
                               value=0,
                               pageSize=3,
                               command=self.setCol)
        self.sR.setScale(0.5, 0.5, 0.5)
        self.sR.setPos(0, 0, 0)
        self.sR.setColor(1, 0, 0)

        #slider G
        self.sG = DirectSlider(self.f,
                               range=(0, 1),
                               value=0,
                               pageSize=3,
                               command=self.setCol)
        self.sG.setScale(0.5, 0.5, 0.5)
        self.sG.setPos(0, 0, -0.1)
        self.sG.setColor(0, 1, 0)

        #slider B
        self.sB = DirectSlider(self.f,
                               range=(0, 1),
                               value=0,
                               pageSize=3,
                               command=self.setCol)
        self.sB.setScale(0.5, 0.5, 0.5)
        self.sB.setPos(0, 0, -0.2)
        self.sB.setColor(0, 0, 1)

        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.setPos(0.8, 12, -0.5)
        self.pandaActor.reparentTo(base.render)

    def setCol(self):
        #print(self.s['value'])
        self.pandaActor.setColor(self.sR['value'], self.sG['value'],
                                 self.sB['value'])
コード例 #42
0
def add_button(self, text, label_id, pos_x, pos_y, width=0.0, hight=0.1):
    if width == 0.0:
        for c in range(len(text)/2):
            width += 0.08
    ls = LineSegs("lines")
    ls.setColor(0,1,0,1)
    ls.drawTo(-width/2, 0, hight/2)
    ls.drawTo(width/2, 0, hight/2)
    ls.drawTo(width/2, 0,-hight/2)
    ls.drawTo(-width/2, 0,-hight/2)
    ls.drawTo(-width/2, 0, hight/2)
    border = ls.create(False)
    border.setTag('back_ground', '1')
    
    array = GeomVertexArrayFormat()
    array.addColumn("vertex", 4, Geom.NTFloat32, Geom.CPoint)
    arr_format = GeomVertexFormat()
    arr_format.addArray(array)
    arr_format = GeomVertexFormat.registerFormat(arr_format)

    vdata = GeomVertexData('fill', arr_format, Geom.UHStatic)
    vdata.setNumRows(4)
    vertex = GeomVertexWriter(vdata, 'vertex')

    vertex.addData3f(-width/2, 0, hight/2)
    vertex.addData3f(width/2, 0, hight/2)
    vertex.addData3f(-width/2, 0,-hight/2)
    vertex.addData3f(width/2, 0,-hight/2)

    prim = GeomTristrips(Geom.UHStatic)
    prim.addVertex(0)
    prim.addVertex(1)
    prim.addVertex(2)
    prim.addVertex(3)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('gnode')
    node.addGeom(geom)
    nodePath = NodePath("button")
    nodePath.attachNewNode(node)
    nodePath.setPos(0,0,0)
    nodePath.setTag('button', '1')
    nodePath.setBin("unsorted", 0)
    nodePath.setDepthTest(False)
    nodePath.setColor(0,0,0,1)
    nodePath.attachNewNode(border)

    nodePath1 = NodePath("button")
    nodePath1.attachNewNode(node)
    nodePath1.setPos(0,0,0)
    nodePath1.setTag('button1', '1')
    nodePath1.setBin("unsorted", 0)
    nodePath1.setDepthTest(False)
    nodePath1.setColor(0,1,0,1)
    nodePath1.attachNewNode(border)


    button=DirectFrame( 
                        enableEdit=1,                      
                        text=text,
                        geom=nodePath,
                        text_scale=0.05,
                        text_fg=(0,1,0,1),
                        borderWidth=(1,1), 
                        relief = None,
                        text_pos=(0,-0.01,0),
                        textMayChange=1,
                        state=DGG.NORMAL,
                        parent=aspect2d
                        )
    button.setPos(pos_x,0,pos_y)
    button.bind(DGG.B1PRESS, button_click, [button])
    button.bind(DGG.WITHIN, button_hover, [button])
    button.bind(DGG.WITHOUT, button_no_hover, [button])
    # button.resetFrameSize()
    # self.button.bind(DGG.WITHIN, self.onMouseHoverInFunction, [button, some_value1])

    defines.ENTITIES[defines.ENTITY_ID] = {'CATEGORY':'button', 'BUTTON':button, 'NODE':nodePath, 'LABEL':label_id,'STATUS': 0}
    defines.ENTITY_ID += 1