diff --git a/direct/src/gui/DirectFrame.py b/direct/src/gui/DirectFrame.py index 19e8717ba6..bcf1f32232 100644 --- a/direct/src/gui/DirectFrame.py +++ b/direct/src/gui/DirectFrame.py @@ -23,6 +23,7 @@ from . import DirectGuiGlobals as DGG from .DirectGuiBase import * from .OnscreenImage import OnscreenImage from .OnscreenGeom import OnscreenGeom +from .OnscreenText import OnscreenText import sys if sys.version_info >= (3, 0): @@ -33,7 +34,8 @@ else: class DirectFrame(DirectGuiWidget): DefDynGroups = ('text', 'geom', 'image') - def __init__(self, parent = None, **kw): + + def __init__(self, parent=None, **kw): # Inherits from DirectGuiWidget optiondefs = ( # Define type of DirectGuiWidget @@ -50,10 +52,10 @@ class DirectFrame(DirectGuiWidget): # Change default value of text mayChange flag from 0 # (OnscreenText.py) to 1 ('textMayChange', 1, None), - ) + ) # Merge keyword options with default options self.defineoptions(kw, optiondefs, - dynamicGroups = DirectFrame.DefDynGroups) + dynamicGroups=DirectFrame.DefDynGroups) # Initialize superclasses DirectGuiWidget.__init__(self, parent) @@ -61,8 +63,37 @@ class DirectFrame(DirectGuiWidget): # Call option initialization functions self.initialiseoptions(DirectFrame) - def destroy(self): - DirectGuiWidget.destroy(self) + def __reinitComponent(self, name, component_class, states, **kwargs): + """Recreates the given component using the given keyword args.""" + assert name in ("geom", "image", "text") + + if len(states) != self['numStates']: + raise ValueError + + # constants should be local to or default arguments of constructors + for c in range(self['numStates']): + component_name = name + str(c) + state = states[c] + + if self.hascomponent(component_name): + if state is None: + self.destroycomponent(component_name) + else: + self[component_name + "_" + name] = state + else: + if state is None: + return + + kwargs[name] = state + self.createcomponent( + component_name, + (), + name, + component_class, + (), + parent=self.stateNodePath[c], + **kwargs + ) def clearText(self): self['text'] = None @@ -70,45 +101,18 @@ class DirectFrame(DirectGuiWidget): def setText(self, text=None): if text is not None: - self['text'] = text + self["text"] = text - # Determine if user passed in single string or a sequence - if self['text'] == None: - textList = (None,) * self['numStates'] - elif isinstance(self['text'], stringType): - # If just passing in a single string, make a tuple out of it - textList = (self['text'],) * self['numStates'] + text = self["text"] + if text is None or isinstance(text, stringType): + text_list = (text,) * self['numStates'] else: - # Otherwise, hope that the user has passed in a tuple/list - textList = self['text'] - # Create/destroy components - for i in range(self['numStates']): - component = 'text' + repr(i) - # If fewer items specified than numStates, - # just repeat last item - try: - text = textList[i] - except IndexError: - text = textList[-1] + text_list = text - if self.hascomponent(component): - if text == None: - # Destroy component - self.destroycomponent(component) - else: - self[component + '_text'] = text - else: - if text == None: - return - else: - from .OnscreenText import OnscreenText - self.createcomponent( - component, (), 'text', - OnscreenText, - (), parent = self.stateNodePath[i], - text = text, scale = 1, mayChange = self['textMayChange'], - sort = DGG.TEXT_SORT_INDEX, - ) + self.__reinitComponent("text", OnscreenText, text_list, + scale=1, + mayChange=self['textMayChange'], + sort=DGG.TEXT_SORT_INDEX) def clearGeom(self): self['geom'] = None @@ -116,48 +120,19 @@ class DirectFrame(DirectGuiWidget): def setGeom(self, geom=None): if geom is not None: - self['geom'] = geom + self["geom"] = geom - # Determine argument type - geom = self['geom'] - - if geom == None: - # Passed in None - geomList = (None,) * self['numStates'] - elif isinstance(geom, NodePath) or \ - isinstance(geom, stringType): - # Passed in a single node path, make a tuple out of it - geomList = (geom,) * self['numStates'] + geom = self["geom"] + if geom is None or \ + isinstance(geom, NodePath) or \ + isinstance(geom, stringType): + geom_list = (geom,) * self['numStates'] else: - # Otherwise, hope that the user has passed in a tuple/list - geomList = geom + geom_list = geom - # Create/destroy components - for i in range(self['numStates']): - component = 'geom' + repr(i) - # If fewer items specified than numStates, - # just repeat last item - try: - geom = geomList[i] - except IndexError: - geom = geomList[-1] - - if self.hascomponent(component): - if geom == None: - # Destroy component - self.destroycomponent(component) - else: - self[component + '_geom'] = geom - else: - if geom == None: - return - else: - self.createcomponent( - component, (), 'geom', - OnscreenGeom, - (), parent = self.stateNodePath[i], - geom = geom, scale = 1, - sort = DGG.GEOM_SORT_INDEX) + self.__reinitComponent("geom", OnscreenGeom, geom_list, + scale=1, + sort=DGG.GEOM_SORT_INDEX) def clearImage(self): self['image'] = None @@ -165,51 +140,21 @@ class DirectFrame(DirectGuiWidget): def setImage(self, image=None): if image is not None: - self['image'] = image + self["image"] = image - # Determine argument type - arg = self['image'] - if arg == None: - # Passed in None - imageList = (None,) * self['numStates'] - elif isinstance(arg, NodePath) or \ - isinstance(arg, Texture) or \ - isinstance(arg, stringType): - # Passed in a single node path, make a tuple out of it - imageList = (arg,) * self['numStates'] + image = self["image"] + if image is None or \ + isinstance(image, NodePath) or \ + isinstance(image, Texture) or \ + isinstance(image, stringType) or \ + isinstance(image, Filename) or \ + (len(image) == 2 and \ + isinstance(image[0], stringType) and \ + isinstance(image[1], stringType)): + image_list = (image,) * self['numStates'] else: - # Otherwise, hope that the user has passed in a tuple/list - if ((len(arg) == 2) and - isinstance(arg[0], stringType) and - isinstance(arg[1], stringType)): - # Its a model/node pair of strings - imageList = (arg,) * self['numStates'] - else: - # Assume its a list of node paths - imageList = arg - # Create/destroy components - for i in range(self['numStates']): - component = 'image' + repr(i) - # If fewer items specified than numStates, - # just repeat last item - try: - image = imageList[i] - except IndexError: - image = imageList[-1] + image_list = image - if self.hascomponent(component): - if image == None: - # Destroy component - self.destroycomponent(component) - else: - self[component + '_image'] = image - else: - if image == None: - return - else: - self.createcomponent( - component, (), 'image', - OnscreenImage, - (), parent = self.stateNodePath[i], - image = image, scale = 1, - sort = DGG.IMAGE_SORT_INDEX) + self.__reinitComponent("image", OnscreenImage, image_list, + scale=1, + sort=DGG.IMAGE_SORT_INDEX)