Esempio n. 1
0
class GUI:
    def __init__(self, rootParent=None):

        self.pg202 = DirectFrame(
            frameColor=(1.0, 1.0, 1.0, 0.0),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            image='chapter3/overlay.png',
            sortOrder=200,
            pos=LPoint3f(0, 0, 0),
            image_scale=LVecBase3f(0.8, 1, 0.8),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.pg202.setTransparency(1)


    def show(self):
        self.pg202.show()

    def hide(self):
        self.pg202.hide()

    def destroy(self):
        self.pg202.destroy()
Esempio n. 2
0
class TrickOrTreatTargetEffect(ScavengerHuntEffect):
    __module__ = __name__

    def __init__(self, beanAmount):
        ScavengerHuntEffect.__init__(self, beanAmount)
        if beanAmount > 0:
            self.pumpkin = DirectFrame(
                parent=self.eventImage,
                relief=None,
                image=ScavengerHuntEffect.images.find('**/tot_pumpkin_tall'))
        return

    def attemptFailedMsg(self):
        pLabel = DirectLabel(parent=self.npRoot,
                             relief=None,
                             pos=(0.0, 0.0, -0.15),
                             text=TTLocalizer.TrickOrTreatMsg,
                             text_fg=(0.95, 0.5, 0.0, 1.0),
                             text_scale=0.12,
                             text_font=ToontownGlobals.getSignFont())
        return

    def destroy(self):
        if hasattr(self, 'pumpkin') and self.pumpkin:
            self.pumpkin.destroy()
        ScavengerHuntEffect.destroy(self)
Esempio n. 3
0
class ScavengerHuntEffect:
    images = None

    def __init__(self, beanAmount):
        if not ScavengerHuntEffect.images:
            ScavengerHuntEffect.images = loader.loadModel('phase_4/models/props/tot_jar')
        self.npRoot = DirectFrame(parent=aspect2d, relief=None, scale=0.75, pos=(0, 0, 0.6))
        if beanAmount > 0:
            self.npRoot.setColorScale(VBase4(1, 1, 1, 0))
            self.jar = DirectFrame(parent=self.npRoot, relief=None, image=ScavengerHuntEffect.images.find('**/tot_jar'))
            self.jar.hide()
            self.eventImage = NodePath('EventImage')
            self.eventImage.reparentTo(self.npRoot)
            self.countLabel = DirectLabel(parent=self.jar, relief=None, text='+0', text_pos=(0.02, -0.2), text_scale=0.25, text_fg=(0.95, 0.0, 0, 1), text_font=ToontownGlobals.getSignFont())

            def countUp(t, startVal, endVal):
                beanCountStr = startVal + t * (endVal - startVal)
                self.countLabel['text'] = '+' + `(int(beanCountStr))`

            def setCountColor(color):
                self.countLabel['text_fg'] = color

            self.track = Sequence(LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Wait(1), Func(self.jar.show), LerpColorScaleInterval(self.eventImage, 1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Parallel(LerpScaleInterval(self.npRoot, 1, scale=0.5, startScale=0.75), LerpPosInterval(self.npRoot, 1, pos=VBase3(-0.9, 0, -0.83))), LerpFunc(countUp, duration=2, extraArgs=[0, beanAmount]), Func(setCountColor, VBase4(0.95, 0.95, 0, 1)), Wait(3), Func(self.destroy))
        else:
            self.npRoot.setColorScale(VBase4(1, 1, 1, 0))
            self.attemptFailedMsg()
            self.track = Sequence(LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Wait(5), LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.destroy))

    def play(self):
        if self.npRoot:
            self.track.start()

    def stop(self):
        if self.track != None:
            if self.track.isPlaying():
                self.track.finish()

    def cleanupIntervals(self, interval):
        while len(interval) > 0:
            if isinstance(interval[0], Sequence) or isinstance(interval[0], Parallel):
                self.cleanupIntervals(interval[0])
                interval.pop(0)
            else:
                interval.pop(0)

    def destroy(self):
        self.stop()
        self.track = None
        if hasattr(self, 'eventImage') and self.eventImage:
            self.eventImage.detachNode()
            del self.eventImage
        if hasattr(self, 'countLabel') and self.countLabel:
            self.countLabel.destroy()
            del self.countLabel
        if hasattr(self, 'jar') and self.jar:
            self.jar.destroy()
            del self.jar
        if hasattr(self, 'npRoot') and self.npRoot:
            self.npRoot.destroy()
            del self.npRoot
Esempio n. 4
0
class GUI:
    def __init__(self, rootParent=None):

        self.frmMain = DirectFrame(
            frameColor=(0.0, 0.0, 0.0, 0.5),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmMain.setTransparency(0)

        self.lblVictory = DirectLabel(
            frameColor=(0.0, 0.0, 0.0, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            scale=LVecBase3f(0.2, 0.2, 0.2),
            text='Won Fight',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmMain,
        )
        self.lblVictory.setTransparency(0)

    def show(self):
        self.frmMain.show()

    def hide(self):
        self.frmMain.hide()

    def destroy(self):
        self.frmMain.destroy()
Esempio n. 5
0
class WinterCarolingEffect(ScavengerHuntEffect):
    def __init__(self, beanAmount):
        ScavengerHuntEffect.__init__(self, beanAmount)

        if beanAmount > 0:
            sm = loader.loadModel(
                "phase_5.5/models/estate/tt_m_prp_ext_snowman_icon")
            self.snowman = DirectFrame(parent=self.eventImage,
                                       relief=None,
                                       image=sm,
                                       scale=20.0)

    def attemptFailedMsg(self):
        pLabel = DirectLabel(
            parent=self.npRoot,
            relief=None,
            pos=(0.0, 0.0, 0.25),
            text=TTLocalizer.WinterCarolingMsg,
            text_fg=(0.9, 0.9, 1.0, 1.0),
            text_scale=0.12,
            text_font=ToontownGlobals.getSignFont(),
        )

    def destroy(self):
        if hasattr(self, "snowman") and self.snowman:
            self.snowman.destroy()
        ScavengerHuntEffect.destroy(self)
 def cleanup(self):
     self.ignoreAll()
     self.clear()
     self.lines = None
     self.ivalDict = None
     self.alertSfx = None
     self.queuedLines = None
     DirectFrame.destroy(self)
Esempio n. 7
0
class Save:
    def __init__(self, nodes, connections, exceptionSave=False):
        self.dlgOverwrite = None
        self.dlgOverwriteShadow = None
        self.jsonElements = JSONTools().get(nodes, connections)

        if exceptionSave:
            tmpPath = os.path.join(tempfile.gettempdir(),
                                   "NEExceptionSave.json")
            self.__executeSave(True, tmpPath)
            logging.info("Wrote crash session file to {}".format(tmpPath))
        else:
            self.browser = DirectFolderBrowser(self.save,
                                               True,
                                               defaultFilename="project.json")

    def save(self, doSave):
        if doSave:
            path = self.browser.get()
            path = os.path.expanduser(path)
            path = os.path.expandvars(path)
            if os.path.exists(path):
                self.dlgOverwrite = YesNoDialog(
                    text="File already Exist.\nOverwrite?",
                    relief=DGG.RIDGE,
                    frameColor=(1, 1, 1, 1),
                    frameSize=(-0.5, 0.5, -0.3, 0.2),
                    sortOrder=1,
                    button_relief=DGG.FLAT,
                    button_frameColor=(0.8, 0.8, 0.8, 1),
                    command=self.__executeSave,
                    extraArgs=[path],
                    scale=300,
                    pos=(base.getSize()[0] / 2, 0, -base.getSize()[1] / 2),
                    parent=base.pixel2d)
                self.dlgOverwriteShadow = DirectFrame(
                    pos=(base.getSize()[0] / 2 + 10, 0,
                         -base.getSize()[1] / 2 - 10),
                    sortOrder=0,
                    frameColor=(0, 0, 0, 0.5),
                    frameSize=self.dlgOverwrite.bounds,
                    scale=300,
                    parent=base.pixel2d)
                self.dlgOverwrite.setBin("gui-popup", 1)
            else:
                self.__executeSave(True, path)
            base.messenger.send("setLastPath", [path])
        self.browser.destroy()
        del self.browser

    def __executeSave(self, overwrite, path):
        if self.dlgOverwrite is not None: self.dlgOverwrite.destroy()
        if self.dlgOverwriteShadow is not None:
            self.dlgOverwriteShadow.destroy()
        if not overwrite: return

        with open(path, 'w') as outfile:
            json.dump(self.jsonElements, outfile, indent=2)
class ScavengerHuntEffect:
    images = None

    def __init__(self, beanAmount):
        if not ScavengerHuntEffect.images:
            ScavengerHuntEffect.images = loader.loadModel('phase_4/models/props/tot_jar')

        self.npRoot = DirectFrame(parent=aspect2d, relief=None, scale=0.75, pos=(0, 0, 0.6))

        if beanAmount > 0:
            self.npRoot.setColorScale(VBase4(1, 1, 1, 0))
            self.jar = DirectFrame(parent=self.npRoot, relief=None, image=ScavengerHuntEffect.images.find('**/tot_jar'))
            self.jar.hide()
            self.eventImage = NodePath('EventImage')
            self.eventImage.reparentTo(self.npRoot)
            self.countLabel = DirectLabel(parent=self.jar, relief=None, text='+0', text_pos=(0.02, -0.2), text_scale=0.25, text_fg=(0.95, 0.0, 0, 1), text_font=ToontownGlobals.getSignFont())

            def countUp(t, startVal, endVal):
                beanCountStr = startVal + t * (endVal - startVal)
                self.countLabel['text'] = '+' + `(int(beanCountStr))`

            def setCountColor(color):
                self.countLabel['text_fg'] = color

            self.track = Sequence(LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Wait(1), Func(self.jar.show), LerpColorScaleInterval(self.eventImage, 1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Parallel(LerpScaleInterval(self.npRoot, 1, scale=0.5, startScale=0.75), LerpPosInterval(self.npRoot, 1, pos=VBase3(-0.9, 0, -0.83))), LerpFunc(countUp, duration=2, extraArgs=[0, beanAmount]), Func(setCountColor, VBase4(0.95, 0.95, 0, 1)), Wait(3), Func(self.destroy))
        else:
            self.npRoot.setColorScale(VBase4(1, 1, 1, 0))
            self.attemptFailedMsg()
            self.track = Sequence(LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Wait(5), LerpColorScaleInterval(self.npRoot, 1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.destroy))

    def play(self):
        if self.npRoot:
            self.track.start()

    def stop(self):
        if self.track != None and self.track.isPlaying():
            self.track.finish()

    def destroy(self):
        self.stop()
        self.track = None

        if hasattr(self, 'eventImage') and self.eventImage:
            self.eventImage.detachNode()
            del self.eventImage
        if hasattr(self, 'countLabel') and self.countLabel:
            self.countLabel.destroy()
            del self.countLabel
        if hasattr(self, 'jar') and self.jar:
            self.jar.destroy()
            del self.jar
        if hasattr(self, 'npRoot') and self.npRoot:
            self.npRoot.destroy()
            del self.npRoot
Esempio n. 9
0
class GUI:
    def __init__(self, rootParent=None):

        self.frmMain = DirectFrame(
            frameColor=(0.0, 0.0, 0.0, 0.75),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmMain.setTransparency(1)

        self.btnQuit = DirectButton(
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, -0.75),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Quit',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmMain,
            command=base.messenger.send,
            extraArgs=["quitRoom"],
            pressEffect=1,
        )
        self.btnQuit.setTransparency(0)

        self.lblMessage = DirectLabel(
            frameColor=(0.0, 0.0, 0.0, 0.0),
            frameSize=(-2.981, 3.106, -0.325, 0.725),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            scale=LVecBase3f(0.2, 0.2, 0.2),
            text='Player A Won',
            text_align=TextNode.A_center,
            text_scale=(1.0, 1.0),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmMain,
        )
        self.lblMessage.setTransparency(0)

    def show(self):
        self.frmMain.show()

    def hide(self):
        self.frmMain.hide()

    def destroy(self):
        self.frmMain.destroy()
Esempio n. 10
0
class PauseGui(Gui):
    def __init__(self, mdt):
        Gui.__init__(self, mdt)
        self.pause_frame = None

    def toggle(self, show_frm=True):
        if not self.mdt.logic.is_paused:
            if show_frm:
                self.pause_frame = DirectFrame(frameColor=(.3, .3, .3, .7),
                                               frameSize=(-1.8, 1.8, -1, 1))
        else:
            if self.pause_frame:
                self.pause_frame.destroy()
class TrickOrTreatTargetEffect(ScavengerHuntEffect):

    def __init__(self, beanAmount):
        ScavengerHuntEffect.__init__(self, beanAmount)
        if beanAmount > 0:
            self.pumpkin = DirectFrame(parent=self.eventImage, relief=None, image=ScavengerHuntEffect.images.find('**/tot_pumpkin_tall'))

    def attemptFailedMsg(self):
        pLabel = DirectLabel(parent=self.npRoot, relief=None, pos=(0.0, 0.0, -0.15), text=TTLocalizer.TrickOrTreatMsg, text_fg=(0.95, 0.5, 0.0, 1.0), text_scale=0.12, text_font=ToontownGlobals.getSignFont())

    def destroy(self):
        if hasattr(self, 'pumpkin') and self.pumpkin:
            self.pumpkin.destroy()
        ScavengerHuntEffect.destroy(self)
class WinterCarolingEffect(ScavengerHuntEffect):

    def __init__(self, beanAmount):
        ScavengerHuntEffect.__init__(self, beanAmount)
        if beanAmount > 0:
            sm = loader.loadModel('phase_5.5/models/estate/tt_m_prp_ext_snowman_icon')
            self.snowman = DirectFrame(parent=self.eventImage, relief=None, image=sm, scale=20.0)

    def attemptFailedMsg(self):
        pLabel = DirectLabel(parent=self.npRoot, relief=None, pos=(0.0, 0.0, -0.15), text=TTLocalizer.WinterCarolingMsg, text_fg=(0.9, 0.9, 1.0, 1.0), text_scale=0.12, text_font=ToontownGlobals.getSignFont())

    def destroy(self):
        if hasattr(self, 'snowman') and self.snowman:
            self.snowman.destroy()
        ScavengerHuntEffect.destroy(self)
Esempio n. 13
0
class TrickOrTreatTargetEffect(ScavengerHuntEffect):
    def __init__(self, beanAmount):
        ScavengerHuntEffect.__init__(self, beanAmount)

        if beanAmount > 0:
            self.pumpkin = DirectFrame(
                parent=self.eventImage,
                relief=None,
                image=ScavengerHuntEffect.images.find('**/tot_pumpkin_tall'),
            )

    def destroy(self):
        if hasattr(self, "pumpkin") and self.pumpkin:
            self.pumpkin.destroy()
        ScavengerHuntEffect.destroy(self)
Esempio n. 14
0
class ChapterBase(DirectObject):
    def __init__(self, backgroundImage, rootParent):
        self.background = DirectFrame(image=backgroundImage,
                                      image_scale=.8,
                                      frameColor=(0, 0, 0, 0),
                                      frameSize=(-.8, .8, -.8, .8),
                                      scale=1,
                                      parent=rootParent)
        tex = self.background.component("image0").getTexture()
        tex.setMagfilter(SamplerState.FT_nearest)
        tex.setMinfilter(SamplerState.FT_nearest)

        self.startPos = (0, 0, 0)

    def destroy(self):
        self.ignoreAll()
        self.background.destroy()
class PiratesDownloadWatcher(DownloadWatcher.DownloadWatcher):
    positions = [
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002)),
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002)),
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002))]
    
    def __init__(self, phaseNames):
        self.phaseNames = phaseNames
        self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadingBar')
        bar = self.model.findTexture('pir_t_gui_gen_loadingBar')
        self.model.find('**/loading_bar').hide()
        self.topFrame = DirectFrame(parent = base.a2dTopRight, pos = (-0.80000000000000004, 0, -0.10000000000000001), sortOrder = NO_FADE_SORT_INDEX + 1)
        self.text = DirectLabel(relief = None, parent = self.topFrame, guiId = 'DownloadWatcherText', pos = (0, 0, 0), text = '                     ', text_fg = (1, 1, 1, 1), text_shadow = (0, 0, 0, 1), text_scale = 0.040000000000000001, textMayChange = 1, text_align = TextNode.ARight, text_pos = (0.17000000000000001, 0), sortOrder = 2)
        self.bar = DirectWaitBar(relief = None, parent = self.topFrame, guiId = 'DownloadWatcherBar', pos = (0, 0, 0), frameSize = (-0.40000000000000002, 0.38, -0.044999999999999998, 0.065000000000000002), borderWidth = (0.02, 0.02), range = 100, frameColor = (1, 1, 1, 1), barColor = (0, 0.29999999999999999, 0, 1), barTexture = bar, geom = self.model, geom_scale = 0.089999999999999997, geom_pos = (-0.014, 0, 0.01), text = '0%', text_scale = 0.040000000000000001, text_fg = (1, 1, 1, 1), text_align = TextNode.ALeft, text_pos = (0.19, 0), sortOrder = 1)
        self.bgFrame = DirectFrame(relief = DGG.FLAT, parent = self.topFrame, pos = (0, 0, 0), frameColor = (0.5, 0.27000000000000002, 0.35999999999999999, 0.20000000000000001), frameSize = (-0.44, 0.39000000000000001, -0.035999999999999997, 0.056000000000000001), borderWidth = (0.02, 0.02), scale = 0.90000000000000002, sortOrder = 0)
        self.accept('launcherPercentPhaseComplete', self.update)

    
    def update(self, phase, percent, reqByteRate, actualByteRate):
        phaseName = self.phaseNames[phase]
        self.text['text'] = OTPLocalizer.DownloadWatcherUpdate % phaseName + '  -'
        self.bar['text'] = '%s %%' % percent
        self.bar['value'] = percent

    
    def foreground(self):
        self.topFrame.reparentTo(base.a2dpTopRight)
        self.topFrame.setBin('gui-fixed', 55)
        self.topFrame['sortOrder'] = NO_FADE_SORT_INDEX + 1

    
    def background(self):
        self.topFrame.reparentTo(base.a2dTopRight)
        self.topFrame.setBin('unsorted', 49)
        self.topFrame['sortOrder'] = -1

    
    def cleanup(self):
        self.text.destroy()
        self.bar.destroy()
        self.bgFrame.destroy()
        self.topFrame.destroy()
        self.ignoreAll()
class PiratesDownloadWatcher(DownloadWatcher.DownloadWatcher):
    positions = [
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002)),
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002)),
        (Point3(1, 0, 0.90000000000000002), Point3(1, 0, 0.90000000000000002))]
    
    def __init__(self, phaseNames):
        self.phaseNames = phaseNames
        self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadingBar')
        bar = self.model.findTexture('pir_t_gui_gen_loadingBar')
        self.model.find('**/loading_bar').hide()
        self.topFrame = DirectFrame(parent = base.a2dTopRight, pos = (-0.80000000000000004, 0, -0.10000000000000001), sortOrder = NO_FADE_SORT_INDEX + 1)
        self.text = DirectLabel(relief = None, parent = self.topFrame, guiId = 'DownloadWatcherText', pos = (0, 0, 0), text = '                     ', text_fg = (1, 1, 1, 1), text_shadow = (0, 0, 0, 1), text_scale = 0.040000000000000001, textMayChange = 1, text_align = TextNode.ARight, text_pos = (0.17000000000000001, 0), sortOrder = 2)
        self.bar = DirectWaitBar(relief = None, parent = self.topFrame, guiId = 'DownloadWatcherBar', pos = (0, 0, 0), frameSize = (-0.40000000000000002, 0.38, -0.044999999999999998, 0.065000000000000002), borderWidth = (0.02, 0.02), range = 100, frameColor = (1, 1, 1, 1), barColor = (0, 0.29999999999999999, 0, 1), barTexture = bar, geom = self.model, geom_scale = 0.089999999999999997, geom_pos = (-0.014, 0, 0.01), text = '0%', text_scale = 0.040000000000000001, text_fg = (1, 1, 1, 1), text_align = TextNode.ALeft, text_pos = (0.19, 0), sortOrder = 1)
        self.bgFrame = DirectFrame(relief = DGG.FLAT, parent = self.topFrame, pos = (0, 0, 0), frameColor = (0.5, 0.27000000000000002, 0.35999999999999999, 0.20000000000000001), frameSize = (-0.44, 0.39000000000000001, -0.035999999999999997, 0.056000000000000001), borderWidth = (0.02, 0.02), scale = 0.90000000000000002, sortOrder = 0)
        self.accept('launcherPercentPhaseComplete', self.update)

    
    def update(self, phase, percent, reqByteRate, actualByteRate):
        phaseName = self.phaseNames[phase]
        self.text['text'] = OTPLocalizer.DownloadWatcherUpdate % phaseName + '  -'
        self.bar['text'] = '%s %%' % percent
        self.bar['value'] = percent

    
    def foreground(self):
        self.topFrame.reparentTo(base.a2dpTopRight)
        self.topFrame.setBin('gui-fixed', 55)
        self.topFrame['sortOrder'] = NO_FADE_SORT_INDEX + 1

    
    def background(self):
        self.topFrame.reparentTo(base.a2dTopRight)
        self.topFrame.setBin('unsorted', 49)
        self.topFrame['sortOrder'] = -1

    
    def cleanup(self):
        self.text.destroy()
        self.bar.destroy()
        self.bgFrame.destroy()
        self.topFrame.destroy()
        self.ignoreAll()
Esempio n. 17
0
class GUI:
    def __init__(self, rootParent=None):

        self.frmMain = DirectFrame(
            frameColor=(1, 1, 1, 1),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmMain.setTransparency(0)

        self.waitbar = DirectWaitBar(
            barColor=(0.0, 0.0, 1.0, 1.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            state='normal',
            text='0%',
            value=50.0,
            text_align=TextNode.A_center,
            text_scale=(0.1, 0.1),
            text_pos=(0, -0.025),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmMain,
        )
        self.waitbar.setTransparency(0)

    def show(self):
        self.frmMain.show()

    def hide(self):
        self.frmMain.hide()

    def destroy(self):
        self.frmMain.destroy()
Esempio n. 18
0
class StoryManager(SogalForm):
    """Story controller of Sogal
    Controls the whole story scene.
    Mainly for logic control
    And graphics is on other  
    Attributes:
    gameTextBox: the current GameTextBox, useful for user scripting
    storyView: the current StoryView, useful for user scripting
    """
    script_space = {}
    _currentDump = None
    __destroyed = False
    


    
    
    def __init__(self):
        self.step = 0    #shows how many commands line it had run
        self.scrStack = []
        self.commandList = []
        
        self.__currentPtr = None
        if not runtime_data.RuntimeData.command_ptr:
            self.nextPtr = 0
        else: self.nextPtr = runtime_data.RuntimeData.command_ptr
        
        if not runtime_data.RuntimeData.command_stack:
            runtime_data.RuntimeData.command_stack = self.scrStack
        else: self.scrStack = runtime_data.RuntimeData.command_stack
        
        if not runtime_data.RuntimeData.command_list:
            runtime_data.RuntimeData.command_list = self.commandList
        else: self.commandList = runtime_data.RuntimeData.command_list
                
        
        self._frame = DirectFrame(parent = aspect2d)  # @UndefinedVariable pydev在傲娇而已不用管
        self._frame.setTransparency(TransparencyAttrib.MAlpha)

        

        
        self.storyView = StoryView()
        self.audioPlayer = base.audioPlayer  # @UndefinedVariable pydev在傲娇而已不用管
        self.menu = StoryMenuBar()
        self.gameTextBox = GameTextBox()
        self.textHistory = TextHistory()
        
        self.button_auto = self.menu.addButton(text = 'Auto',state = DGG.NORMAL,command = self.autoPlayButton)
        self.button_history = self.menu.addButton(text = 'History',state = DGG.NORMAL,command = self.showTextHistoryButton)
        self.button_skip = self.menu.addButton(text = 'Skip',state = DGG.DISABLED,command = self.startSkippingButton)
        self.button_lastchoice = self.menu.addButton(text = 'Last Choice',state = DGG.DISABLED,command = self.lastChoice)
        self.button_save = self.menu.addButton(text = 'Save',state = DGG.DISABLED, command = self.saveButton)
        self.button_load = self.menu.addButton(text = 'Load',state = DGG.NORMAL,command = self.loadButton)
        self.button_quicksave = self.menu.addButton(text = 'Quick Save',state = DGG.DISABLED,command = self.quickSaveButton)
        self.button_quickload = self.menu.addButton(text = 'Quick Load',state = DGG.DISABLED,command = self.quickLoadButton)
        self.button_config = self.menu.addButton(text = 'Options', state = DGG.NORMAL, command = self._configButton)
        self.button_title = self.menu.addButton(text = 'Title',state = DGG.NORMAL,command = self.returnToTitle)
        
        self._inputReady = True
        self.__arrow_shown = False
        self._choiceReady = True
        self._currentMessage = ''
        self.__currentSelection = None
        self.__finishing = False
        self.__lock = Lock()
        self.forcejump = False
        self.__autoInput = False
        self.__focused = False
        self.intervals = []
        self.__skipping = False
        self.__autoplaying = False
        self.__autoInterval = None
        self.__autoplaystep = None
        
        self.mapScriptSpace()
        SogalForm.__init__(self)
        self.show()
        taskMgr.add(self.loopTask,'story_manager_loop',sort = 2,priority = 1)  # @UndefinedVariable 傲娇的pydev……因为panda3D的"黑魔法"……
      
        taskMgr.doMethodLater(runtime_data.game_settings['jump_span'],self.__jumpCheck,'story_jump_check', sort = 5, priority = 1)  # @UndefinedVariable
        
        
        
        
        
    def focused(self):
        if not self.__focused:
            self.accept('mouse1', self.input, [1])
            self.accept('enter', self.input, [1])
            self.accept('mouse3', self.input, [3])
            self.accept('wheel_up', self.showTextHistory)
            self.accept('escape', self.showMenu)
            self.accept('control',self.setForceJump, [True])
            self.accept('control-up',self.setForceJump, [False])
            SogalForm.focused(self)
            self.__focused = True
    
    
    def defocused(self):
        if self.__focused:
            self.ignore('mouse1')
            self.ignore('enter')
            self.ignore('mouse3')
            self.ignore('wheel_up')
            self.ignore('escape')
            self.ignore('control')
            self.ignore('control-up')
            self.setForceJump(False)
            SogalForm.defocused(self)
            self.__arrow_shown = False
            self.gameTextBox.hideArrow()
            self.__focused = False
   
        
    def destroy(self):
        self.__destroyed = True
        taskMgr.remove('story_manager_loop')  # @UndefinedVariable
        taskMgr.remove('story_jump_check')  # @UndefinedVariable
        if self._frame:
            self._frame.destroy()
            self._frame = None
        
        if self.__currentSelection:
            self.__currentSelection.destroy()
        self.gameTextBox.destroy()
        self.storyView.destroy()
        self.menu.destroy()
        self.textHistory.destroy()
        SogalForm.destroy(self)
            
    def loopTask(self,task):
        '''
        The task loop of StoryManager, trying to advance every task frame
        '''
        if not self.__destroyed:
            if self.hasFocus():
                self.forward(False)
            return task.cont
        else: return task.done


        
    def _enableSavingButton(self):
        self.button_save['state'] = DGG.NORMAL
        self.button_quicksave['state'] = DGG.NORMAL

    def _disableSavingButton(self):
        self.button_save['state'] = DGG.DISABLED
        self.button_quicksave['state'] = DGG.DISABLED
    
        
    def presave(self):
        if self.nextPtr is not None:
            runtime_data.RuntimeData.command_ptr = self.nextPtr
        self.gameTextBox.presave()
        self.storyView.presave()
        self.audioPlayer.presave()
        
    def reload(self):
        taskMgr.remove('storyManagerLoop')  # @UndefinedVariable
        self.nextPtr = runtime_data.RuntimeData.command_ptr
        self.mapScriptSpace()
        self.gameTextBox.reload()
        self.storyView.reload()
        self.audioPlayer.reload()
        taskMgr.add(self.loopTask,'storyManagerLoop',sort = 2,priority = 1)  # @UndefinedVariable 傲娇的pydev……因为panda3D的"黑魔法"……
       
      
    def mapScriptSpace(self):
        if runtime_data.RuntimeData.script_space:  #map script space
            self.script_space = runtime_data.RuntimeData.script_space
        else: runtime_data.RuntimeData.script_space = self.script_space 
        script_global['goto'] = self.goto
        script_global['story_manager'] = self    
        script_global['game_text_box'] = self.gameTextBox
        script_global['story_view'] = self.storyView
        script_global['audio_player'] = self.audioPlayer
        
    def quickfinish(self):
        self.__lock.acquire()
        if not self.__finishing:
            self.__finishing = True
            self.storyView.quickfinish()
            self.gameTextBox.quickFinish()
            for itv in self.intervals:
                itv.finish()
        self.__lock.release()
    
    def input(self,type = 1):
        self.stopSkipping()
        self.stopAutoPlaying()
        
        if not self.hasFocus():
            return
        #left mouse button or enter key
        if type == 1 :
            if not self.getSceneReady():
                self.quickfinish()
            else:
                self.setTextInputReady(True)
        #right mouse button
        elif type == 3:
            self.quickfinish()
            if self.getSceneReady():
                self.menu.show()
                
    def showMenu(self):
        self.stopSkipping()
        self.stopAutoPlaying()
        
        self.quickfinish()
        if self.getSceneReady() and not self.forcejump:
            self.menu.show()   
            
    def showTextHistory(self):
        if self.getSceneReady() and not self.forcejump:
            self.textHistory.show()
                
    def saveButton(self):
        self.menu.hide()
        base.saveForm.setData(self._currentDump, self._currentMessage)
        base.saveForm.show()
        
    def loadButton(self):
        self.menu.hide()
        base.loadForm.show()
            
    def quickSaveButton(self):
        '''quicksave the data'''
        self.menu.hide()
        self.button_quicksave['state'] = DGG.DISABLED
        self.button_quickload['state'] = DGG.DISABLED
        if self._currentDump:
            messenger.send('quick_save', [self._currentDump,self._currentMessage])
            
    def quickLoadButton(self):
        ConfirmDialog(text= '要读取吗?',command= self.__confirmedQuickLoad)
        
    def _configButton(self):
        messenger.send('config_form')
        
    def returnToTitle(self):
        ConfirmDialog(text= '回到标题界面?',command= self.__confirmedReturnToTitle)
    
    def __confirmedReturnToTitle(self):
        messenger.send('return_to_title')
        
    def showTextHistoryButton(self):
        self.menu.hide()
        self.showTextHistory()
        
    def startSkippingButton(self):
        self.menu.hide()
        self.startSkipping()
        
    def autoPlayButton(self):
        self.menu.hide()
        if self.__autoplaying:
            self.stopAutoPlaying()
        else: self.startAutoPlaying()
        
    def lastChoice(self):
        ConfirmDialog(text= '要回到上一个选择枝吗?',command= self.__confirmedLastChoice)
        
    def __confirmedQuickLoad(self):
            messenger.send('quick_load')  # @UndefinedVariable        
    
    def __confirmedLastChoice(self):
        if runtime_data.RuntimeData.last_choice:
            messenger.send('load_memory',[runtime_data.RuntimeData.last_choice])            # @UndefinedVariable
            
    def autoSave(self,info = ''):
        if not info:
            info = self._currentMessage
        messenger.send('auto_save',[self._currentDump,info])
    
    def getSceneReady(self):
        '''Get if the scene is ready'''
        textbox_ready = False
        view_ready = False
        intervals_ready = True
        
        if not self.gameTextBox.getIsWaiting():
            textbox_ready = True
            
        if not self.storyView.getIsWaiting():
            view_ready = True
            
        for itv in self.intervals:
            if itv.isPlaying():
                intervals_ready = False
                break
            
        scene_ready = textbox_ready and view_ready and intervals_ready
        
        if not scene_ready:
            return False
        
        #auto play span
        if scene_ready and self.__autoplaying:
            if self.__autoplaystep != self.step:
                self.__autoplaystep = self.step
                self.__autoInterval = Wait(runtime_data.game_settings['auto_span'])
                self.__autoInterval.start()
                scene_ready = False
            else:
                if self.__autoInterval.isPlaying():
                    scene_ready = False
                    
            if self.audioPlayer.isVoicePlaying():
                scene_ready = False
        
        return scene_ready
    
    def getInputReady(self):
        '''define is user's 'next' command given'''
        textinput_ready = self._inputReady or self.__autoInput
        choice_ready = self.getChoiceReady()
        
        if self.__autoInput:
            self.__autoInput = False
        
        if textinput_ready and choice_ready:
            return True
        return False
    
    def setTextInputReady(self, value):
        self._inputReady = value
        
    def getChoiceReady(self):
        return self._choiceReady
    

    def forward(self,is_user = False):
        '''run nextCommand() or finish current operations quickly
        @param is_user: define if this operation is started by the player 
        '''
        scene_ready = self.getSceneReady()
            
            
        if scene_ready and not self.__arrow_shown:
            self.gameTextBox.showArrow()
            self.__arrow_shown = False
        
        if scene_ready and self.getInputReady():
            self.nextCommand()
            
        if self.forcejump or self.__skipping:
            self.quickfinish()
        
    def nextCommand(self):
        '''Process the next command in the non-processed queue
        '''
        #TODO: 还要添加循环的支持,用到runtime_data.command_stack来暂存需要回跳的命令组和回跳节点
        #TODO:添加对条件和选择的支持
        self.__finishing = False
        
        self.__arrow_shown = False
        self.gameTextBox.hideArrow()
        
        #Dumps story data for saving or further use
        if self.__destroyed:
            return
        
         
        self.presave()
        self._currentDump = copy.deepcopy(runtime_data.RuntimeData)
        
        if self.nextPtr < 0: self.nextPtr = 0
        self.__currentPtr = self.nextPtr
        self.nextPtr += 1
        
        if not self.commandList:
            return
        
        if len(self.commandList) > self.__currentPtr:
            handled = False
            if self.commandList[self.__currentPtr].command:
                comline = self.commandList[self.__currentPtr].command.strip()
                if comline.startswith('mark ')or comline.startswith('mark:'):
                    handled = True
                    
                # 条件判断处理 If condition
                elif comline.startswith('if '):
                    splited = space_cutter.split(comline, 1)
                    if len(splited)<2:
                        raise Exception('没条件玩毛线')
                    if self.scriptEval(splited[1]):
                        handled = True
                        
                    else:
                        relative_depth = 0
                        #if not match the condition, try to jump to elif or else
                        for i in range(self.__currentPtr+1,len(self.commandList)):
                            cli = self.commandList[i]
                            if cli.command:
                                cl = cli.command.strip()
                            else: continue
                            #一个嵌套循环的情况! A inner if
                            if cl.startswith('if '):
                                relative_depth += 1
                                continue
                            elif relative_depth == 0 and cl.startswith('elif '):
                                splited = space_cutter.split(cl, 1)
                                if len(splited)<2:
                                    raise Exception('没条件玩毛线')
                                if self.scriptEval(splited[1]):
                                    self.nextPtr = i + 1
                                    handled = True
                                    break
                                else: continue
                            elif relative_depth == 0 and cl == 'else':
                                self.nextPtr = i + 1
                                handled = True
                                break
                            elif cl == 'end' or cl.startswith('end '):
                                if relative_depth == 0:
                                    self.nextPtr = i + 1
                                    handled = True
                                    break
                                else: 
                                    relative_depth -= 1
                                    continue
                                    
                #if we meet else or elif then jump to end
                elif comline.startswith('elif ') or comline == 'else':

                    relative_depth = 0
                    for i in range(self.__currentPtr+1,len(self.commandList)):
                        cli = self.commandList[i]
                        if cli.command:
                            cl = cli.command.strip()
                        else: continue
                        if cl.startswith('if '):
                            relative_depth += 1
                            continue
                        elif cl == 'end' or cl.startswith('end '):
                            if relative_depth == 0:
                                self.nextPtr = i + 1
                                handled = True
                                break
                            else: 
                                relative_depth -= 1
                                continue                        
                
                #ignore end
                elif comline == 'end' or comline.startswith('end '):
                    handled = True
                
                                     
            
            if not handled:
                self.processCommand(self.commandList[self.__currentPtr])
            
            #self.scrPtr = self.scrPtr + 1
            #runtime_data.RuntimeData.command_ptr = self.scrPtr
        
        
        if base.hasQuickData():
            self.button_quickload['state'] = DGG.NORMAL 
            
        if runtime_data.RuntimeData.last_choice:
            self.button_lastchoice['state'] = DGG.NORMAL 
            

            
            
        if self._currentDump: 
            self._enableSavingButton()
            
        self.step += 1  #mark step
    
    def goto(self, target):
        '''Jump to a mark'''
        for i in range(0, len(self.commandList)):
            if self.commandList[i].command:
                mark = mark_cutter.split(self.commandList[i].command , 1)
                if len(mark) > 1:
                    markText = mark[1].strip()
                    if markText == target:
                        self.nextPtr = i    #Solved: #this is not a good solution but this method runs at 'nextCommand', and ths scrPtr would plus 1 afterwards
                        return
        safeprint('unable to find mark')

    def processCommand(self,command):
        '''Process a StoryCommand
        @param command: The StoryCommand to deal with
        '''    
        
        
        def seval(strs):
            return self.scriptEval(strs)
        
        
        #Mark read
        if not runtime_data.read_text.has_key(command.fileLoc):
            runtime_data.read_text[command.fileLoc] = {}
        if not runtime_data.read_text[command.fileLoc].has_key(command.index):
            already_read = False
            self.stopSkipping()
        else: already_read = True
        runtime_data.read_text[command.fileLoc][command.index] = True
        if already_read:
            self.button_skip['state'] = DGG.NORMAL
        else: self.button_skip['state'] = DGG.DISABLED
        
        self.storyView.clearQuickItems()  #clear out quick items
        
        name = ''
        continuous = False
        is_script = False
        is_selection = False
        spaceCutter = space_cutter
        
        hidingtext = False

        voiceFlag = False                   #it will be True if voice is stopped in this line of command 
                                            #used for disable cross voice of different command lines
                                            #but enable one command line with multiple voices
                                            
        autoSaving = False                  #Mark if autosaving is needed at the end of this step
        autoSavingInfo = ''
        
        #read command line
        if command.command:
            commands = command.command.split(',')
            comm = ''
            for item in commands:
                comm = item.strip()
                if comm:
                    messenger.send('sogalcommand',[comm]) #allow other tools to deal with it @UndefinedVariable
                #名字设置命令
                if comm.startswith('name ') or comm.startswith('name='): 
                    nameCutter = re.compile(ur'name *=?',re.UNICODE) 
                    name = nameCutter.split(comm,1)[1].strip()
        
                #改变文本框格式命令
                elif comm.startswith('textboxstyle '):
                    if self.gameTextBox:
                        self.gameTextBox.setTextBoxStyle(spaceCutter.split(comm, 1)[1])
                        self.gameTextBox.applyStyle()
                
                #文本框分段命令
                elif comm == 'p':
                    if self.gameTextBox:
                        self.gameTextBox.paragraphSparator()
                        
                elif comm == 'c':
                    continuous = True
                    
                elif comm.startswith('wait '):
                    temp = spaceCutter.split(comm,1)
                    if len(temp) > 1:
                        self.sceneWait(seval(temp[1]))
                
                #文本框属性设置命令
                elif comm.startswith('textbox '):
                    temp = spaceCutter.split(comm,2)
                    if temp[1] == 'apply':
                        self.gameTextBox.applyTextBoxProperties()
                    elif len(temp)>=3:
                        self.gameTextBox.setTextBoxProperty(temp[1],seval(temp[2]))
                    else:
                        safeprint('Not enough: ' + comm)
                        
                #背景设置命令
                elif comm.startswith('bg '):
                    temp = spaceCutter.split(comm,2)
                    if len(temp) >= 3:
                        fadein = seval(temp[2])
                    else: fadein = 0
                    self.storyView.changeBackground(temp[1],fadein)
                
                #图片显示命令
                elif comm.startswith('p '):
                    temp = spaceCutter.split(comm,6)
                    if len(temp) >= 7:
                        fadein = seval(temp[6])
                    else:
                        fadein = 0
                    if len(temp) >= 6:
                        scale = seval(temp[5])
                    else:
                        scale = 1
                    if len(temp) >= 5:
                        location = (seval(temp[3]),0,seval(temp[4]))
                    else:
                        if self.storyView.itemEntries.has_key(temp[1]):
                            location = self.storyView.itemEntries[temp[1]].pos
                        else: location = (0,0,0)
                    svie = StoryViewItemEntry(temp[1],temp[2],SVIC.FG,pos = location,scale = (scale,scale,scale),color = (1,1,1,1),fadein = fadein)
                    self.storyView.newItem(svie)
                    
                elif comm.startswith('del '):
                    temp = spaceCutter.split(comm,2)
                    if len(temp)>=3:
                        self.storyView.deleteItem(temp[1], seval(temp[2]))
                    else:
                        self.storyView.deleteItem(temp[1])
                    
                elif comm.startswith('ploc '):
                    temp = spaceCutter.split(comm,5)
                    if len(temp) >= 5:
                        location =  (seval(temp[2]),seval(temp[3]),seval(temp[4]))
                    else:
                        location =  (seval(temp[2]),0,seval(temp[3]))
                    if len(temp) >= 6:
                        fadein = seval(temp[5])
                    else: fadein = 0
                    self.storyView.changePosColorScale(temp[1], pos = location,time = fadein)
                    
                elif comm.startswith('pcolor '):
                    temp = spaceCutter.split(comm,6)
                    color = (seval(temp[2]),seval(temp[3]),seval(temp[4]),seval(temp[5]))
                    if len(temp) >= 7:
                        fadein = seval(temp[6])
                    else: fadein = 0
                    self.storyView.changePosColorScale(temp[1], color = color, time = fadein)
                    
                elif comm.startswith('pscale '):
                    temp = spaceCutter.split(comm,5)
                    if len(temp) >= 5:
                        scale = (seval(temp[2]),seval(temp[3]),seval(temp[4]))
                    else: scale = (seval(temp[2]),seval(temp[2]),seval(temp[2]))
                    if len(temp) == 6:
                        fadein = seval(temp[5])
                    elif len(temp) == 4:
                        fadein = seval(temp[3])
                    else: fadein = 0
                    self.storyView.changePosColorScale(temp[1], scale = scale, time = fadein)
                
                elif comm.startswith('o3d '):
                    temp = spaceCutter.split(comm)
                    svie = StoryViewItemEntry(temp[1],temp[2],SVIC.O3D,pos = (seval(temp[3]),seval(temp[4]),seval(temp[5]))
                                              ,scale = (seval(temp[10]),seval(temp[11]),seval(temp[12])),color = (seval(temp[6]),seval(temp[7]),seval(temp[8]),seval(temp[9])))
                    self.storyView.newItem(svie)
                
                elif comm.startswith('o2d '):
                    temp = spaceCutter.split(comm)
                    svie = StoryViewItemEntry(temp[1],temp[2],SVIC.O2D,pos = (seval(temp[3]),seval(temp[4]),seval(temp[5]))
                                              ,scale = (seval(temp[10]),seval(temp[11]),seval(temp[12])),color = (seval(temp[6]),seval(temp[7]),seval(temp[8]),seval(temp[9])))
                    self.storyView.newItem(svie)
                    
                elif comm.startswith('pa '):
                    temp = spaceCutter.split(comm)
                    if len(temp) >= 8:
                        fadein = seval(temp[7])
                    else: fadein = 0
                    svie = StoryViewItemEntry(temp[1],temp[2],SVIC.AFG,pos = (seval(temp[3]),0,seval(temp[4]))
                                              ,scale = (seval(temp[5]),1,seval(temp[6])),fadein = fadein)
                    self.storyView.newItem(svie)
                
                elif comm == 'clear':
                    hidingtext = True
                    self.storyView.clear()
                    
                elif comm.startswith('clear '):
                    hidingtext = True
                    temp = spaceCutter.split(comm,2)
                    if len(temp)>=3:
                        self.storyView.clear(seval(temp[1]),temp[2])
                    elif len(temp)==2:
                        self.storyView.clear(seval(temp[1]))
                    else:
                        self.storyView.clear()
                        
                elif comm.startswith('delbg '):
                    temp = spaceCutter.split(comm,1)
                    if len('temp')>=2:
                        self.storyView.deleteItem('__bg__', seval(temp[1]))
                    else:
                        self.storyView.deleteItem('__bg__')
                        
                elif comm.startswith('qp '):
                    temp = spaceCutter.split(comm,3)
                    svie = StoryViewItemEntry('quickitem',temp[1],SVIC.FG,
                                              pos = (seval(temp[2]),0,seval(temp[3])),
                                              quickitem = True
                                              )
                    self.storyView.newItem(svie)
                
                elif comm.startswith('v '):
                    if not voiceFlag:
                        self.audioPlayer.stopVoice()
                        voiceFlag = True
                    temp = spaceCutter.split(comm , 2)
                    if len(temp)>=3:
                        volume = seval(temp[2])
                    else: volume = 1
                    self.audioPlayer.playVoice(temp[1],volume)
                    
                elif comm.startswith('se '):
                    temp = spaceCutter.split(comm , 2)
                    if len(temp)>=3:
                        volume = seval(temp[2])
                    else: volume = 1
                    self.audioPlayer.playSound(temp[1],volume)
                    
                elif comm == 'vstop':
                    self.audioPlayer.stopVoice()
                    voiceFlag = True
                    
                elif comm == 'sestop':
                    self.audioPlayer.stopSound()
                    
                elif comm.startswith('bgm '):
                    temp = spaceCutter.split(comm , 4)
                    if len(temp)>=3:
                        fadein = seval(temp[2])
                    else: fadein = 0
                    if len(temp)>=4:
                        volume = seval(temp[3])
                    else: volume = 1
                    if len(temp)>=5:
                        loop = bool(seval(temp[4]))
                    else: loop = True
                    self.audioPlayer.playBGM(temp[1], fadein=fadein, volume=volume, loop=loop)      
                    
                elif comm.startswith('env '):
                    temp = spaceCutter.split(comm , 4)
                    if len(temp)>=3:
                        fadein = seval(temp[2])
                    else: fadein = 0
                    if len(temp)>=4:
                        volume = seval(temp[3])
                    else: volume = 1
                    if len(temp)>=5:
                        loop = bool(seval(temp[4]))
                    else: loop = True
                    self.audioPlayer.playENV(temp[1], fadein=fadein, volume=volume, loop=loop)        
                
                elif comm.startswith('bgmstop ') or comm == 'bgmstop':
                    temp = spaceCutter.split(comm , 1)
                    if len(temp)>=2:
                        fadeout = seval(temp[1])
                    else: fadeout = 0
                    self.audioPlayer.stopBGM(fadeout)
                    
                elif comm.startswith('envstop ') or comm == 'envstop':
                    temp = spaceCutter.split(comm , 1)
                    if len(temp)>=2:
                        fadeout = seval(temp[1])
                    else: fadeout = 0
                    self.audioPlayer.stopENV(fadeout)
                    
                elif comm.startswith('audiostop ') or comm == 'audiostop':
                    temp = spaceCutter.split(comm , 1)
                    if len(temp)>=2:
                        fadeout = seval(temp[1])
                    else: fadeout = 0
                    self.audioPlayer.stopAll(fadeout)
                    
                elif comm == 'script':
                    is_script = True
                    
                elif comm.startswith('script '):
                    temp = spaceCutter.split(comm , 1)
                    self.runScriptFile(temp[1])    
                    
                elif comm == 'choice' or comm.startswith('choice '):
                    '''
                    Selection
                    '''
                    is_selection = True
                    temp = spaceCutter.split(comm, 1)
                    if len(temp) > 1:
                        striped = temp[1].strip()
                        if striped:
                            self.pushText(text = striped, speaker = None, needInput = False, read = already_read)
                            
                elif comm.startswith('jump '):
                    temp = spaceCutter.split(comm , 1)
                    self.beginScene(temp[1].strip())
                    
                elif comm.startswith('expand '):
                    temp = spaceCutter.split(comm , 1)
                    self.expandScene(temp[1].strip())
                    
                elif comm.startswith('goto '):
                    temp = spaceCutter.split(comm , 1)
                    self.goto(temp[1].strip())       
                    
                elif comm.startswith('theme '):
                    temp = spaceCutter.split(comm , 1)
                    self.reloadTheme(temp[1].strip())
               
                elif comm == 'autosave' or comm.startswith('autosave '):
                    if self.step > 0:
                        autoSaving = True
                        temp = spaceCutter.split(comm , 1)
                        if len(temp) > 1:
                            autoSavingInfo = temp[1]
        
                else: 
                    if comm:
                        safeprint('extra command: ' + comm)
                        
        if command.text:
            if is_script:
                self.runScript(command.text)
            
            elif is_selection:
                '''
                If encountered a selection
                '''
                choiceList = []
                enablesList = []
                textlines = command.text.splitlines()
                for tl in textlines:
                    if tl.startswith('--'):  #--means disabled
                        text = tl[2:]
                        enablesList.append(False)
                    else:
                        text = tl
                        enablesList.append(True)
                    choiceList.append(text)
                self.showSelection(choiceList = choiceList, enablesList = enablesList)
            
            else:
                self.pushText(text = command.text, speaker = name, continuous = continuous, read = already_read)
            
        else:
            if hidingtext:
                self.gameTextBox.hide()    #better to hide the textbox when 'vclear'
                
        if self.gameTextBox.newText:
            runtime_data.RuntimeData.latest_text = self.gameTextBox.newText
        if runtime_data.RuntimeData.latest_text:
            self._currentMessage = runtime_data.RuntimeData.latest_text
        
        #Autosave
        if autoSaving:
            if autoSavingInfo:
                self.autoSave(autoSavingInfo)
            else: self.autoSave()

                
    
    def pushText(self, text, speaker = None, continuous = False, needInput = True, read = False):
        
        def translate(t):
            '''
            ,实现通配,__代替空行已经在一开始实现
            '''
            return t.replace(ur'\:', ur':').replace(ur'\:',ur':').replace(ur'\#',ur'#')
        #检查有无在文本中的name
        #name: formation checking
        textlines = text.splitlines()
        first_line = unicode(textlines[0])
        
        #匹配第一行中是否有表示name的冒号,正则表达式表示前面不是\的冒号(@name 命令行的简写形式判断)
        pattern = re.compile(ur'(?<!\\)[:(:)]',re.UNICODE)  
        
        splited = pattern.split(first_line,maxsplit = 1)
        #print(splited)    #测试用,废弃
        
        #如果存在name即分割成功
        if len(splited)>1:
            speaker = translate(splited[0]).strip()
            if splited[1].strip():
                textlines[0] = splited[1]
            else:
                textlines[0] = None
                
        final_text = ''

        #生成文本并解决转义符
        #Generate the final text
        for item in textlines:
            if item:
                final_text += translate(item) + '\n'
                
        if final_text:
            self.textHistory.append(final_text, speaker, None)
        
        self.gameTextBox.pushText(text = final_text, speaker = speaker, continuous = continuous,read= read)
        if needInput:
            self._inputReady = False
        self.gameTextBox.show()        
    
    def runScript(self,pscriptText):
        exec(pscriptText,script_global,self.script_space)
    
    def runScriptFile(self,fileName):
        #'''note that would ignore panda virtual pathes'''
        pathes = runtime_data.game_settings['pscriptpathes']
        types = runtime_data.game_settings['pscripttypes']
        for ft in ((folder,type) for folder in pathes for type in types):
            if exists(ft[0] + fileName + ft[1]):
                handle = open(ft[0] + fileName + ft[1])
                script = handle.read()
                handle.close()
                break
        if script:
            self.runScript(script)
        else:
            safeprint("file not find: "+ fileName) 
        
    def beginScene(self,fileName):
        '''Load target .sogal script file and go to that file.
        '''
        self.nextPtr = 0 
        self.scrStack = []  #used for stack controller pointers
        self.commandList = loadScriptData(fileName)
        runtime_data.RuntimeData.command_stack = self.scrStack
        runtime_data.RuntimeData.command_list = self.commandList
        
    def expandScene(self,fileName):
        '''expand a scene, inserting another sogal file in to current point'''
        expanding = loadScriptData(fileName)
        if len(self.commandList)> self.__currentPtr+1:
            self.commandList = self.commandList[:self.__currentPtr] + expanding + self.commandList[self.__currentPtr+1:]
        else:
            self.commandList = self.commandList[:self.__currentPtr] + expanding
        runtime_data.RuntimeData.command_stack = self.scrStack
        runtime_data.RuntimeData.command_list = self.commandList
        self.nextPtr = self.__currentPtr    #Solved: # this is not a good solution but this method runs at 'nextCommand', and ths scrPtr would plus 1 afterwards
        
    def showSelection(self,choiceList = ['A','B'],enablesList = None):
        '''This method shows a selection, which sets 'last_choice' in 
        script space to player's choice. (0 is the first, 1 is the second etc.)
        you can disable some of the selections with enablesList
        for example for choiceList ['A','B','C'] and enablesList
        '''
        #Store the last selection
        rdc = copy.deepcopy(self._currentDump)
        rdc.last_choice = None
        self.__tempDumpedLastChoice = pickle.dumps(rdc, 2)

        self._choiceReady = False
        startPos = (0,0,0.1 * len(choiceList))
        frameSize = (-0.6,0.6,-0.05 - 0.1*len(choiceList), 0.1 + 0.1*len(choiceList))
        buttonSize = (-0.5,0.5,-0.050,0.10)
        margin = 0.05
        self.__currentSelection = SogalDialog(enableMask = False, fadeScreen= None, command = self.__selected, 
                                              textList= choiceList, enablesList= enablesList, sortType= 1,noFocus = True,
                                              startPos = startPos,frameSize = frameSize,margin = margin,
                                              buttonSize = buttonSize)
        
        
        
    def __selected(self,choice):
        #Store the last selection
        if self.__tempDumpedLastChoice:
            runtime_data.RuntimeData.last_choice = self.__tempDumpedLastChoice 
        
        self.script_space['last_choice'] = choice
        self._choiceReady = True
        
    def scriptEval(self,str):
        return eval(str,script_global,runtime_data.RuntimeData.script_space)
    
    def setForceJump(self,forcejump):
        if forcejump:
            if not self.forcejump:
                self.forcejump = True
                self.setTextInputReady(True)
                self.__skipping = False
                self.stopAutoPlaying()
        else:
            self.forcejump = False
            
    def __jumpCheck(self,task):
        if self.hasFocus():
            if self.forcejump or self.__skipping or self.__autoplaying:
                self.__autoInput = True
        return task.again
    
    def sceneWait(self,time,hidetextbox = True):
        waitinterval = Wait(time)
        self.intervals.append(waitinterval)
        waitinterval.start()
        if hidetextbox:
            self.gameTextBox.hide()
            
    def reloadTheme(self,theme):
        base.setStyle(theme)
        self.menu.reloadTheme()
        self.textHistory.reloadTheme()
        self.gameTextBox.reloadTheme()
        
    def stopSkipping(self):
        self.__skipping = False
        if not self.forcejump:
            self.__autoInput = False
        
    def startSkipping(self):
        self.stopAutoPlaying()
        self.__skipping = True
        
    def startAutoPlaying(self):
        self.__skipping = False
        self.__autoplaying = True
        self.button_auto['text'] = 'Stop Auto'
        
    def stopAutoPlaying(self):
        self.__autoplaying = False
        if self.__autoInterval:
            self.__autoInterval.pause()
        self.button_auto['text'] = 'Auto'
class ExporterProject:
    def __init__(self,
                 fileName,
                 guiElementsDict,
                 getEditorFrame,
                 usePixel2D,
                 exceptionSave=False,
                 autosave=False,
                 tooltip=None):
        self.guiElementsDict = guiElementsDict
        self.getEditorFrame = getEditorFrame
        self.usePixel2D = usePixel2D
        self.isAutosave = False

        if exceptionSave:
            self.excSave()
            return

        if autosave:
            self.isAutosave = True
            self.autoSave(fileName)
            return

        self.dlgPathSelect = PathSelect(self.save, "Save Project File",
                                        "Save file path", "Save", fileName,
                                        tooltip)

    def excSave(self):
        self.dlgOverwrite = None
        self.dlgOverwriteShadow = None

        tmpPath = os.path.join(tempfile.gettempdir(), "DGDExceptionSave.json")
        self.__executeSave(True, tmpPath)
        logging.info("Wrote crash session file to {}".format(tmpPath))

    def autoSave(self, fileName=""):
        self.dlgOverwrite = None
        self.dlgOverwriteShadow = None
        if fileName == "":
            fileName = os.path.join(tempfile.gettempdir(), "DGDAutosave.json")
        self.__executeSave(True, fileName)
        logging.info("Wrote autosave file to {}".format(fileName))

    def save(self, doSave):
        if doSave:
            self.dlgOverwrite = None
            self.dlgOverwriteShadow = None
            path = self.dlgPathSelect.getPath()
            path = os.path.expanduser(path)
            path = os.path.expandvars(path)
            if os.path.exists(path):
                self.dlgOverwrite = YesNoDialog(
                    text="File already Exist.\nOverwrite?",
                    relief=DGG.RIDGE,
                    frameColor=(1, 1, 1, 1),
                    frameSize=(-0.5, 0.5, -0.3, 0.2),
                    sortOrder=1,
                    button_relief=DGG.FLAT,
                    button_frameColor=(0.8, 0.8, 0.8, 1),
                    command=self.__executeSave,
                    extraArgs=[path],
                    scale=300,
                    pos=(base.getSize()[0] / 2, 0, -base.getSize()[1] / 2),
                    parent=base.pixel2d)
                self.dlgOverwriteShadow = DirectFrame(
                    pos=(base.getSize()[0] / 2 + 10, 0,
                         -base.getSize()[1] / 2 - 10),
                    sortOrder=0,
                    frameColor=(0, 0, 0, 0.5),
                    frameSize=self.dlgOverwrite.bounds,
                    scale=300,
                    parent=base.pixel2d)
            else:
                self.__executeSave(True, path)
            base.messenger.send("setLastPath", [path])
        self.dlgPathSelect.destroy()
        del self.dlgPathSelect

    def __executeSave(self, overwrite, path):
        if self.dlgOverwrite is not None: self.dlgOverwrite.destroy()
        if self.dlgOverwriteShadow is not None:
            self.dlgOverwriteShadow.destroy()
        if not overwrite: return

        jsonTools = JSONTools()
        jsonElements = jsonTools.getProjectJSON(self.guiElementsDict,
                                                self.getEditorFrame,
                                                self.usePixel2D)
        with open(path, 'w') as outfile:
            json.dump(jsonElements, outfile, indent=2)

        if not self.isAutosave:
            base.messenger.send("clearDirtyFlag")
Esempio n. 20
0
class NodeBase(DirectObject):
    def __init__(self, name, parent):
        self.right = 0.5
        self.left = -0.5
        self.name = name
        self.nodeID = uuid4()
        self.inputList = []
        self.outputList = []
        self.selected = False

        self.frame = DirectFrame(state=DGG.NORMAL,
                                 text=name,
                                 text_align=TextNode.A_left,
                                 text_scale=0.1,
                                 text_pos=(self.left, 0.12),
                                 text_fg=(1, 1, 1, 1),
                                 frameColor=(0.25, 0.25, 0.25, 1),
                                 frameSize=(-0.5, 0.5, -.6, 0.2),
                                 parent=parent)

        self.setupBind()
        self.hide()

        self.setPos = self.frame.setPos
        self.getPos = self.frame.getPos

    def addIn(self, name, socketType):
        """Add a new input socket of the given socket type"""
        inSocket = socketType(self, name)
        self.inputList.append(inSocket)

    def addOut(self, name):
        """Add a new output socket"""
        outSocket = OutSocket(self, name)
        self.outputList.append(outSocket)

    def isLeaveNode(self):
        """Returns true if this is a leave node.
        Leave nodes do not have any input connections. Either if no
        input sockets are defined at all or none of the sockets is
        connected."""

        # check if we have any input sockets and if so if any of them is connected
        for inSocket in self.inputList:
            if inSocket.connected: return False
        return True

    def logic(self):
        """Run the logic of this node, process all in and output data.
        This is a stub and should be overwritten by the derived classes"""
        pass

    def update(self):
        """Show all sockets and resize the frame to fit all sockets in"""
        z = 0

        for outSocket in self.outputList:
            outSocket.show(z, self.right)
            z -= outSocket.height

        for inSocket in self.inputList:
            inSocket.show(z, self.left)
            z -= inSocket.height

        fs = self.frame["frameSize"]
        self.frame["frameSize"] = (fs[0], fs[1], z, fs[3])

    def create(self):
        """Place and show the node under the mouse and start draging it."""
        mwn = base.mouseWatcherNode
        if mwn.hasMouse():
            newPos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])
            self.frame.setPos(render2d, newPos)
        self._dragStart(self.frame, None)
        self.show()

    def show(self):
        """Shows the Node frame and updates its sockets"""
        self.update()
        self.frame.show()

    def hide(self):
        """Hide the Node frame"""
        self.frame.hide()

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

    def setupBind(self):
        """Setup the mousebutton actions for drag and drop feature"""
        self.frame.bind(DGG.B1PRESS, self._dragStart, [self.frame])
        self.frame.bind(DGG.B1RELEASE, self._dragStop)

    def select(self, select):
        """Set this node as selected or deselected"""
        if self.selected == select: return
        self.selected = select
        if self.selected:
            self.frame["frameColor"] = (0.45, 0.45, 0.45, 1)
        else:
            self.frame["frameColor"] = (0.25, 0.25, 0.25, 1)

    def _dragStart(self, nodeFrame, event):
        # Mark this node as selected
        base.messenger.send("selectNode", [
            self, True,
            base.mouseWatcherNode.isButtonDown(KeyboardButton.shift()), True
        ])
        # tell everyone we started to drag this node
        base.messenger.send("dragNodeStart", [self])

        # Remove any previous started drag tasks
        taskMgr.remove("dragNodeDropTask")

        # get some positions
        vWidget2render2d = nodeFrame.getPos(render2d)
        vMouse2render2d = Point3(0)
        if event is not None:
            # we get the mouse position from the event
            vMouse2render2d = Point3(event.getMouse()[0], 0,
                                     event.getMouse()[1])
        else:
            # we try to get the current mouse position from the mouse watcher
            mwn = base.mouseWatcherNode
            if mwn.hasMouse():
                vMouse2render2d = Point3(mwn.getMouse()[0], 0,
                                         mwn.getMouse()[1])
        editVec = Vec3(vWidget2render2d - vMouse2render2d)
        self.hasMoved = False

        # Initiate the task to move the node and pass it some initial values
        t = taskMgr.add(self.dragTask, "dragNodeDropTask")
        t.nodeFrame = nodeFrame
        t.editVec = editVec
        t.mouseVec = vMouse2render2d

    def dragTask(self, t):
        mwn = base.mouseWatcherNode
        if mwn.hasMouse():
            # get the current mouse position fitting for a render2d position
            vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])

            # check if the cursor has moved enough to drag this node
            # this gives us some puffer zone for clicking
            if not self.hasMoved and (t.mouseVec -
                                      vMouse2render2d).length() < 0.01:
                return t.cont

            # We actually have moved now
            self.hasMoved = True

            # calculate the new position
            newPos = vMouse2render2d + t.editVec

            # move the node to the new position
            t.nodeFrame.setPos(render2d, newPos)

            # tell everyone we moved the node
            base.messenger.send("dragNodeMove", [t.mouseVec, vMouse2render2d])

        return t.cont

    def _dragStop(self, event=None):
        self.ignore("mouse1-up")
        # remove the node dragging task
        taskMgr.remove("dragNodeDropTask")

        # check if the node has moved
        if not self.hasMoved:
            # we want to select this node as it has not been moved
            base.messenger.send("selectNode", [
                self, True,
                base.mouseWatcherNode.isButtonDown(KeyboardButton.shift())
            ])
        # tell everyone we stopped moving the node
        base.messenger.send("dragNodeStop", [self])

    def getLeftEdge(self):
        """Get the left edge of the frame as seen from the frame"""
        return self.frame["frameSize"][0]

    def getRightEdge(self):
        """Get the right edge of the frame as seen from the frame"""
        return self.frame["frameSize"][1]

    def getBottomEdge(self):
        """Get the bottom edge of the frame as seen from the frame"""
        return self.frame["frameSize"][2]

    def getTopEdge(self):
        """Get the top edge of the frame as seen from the frame"""
        return self.frame["frameSize"][3]

    def getLeft(self, np=None):
        """Get left edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getX() + self.frame["frameSize"][0]

    def getRight(self, np=None):
        """Get right edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getX() + self.frame["frameSize"][1]

    def getBottom(self, np=None):
        """Get bottom edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getZ() + self.frame["frameSize"][2]

    def getTop(self, np=None):
        """Get top edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getZ() + self.frame["frameSize"][3]
class QuestRewardFrame(DirectFrame):
    notify = directNotify.newCategory('QuestRewardFrame')

    def __init__(self, poster, reward, **kw):
        optiondefs = (('relief', None, None), ('image',
                                               QuestGlobals.getJBIcon(), None),
                      ('image_scale', QuestGlobals.JB_JAR_SCALE,
                       None), ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)

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

        gagShopGeom = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.info = DirectFrame(parent=self,
                                relief=None,
                                geom=gagShopGeom.find('**/Char_Pnl'),
                                geom_scale=(0.15, 0, 0.1275),
                                text='0',
                                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, 0, -0.06))
        self.info.setBin('gui-popup', 40)

        gagShopGeom.removeNode()
        self.hide()

    def setup(self):
        if self.reward.rewardType == 1:
            # This is a jellybeans reward.
            self.setPos(QuestGlobals.LEFT_JB_JAR_POS)
            self.info['text'] = str(self.reward.rewardValue)
        elif self.reward.rewardType == 2:
            # This is a teleport access reward.
            self['image'] = QuestGlobals.getTPAccessIcon()
            self['image_scale'] = QuestGlobals.TP_ACCESS_SCALE
            self.setPos(QuestGlobals.LEFT_TP_ACCESS_POS)
            self.info['text'] = ZoneUtil.ZoneId2HoodAbbr[
                self.reward.rewardValue]
            self.info.setPos(-0.0025, 0, -0.04)
        elif self.reward.rewardType == 3:
            # This is a laff boost reward.
            r, g, b, _ = base.localAvatar.getHeadColor()
            hp = base.localAvatar.getMaxHealth() + self.reward.rewardValue
            laffMeter = LaffOMeter()
            laffMeter.generate(r,
                               g,
                               b,
                               base.localAvatar.getAnimal(),
                               maxHP=hp,
                               initialHP=hp)
            self['image'] = laffMeter
            self['image_scale'] = QuestGlobals.LAFF_METER_SCALE
            self.setPos(QuestGlobals.LEFT_LAFF_METER_POS)
            self.info['text'] = '+%d' % self.reward.rewardValue
            self.info.setPos(0, 0, -0.05)
            laffMeter.destroy()
        elif self.reward.rewardType == 5:
            # This is a gag slot reward.
            icon = QuestGlobals.getGagSlotIcon(self.reward.rewardValue)
            self['image'] = icon
            self['image_scale'] = QuestGlobals.GAG_SLOT_ICON_SCALE
            self.setTransparency(TransparencyAttrib.MAlpha)
            self.setPos(QuestGlobals.LEFT_GAG_SLOT_POS)
            self.info.hide()

        self.show()

    def destroy(self):
        if hasattr(self, 'reward'):
            self.info.destroy()
            del self.info
            del self.reward
            DirectFrame.destroy(self)
Esempio n. 22
0
class GUI:
    def __init__(self, rootParent=None):

        self.frmMain = DirectFrame(
            frameColor=(1, 1, 1, 1),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            image='menu/background.png',
            pos=LPoint3f(0, 0, 0),
            image_scale=LVecBase3f(1, 1, 1),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmMain.setTransparency(0)

        self.btnStart = DirectButton(
            frameColor=(1.0, 1.0, 0.5, 0.1),
            frameSize=(-1.9, 1.8, -0.6, 0.6),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.46),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Start Game',
            text_align=TextNode.A_center,
            text_scale=(0.42, 0.4),
            text_pos=(0.03, -0.45),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmMain,
            command=base.messenger.send,
            extraArgs=["startGame"],
            pressEffect=1,
        )
        self.btnStart.setTransparency(0)

        self.btnOptions = DirectButton(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-1.825, 1.925, -0.437, 0.85),
            hpr=LVecBase3f(35, -28, 20),
            pos=LPoint3f(0.6, 0, -0.125),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Options',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0.7, 0.7, 0.7, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmMain,
            command=base.messenger.send,
            extraArgs=["options"],
            pressEffect=0,
        )
        self.btnOptions.setTransparency(0)

        self.btnExit = DirectButton(
            frameColor=(0.1, 0.7, 0.1, 1.0),
            frameSize=(-1.5249999523162843, 1.6499999523162843,
                       -0.21250001192092896, 0.8250000238418579),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.45, 0, -0.6),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='EXIT',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0.9, 0.9, 0.9, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmMain,
            command=base.messenger.send,
            extraArgs=["exit"],
            pressEffect=0,
        )
        self.btnExit.setTransparency(0)

    def show(self):
        self.frmMain.show()

    def hide(self):
        self.frmMain.hide()

    def destroy(self):
        self.frmMain.destroy()
class DirectFolderBrowser(DirectObject):
    def __init__(self, command, fileBrowser=False, defaultPath="~", defaultFilename="unnamed.txt", fileExtensions=[], tooltip=None):
        """
        A simple file and folder browser

        command: The command that will be called on closing the browser
        fileBrowser: If set to True the browser will show files, otherwise it will only show folders
        defaultPath: The initial path the browser will be set to show
        defaultFilename: The filename that will be set by default, only usefull if fileBrowser is True
        fileExtensions: A list of extensions. Only files with those extensions will be shown. Only usefull if fileBrowser is True
        tooltip: An instance of the Tooltip class to display tooltips for certain parts of the editor
        """
        self.tt = tooltip
        self.command = command
        self.showFiles = fileBrowser
        self.fileExtensions = fileExtensions
        self.showHidden = False

        self.currentPath = os.path.expanduser(defaultPath)
        if not os.path.exists(self.currentPath):
            self.currentPath = os.path.expanduser("~")
        self.previousPath = self.currentPath

        self.screenWidthPx = base.getSize()[0]
        self.screenWidthPxHalf = self.screenWidthPx * 0.5
        self.screenHeightPx = base.getSize()[1]
        self.screenHeightPxHalf = self.screenHeightPx * 0.5

        self.mainFrame = DirectFrame(
            relief=1,
            frameSize=(-self.screenWidthPxHalf,self.screenWidthPxHalf,-self.screenHeightPxHalf,self.screenHeightPxHalf),
            frameColor=(1, 1, 1, 1),
            pos=LPoint3f(base.getSize()[0]/2, 0, -base.getSize()[1]/2),
            parent=base.pixel2d,
            state=DGG.NORMAL,
        )

        self.pathRightMargin = 153
        self.pathEntryWidth = self.screenWidthPx - self.pathRightMargin

        self.pathEntry = DirectEntry(
            parent=self.mainFrame,
            relief=DGG.SUNKEN,
            frameColor=(1, 1, 1, 1),
            pad=(0.2, 0.2),
            pos=LPoint3f(-self.screenWidthPxHalf + 15, 0, self.screenHeightPxHalf - 25),
            scale=12,
            width=self.pathEntryWidth/12,
            overflow=True,
            command=self.entryAccept,
            initialText=self.currentPath,
            focusInCommand=base.messenger.send,
            focusInExtraArgs=["unregisterKeyboardEvents"],
            focusOutCommand=base.messenger.send,
            focusOutExtraArgs=["reregisterKeyboardEvents"],
        )
        x = self.pathEntryWidth/2-28
        self.btnReload = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-14, 14, -10, 18),
            pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25),
            command=self.folderReload,
            image="icons/Reload.png",
            image_scale=14,
            image_pos=(0,0,4),
        )
        self.btnReload.setTransparency(TransparencyAttrib.M_multisample)
        if self.tt is not None:
            self.btnReload.bind(DGG.ENTER, self.tt.show, ["Reload Folder"])
            self.btnReload.bind(DGG.EXIT, self.tt.hide)
        x += 28
        self.btnFolderUp = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-14, 14, -10, 18),
            pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25),
            command=self.folderUp,
            image="icons/FolderUp.png",
            image_scale=14,
            image_pos=(0,0,4),
        )
        self.btnFolderUp.setTransparency(TransparencyAttrib.M_multisample)
        if self.tt is not None:
            self.btnFolderUp.bind(DGG.ENTER, self.tt.show, ["Move up one level"])
            self.btnFolderUp.bind(DGG.EXIT, self.tt.hide)
        x += 28
        self.btnFolderNew = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-14, 14, -10, 18),
            pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25),
            command=self.folderNew,
            image="icons/FolderNew.png",
            image_scale=14,
            image_pos=(0,0,4),
        )
        self.btnFolderNew.setTransparency(TransparencyAttrib.M_multisample)
        if self.tt is not None:
            self.btnFolderNew.bind(DGG.ENTER, self.tt.show, ["Create new folder"])
            self.btnFolderNew.bind(DGG.EXIT, self.tt.hide)
        x += 28
        self.btnFolderShowHidden = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-14, 14, -10, 18),
            pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25),
            command=self.folderShowHidden,
            image="icons/FolderShowHidden.png",
            image_scale=14,
            image_pos=(0,0,4),
        )
        self.btnFolderShowHidden.setTransparency(TransparencyAttrib.M_multisample)
        if self.tt is not None:
            self.btnFolderShowHidden.bind(DGG.ENTER, self.tt.show, ["Show/Hide hidden files and folders"])
            self.btnFolderShowHidden.bind(DGG.EXIT, self.tt.hide)

        color = (
            (0.8, 0.8, 0.8, 1), # Normal
            (0.9, 0.9, 1, 1), # Click
            (0.8, 0.8, 1, 1), # Hover
            (0.5, 0.5, 0.5, 1)) # Disabled
        self.container = DirectScrolledFrame(
            relief=DGG.RIDGE,
            borderWidth=(2, 2),
            frameColor=(1, 1, 1, 1),
            frameSize=(-self.screenWidthPxHalf+10, self.screenWidthPxHalf-10, -self.screenHeightPxHalf+50, self.screenHeightPxHalf-50),
            canvasSize=(-self.screenWidthPxHalf+31, self.screenWidthPxHalf-10, -self.screenHeightPxHalf+50, self.screenHeightPxHalf-50),
            pos=LPoint3f(0, 0, 0),
            parent=self.mainFrame,
            scrollBarWidth=20,
            verticalScroll_scrollSize=20,
            verticalScroll_thumb_relief=DGG.FLAT,
            verticalScroll_incButton_relief=DGG.FLAT,
            verticalScroll_decButton_relief=DGG.FLAT,
            verticalScroll_thumb_frameColor=color,
            verticalScroll_incButton_frameColor=color,
            verticalScroll_decButton_frameColor=color,
            horizontalScroll_thumb_relief=DGG.FLAT,
            horizontalScroll_incButton_relief=DGG.FLAT,
            horizontalScroll_decButton_relief=DGG.FLAT,
            horizontalScroll_thumb_frameColor=color,
            horizontalScroll_incButton_frameColor=color,
            horizontalScroll_decButton_frameColor=color,
            state=DGG.NORMAL,
        )
        self.container.bind(DGG.MWDOWN, self.scroll, [0.01])
        self.container.bind(DGG.MWUP, self.scroll, [-0.01])

        self.btnOk = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-45, 45, -6, 14),
            pos=LPoint3f(self.screenWidthPxHalf-160, 0, -self.screenHeightPxHalf+25),
            text = "ok",
            text_scale=12,
            command=command,
            extraArgs=[1],
        )
        self.btnCancel = DirectButton(
            parent=self.mainFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-45, 45, -6, 14),
            pos=LPoint3f(self.screenWidthPxHalf-55, 0, -self.screenHeightPxHalf+25),
            text = "Cancel",
            text_scale=12,
            command=command,
            extraArgs=[0]
        )

        if self.showFiles:
            self.txtFileName = DirectEntry(
                parent=self.mainFrame,
                relief=DGG.SUNKEN,
                frameColor=(1, 1, 1, 1),
                pad=(0.2, 0.2),
                pos=LPoint3f(-self.screenWidthPxHalf+25, 0, -self.screenHeightPxHalf+25),
                scale=12,
                width=200/12,
                overflow=True,
                command=self.filenameAccept,
                initialText=defaultFilename,
                focusInCommand=base.messenger.send,
                focusInExtraArgs=["unregisterKeyboardEvents"],
                focusOutCommand=base.messenger.send,
                focusOutExtraArgs=["reregisterKeyboardEvents"],
            )

        self.newFolderFrame = DirectFrame(
            parent=self.mainFrame,
            relief=1,
            frameSize=(-self.screenWidthPxHalf+10,self.screenWidthPxHalf-10,-20,20),
            pos=LPoint3f(0, 0, self.screenHeightPxHalf-55),
            frameColor=(0.5,0.5,0.5,1),
        )
        self.txtNewFolderName = DirectLabel(
            parent=self.newFolderFrame,
            text="New Folder Name",
            text_scale=12,
            frameColor=(0,0,0,0),
            text_align=TextNode.ALeft,
            pos=(-self.screenWidthPxHalf+15, 0, -3),
        )
        self.folderName = DirectEntry(
            parent=self.newFolderFrame,
            relief=DGG.SUNKEN,
            frameColor=(1, 1, 1, 1),
            pad=(0.2, 0.2),
            pos=LPoint3f(-self.screenWidthPxHalf+25 + self.txtNewFolderName.getWidth(), 0, -4),
            scale=12,
            width=((self.screenWidthPxHalf-25)*2-self.txtNewFolderName.getWidth() - 100)/12,
            overflow=True,
            command=self.entryAccept,
            initialText="New Folder",
            focusInCommand=base.messenger.send,
            focusInExtraArgs=["unregisterKeyboardEvents"],
            focusOutCommand=base.messenger.send,
            focusOutExtraArgs=["reregisterKeyboardEvents"],
        )
        self.btnCreate = DirectButton(
            parent=self.newFolderFrame,
            relief=1,
            frameColor = (
                (0.8, 0.8, 0.8, 1), # Normal
                (0.9, 0.9, 1, 1), # Click
                (0.8, 0.8, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-45, 45, -6, 14),
            pos=LPoint3f(self.screenWidthPxHalf-65, 0, -4),
            text = "Create",
            text_scale=12,
            command=self.folderCreate,
            extraArgs=[0]
        )
        self.newFolderFrame.hide()

        self.folderReload()

        # handle window resizing
        self.prevScreenSize = base.getSize()
        self.accept("window-event", self.windowEventHandler)

    def show(self):
        self.mainFrame.show()
        self.accept("window-event", self.windowEventHandler)

    def hide(self):
        self.ignore("window-event")
        self.mainFrame.hide()

    def destroy(self):
        self.ignore("window-event")
        self.mainFrame.destroy()

    def scroll(self, scrollStep, event):
        self.container.verticalScroll.scrollStep(scrollStep)

    def get(self):
        if self.showFiles:
            return os.path.join(self.currentPath, self.txtFileName.get(True))
        return self.currentPath

    def filenameAccept(self, filename):
        self.command(1)

    def entryAccept(self, path):
        self.folderReload()

    def folderReload(self):

        for element in self.container.getCanvas().getChildren():
            element.removeNode()

        path = self.pathEntry.get(True)
        path = os.path.expanduser(path)
        path = os.path.expandvars(path)
        if not os.path.exists(path): return
        self.currentPath = path

        try:
            content = os.scandir(path)
        except PermissionError:
            base.messenger.send("showWarning", ["Access denied!"])
            self.pathEntry.set(self.previousPath)
            self.currentPath = self.previousPath
            self.folderReload()
            return

        # start position for the folders and files
        xPos = -self.screenWidthPxHalf + 20 + 50 - 110
        zPos = self.screenHeightPxHalf-60-40

        dirList = []
        fileList = []
        unkList = []

        for entry in content:
            if entry.name.startswith(".") and not self.showHidden:
                continue
            if entry.is_dir():
                dirList.append(entry)
            elif entry.is_file() and self.showFiles:
                if len(self.fileExtensions) > 0:
                    if os.path.splitext(entry.name)[1] in self.fileExtensions:
                        fileList.append(entry)
                else:
                    fileList.append(entry)
            elif self.showFiles:
                unkList.append(entry)

        def moveNext(entry):
            nonlocal xPos
            nonlocal zPos
            if entry.is_dir() or self.showFiles:
                if xPos + 110 > self.screenWidthPxHalf - 45:
                    # move to the next line if we hit the right border (incl. scrollbar size)
                    xPos = -self.screenWidthPxHalf + 20 + 50
                    zPos -= 110
                else:
                    # move right the next position
                    xPos += 110

        def getKey(item):
            return item.name.lower()

        for entry in sorted(dirList, key=getKey):
            moveNext(entry)
            self.__createFolder(entry, xPos, zPos)
        for entry in sorted(fileList, key=getKey):
            moveNext(entry)
            self.__createFile(entry.name, xPos, zPos)
        for entry in sorted(unkList, key=getKey):
            moveNext(entry)
            self.__createUnknown(entry.name, xPos, zPos)

        # recalculate the canvas size
        self.container["canvasSize"] = (-self.screenWidthPxHalf+31, self.screenWidthPxHalf-15, zPos-90, self.screenHeightPxHalf-50)
        self.container.setCanvasSize()

    def folderUp(self):
        self.previousPath = self.currentPath
        self.currentPath = os.path.normpath(os.path.join(self.currentPath, ".."))
        self.pathEntry.set(self.currentPath)
        self.folderReload()

    def folderMoveIn(self, path):
        path = os.path.expanduser(path)
        path = os.path.expandvars(path)
        self.previousPath = self.currentPath
        self.currentPath = path
        self.pathEntry.set(path)
        self.folderReload()
        self.container.verticalScroll["value"] = 0

    def folderNew(self):
        if self.newFolderFrame.isHidden():
            self.newFolderFrame.show()
        else:
            self.newFolderFrame.hide()

    def folderShowHidden(self):
        self.showHidden = not self.showHidden
        self.folderReload()

    def folderCreate(self, path=""):
        try:
            os.makedirs(os.path.join(self.currentPath, self.folderName.get(True)))
        except:
            base.messenger.send("showWarning", ["Can't create folder"])
        self.newFolderFrame.hide()
        self.folderReload()

    def __createFolder(self, entry, xPos, zPos):
        name = entry.name
        if len(entry.name) > 10:
            name = ""
            for i in range(max(math.ceil(len(entry.name)/10), 4)):
                name += entry.name[i*10:i*10+10]+"\n"
            name = name[:-1]
            if math.ceil(len(entry.name)/10) > 4:
                name += "..."
        btn = DirectButton(
            parent=self.container.getCanvas(),
            image="icons/Folder.png",
            image_scale=35,
            relief=1,
            frameColor = (
                (0.9, 0.9, 0.9, 0), # Normal
                (0.95, 0.95, 1, 1), # Click
                (0.9, 0.9, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-40, 40, -40, 40),
            pos=LPoint3f(xPos, 0, zPos),
            text = name,
            text_scale=12,
            text_pos=(0,-40),
            command=self.folderMoveIn,
            extraArgs=[entry.path]
        )
        btn.bind(DGG.MWDOWN, self.scroll, [0.01])
        btn.bind(DGG.MWUP, self.scroll, [-0.01])
        btn.setTransparency(TransparencyAttrib.M_multisample)

    def __createFile(self, filename, xPos, zPos):
        name = filename
        if len(filename) > 10:
            name = ""
            for i in range(min(math.ceil(len(filename)/10), 4)):
                name += filename[i*10:i*10+10]+"\n"
            name = name[:-1]
            if math.ceil(len(filename)/10) > 4:
                name += "..."
        btn = DirectButton(
            parent=self.container.getCanvas(),
            image="icons/File.png",
            image_scale=35,
            relief=1,
            frameColor = (
                (0.9, 0.9, 0.9, 0), # Normal
                (0.95, 0.95, 1, 1), # Click
                (0.9, 0.9, 1, 1), # Hover
                (0.5, 0.5, 0.5, 1)), # Disabled
            frameSize=(-40, 40, -40, 40),
            pos=LPoint3f(xPos, 0, zPos),
            text = name,
            text_scale=12,
            text_pos=(0,-40),
            command=self.txtFileName.set,
            extraArgs=[filename]
        )
        btn.bind(DGG.MWDOWN, self.scroll, [0.01])
        btn.bind(DGG.MWUP, self.scroll, [-0.01])
        btn.setTransparency(TransparencyAttrib.M_multisample)

    def __createUnknown(self, filename, xPos, zPos):
        name = filename
        if len(filename) > 10:
            name = ""
            for i in range(math.ceil(len(filename)/10)):
                name += filename[i*10:i*10+10]+"\n"
            name = name[:-1]
        lbl = DirectLabel(
            parent=self.container.getCanvas(),
            image="icons/File.png",
            image_scale=35,
            image_color=(0.9,0.5,0.5,1),
            relief=1,
            frameColor = (0.7, 0.7, 0.7, 0),
            frameSize=(-40, 40, -40, 40),
            pos=LPoint3f(xPos, 0, zPos),
            text = name,
            text_scale=12,
            text_pos=(0,-40),
        )
        lbl.bind(DGG.MWDOWN, self.scroll, [0.01])
        lbl.bind(DGG.MWUP, self.scroll, [-0.01])
        lbl.setTransparency(TransparencyAttrib.M_multisample)


    def windowEventHandler(self, window=None):
        if window != base.win:
            # This event isn't about our window.
            return


        if window is not None: # window is none if panda3d is not started
            if self.prevScreenSize == base.getSize():
                return
            self.prevScreenSize = base.getSize()
            self.screenWidthPx = base.getSize()[0]
            self.screenWidthPxHalf = self.screenWidthPx * 0.5
            self.screenHeightPx = base.getSize()[1]
            self.screenHeightPxHalf = self.screenHeightPx * 0.5

            # reposition and resize all gui elements
            self.mainFrame.setPos(self.screenWidthPx/2, 0, -self.screenHeightPx/2)
            self.mainFrame["frameSize"] = (-self.screenWidthPxHalf,self.screenWidthPxHalf,-self.screenHeightPxHalf,self.screenHeightPxHalf)

            self.pathEntryWidth = self.screenWidthPx - self.pathRightMargin
            self.pathEntry.setPos(LPoint3f(-self.screenWidthPxHalf + 15, 0, self.screenHeightPxHalf - 25))
            self.pathEntry["width"] = self.pathEntryWidth/12
            self.pathEntry.resetFrameSize()

            # reposition top right icons
            x = self.pathEntryWidth/2-28
            self.btnReload.setPos(LPoint3f(x, 0, self.screenHeightPxHalf - 25))
            x += 28
            self.btnFolderUp.setPos(pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25))
            x += 28
            self.btnFolderNew.setPos(pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25))
            x += 28
            self.btnFolderShowHidden.setPos(pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25))

            # resize the browsing area
            self.container["frameSize"] = (-self.screenWidthPxHalf+10, self.screenWidthPxHalf-10, -self.screenHeightPxHalf+50, self.screenHeightPxHalf-50)
            # Note: canvas size of the container will be reset in the
            #       folder Reload call at the end of this function
            self.btnOk.setPos(LPoint3f(self.screenWidthPxHalf-160, 0, -self.screenHeightPxHalf+25))
            self.btnCancel.setPos(LPoint3f(self.screenWidthPxHalf-55, 0, -self.screenHeightPxHalf+25))
            if self.showFiles:
                self.txtFileName.setPos(LPoint3f(-self.screenWidthPxHalf+25, 0, -self.screenHeightPxHalf+25))
            self.newFolderFrame.setPos(LPoint3f(0, 0, self.screenHeightPxHalf-55))
            self.newFolderFrame["frameSize"] = (-self.screenWidthPxHalf+10,self.screenWidthPxHalf-10,-20,20)
            self.txtNewFolderName.setPos(-self.screenWidthPxHalf+15, 0, -3)
            self.folderName.setPos(LPoint3f(-self.screenWidthPxHalf+25 + self.txtNewFolderName.getWidth(), 0, -4))
            self.folderName["width"]=((self.screenWidthPxHalf-25)*2-self.txtNewFolderName.getWidth() - 100)/12
            self.btnCreate.setPos(LPoint3f(self.screenWidthPxHalf-65, 0, -4))

            self.folderReload()
Esempio n. 24
0
class GUI:
    def __init__(self, rootParent=None):

        self.table = DirectFrame(
            frameColor=(1.0, 1.0, 1.0, 0.0),
            frameSize=(-1, 1, -1, 1),
            hpr=LVecBase3f(0, 0, 0),
            image='chapter1/table.png',
            pos=LPoint3f(0.55, 0, -0.575),
            sortOrder=200,
            image_scale=LVecBase3f(0.256, 1, 0.312),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.table.setTransparency(1)

        self.btnFlashlight = DirectButton(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-0.4, 0.4, -0.4, 0.4),
            hpr=LVecBase3f(0, 0, 0),
            image='chapter1/flashlight.png',
            pos=LPoint3f(0.39, 0, -0.39),
            sortOrder=201,
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='',
            image_scale=LVecBase3f(0.4, 0, 0.4),
            image_pos=LPoint3f(0, 0, 0),
            text_align=TextNode.A_center,
            text_scale=(1.0, 1.0),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["chapter1_flashlight"],
            pressEffect=1,
        )
        self.btnFlashlight.setTransparency(1)

        self.btnTelephone = DirectButton(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-0.4, 0.4, -0.4, 0.4),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.625, 0, -0.125),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["chapter1_telephone"],
            pressEffect=1,
        )
        self.btnTelephone.setTransparency(0)

        self.btnDoor = DirectButton(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-0.5, 0.5, -2.0, 2.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.75, 0, -0.125),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["chapter1_door"],
            pressEffect=1,
        )
        self.btnDoor.setTransparency(0)

        self.ringRing = DirectFrame(
            frameColor=(1.0, 1.0, 1.0, 0.0),
            frameSize=(-0.1, 0.1, -0.1, 0.1),
            hpr=LVecBase3f(0, 0, 0),
            image='chapter1/ringRing.png',
            pos=LPoint3f(0.5, 0, -0.025),
            image_scale=LVecBase3f(0.1, 1, 0.1),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.ringRing.setTransparency(1)


    def show(self):
        self.table.show()
        self.btnFlashlight.show()
        self.btnTelephone.show()
        self.btnDoor.show()
        self.ringRing.show()

    def hide(self):
        self.table.hide()
        self.btnFlashlight.hide()
        self.btnTelephone.hide()
        self.btnDoor.hide()
        self.ringRing.hide()

    def destroy(self):
        self.table.destroy()
        self.btnFlashlight.destroy()
        self.btnTelephone.destroy()
        self.btnDoor.destroy()
        self.ringRing.destroy()
Esempio n. 25
0
class GUI:
    def __init__(self, rootParent=None):
        
        self.frmInventory = DirectFrame(
            frameColor=(0.2, 0.2, 0.2, 1.0),
            frameSize=(-0.3, 0.3, -0.5, 0.5),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.725, 0, 0.2),
            parent=rootParent,
        )
        self.frmInventory.setTransparency(0)

        self.frmContent = DirectScrolledFrame(
            canvasSize=(-0.8, 0.8, -0.8, 0.8),
            frameColor=(0.2, 0.2, 0.2, 1.0),
            frameSize=(-0.8, 0.8, -0.8, 0.8),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.475, 0, 0.1),
            scrollBarWidth=0.08,
            state='normal',
            horizontalScroll_borderWidth=(0.01, 0.01),
            horizontalScroll_frameSize=(-0.05, 0.05, -0.04, 0.04),
            horizontalScroll_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_pos=LPoint3f(0, 0, 0),
            horizontalScroll_decButton_borderWidth=(0.01, 0.01),
            horizontalScroll_decButton_frameSize=(-0.05, 0.05, -0.04, 0.04),
            horizontalScroll_decButton_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_decButton_pos=LPoint3f(0, 0, 0),
            horizontalScroll_incButton_borderWidth=(0.01, 0.01),
            horizontalScroll_incButton_frameSize=(-0.05, 0.05, -0.04, 0.04),
            horizontalScroll_incButton_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_incButton_pos=LPoint3f(0, 0, 0),
            horizontalScroll_thumb_borderWidth=(0.01, 0.01),
            horizontalScroll_thumb_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_thumb_pos=LPoint3f(0, 0, 0),
            verticalScroll_borderWidth=(0.01, 0.01),
            verticalScroll_frameSize=(-0.04, 0.04, -0.05, 0.05),
            verticalScroll_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_pos=LPoint3f(0, 0, 0),
            verticalScroll_decButton_borderWidth=(0.01, 0.01),
            verticalScroll_decButton_frameSize=(-0.04, 0.04, -0.05, 0.05),
            verticalScroll_decButton_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_decButton_pos=LPoint3f(0, 0, 0),
            verticalScroll_incButton_borderWidth=(0.01, 0.01),
            verticalScroll_incButton_frameSize=(-0.04, 0.04, -0.05, 0.05),
            verticalScroll_incButton_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_incButton_pos=LPoint3f(0, 0, 0),
            verticalScroll_thumb_borderWidth=(0.01, 0.01),
            verticalScroll_thumb_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_thumb_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmContent.setTransparency(1)

        self.btnQuit = DirectButton(
            frameSize=(-3.0, 3.0, -0.3, 0.9),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.725, 0, -0.85),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Quit',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["quitGame"],
            pressEffect=1,
        )
        self.btnQuit.setTransparency(0)

        self.btnAudioToggle = DirectButton(
            frameSize=(-3.0, 3.0, -0.3, 0.9),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.725, 0, -0.7),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Audio On',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["toggleAudio"],
            pressEffect=1,
        )
        self.btnAudioToggle.setTransparency(0)

        self.frmBorderOverlay = DirectFrame(
            frameColor=(1.0, 1.0, 1.0, 0.0),
            frameSize=(-0.8, 0.8, -0.8, 0.8),
            hpr=LVecBase3f(0, 0, 0),
            image='gameScreen/border.png',
            pos=LPoint3f(-0.475, 0, 0.1),
            image_scale=LVecBase3f(0.8, 1, 0.8),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmBorderOverlay.setTransparency(1)

        self.lblInventory = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.725, 0, 0.775),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Inventory',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0.9, 0.9, 0.9, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
        )
        self.lblInventory.setTransparency(0)

        self.lblStory = DirectLabel(
            frameSize=(-0.125, 12.0, -0.313, 0.925),
            hpr=LVecBase3f(0, 0, 0),
            pad=(0.2, 0.2),
            pos=LPoint3f(-1.26, 0, -0.845),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='',
            text_align=TextNode.A_left,
            text_scale=(0.4, 0.4),
            text_pos=(0.0, 0.4),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=29.8,
            parent=rootParent,
        )
        self.lblStory.setTransparency(0)

        self.btnContinue = DirectButton(
            frameSize=(-1.8, 1.8, -0.3, 0.9),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.145, 0, -0.845),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Cont.',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["story_continue"],
            pressEffect=1,
        )
        self.btnContinue.setTransparency(0)

        self.frmFadeOverlay = DirectFrame(
            frameColor=(0.0, 0.0, 0.0, 1.0),
            frameSize=(-0.8, 0.8, -0.8, 0.8),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.475, 0, 0.1),
            parent=rootParent,
        )
        self.frmFadeOverlay.setTransparency(1)


    def show(self):
        self.frmInventory.show()
        self.frmContent.show()
        self.btnQuit.show()
        self.btnAudioToggle.show()
        self.frmBorderOverlay.show()
        self.lblInventory.show()
        self.lblStory.show()
        self.btnContinue.show()
        self.frmFadeOverlay.show()

    def hide(self):
        self.frmInventory.hide()
        self.frmContent.hide()
        self.btnQuit.hide()
        self.btnAudioToggle.hide()
        self.frmBorderOverlay.hide()
        self.lblInventory.hide()
        self.lblStory.hide()
        self.btnContinue.hide()
        self.frmFadeOverlay.hide()

    def destroy(self):
        self.frmInventory.destroy()
        self.frmContent.destroy()
        self.btnQuit.destroy()
        self.btnAudioToggle.destroy()
        self.frmBorderOverlay.destroy()
        self.lblInventory.destroy()
        self.lblStory.destroy()
        self.btnContinue.destroy()
        self.frmFadeOverlay.destroy()
Esempio n. 26
0
class GUI:
    def __init__(self, rootParent=None):

        self.frmBack = DirectFrame(
            frameColor=(0.0, 0.0, 0.0, 1.0),
            frameSize=(-0.8, 0.8, -0.8, 0.8),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmBack.setTransparency(0)

        self.pg671 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-0.893750011920929, 1.0187499523162842,
                       -0.11250001192092896, 0.7124999761581421),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.5),
            scale=LVecBase3f(0.2, 0.2, 0.2),
            text='END',
            text_align=TextNode.A_center,
            text_scale=(1.0, 1.0),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg671.setTransparency(0)

        self.lblEnding = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-8.0, 8.0, -0.325, 0.75),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0.025, 0, -0.675),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text="You've found ending x/x",
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.lblEnding.setTransparency(0)

        self.pg6340 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-0.893750011920929, 1.0187499523162842,
                       -0.11250001192092896, 0.7124999761581421),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.125, 0, 0.65),
            scale=LVecBase3f(0.05, 0.05, 0.05),
            text='the',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg6340.setTransparency(0)

        self.pg1228 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-8.0, 8.0, -0.325, 0.75),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.35),
            scale=LVecBase3f(0.05, 0.1, 0.056),
            text='A Game By',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg1228.setTransparency(0)

        self.pg1785 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-8.0, 8.0, -0.325, 0.75),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.275),
            scale=LVecBase3f(0.08, 0.1, 0.08),
            text='Fireclaw',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg1785.setTransparency(0)

        self.pg4435 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-8.0, 8.0, -0.325, 0.75),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.175),
            scale=LVecBase3f(0.05, 0.1, 0.056),
            text='Music from Jamendo by Golden Antelope',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg4435.setTransparency(0)

        self.pg5320 = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            frameSize=(-8.0, 8.0, -0.325, 0.75),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.1),
            scale=LVecBase3f(0.05, 0.1, 0.056),
            text='Audio from freesound by reinsamba',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(1, 1, 1, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            text_wordwrap=None,
            parent=self.frmBack,
        )
        self.pg5320.setTransparency(0)

    def show(self):
        self.frmBack.show()

    def hide(self):
        self.frmBack.hide()

    def destroy(self):
        self.frmBack.destroy()
Esempio n. 27
0
class RadialMenu(DirectObject):
    def __init__(self, items):
        ''' 
            Initialize using the set of items specified
            Set of items should be passed as RadialItems
        '''
        DirectObject.__init__(self)
        # Initialize variables
        self.isActive = 0
        self.selected = 0

        self.items = items

        # Load the palletized gui model
        gui = loader.loadModel("resources/camera_gui.bam")

        # Create the frame
        self.frame = DirectFrame(geom=gui.find("**/radial_menu_bg"),
                                 parent=hidden,
                                 scale=1.3,
                                 relief=None)

        # Create the selection indicator
        self.selector = OnscreenImage(
            image=gui.find("**/radial_menu_bg_quarter"), parent=self.frame)

        # Create the selected item description box
        self.descriptionBox = OnscreenText(parent=self.frame,
                                           pos=(0, -.6),
                                           style=3,
                                           font=ToontownGlobals.getSignFont(),
                                           scale=0.05,
                                           bg=(0, 0, 0, .4))

        # Load all the and calculate their positions
        self.itemAngle = 360 / len(items)
        self.itemImages = []
        for i in range(len(items)):
            x = .38 * math.cos(i * deg2Rad(self.itemAngle))
            z = .38 * math.sin(i * deg2Rad(self.itemAngle))
            img = OnscreenImage(image=self.items[i].nodepath,
                                scale=0.2,
                                parent=self.frame,
                                pos=(x, 0, z))
            self.itemImages.append(img)

    def activate(self):
        ''' Shows the menu and spawns the mouse reader task '''
        self.frame.reparentTo(aspect2d)
        taskMgr.add(self.radialTask, 'cam-radialTask')
        self.isActive = 1

    def deactivate(self):
        ''' Hides the menu and kills the mouse reader task '''
        taskMgr.remove('cam-radialTask')
        self.frame.reparentTo(hidden)
        self.isActive = 0

    def destroy(self):
        ''' Destroy everything '''
        self.frame.destroy()
        self.selector.destroy()
        for item in self.itemImages:
            item.destroy()
            del item

        for item in self.items:
            del item
        del self.frame
        del self.selector

    def getChoice(self):
        ''' Convenience Function Get the selected item '''
        return self.selected

    def radialTask(self, task):
        ''' Reads the mouse position and calculates which object it is looking at '''
        # Initialize these as 0 incase we can't read the mouses position
        mouseX = 0
        mouseY = 0
        # Read the mouse position
        if base.mouseWatcherNode.hasMouse():
            mouseX = base.mouseWatcherNode.getMouseX()
            mouseY = base.mouseWatcherNode.getMouseY()
        # Calculate the angle that the mouse is at from the cursor
        menuAngle = rad2Deg(math.atan2(mouseY, mouseX)) + 45

        # Get the index of the item at the mouse angle
        self.selected = int(math.floor((menuAngle % 360) / self.itemAngle))

        # Set the rotation of the selector
        # The selector image is from 12 o'clock to 3 o'clock, so we need to
        # rotate it counter clockwise 45 degrees
        self.selector.setR(-self.itemAngle * self.selected + 45)

        # Highlight the selected item
        for i in self.itemImages:
            i.setColorScale(1.0, 1.0, 1.0, 1.0)
            i.setScale(0.2)
        self.itemImages[self.selected].setScale(0.25)
        self.itemImages[self.selected].setColorScale(0.3, 1.0, 1.0, 1.0)

        self.descriptionBox['text'] = self.items[self.selected].description

        return Task.cont
Esempio n. 28
0
class MatchMsgFrm(GameObject):
    def __init__(self, menu_args):
        GameObject.__init__(self)
        self.eng.log('created match message form')
        self.chat = None
        self.msg_frm = DirectFrame(frameSize=(-.02, 2.5, 0, 1.22),
                                   frameColor=(.2, .2, .2, .5),
                                   pos=(.04, 1, -1.69),
                                   parent=base.a2dTopLeft)
        t_a = menu_args.text_args
        t_a['scale'] = .05
        t_a['fg'] = menu_args.text_normal
        self.dst_txt = OnscreenText(text='',
                                    pos=(0, 1.16),
                                    parent=self.msg_frm,
                                    align=TextNode.A_left,
                                    **t_a)
        self.ent = Entry(scale=.04,
                         pos=(0, 1, .03),
                         entryFont=menu_args.font,
                         width=62,
                         frameColor=menu_args.btn_color,
                         parent=self.msg_frm,
                         initialText=_('write here your message'),
                         command=self.on_typed_msg,
                         focusInCommand=self.on_focus,
                         focusInExtraArgs=['in'],
                         focusOutCommand=self.on_focus,
                         focusOutExtraArgs=['out'],
                         text_fg=menu_args.text_active)
        self.ent['state'] = DISABLED
        self.txt_frm = DirectScrolledFrame(
            frameSize=(-.02, 2.46, -.02, 1.02),
            canvasSize=(-.02, 2.42, -.02, 1.02),
            scrollBarWidth=.036,
            verticalScroll_relief=FLAT,
            verticalScroll_frameColor=(.2, .2, .2, .4),
            verticalScroll_thumb_relief=FLAT,
            verticalScroll_thumb_frameColor=(.8, .8, .8, .6),
            verticalScroll_incButton_relief=FLAT,
            verticalScroll_incButton_frameColor=(.8, .8, .8, .6),
            verticalScroll_decButton_relief=FLAT,
            verticalScroll_decButton_frameColor=(.8, .8, .8, .6),
            horizontalScroll_relief=FLAT,
            frameColor=(1, 1, 1, .0),
            pos=(.02, 1, .11),
            parent=self.msg_frm)
        t_a['scale'] = .046
        self.msg_txt = OnscreenText(text='',
                                    pos=(0, .24),
                                    parent=self.txt_frm.getCanvas(),
                                    align=TextNode.A_left,
                                    wordwrap=52,
                                    **t_a)
        lab_args = menu_args.label_args
        lab_args['scale'] = .046
        lab_args['text_fg'] = menu_args.text_normal
        self.lab_frm = Btn(frameSize=(-.02, 2.5, -.01, .05),
                           frameColor=(1, 1, 1, 0),
                           pos=(0, 1, 1.15),
                           parent=self.msg_frm)
        self.lab_frm.bind(ENTER, self.on_enter)
        self.lab_frm.bind(EXIT, self.on_exit)
        self.tooltip = DirectLabel(text='',
                                   pos=(2.4, 1, -.06),
                                   parent=self.lab_frm,
                                   text_wordwrap=50,
                                   text_bg=(.2, .2, .2, .8),
                                   text_align=TextNode.A_right,
                                   **lab_args)
        self.tooltip.set_bin('gui-popup', 10)
        self.tooltip.hide()

    def on_enter(self, pos):
        self.tooltip.show()

    def on_exit(self, pos):
        self.tooltip.hide()

    def add_msg_txt(self, msg):
        self.msg_txt['text'] += ('\n' if self.msg_txt['text'] else '') + msg
        txt_height = self.msg_txt.textNode.getUpperLeft3d()[2] - \
            self.msg_txt.textNode.getLowerRight3d()[2]
        self.txt_frm['canvasSize'] = (-.02, .72, .28 - txt_height, .28)

    def set_title(self, title):
        ttitle = self.trunc(title, 160)
        fix_name = lambda name: name if '@' not in name else name.split('@')[
            0] + '\1smaller\1@' + name.split('@')[1] + '\2'
        if title:
            if ',' in ttitle:
                is_muc = True
                ttitle = ttitle
                names = ttitle.split(',')
                names = [name.strip() for name in names]
                names = [fix_name(name) for name in names]
                ttitle = ', '.join(names)
            else:
                ttitle = fix_name(ttitle)
        self.dst_txt['text'] = ttitle
        self.tooltip['text'] = title

    @staticmethod
    def trunc(name, lgt):
        if len(name) > lgt: return name[:lgt] + '...'
        return name

    def on_typed_msg(self, val):
        #self.add_msg_txt('\1italic\1' + _('you') + '\2: ' + val)
        self.ent.set('')
        self.eng.xmpp.client.send_message(
            mfrom=self.eng.xmpp.client.boundjid.full,
            mto=self.chat.dst,
            mtype='groupchat',
            mbody=val)
        self.ent['focus'] = 1

    def on_groupchat_msg(self, msg):
        src = str(JID(msg['mucnick']))
        src = src.split('@')[0] + '\1smaller\1@' + src.split('@')[1] + '\2'
        self.eng.log('received groupchat message from %s in the chat %s' %
                     (msg['mucnick'], JID(msg['from']).bare))
        str_msg = '\1italic\1' + src + '\2: ' + str(msg['body'])
        if not self.chat:
            self.chat = MUC(str(JID(msg['from']).bare))
        self.chat.messages += [str_msg]
        if self.dst_txt['text'] == '':
            self.set_chat(self.chat)
        elif self.chat.dst == str(JID(msg['from']).bare):
            self.add_msg_txt(str_msg)

    def on_presence_available_room(self, msg):
        room = str(JID(msg['muc']['room']).bare)
        nick = str(msg['muc']['nick'])
        self.eng.log('user %s has logged in the chat %s' % (nick, room))
        self.chat.users += [nick]
        self.set_title(self.chat.title)

    def on_presence_unavailable_room(self, msg):
        room = str(JID(msg['muc']['room']).bare)
        nick = str(msg['muc']['nick'])
        self.eng.log('user %s has left the chat %s' % (nick, room))
        self.chat.users.remove(nick)
        self.set_title(self.chat.title)

    def add_groupchat(self, room, usr):
        self.set_title(usr)
        if not self.chat:
            self.chat = MUC(room)
        self.set_chat(self.chat)

    def set_chat(self, chat):
        self.set_title(chat.title)
        self.msg_txt['text'] = '\n'.join(chat.messages)
        txt_height = self.msg_txt.textNode.getUpperLeft3d()[2] - \
            self.msg_txt.textNode.getLowerRight3d()[2]
        self.txt_frm['canvasSize'] = (-.02, .72, .28 - txt_height, .28)
        self.ent['state'] = NORMAL

    def on_focus(self, val):
        if val == 'in' and self.ent.get() == _('write here your message'):
            self.ent.set('')
        self.notify('on_match_msg_focus', val)

    def destroy(self):
        self.eng.log('message form destroyed')
        self.msg_frm.destroy()
        GameObject.destroy(self)
Esempio n. 29
0
class GUI:
    def __init__(self, rootParent=None):

        self.lblDescription = DirectFrame(
            frameColor=(1.0, 1.0, 1.0, 0.0),
            frameSize=(-0.75, 0.75, -0.8, 0.8),
            hpr=LVecBase3f(0, 0, 0),
            image='./assets/quest/QuestBG.png',
            pos=LPoint3f(0, 0, 0),
            image_scale=LVecBase3f(0.75, 1, 0.8),
            image_pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.lblDescription.setTransparency(2)

        self.lblHeader = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0.59),
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Quest',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.lblDescription,
        )
        self.lblHeader.setTransparency(1)

        self.lblQuestDesc = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.6, 0, 0.525),
            scale=LVecBase3f(0.05, 0.05, 0.05),
            text='Quest description part 1',
            text_align=TextNode.A_left,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.lblDescription,
        )
        self.lblQuestDesc.setTransparency(1)

        self.lblControl = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.6, 0, -0.25),
            scale=LVecBase3f(0.08, 0.08, 0.08),
            text='Controls',
            text_align=TextNode.A_left,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.lblDescription,
        )
        self.lblControl.setTransparency(1)

        self.lblControlDesc = DirectLabel(
            frameColor=(0.8, 0.8, 0.8, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(-0.6, 0, -0.315),
            scale=LVecBase3f(0.05, 0.05, 0.05),
            text="If it's your turn, click the dice button or hit D",
            text_align=TextNode.A_left,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.lblDescription,
        )
        self.lblControlDesc.setTransparency(1)

        self.btnClose = DirectButton(
            frameColor=(0.8, 0.8, 0.8, 0.75),
            frameSize=(-1.288, 1.387, -0.213, 0.825),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, -0.65),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='Close',
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.lblDescription,
            pressEffect=1,
        )
        self.btnClose.setTransparency(0)

    def show(self):
        self.lblDescription.show()

    def hide(self):
        self.lblDescription.hide()

    def destroy(self):
        self.lblDescription.destroy()
Esempio n. 30
0
class Results(GameObject, DirectObject):
    def __init__(self, rprops):
        GameObject.__init__(self)
        self.__res_txts = []
        self._buttons = []
        self.players = self.result_frm = None
        self.rprops = rprops
        self.font = rprops.season_props.gameprops.menu_props.font
        self.text_fg = rprops.season_props.gameprops.menu_props.text_active_col
        self.text_bg = rprops.season_props.gameprops.menu_props.text_normal_col

    def show(self, race_ranking, lap_times, players):
        track = self.rprops.track_path
        self.players = players
        self.result_frm = DirectFrame(frameColor=(.8, .8, .8, .64),
                                      frameSize=(-2, 2, -1, 1))
        laps = len(lap_times)
        text_bg = self.rprops.season_props.gameprops.menu_props.text_normal_col
        pars = {
            'scale': .1,
            'fg': text_bg,
            'font': self.rprops.season_props.gameprops.menu_props.font
        }
        self.__res_txts = [
            OnscreenText(str(round(lap_times[i], 2)),
                         pos=(0, .52 - .2 * (i + 1)),
                         **pars) for i in range(laps)
        ]
        self.__res_txts += [OnscreenText(_('LAP'), pos=(-.6, .68), **pars)]
        self.__res_txts += [OnscreenText(_('TIME'), pos=(0, .68), **pars)]
        self.__res_txts += [
            OnscreenText(_('RANKING'),
                         pos=(.5, .68),
                         align=TextNode.A_left,
                         **pars)
        ]
        self.__res_txts += [
            OnscreenText(str(i), pos=(-.6, .52 - .2 * i), **pars)
            for i in range(1, 4)
        ]
        race_ranking_sorted = sorted(race_ranking.items(), key=lambda x: x[1])
        race_ranking_sorted = reversed([el[0] for el in race_ranking_sorted])

        for i, car in enumerate(race_ranking_sorted):
            dpars = i, car, .76, .54, str(i + 1) + '. %s'
            txt, img = RankingGui.set_drv_txt_img(self, *dpars, self.players)
            self.__res_txts += [txt, img]
        self.__res_txts += [
            OnscreenText(_('share:'),
                         pos=(-.1, -.82),
                         align=TextNode.A_right,
                         **pars)
        ]
        self._buttons = []

        min_time = min(lap_times or [0])
        facebook_url = self.rprops.share_urls[0]
        twitter_url = self.rprops.share_urls[1]
        twitter_url = twitter_url.format(time=round(min_time, 2), track=track)
        # plus_url = self.rprops.share_urls[2]
        # tumblr_url = self.rprops.share_urls[3]
        sites = [('facebook', facebook_url), ('twitter', twitter_url)]
        # ('google_plus', plus_url), ('tumblr', tumblr_url)
        menu_props = self.rprops.season_props.gameprops.menu_props
        self._buttons += [
            ImgBtn(scale=(.078, .078),
                   pos=(.02 + i * .18, -.79),
                   frame_col=(0, 0, 0, 0),
                   img=menu_props.social_imgs_dirpath % site[0],
                   cmd=self.eng.open_browser,
                   extra_args=[site[1]],
                   over_snd=menu_props.over_sfx,
                   click_snd=menu_props.click_sfx)
            for i, site in enumerate(sites)
        ]

        def step():
            if self.eng.server.is_active:
                self.eng.server.send([NetMsgs.end_race])
            self.notify('on_race_step', race_ranking)
            self.destroy()
            GameObject.destroy(self)

        cont_btn = Btn(
            text=_('Continue'),
            pos=(0, -.6),
            cmd=step,
            **self.rprops.season_props.gameprops.menu_props.btn_args)
        self._buttons += [cont_btn]
        for i in range(self.eng.joystick_mgr.joystick_lib.num_joysticks):
            self.accept('joypad%s-face_a-up' % i, step)

    def destroy(self):
        if not self.result_frm or self.result_frm.isEmpty():
            return
        # if it is reached by step then there are two destroys: step's one
        # and race.gui's one
        list(map(lambda txt: txt.destroy(), self.__res_txts))
        list(map(lambda btn: btn.destroy(), self._buttons))
        for i in range(self.eng.joystick_mgr.joystick_lib.num_joysticks):
            self.ignore('joypad%s-face_a-up' % i)
        self.result_frm.destroy()
        GameObject.destroy(self)
Esempio n. 31
0
class GUI:
    def __init__(self, rootParent=None):
        
        self.frmChat = DirectFrame(
            frameColor=(0.25, 0.25, 0.25, 1.0),
            frameSize=(-0.4, 0.4, -1.25, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, 0),
            parent=rootParent,
        )
        self.frmChat.setTransparency(0)

        self.frmMessages = DirectScrolledFrame(
            borderWidth=(0.005, 0.005),
            canvasSize=(-0.38, 0.34, -1.2, 0.0),
            frameColor=(1, 1, 1, 1),
            frameSize=(-0.38, 0.38, -1.0, 0.0),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, -0.1),
            relief=3,
            scrollBarWidth=0.03,
            state='normal',
            horizontalScroll_borderWidth=(0.01, 0.01),
            horizontalScroll_frameSize=(-0.05, 0.05, -0.015, 0.015),
            horizontalScroll_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_pos=LPoint3f(0, 0, 0),
            horizontalScroll_decButton_borderWidth=(0.01, 0.01),
            horizontalScroll_decButton_frameSize=(-0.05, 0.05, -0.04, 0.04),
            horizontalScroll_decButton_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_decButton_pos=LPoint3f(0, 0, 0),
            horizontalScroll_incButton_borderWidth=(0.01, 0.01),
            horizontalScroll_incButton_frameSize=(-0.05, 0.05, -0.04, 0.04),
            horizontalScroll_incButton_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_incButton_pos=LPoint3f(0, 0, 0),
            horizontalScroll_thumb_borderWidth=(0.01, 0.01),
            horizontalScroll_thumb_hpr=LVecBase3f(0, 0, 0),
            horizontalScroll_thumb_pos=LPoint3f(0, 0, 0),
            verticalScroll_borderWidth=(0.01, 0.01),
            verticalScroll_frameSize=(-0.015, 0.015, -0.05, 0.05),
            verticalScroll_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_pos=LPoint3f(0, 0, 0),
            verticalScroll_decButton_borderWidth=(0.01, 0.01),
            verticalScroll_decButton_frameSize=(-0.04, 0.04, -0.05, 0.05),
            verticalScroll_decButton_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_decButton_pos=LPoint3f(0.36, 0, -0.02),
            verticalScroll_incButton_borderWidth=(0.01, 0.01),
            verticalScroll_incButton_frameSize=(-0.04, 0.04, -0.05, 0.05),
            verticalScroll_incButton_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_incButton_pos=LPoint3f(0.36, 0, -0.98),
            verticalScroll_thumb_borderWidth=(0.01, 0.01),
            verticalScroll_thumb_hpr=LVecBase3f(0, 0, 0),
            verticalScroll_thumb_pos=LPoint3f(0.36, 0, -0.418625),
            parent=self.frmChat,
        )
        self.frmMessages.setTransparency(0)

        self.txtMessage = DirectEntry(
            borderWidth=(0.005, 0.005),
            frameColor=(1.0, 1.0, 1.0, 1.0),
            hpr=LVecBase3f(0, 0, 0),
            overflow=1,
            pos=LPoint3f(-0.375, 0, -1.195),
            relief=3,
            scale=LVecBase3f(0.045, 0.045, 0.045),
            width=14.0,
            text_align=TextNode.A_left,
            text_scale=(1.0, 1.0),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmChat,
        )
        self.txtMessage.setTransparency(0)

        self.btnSend = DirectButton(
            frameColor=(0.0, 0.0, 0.0, 0.0),
            frameSize=(-0.4, 0.4, -0.4, 0.4),
            hpr=LVecBase3f(0, 0, 0),
            image='assets/chat/ChatSend.png',
            pos=LPoint3f(0.33, 0, -1.18),
            relief=1,
            scale=LVecBase3f(0.1, 0.1, 0.1),
            text='',
            image_scale=LVecBase3f(0.4, 1, 0.4),
            image_pos=LPoint3f(0, 0, 0),
            text_align=TextNode.A_center,
            text_scale=(1, 1),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0, 0, 0, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=self.frmChat,
            command=base.messenger.send,
            extraArgs=["sendMessage"],
        )
        self.btnSend.setTransparency(1)

        self.btnToggleChat = DirectButton(
            frameColor=(0.15, 0.15, 0.15, 1.0),
            frameSize=(-0.4, 0.4, -0.02, 0.05),
            hpr=LVecBase3f(0, 0, 0),
            pos=LPoint3f(0, 0, -0.05),
            relief=1,
            scale=LVecBase3f(1, 1, 1),
            text='Toggle Chat',
            text_align=TextNode.A_center,
            text_scale=(0.05, 0.05),
            text_pos=(0, 0),
            text_fg=LVecBase4f(0.8, 0.8, 0.8, 1),
            text_bg=LVecBase4f(0, 0, 0, 0),
            parent=rootParent,
            command=base.messenger.send,
            extraArgs=["toggleChat"],
        )
        self.btnToggleChat.setTransparency(0)


    def show(self):
        self.frmChat.show()
        self.btnToggleChat.show()

    def hide(self):
        self.frmChat.hide()
        self.btnToggleChat.hide()

    def destroy(self):
        self.frmChat.destroy()
        self.btnToggleChat.destroy()
Esempio n. 32
0
class Results(Subject):
    def __init__(self, result_props):
        Subject.__init__(self)
        self.__res_txts = []
        self.__buttons = []
        self.result_frm = None
        self.props = result_props

    def show(self, race_ranking, lap_times, drivers, player_car_name):
        track = self.props.track_path
        self.result_frm = DirectFrame(frameColor=(.8, .8, .8, .64),
                                      frameSize=(-2, 2, -1, 1))
        laps = len(lap_times)
        text_bg = self.props.menu_args.text_bg
        pars = {'scale': .1, 'fg': text_bg, 'font': self.props.menu_args.font}
        # ref into race
        self.__res_txts = [
            OnscreenText(str(round(lap_times[i], 2)),
                         pos=(0, .47 - .2 * (i + 1)),
                         **pars) for i in range(laps)
        ]
        self.__res_txts += [OnscreenText(_('LAP'), pos=(-.6, .6), **pars)]
        self.__res_txts += [OnscreenText(_('TIME'), pos=(0, .6), **pars)]
        self.__res_txts += [
            OnscreenText(_('RANKING'),
                         pos=(.5, .6),
                         align=TextNode.A_left,
                         **pars)
        ]
        self.__res_txts += [
            OnscreenText(str(i), pos=(-.6, .47 - .2 * i), **pars)
            for i in range(1, 4)
        ]
        race_ranking_sorted = sorted(race_ranking.items(), key=lambda x: x[1])
        race_ranking_sorted = reversed([el[0] for el in race_ranking_sorted])
        for i, car in enumerate(race_ranking_sorted):
            carinfo = next(drv for drv in drivers if drv[3] == car)
            idx, name, skills, _car = carinfo
            is_car = car == player_car_name
            fgc = self.props.menu_args.text_fg if is_car else text_bg
            txt = OnscreenText(text=str(i + 1) + '. ' + name,
                               align=TextNode.A_left,
                               scale=.072,
                               pos=(.68, .44 - .16 * (i + 1)),
                               font=self.props.menu_args.font,
                               fg=fgc)
            img = OnscreenImage(self.props.cars_imgs % car,
                                pos=(.58, 1, .47 - (i + 1) * .16),
                                scale=.074)
            with open(eng.curr_path + 'yyagl/assets/shaders/filter.vert') as f:
                vert = f.read()
            with open(eng.curr_path +
                      'yyagl/assets/shaders/drv_car.frag') as f:
                frag = f.read()
            shader = Shader.make(Shader.SL_GLSL, vert, frag)
            img.setShader(shader)
            img.setTransparency(True)
            ts = TextureStage('ts')
            ts.setMode(TextureStage.MDecal)
            txt_path = self.props.drivers_imgs % idx
            img.setTexture(ts, loader.loadTexture(txt_path))
            self.__res_txts += [txt, img]
        self.__res_txts += [
            OnscreenText(_('share:'),
                         pos=(-.1, -.82),
                         align=TextNode.A_right,
                         **pars)
        ]
        self.__buttons = []

        curr_time = min(game.player_car.logic.lap_times or [0])
        facebook_url = self.props.share_urls[0]
        #TODO: find a way to share the time on Facebook
        twitter_url = self.props.share_urls[1]
        twitter_url = twitter_url.format(time=round(curr_time, 2), track=track)
        plus_url = self.props.share_urls[2]
        #TODO: find a way to share the time on Google Plus
        tumblr_url = self.props.share_urls[3]
        #TODO: find a way to share the time on Tumblr
        sites = [('facebook', facebook_url), ('twitter', twitter_url),
                 ('google_plus', plus_url), ('tumblr', tumblr_url)]
        self.__buttons += [
            ImageButton(scale=.078,
                        pos=(.02 + i * .18, 1, -.79),
                        frameColor=(0, 0, 0, 0),
                        image=self.props.share_imgs % site[0],
                        command=eng.open_browser,
                        extraArgs=[site[1]],
                        rolloverSound=self.props.menu_args.rollover,
                        clickSound=self.props.menu_args.click)
            for i, site in enumerate(sites)
        ]

        def step():
            self.notify('on_race_step', race_ranking)
            self.destroy()
            Subject.destroy(self)

        cont_btn = DirectButton(text=_('Continue'),
                                pos=(0, 1, -.6),
                                command=step,
                                **self.props.menu_args.btn_args)
        self.__buttons += [cont_btn]

    def destroy(self):
        if not self.result_frm or self.result_frm.isEmpty():
            return
        # if it is reached by step then there are two destroys: step's one
        # and race.gui's one
        map(lambda txt: txt.destroy(), self.__res_txts)
        map(lambda btn: btn.destroy(), self.__buttons)
        self.result_frm.destroy()
 def destroy(self):
     if hasattr(self, 'reward'):
         self.info.destroy()
         del self.info
         del self.reward
         DirectFrame.destroy(self)
Esempio n. 34
0
class GUIFrame(GUIComponent):
    def __init__(self):
        GUIComponent.__init__(self)
        self.bg_color = (0, 0, 0, 0)
        self.bg_image = None
        self.padding = 0
        self.fit_width_to_content = False  # if the width should conform to the child
        self.fit_height_to_content = False  # if the height should conform to the child
        self.frame = None

    # Sets background color
    def set_bg_color(self, bg_color):
        self.bg_color = bg_color
        self.update()

    # Sets the background image
    def set_bg_image(self, image_path):
        image_folder_path = Path(
            path.realpath(__file__)).parent.parent.parent.parent / "res/images"
        self.bg_image = Filename(image_folder_path / image_path).cStr()
        self.update()

    # Default behavior is to fill in the bounding box with bg color
    def update(self):
        if self.frame is not None:
            # Set background color and texture
            self.frame["frameColor"] = self.bg_color
            if self.bg_image is not None:
                self.frame["frameTexture"] = self.bg_image

            # Set bbox
            x, y, width, height = GUIUtils.get_panda_coords(
                self.bbox.x, self.bbox.y, self.bbox.width, self.bbox.height)
            self.frame.setPos(x, 0, y)
            self.frame["frameSize"] = (-width / 2, width / 2, -height / 2,
                                       height / 2)
            self.frame.resetFrameSize()

            # Set up scissor test
            clip_x, clip_y, clip_w, clip_h = GUIUtils.get_panda_clip_coords(
                self.clip_region.x, self.clip_region.y, self.clip_region.width,
                self.clip_region.height)
            render_attrib = ScissorAttrib.make(
                LVector4f(clip_x, clip_x + clip_w, clip_y - clip_h, clip_y))
            self.frame.setAttrib(render_attrib)

            # Adjust child bbox
            if self.child is not None:
                self.child.bbox.x = self.bbox.x + self.padding
                self.child.bbox.y = self.bbox.y + self.padding
                if self.fit_width_to_content:
                    self.bbox.width = self.child.bbox.width + 2 * self.padding
                else:
                    self.child.bbox.width = self.bbox.width - 2 * self.padding
                if self.fit_height_to_content:
                    self.bbox.height = self.child.bbox.height + 2 * self.padding
                else:
                    self.child.bbox.height = self.bbox.height - 2 * self.padding

                self.child.set_clip_region(
                    self.clip_region.get_intersection(self.bbox))
                self.child.update()

    def add_render(self):
        self.rendering = True
        self.frame = DirectFrame(frameSize=(-1, 1, 1, -1))
        if self.child is not None:
            self.child.add_render()
        self.update()

    def stop_render(self):
        if self.rendering:
            self.frame.destroy()
            self.frame = None
        self.rendering = False
        if self.child is not None:
            self.child.stop_render()
        self.update()
Esempio n. 35
0
class SogalDialog(SogalForm):
    '''
    A dialog that derived from SogalForm
    (Which contains a DirectDialog)
    '''
    def __init__(self,
                 enableMask = True, #NOTE THAT IT IS TRUE BY DEFAULT
                 autoDestroy = True,
                 sortType = 0, #0 for horizontal, 1 for vertical
                 margin = 0.2,
                 textList = ['OK','Cancel'],
                 enablesList = None,
                 command = None,
                 frameSize = (-0.6,0.6,-0.45,0.45),
                 buttonSize = BUTTON_SIZE,
                 text = '',
                 textPos = (0,0.2),
                 startPos = (-0.4,0,-0.2),
                 extraArgs = [],
                 style = None,
                 fadeScreen = 0.5,
                 backgroundColor = None,
                 **kwargs):
        if backgroundColor:
            bgColor = backgroundColor
        elif fadeScreen is not None:
            bgColor = (0,0,0,fadeScreen)
        else:
            bgColor = None
        
        SogalForm.__init__(self,enableMask = enableMask,backgroundColor=bgColor, **kwargs)
        if enableMask:
            self.reparentTo(aspect2d, sort = 1000)
        if not style:
            self.__style = base.getStyle()
        else:
            self.__style = color_themes.styles[style]
        
        self.__frame = DirectFrame(parent = self,frameSize = frameSize,**self.__style['hardframe'])
        self.__buttonList = []#DirectButton(parent = self, s)
        self.__text = OnscreenText(parent = self,text = text ,pos = textPos, **self.__style['text'])
        self.__command = command
        self.__autoDestroy = autoDestroy
        self._extraArgs = extraArgs
        
        if sortType == 0:
            self.__box = HLayout(margin = margin)
        else: self.__box = VLayout(margin = margin)
        self.__box.reparentTo(self)
        self.__box.setPos(startPos)
        
        for i in range(len(textList)):
            btn = DirectButton(text = textList[i], command = self.buttonCommand(i),frameSize = buttonSize, **self.__style['button'])
            self.__buttonList.append(btn)
            self.__box.append(btn)
            
        if enablesList:
            for i in range(len(enablesList)):
                if i >= len(self.__buttonList):
                    break
                if enablesList[i]:
                    self.__buttonList[i]['state'] = DGG.NORMAL
                else: self.__buttonList[i]['state'] = DGG.DISABLED
                
        self.show()
        
    def buttonCommand(self, i):
        commandindex = i
        def process():
            if self.__command:
                self.__command(commandindex, *self._extraArgs)
            if self.__autoDestroy:
                self.close()
        return process

    def close(self):
        for btn in self.__buttonList:
            btn['state'] = DGG.DISABLED
        if self._getFading():
            seq = Sequence(Func(self.hide),
                           Wait(self._getFadingDuration()+2),
                           Func(self.destroy),
                           )
            seq.start()
        else: self.destroy()        
    
            
    def destroy(self):
        for btn in self.__buttonList:
            btn.destroy()
        self.__frame.destroy()
        self.__box.removeNode()
        SogalForm.destroy(self)