Procházet zdrojové kódy

dgui: refactor code common to DirectFrame setGeom, setImage, setText

Closes #776

Co-authored-by: rdb <[email protected]>
max před 6 roky
rodič
revize
2ca37b8c97
1 změnil soubory, kde provedl 76 přidání a 131 odebrání
  1. 76 131
      direct/src/gui/DirectFrame.py

+ 76 - 131
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
-
-        # 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']
+            self["text"] = text
+
+        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]
-
-            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,
-                        )
+            text_list = text
+
+        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
-
-        # 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']
+            self["geom"] = geom
+
+        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
-
-        # 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)
+            geom_list = geom
+
+        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
-
-        # 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']
+            self["image"] = image
+
+        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]
-
-            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)
+            image_list = image
+
+        self.__reinitComponent("image", OnscreenImage, image_list,
+            scale=1,
+            sort=DGG.IMAGE_SORT_INDEX)