Hi all,
I am preparing a dialog system for an adventure game and
I needed a way of changing the color of a text and clicking on a
text. DirectButton and onScreenText did not allow me to do that, or
I did not find how to do it. So, I looked for another solution:
import sys
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.DirectGui import *
from direct.task import Task
from direct.showbase import DirectObject
class Rectangle:
def __init__(self):
self.data = [0, 0, 0, 0]
def set(self, x1, y1, x2, y2):
self.data[0] = x1
self.data[1] = y1
self.data[2] = x2
self.data[3] = y2
def isInto(self, position):
if not isinstance(position, Point3):
raise "Position parameter is not of Point3 type"
if (self.data[0] < position.getX() and position.getX() < self.data[2]) \
and (self.data[1] < position.getY() and position.getY() < self.data[3]):
return True
else:
return False
def __str__(self):
return "Rectangle: [%f, %f - %f, %f]" % \
(self.data[0],self.data[1],self.data[2],self.data[3])
text = TextNode('node name')
text.setText("Every day in every way I'm getting better and better.")
text.setTextColor(1, 0.5, 0.5, 1)
text.setWordwrap(10.0) # In screen units
text.setAlign(TextNode.ACenter)
# TextNode.ALeft, TextNode.ACenter, or TextNode.ARight
text.setFrameColor(0, 0, 1, 1)
text.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
# left, right, bottom, top
#text.setFrameActual(-0.1, 16.0, -1.0, 0.2)
#Show in the screen
textNodePath = aspect2d.attachNewNode(text)
# By default scale = 1.0
myScale = 0.07
textNodePath.setScale(myScale)
textNodePath.setPos(0.0, 0.0, 0.0)
box = text.getFrameActual()
## print box
## print "get.isFrameAsMargin() = ",text.isFrameAsMargin()
## print "get.frameAsSet() = ", text.getFrameAsSet()
rec = Rectangle()
l = box[0]
r = box[1]
b = box[2]
t = box[3]
#rec.set(l, b, r, t)
#print rec
# Position of the frame in rende2d coordinates space
ll = render2d.getRelativePoint(textNodePath, Point3(l, 0, b))
ur = render2d.getRelativePoint(textNodePath, Point3(r, 0, t))
#rec.set(ll[0], ll[2], ur[0], ur[2])
rec.set(ll.getX(), ll.getZ(), ur.getX(), ur.getZ())
#print rec
p1 = OnscreenText(text = 'll',
pos = (box[0] * myScale, box[2] * myScale),
scale = myScale)
p2 = OnscreenText(text = 'ur',
pos = (box[1] * myScale, box[3] * myScale),
scale = myScale)
# It returns the coordinates of the mouse in the render2d
# coordinates space
def getMousePosition():
p = None
if base.mouseWatcherNode.hasMouse():
x=base.mouseWatcherNode.getMouseX()
y=base.mouseWatcherNode.getMouseY()
# Set as Rectangle class expected it
p = Point3(x,y,0)
# Convert to aspect2d
#p1 = aspect2d.getRelativePoint(render2d, p)
#print p1
return p
def exampleTask(task):
# Get mouse position
p = getMousePosition()
if p != None:
#print p
if rec.isInto(p):
#print "Into"
# Change the color of the text
text.setTextColor(0.5, 1.0, 0.5, 1)
else:
#print "Not into"
text.setTextColor(1, 0.5, 0.5, 1)
## if task.time > 15.0:
## print "Task done"
## return Task.done
return Task.cont
class Hello(DirectObject.DirectObject):
def __init__(self):
self.accept('mouse1', self.printHello)
self.accept('q', self.exit)
def printHello(self):
# Get mouse position
p = getMousePosition()
if p != None:
if rec.isInto(p):
print 'click on text'
def exit(self):
print "exit"
sys.exit(0)
h = Hello()
taskMgr.add(exampleTask, 'MyTaskName')
run()
Regards.
Alberto