Browse Source

*** empty log message ***

David Rose 25 years ago
parent
commit
99a79420a6

+ 1 - 1
direct/src/directdevices/DirectJoybox.py

@@ -55,7 +55,7 @@ class DirectJoybox(PandaObject):
         self.refCS = direct.cameraControl.coaMarker
         self.tempCS = direct.group.attachNewNode('JoyboxTempCS')
         # Text object to display current mode
-        self.readout = OnscreenText.OnscreenText( '', -0.9, -0.95 )
+        self.readout = OnscreenText.OnscreenText( pos = (-0.9, -0.95) )
         # List of functions to cycle through
         self.modeList = [self.joeMode, self.driveMode, self.orbitMode]
         # Pick initial mode

+ 1 - 1
direct/src/directtools/DirectSession.py

@@ -45,7 +45,7 @@ class DirectSession(PandaObject):
         self.ancestry = []
         self.ancestryIndex = 0
 
-        self.readout = OnscreenText.OnscreenText( '', 0.1, -0.95 )
+        self.readout = OnscreenText.OnscreenText( pos = (0.1, -0.95) )
         # Make sure readout is never lit or drawn in wireframe
         useDirectRenderStyle(self.readout)
         # self.readout.textNode.setCardColor(0.5, 0.5, 0.5, 0.5)

+ 3 - 11
direct/src/gui/ForceAcknowledge.py

@@ -51,14 +51,9 @@ class ForceAcknowledge(StateData.StateData):
 	    return None
 
 	# create a message
-	self.text = OnscreenText.OnscreenText("", 0.0, 0.25)
-        self.text.freeze()
-	self.text.node().setAlign(0)
-	self.text.node().setTextColor(0.0, 0.0, 0.0, 1.0)
-	self.text.node().setFrameColor(1.0, 1.0, 1.0, 1.0)
-	self.text.setScale(0.08)
-        self.text.thaw()
-
+	self.text = OnscreenText.OnscreenText(parent = hidden,
+                                              scale = 0.08,
+                                              pos = (0.0, 0.25))
 	# create a button
 	self.okButton = Button.Button("ForceAcknowledge", "OK")
 	self.okButton.setPos(0.0, -0.5)
@@ -79,9 +74,6 @@ class ForceAcknowledge(StateData.StateData):
 	self.exit()
 
 	# GUI
-	self.text.removeNode()
-	self.text.cleanup()
-	self.text = None
 	self.okButton.cleanup()
 	self.okButton = None
 	self.isLoaded = 0

+ 3 - 0
direct/src/gui/Label.py

@@ -88,6 +88,9 @@ def textLabelAndText(string, style,
     elif style == ScrollItem:
         pass
 
+    else:
+        raise ValueError
+
 
     # Don't set the text until the very last thing, so the TextNode
     # has minimal work to do (even though it's frozen).

+ 203 - 38
direct/src/gui/OnscreenText.py

@@ -2,75 +2,240 @@
 
 from PandaObject import *
 from GuiGlobals import *
+import types
+
+## These are the styles of text we might commonly see.  They set the
+## overall appearance of the text according to one of a number of
+## pre-canned styles.  You can further customize the appearance of the
+## text by specifying individual parameters as well.
+Plain = 1
+ScreenTitle = 2
+ScreenPrompt = 3
+NameConfirm = 4
 
 class OnscreenText(PandaObject, NodePath):
 
-    def __init__(self, string, x=0.0, y=0.0, font=getDefaultFont()):
-        """__init__(self, string, float=0.0, float=0.0,
-        font=GuiGlobals.getDefaultFont())
-        Make a text node from string, put it into the 2d sg and place
-        it at x, y in screen space
+    def __init__(self, text = '',
+                 style = Plain,
+                 pos = (0, 0),
+                 scale = None,
+                 fg = None,
+                 bg = None,
+                 shadow = None,
+                 frame = None,
+                 align = None,
+                 wordwrap = None,
+                 drawOrder = getDefaultDrawOrder(),
+                 font = getDefaultFont(),
+                 parent = aspect2d):
+        """__init__(self, ...)
+
+        Make a text node from string, put it into the 2d sg and set it
+        up with all the indicated parameters.
+        
         """
-        # become one with our NodePath-ness
-        NodePath.__init__(self)
 
         # make a text node
-        self.textNode = textNode = TextNode()
+        textNode = TextNode()
+        self.textNode = textNode
+
+        # We ARE the node path that references this text node.
+        NodePath.__init__(self, parent.attachNewNode(textNode))
+
+        # Choose the default parameters according to the selected
+        # style.
+        if style == Plain:
+            scale = scale or 0.07
+            fg = fg or (0, 0, 0, 1)
+            bg = bg or (0, 0, 0, 0)
+            shadow = shadow or (0, 0, 0, 0)
+            frame = frame or (0, 0, 0, 0)
+            align = align or TMALIGNCENTER
+
+        elif style == ScreenTitle:
+            scale = scale or 0.15
+            fg = fg or (1, 0.2, 0.2, 1)
+            bg = bg or (0, 0, 0, 0)
+            shadow = shadow or (0, 0, 0, 1)
+            frame = frame or (0, 0, 0, 0)
+            align = align or TMALIGNCENTER
+
+        elif style == ScreenPrompt:
+            scale = scale or 0.1
+            fg = fg or (1, 1, 0, 1)
+            bg = bg or (0, 0, 0, 0)
+            shadow = shadow or (0, 0, 0, 1)
+            frame = frame or (0, 0, 0, 0)
+            align = align or TMALIGNCENTER
+
+        elif style == NameConfirm:
+            scale = scale or 0.1
+            fg = fg or (0, 1, 0, 1)
+            bg = bg or (0, 0, 0, 0)
+            shadow = shadow or (0, 0, 0, 0)
+            frame = frame or (0, 0, 0, 0)
+            align = align or TMALIGNCENTER
+
+        else:
+            raise ValueError
+
+        if not isinstance(scale, types.TupleType):
+            # If the scale is already a tuple, it's a 2-d (x,y) scale.
+            # Otherwise, it's a uniform scale--make it a tuple.
+            scale = (scale, scale)
+
+        # Save some of the parameters for posterity.
+        self.scale = scale
+        self.pos = pos
+        
         # Freeze the node while we set all the properties
         textNode.freeze()
-        textNode.setBillboard(0)
-        textNode.setTextColor(0.0, 0.0, 0.0, 1.0)
-        textNode.setCardColor(1.0, 1.0, 1.0, 1.0)
-        textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
-        # textNode.setFrameColor(0.0, 0.0, 0.0, 1.0)
-        # textNode.setFrameAsMargin(0.15, 0.15, 0.15, 0.15)
         textNode.setFont(font)
-        textNode.setText(string)
-        textNode.clearCardBorder()
-        textNode.clearFrame()
-        # Ok, now update the node
-        textNode.thaw()
+        textNode.setTextColor(fg[0], fg[1], fg[2], fg[3])
+        textNode.setAlign(align)
+
+        if wordwrap:
+            textNode.setWordwrap(wordwrap)
 
-        # put the text node into the 2d scene graph
-        textNodePath = render2d.attachNewNode(textNode)
+        if bg[3] != 0:
+            # If we have a background color, create a card.
+            textNode.setCardColor(bg[0], bg[1], bg[2], bg[3])
+            textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
 
-        # we ARE this node path
-        self.assign(textNodePath)
+        if shadow[3] != 0:
+            # If we have a shadow color, create a shadow.
+            textNode.setShadowColor(shadow[0], shadow[1], shadow[2], shadow[3])
+            textNode.setShadow(0.03, 0.03)
 
-        # position ourselves
-        self.setPos(x, y)
+        if frame[3] != 0:
+            # If we have a frame color, create a frame.
+            textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
+            textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
 
-        self.setScale(0.069)
+        # Create a transform for the text for our scale and position.
+        # We'd rather do it here, on the text itself, rather than on
+        # our NodePath, so we have one fewer transforms in the scene
+        # graph.
+        mat = Mat4.scaleMat(scale[0], 1, scale[1]) * Mat4.translateMat(pos[0], 0, pos[1])
+        textNode.setTransform(mat)
+
+        textNode.setBin('fixed')
+        textNode.setDrawOrder(drawOrder)
+
+        textNode.setText(text)
+
+        # Ok, now update the node
+        textNode.thaw()
 	self.isClean = 0
-	return None
 
+    def __del__(self):
+        # Make sure the node is removed when we delete the
+        # OnscreenText object.  This means we don't have to explicitly
+        # remove an OnscreenText object; it can do it by itself.
+        # Maybe this will be too confusing because we *do* have to
+        # explicitly remove other kinds of onscreen objects.
+        self.cleanup()
+    
     def cleanup(self):
 	"""cleanup(self)
 	"""
 	self.textNode = None
 	if self.isClean == 0:
 	    self.isClean = 1
+            if self.hasArcs():
+                self.removeNode()
        	    NodePath.__del__(self) 
-	return None
 
     def freeze(self):
         self.textNode.freeze()
 
     def thaw(self):
         self.textNode.thaw()
- 
-    def setText(self, string):
-        """setText(self, string)
-        Set the text of the onscreen text
-        """
-        self.node().setText(string)
+
+    # Allow changing of several of the parameters after the text has
+    # been created.  These should be used with caution; it is better
+    # to set all the parameters up front.  These functions are
+    # primarily intended for interactive placement of the initial
+    # text, and for those rare occasions when you actually want to
+    # change a text's property after it has been created.
+
+    # If you need to change several properties at the same time at
+    # runtime, you should call freeze() first and thaw() afterward.
+
+    def setText(self, text):
+        self.textNode.setText(text)
         
     def setPos(self, x, y):
         """setPos(self, float, float)
         Position the onscreen text in 2d screen space
         """
-        # render2d has x across and z up
-        NodePath.setPos(self, x, 0.0, y)
+        self.pos = (x, y)
+        mat = Mat4.scaleMat(self.scale[0], 1, self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
+        self.textNode.setTransform(mat)
+
+    def getPos(self):
+        return self.pos
+        
+    def setScale(self, sx, sy = None):
+        """setScale(self, float, float)
+        Scale the text in 2d space.  You may specify either a single
+        uniform scale, or two scales, or a tuple of two scales.
+        """
+
+        if sy == None:
+            if isinstance(sx, types.TupleType):
+                self.scale = sx
+            else:
+                self.scale = (sx, sx)
+        else:
+            self.scale = (sx, sy)
+        mat = Mat4.scaleMat(self.scale[0], 1, self.scale[1]) * Mat4.translateMat(self.pos[0], 0, self.pos[1])
+        self.textNode.setTransform(mat)
 
-    def setColor(self, color):
-        self.textNode.setCardColor(color[0],color[1],color[2],color[3])
+    def getScale(self):
+        if self.scale[0] == self.scale[1]:
+            return self.scale[0]
+        else:
+            return self.scale
+        
+    def setWordwrap(self, wordwrap):
+        if wordwrap:
+            self.textNode.setWordwrap(wordwrap)
+        else:
+            self.textNode.clearWordwrap()
+        
+    def setFg(self, fg):
+        self.textNode.setTextColor(fg[0], fg[1], fg[2], fg[3])
+
+    def setBg(self, bg):
+        self.textNode.freeze()
+        if bg[3] != 0:
+            # If we have a background color, create a card.
+            self.textNode.setCardColor(bg[0], bg[1], bg[2], bg[3])
+            self.textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
+        else:
+            # Otherwise, remove the card.
+            self.textNode.clearCard()
+        self.textNode.thaw()
+
+    def setShadow(self, shadow):
+        self.textNode.freeze()
+        if shadow[3] != 0:
+            # If we have a shadow color, create a shadow.
+            self.textNode.setShadowColor(shadow[0], shadow[1], shadow[2], shadow[3])
+            self.textNode.setShadow(0.03, 0.03)
+        else:
+            # Otherwise, remove the shadow.
+            self.textNode.clearShadow()
+        self.textNode.thaw()
+
+    def setFrame(self, frame):
+        self.textNode.freeze()
+        if frame[3] != 0:
+            # If we have a frame color, create a frame.
+            self.textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
+            self.textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
+        else:
+            # Otherwise, remove the frame.
+            self.textNode.clearFrame()
+        self.textNode.thaw()

+ 4 - 2
direct/src/leveleditor/LevelEditor.py

@@ -2838,7 +2838,7 @@ class LevelStyleManager:
         # Attach the color chips to the new menu and adjust sizes
         for i in range (numItems):
             # Create the node and set its color
-            node = OnscreenText('    ', 0.0, 0.0)
+            node = OnscreenText('    ')
             node.setColor(colorList[i])
             bounds = node.getBounds()
             center = bounds.getCenter()
@@ -2944,7 +2944,7 @@ class LevelStyleManager:
         for i in range (numItems):
             # Create onscreen text node for each item
             if (textList[i] != None):
-                node = OnscreenText(str(textList[i]),0,0)
+                node = OnscreenText(str(textList[i]))
             else:
                 node = None
             if node:
@@ -2952,10 +2952,12 @@ class LevelStyleManager:
                 bounds = node.getBounds()
                 center = bounds.getCenter()
                 center = center * (sf * node.getScale()[0])
+                node.freeze()
                 node.setPos(radius * math.cos(i * angle) - center[0],
                             ((radius * aspectRatio * math.sin(i * angle)) -
                              center[2]))
                 node.setScale(node.getScale() * sf)
+                node.thaw()
                 # Add it to the newMenu
                 node.reparentTo(newMenu)
         # Scale the whole shebang down by 0.5