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()
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)
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
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()
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)
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
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()
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)
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)
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 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()
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")
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)
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()
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()
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()
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()
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
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)
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()
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)
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()
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)
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()
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)