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

Closes #776

Co-authored-by: rdb <git@rdb.name>
This commit is contained in:
max 2019-12-11 17:57:15 +01:00 committed by rdb
parent 49f423822d
commit 2ca37b8c97

View File

@ -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)