Simple chat

How to make multi colored text?

# -*- coding: utf-8 -*- 
import direct.directbase.DirectStart,sys,time 
from pandac.PandaModules import TextNode,ButtonThrower,GeomVertexWriter,VBase3 
from direct.gui.DirectGui import DirectEntry 
from direct.gui.DirectGui import DGG 
from direct.showbase.DirectObject import DirectObject 

class Chat(DirectObject): 
    def __init__(self): 
        self.root=aspect2d.attachNewNode('croot') 
        self.wid=16 
        self.rows=12        
        self.cur=['\n']*self.rows 
        self.str='\n'*self.rows 
        self.log=['\n']*256 
        self.index=0 
        
        #events 
        base.buttonThrowers[0].node().setButtonDownEvent('bdown') 
        base.buttonThrowers[0].node().setButtonUpEvent('bup')            
        
        #accept all keys 
        self.accept('bdown', self.kpress,[True]) 
        self.accept('bup', self.kpress,[False])          
        
        self.drag=False 
        self.opos=False 
        self.posdif=[0,0] 
        
        self.draw() 
        taskMgr.add(self.run,'run') 

    def run(self,task): 
        
        if base.mouseWatcherNode.hasMouse(): 
            ratio=float(base.win.getXSize())/base.win.getYSize() 
            x=(base.mouseWatcherNode.getMouseX())*ratio 
            y=base.mouseWatcherNode.getMouseY() 
            if self.drag: 
                if not self.opos: 
                    self.opos=self.root.getPos()-VBase3(x,0,y) 
                else: 
                    self.root.setPos(self.opos+VBase3(x,0,y)) 
            elif self.opos: 
                self.opos=False 
        
        return task.cont 
    
    def draw(self): 
        #instructions 
        tex=TextNode('tex') 
        tex.setTextColor(1,1,1, 1)
        tt=''
        tt+='ENTER - focus chat/ener chat\n' 
        tt+='ESC - cancel chat/exit app\n'
        tt+='MOUSE1 - on entry - focus chat\n'
        tt+='MOUSE1 - not on entry - cancel chat\n'
        tt+='MOUSE3 - not on entry - move chat\n' 
        tt+='WHEEL - scroll if more than max lines'
        tex.setText(tt) 

        inode=aspect2d.attachNewNode(tex) 
        inode.setPos(-1,0,0.9) 
        inode.setScale(0.06)        
        
        
          
        b = DirectEntry(text = "" , 
        numLines = 1, 
        focusInCommand=self.clear, 
        width=self.wid 
        ) 
        b.guiItem.setOverflowMode(True) 
        tcol=(1,1,1,1) 
        b['text_fg']=tcol 
        
        #change cursor color 
        data=b.guiItem.getCursorDef().getChild(0).node().modifyGeom(0).modifyVertexData()        
        color=GeomVertexWriter(data,'color') 
        color.setData4f(tcol) 
        color.setData4f(tcol) 
        
        b['frameColor']=(0,0,0,1) 
        b['text_align']=TextNode.ALeft 
        b.reparentTo(self.root)        
        self.ent=b 
        
        text=TextNode('text')        
        text.setTextColor(0,0,0, 1) 
        text.setWordwrap(self.wid) 
        text.setMaxRows(self.rows) 
        text.setText('chat text')        
        self.text=text 
        
        self.lnode=self.root.attachNewNode(text) 
        self.lnode.setZ(self.rows+0.2) 
        ft=TextNode('format') 
        ft=TextNode('text')        
        ft.setWordwrap(self.wid) 
        self.ft=ft        
        self.root.setScale(0.04)                

    def kpress(self,tag,but): 
        if but=='escape' and tag: 
            if self.ent['focus']: 
                self.ent['focus']=False 
            else: 
                sys.exit() 
        elif but=='enter' and tag: 
            self.set() 
        elif but=='wheel_up' and tag: 
            self.scroll(1)        
        elif but=='wheel_down' and tag: 
            self.scroll(-1) 
        elif but=='mouse1' and tag: 
            self.ent['focus']=False 
        elif but=='mouse3': 
            self.drag=tag 
            
        
    def ud(self): 
        str='' 
        lnr=0 
        for nr in range(self.rows): 
            line=self.log[self.index+self.rows-nr-1]                    
            str+=line 
        self.text.setWtext(str) 
        
    def clear(self): 
        self.ent.enterText('') 
        
    def set(self): 
        if self.ent['focus'] and self.ent.get()!='': 
            text=unicode(self.ent.get()) 
            if text!='': 
                self.index=0 
                tt=unicode(time.strftime("(%H:%M)", time.localtime())+' '+'Player_name:') 
                
                self.ft.setWtext(tt+' '+text) 
                ftext=self.ft.getWordwrappedWtext() 
                tlines=ftext.split('\n') 
                
                for line in tlines: 
                    self.log.pop()                    
                    self.log.insert(0,line+'\n')    
                self.ud()                
                self.ent['focus']=True 
        else: 
            self.ent['focus']=True 
        
    def scroll(self,nr): 
        ind=self.index 
        ind+=nr        
        if ind<0: 
            ind=0 
        elif ind>len(self.log)-self.rows: 
            ind=len(self.log)-self.rows        
            
        
        if nr>0 and len(self.log[ind+self.rows-1])==1: 
            ind=self.index        
            
        if ind!=self.index: 
            self.index=ind 
            self.ud()            
        
ch=Chat()        

run()