def test_entry_auto_capitalize(): # Now we can generate the DirectEntry component itself. In normal use, we # would pass "autoCapitalize=1" to DirectEntry's constructor in order for # DirectEntry._autoCapitalize() to be called upon typing into the entry # GUI, however in the case of this unit test where there is no GUI to type # into, we don't need to bother doing that; we're just calling the function # ourselves anyway. entry = DirectEntry() # Test DirectEntry._autoCapitalize(). The intended behavior would be that # the first letter of each word in the entry would be capitalized, so that # is what we will check for: entry.set('auto capitalize test') entry._autoCapitalize() assert entry.get() == 'Auto Capitalize Test' # Test DirectEntry._autoCapitalize() with a unicode object this time. entry.set(u'àütò çapítalízè ţèsţ') assert entry.get() == u'àütò çapítalízè ţèsţ' entry._autoCapitalize() assert entry.get() == u'Àütò Çapítalízè Ţèsţ' # Also test it with a UTF-8 encoded byte string in Python 2. if sys.version_info < (3, 0): entry.set(u'àütò çapítalízè ţèsţ'.encode('utf-8')) assert entry.get() == u'àütò çapítalízè ţèsţ' entry._autoCapitalize() assert entry.get() == u'Àütò Çapítalízè Ţèsţ'
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()
def test_entry_get(): entry = DirectEntry() assert isinstance(entry.get(), str)
class Menu: def __init__(self, otherProperties, baseClass): self.text_pointers = [] self.keyboard = Controller() self.IsFullScreen = False self.others = otherProperties self.baseClass = baseClass def __del__(self): print('Destructor called') def start(self): self.fullScreenShape = loader.loadModel("models/fullscreen_shape.bam") self.fullScreenShape.reparentTo(render) self.fullScreenShape.setScale(0.25, 0.25, 0.25) self.fullScreenShape.setPos(-1.5, 6, -1) self.fondo = loader.loadModel("models/fondo_menu.bam") self.fondo.reparentTo(render) self.fondo.setScale(0.27, 0.01, 0.32) self.fondo.setPos(0, 7, 0) font = loader.loadFont('./fonts/comic/comic.ttf') self.TextInsertName = OnscreenText(font=font, text='Ingrese su nombre:', pos=(-0.5, 0.02), scale=0.07, fg=(143 / 255, 250 / 255, 2 / 255, 1)) self.TextFullScreen = OnscreenText(font=font, text='Fulscreen:', pos=(-0.99, -0.67), scale=0.04, fg=(143 / 255, 250 / 255, 2 / 255, 1)) self.TextInsertNameInput = DirectEntry(text="", scale=.05, numLines=1, focus=1) self.ButtonInsertName = DirectButton(text=("Insertar nombre"), scale=.05, pos=(0.25, 0, -0.10), command=self.make_player) self.InvisibleButton = DirectButton(text=("*"), scale=.05, pos=(-1, 5, -0.73), command=self.setFullScreen) self.InvisibleButton.bind(WITHIN, command=self.mouseOver) self.fullScreenShape.reparentTo(render) self.fondo.reparentTo(render) self.TextInsertNameInput.show() self.fullScreenShape.show() self.fondo.show() self.TextInsertName.show() self.TextFullScreen.show() self.ButtonInsertName.show() self.InvisibleButton.show() def stop(self): self.fullScreenShape.hide() self.fondo.remove_node() self.TextInsertName.hide() self.TextFullScreen.hide() self.ButtonInsertName.hide() self.InvisibleButton.hide() self.TextInsertNameInput.hide() self.keyboard.press('3') self.keyboard.release('3') self.__del__() def mouseOver(self, argumento): rotation_interval = self.fullScreenShape.hprInterval( 10, Vec3(360, 0, 0)) rotation_interval.start() def setFullScreen(self): props = self.others if (self.IsFullScreen == True): props.fullscreen = False self.IsFullScreen = False else: props.fullscreen = True self.IsFullScreen = True self.baseClass.win.requestProperties(props) def make_player(self): self.player = player.Player(self.TextInsertNameInput.get()) self.player.savefile() self.stop()
class PathSelect(DirectObject): def __init__(self, command, headerText, actionText, affirmText, filePath, tooltip): self.command = command self.darkenFrame = DirectFrame( relief=1, frameSize=(0, base.getSize()[0], -base.getSize()[1], 0), frameColor=(0, 0, 0, 0.45), state=DGG.NORMAL, parent=base.pixel2d, ) self.mainFrame = DirectFrame( relief=1, frameSize=(-300, 300, -150, 150), frameColor=(1, 1, 1, 1), pos=LPoint3f(base.getSize()[0] / 2, 0, -base.getSize()[1] / 2), parent=base.pixel2d, ) # Header headerFrame = DirectFrame( parent=self.mainFrame, relief=1, frameSize=(-300, 300, -20, 20), frameColor=(0.25, 0.25, 0.25, 1.0), pos=LPoint3f(0, 0, 130), scale=LVecBase3f(1, 0.1, 1), ) DirectLabel( parent=headerFrame, frameColor=(0.8, 0.8, 0.8, 0.0), pos=LPoint3f(-295, 0, -5), text=headerText, text_align=0, text_fg=(1, 1, 1, 1), scale=16, ) # Entry DirectLabel( parent=self.mainFrame, frameColor=(0.8, 0.8, 0.8, 0.0), pos=LPoint3f(-250, 0, 0), scale=12, text=actionText, text_align=0, ) self.pathEntry = DirectEntry(parent=self.mainFrame, relief=DGG.SUNKEN, frameColor=(1, 1, 1, 1), pad=(0.2, 0.2), pos=LPoint3f(-250, 0, -20), scale=12, width=(500 - 90) / 12, overflow=True, command=self.entryCommandHandler, initialText=filePath) 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(235, 0, -20), text="Browse", text_scale=12, command=self.browse, ) self.browser = DirectFolderBrowser(self.selectPath, True, os.path.dirname(filePath), os.path.split(filePath)[1], tooltip=tooltip) self.browser.hide() # Command Buttons 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(140, 0, -135), text=affirmText, text_scale=12, command=command, extraArgs=[1], ) 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(245, 0, -135), text="Cancel", text_scale=12, command=command, extraArgs=[0]) # handle window resizing self.prevScreenSize = base.getSize() self.accept("window-event", self.windowEventHandler) self.accept("escape", command, extraArgs=[0]) def browse(self): self.browser.show() def selectPath(self, confirm): if confirm: self.pathEntry.set(self.browser.get()) self.browser.hide() def entryCommandHandler(self, text): self.command(1) def destroy(self): self.ignoreAll() self.browser.destroy() self.darkenFrame.destroy() self.mainFrame.destroy() def getPath(self): return self.pathEntry.get() 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() screenWidthPx = base.getSize()[0] screenHeightPx = base.getSize()[1] self.mainFrame.setPos(screenWidthPx / 2, 0, -screenHeightPx / 2) self.darkenFrame["frameSize"] = (0, screenWidthPx, -screenHeightPx, 0)
class DriverPageGui(ThanksPageGui): def __init__(self, mdt, menu_args, driverpage_props): self.props = driverpage_props ThanksPageGui.__init__(self, mdt, menu_args) def bld_page(self): self.skills = [drv[2] for drv in self.props.drivers] menu_gui = self.mdt.menu.gui menu_args = self.mdt.menu.gui.menu_args widgets = [ OnscreenText(text=_('Select the driver'), pos=(0, .8), **menu_gui.menu_args.text_args) ] self.track_path = self.mdt.menu.track t_a = self.mdt.menu.gui.menu_args.text_args.copy() del t_a['scale'] name = OnscreenText(_('Write your name:'), pos=(-.1, .6), scale=.06, align=TextNode.A_right, **t_a) self.ent = DirectEntry(scale=.08, pos=(0, 1, .6), entryFont=menu_args.font, width=12, frameColor=menu_args.btn_color, initialText=self.props.player_name or _('your name')) self.ent.onscreenText['fg'] = menu_args.text_fg self.drivers = [] for row, col in product(range(2), range(4)): idx = (col + 1) + row * 4 widgets += [ ImgBtn(scale=.24, pos=(-.75 + col * .5, 1, .25 - row * .5), frameColor=(0, 0, 0, 0), image=self.props.drivers_img[0] % idx, command=self.on_click, extraArgs=[idx], **self.mdt.menu.gui.menu_args.imgbtn_args) ] self.drivers += [widgets[-1]] sign = lambda x: '\1green\1+\2' if x > 0 else '' psign = lambda x: '+' if x == 0 else sign(x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) def add_lab(txt, pos_z): return OnscreenText(txt + ':', pos=(-.95 + col * .5, pos_z - row * .5), scale=.046, align=TextNode.A_left, **t_a) def add_txt(val, pos_z): return OnscreenText('%s%s%%' % (psign(val), pcol(val)), pos=(-.55 + col * .5, pos_z - row * .5), scale=.052, align=TextNode.A_right, **t_a) lab_lst = [(_('adherence'), .04), (_('speed'), .16), (_('stability'), .1)] widgets += map(lambda lab_def: add_lab(*lab_def), lab_lst) txt_lst = [(self.skills[idx - 1][1], .04), (self.skills[idx - 1][0], .16), (self.skills[idx - 1][2], .1)] widgets += map(lambda txt_def: add_txt(*txt_def), txt_lst) self.img = OnscreenImage(self.props.cars_img % self.mdt.car, parent=base.a2dBottomRight, pos=(-.38, 1, .38), scale=.32) widgets += [self.img, name, self.ent] map(self.add_widget, widgets) fpath = eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(fpath) as ffilter: vert = ffilter.read() shader = Shader.make(Shader.SL_GLSL, vert, frag) self.img.setShader(shader) self.img.setTransparency(True) self.t_s = TextureStage('ts') self.t_s.setMode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.img.setTexture(self.t_s, tex) ThanksPageGui.bld_page(self) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False) def enable_buttons(self, enable): for drv in self.drivers: drv['state'] = NORMAL if enable else DISABLED drv.setShaderInput('enable', 1 if enable else .2) # do wdg.enable, wdg.disable def update_text(self, task): has_name = self.ent.get() != _('your name') if has_name and self.ent.get().startswith(_('your name')): self.ent.enterText(self.ent.get()[len(_('your name')):]) self.enable_buttons(True) elif self.ent.get() in [_('your name')[:-1], '']: self.ent.enterText('') self.enable_buttons(False) elif self.ent.get() not in [_('your name'), '']: self.enable_buttons(True) return task.cont # don't do a task, attach to modifications events def on_click(self, i): txt_path = self.props.drivers_img[1] self.img.setTexture(self.t_s, loader.loadTexture(txt_path % i)) self.widgets[-1]['state'] = DISABLED self.enable_buttons(False) taskMgr.remove(self.update_tsk) names = Utils().get_thanks(6) cars = self.props.cars[:] cars.remove(self.mdt.car) shuffle(cars) drv_idx = range(1, 9) drv_idx.remove(i) shuffle(drv_idx) drivers = [(i, self.ent.get(), self.skills[i - 1], self.mdt.car)] drivers += [(drv_idx[j], names[j], self.skills[j - 1], cars[j]) for j in range(6)] self.mdt.menu.gui.notify('on_driver_selected', self.ent.get(), drivers, self.mdt.track, self.mdt.car) def destroy(self): self.img = None taskMgr.remove(self.update_tsk) PageGui.destroy(self)
class DirectFolderBrowser(DirectObject): def __init__(self, command, fileBrowser=False, defaultPath="~", defaultFilename="unnamed.txt", fileExtensions=[], tooltip=None, iconDir=None, parent=None, theme=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 iconDir: A directory path that contains replacement images. It must contain all required images which are: File.png Folder.png FolderNew.png FolderShowHidden.png FolderUp.png Reload.png parent: Another DirectGUI element which has pixel2d as root parent. The browser frame is placed centered so a frame for example should have equal sizes in horizontal and vertical directions e.g. frameSize=(-250,250,-200,200) """ self.theme = theme if theme is not None else LightTheme() self.tt = tooltip self.command = command self.showFiles = fileBrowser self.fileExtensions = fileExtensions self.showHidden = False self.parent = parent self.imageOpts = LoaderOptions() self.imageOpts.set_auto_texture_scale(ATS_none) if self.theme.icon_dir is not None: self.iconDir = self.theme.icon_dir elif iconDir is None: fn = Filename.fromOsSpecific(os.path.dirname(__file__)) fn.makeTrueCase() self.iconDir = str(fn) + "/icons" else: self.iconDir = iconDir self.selectedViewType = "Symbol" self.currentPath = os.path.expanduser(defaultPath) if not os.path.exists(self.currentPath): self.currentPath = os.path.expanduser("~") self.previousPath = self.currentPath if self.parent is None: self.parent = base.pixel2d self.screenWidthPx = base.getSize()[0] self.screenHeightPx = base.getSize()[1] self.position = LPoint3f(base.getSize()[0] / 2, 0, -base.getSize()[1] / 2) else: self.screenWidthPx = self.parent.getWidth() self.screenHeightPx = self.parent.getHeight() self.position = LPoint3f(0) self.screenWidthPxHalf = self.screenWidthPx * 0.5 self.screenHeightPxHalf = self.screenHeightPx * 0.5 self.mainFrame = DirectFrame( relief=1, frameSize=(-self.screenWidthPxHalf, self.screenWidthPxHalf, -self.screenHeightPxHalf, self.screenHeightPxHalf), frameColor=self.theme.main_background, pos=self.position, parent=self.parent, state=DGG.NORMAL, ) self.pathRightMargin = 155 # NOTE: Add 28 for each button to the right + 15px margin self.pathEntryWidth = self.screenWidthPx - self.pathRightMargin - 28 # The path entry on top of the window self.pathEntry = DirectEntry( text_fg=self.theme.default_text_color, parent=self.mainFrame, relief=DGG.SUNKEN, frameColor=self.theme.entry_background, 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"], ) # ---------------- # CONTROL BUTTONS # ---------------- x = self.screenWidthPxHalf - self.pathRightMargin + 18 # RELOAD self.btnReload = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.icon_button_background, frameSize=(-14, 14, -10, 18), pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25), command=self.folderReload, image=loader.load_texture(f"{self.iconDir}/Reload.png", loaderOptions=self.imageOpts), 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) # MOVE UP ONE FOLDER x += 28 self.btnFolderUp = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.icon_button_background, frameSize=(-14, 14, -10, 18), pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25), command=self.folderUp, image=loader.load_texture(f"{self.iconDir}/FolderUp.png", loaderOptions=self.imageOpts), 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) # CREATE NEW FOLDER x += 28 self.btnFolderNew = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.icon_button_background, frameSize=(-14, 14, -10, 18), pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25), command=self.folderNew, image=loader.load_texture(f"{self.iconDir}/FolderNew.png", loaderOptions=self.imageOpts), 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) # SHOW HIDDEN FOLDERS x += 28 self.btnFolderShowHidden = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.icon_button_background, frameSize=(-14, 14, -10, 18), pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25), command=self.folderShowHidden, image=loader.load_texture(f"{self.iconDir}/FolderShowHidden.png", loaderOptions=self.imageOpts), 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) # TOGGLE VIEW TYPE x += 28 self.btnViewType = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.icon_button_background, frameSize=(-14, 14, -10, 18), pos=LPoint3f(x, 0, self.screenHeightPxHalf - 25), command=self.toggleViewType, image=loader.load_texture(f"{self.iconDir}/ViewTypeSymbol.png", loaderOptions=self.imageOpts), image_scale=14, image_pos=(0, 0, 4), ) self.btnViewType.setTransparency(TransparencyAttrib.M_multisample) if self.tt is not None: self.btnViewType.bind( DGG.ENTER, self.tt.show, ["Toggle view between Symbols and Detail list"]) self.btnViewType.bind(DGG.EXIT, self.tt.hide) # -------------- # CONTENT FRAME # -------------- color = self.theme.scrollbar_controlls_color self.container = DirectScrolledFrame( relief=DGG.RIDGE, borderWidth=(2, 2), frameColor=self.theme.main_background, 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, verticalScroll_frameColor=self.theme.scroll_background, 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, horizontalScroll_frameColor=self.theme.scroll_background, state=DGG.NORMAL, ) self.container.bind(DGG.MWDOWN, self.scroll, [0.01]) self.container.bind(DGG.MWUP, self.scroll, [-0.01]) # ACCEPT BUTTON self.btnOk = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.text_button_background, frameSize=(-45, 45, -6, 14), pos=LPoint3f(self.screenWidthPxHalf - 160, 0, -self.screenHeightPxHalf + 25), text="ok", text_scale=12, text_fg=self.theme.default_text_color, command=command, extraArgs=[1], ) # CANCEL BUTTON self.btnCancel = DirectButton( parent=self.mainFrame, relief=1, frameColor=self.theme.text_button_background, frameSize=(-45, 45, -6, 14), pos=LPoint3f(self.screenWidthPxHalf - 55, 0, -self.screenHeightPxHalf + 25), text="Cancel", text_scale=12, text_fg=self.theme.default_text_color, command=command, extraArgs=[0]) # SELECTED FILE ENTRY FIELD if self.showFiles: self.txtFileName = DirectEntry( text_fg=self.theme.default_text_color, parent=self.mainFrame, relief=DGG.SUNKEN, frameColor=self.theme.entry_background, 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"], ) # ------------------ # CREATE NEW FOLDER # ------------------ # FRAME FOR CREATING NEW FOLDER 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=self.theme.popup_frame_background, ) # LABEL FOR NEW FOLDER NAME ENTRY self.txtNewFolderName = DirectLabel( parent=self.newFolderFrame, text="New Folder Name", text_scale=12, text_fg=self.theme.default_text_color, frameColor=(0, 0, 0, 0), text_align=TextNode.ALeft, pos=(-self.screenWidthPxHalf + 15, 0, -3), ) # ENTRY FOR THE NEW FOLDER NAME self.folderName = DirectEntry( text_fg=self.theme.default_text_color, parent=self.newFolderFrame, relief=DGG.SUNKEN, frameColor=self.theme.entry_background, 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"], ) # ACCEPT BUTTON FOR THE CREATE NEW FOLDER self.btnCreate = DirectButton( parent=self.newFolderFrame, relief=1, frameColor=self.theme.text_button_background, frameSize=(-45, 45, -6, 14), pos=LPoint3f(self.screenWidthPxHalf - 65, 0, -4), text="Create", text_scale=12, text_fg=self.theme.default_text_color, command=self.folderCreate, extraArgs=[0]) # Hide the create new folder frame by default self.newFolderFrame.hide() # --------------- # UPDATE CONTENT # --------------- # Initial loading of the files and folders of the current path self.folderReload() # handle window resizing self.prevScreenSize = base.getSize() if self.parent is base.pixel2d: self.accept("window-event", self.windowEventHandler) def show(self): self.mainFrame.show() if self.parent is None: 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 VIEWTYPE[self.selectedViewType](self, content) 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 toggleViewType(self): if self.selectedViewType == "Symbol": self.selectedViewType = "Detail" self.btnViewType["image"] = loader.load_texture( f"{self.iconDir}/ViewTypeDetail.png", loaderOptions=self.imageOpts) else: self.selectedViewType = "Symbol" self.btnViewType["image"] = loader.load_texture( f"{self.iconDir}/ViewTypeSymbol.png", loaderOptions=self.imageOpts) 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 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 - 28 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.screenWidthPxHalf - self.pathRightMargin + 14 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)) x += 28 self.btnViewType.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()