Module dgstuff
[frames] | no frames]

Source Code for Module dgstuff

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3  Fancy directgui wrapper. 
  4  It contains helper classes to speed up the making of menus and other visual stuff like that. 
  5   
  6  @author: fabius 
  7  @copyright: fabius@2010 
  8  @license: GCTA give credit to (the) authors 
  9  @version: 0.1 
 10  @date: 2010-09 
 11  @contact: astelix (U{panda3d forums<http://www.panda3d.org/forums/profile.php?mode=viewprofile&u=752>}) 
 12  @status: eternal WIP 
 13   
 14  @note: see the __main__ section for a sample usage and read comments to understand how it works. 
 15   
 16  Post your dubts and inquiries in U{this forum thread<http://www.panda3d.org/phpbb2/viewtopic.php?p=56992>} 
 17   
 18  """ 
 19  import random 
 20  from pandac.PandaModules import * 
 21  from direct.gui.DirectGui import * 
 22  from direct.showbase.DirectObject import DirectObject 
 23   
 24  #========================================================================= 
 25  # 
26 -class dgstuff(DirectObject):
27 _DEBUG=False
28 - def __init__(self, data):
29 self.defaultdata={} 30 # 31 self._setdefaultdata() 32 #** 33 # default data merge w/ custom data and pour back to the source 34 self.data=data 35 self.defaultdata.update(self.data) 36 self.data.update(self.defaultdata) 37 self._postdatamerge() 38 self._buildcanvas() 39 self.play()
40 #----------------------------------------------------- 41 #
42 - def play(self): pass
43 - def pause(self): pass
44 - def _buildcanvas(self): pass
45 - def _postdatamerge(self): pass
46 - def _setdefaultdata(self): pass
47 #----------------------------------------------------- 48 #
49 - def dbgprint(self, msg):
50 if self._DEBUG: print msg
51 #--------------------------------------------------- 52 #
53 - def settexture(self, model, texture=None, wrapmode='clamp', scale=None):
54 """ Apply a texture over the menu panel model and set transparency automatically 55 """ 56 wraps={'repeat': Texture.WMRepeat, 'clamp': Texture.WMClamp,} 57 if texture: 58 tex = loader.loadTexture(texture) 59 model.clearTexture() 60 tex.setWrapU(wraps[wrapmode]) 61 tex.setWrapV(wraps[wrapmode]) 62 tex.setMinfilter(Texture.FTLinearMipmapNearest) 63 ts = TextureStage('ts') 64 model.setTexture(ts, tex, 1) 65 if scale: model.setTexScale(ts, scale[0], scale[1]) 66 # autotransparent if png image file 67 if texture.endswith('.png'): 68 model.setTransparency(TransparencyAttrib.MAlpha)
69 70 #========================================================================= 71 #
72 -class dgscroll(dgstuff):
73 """ An helper class to ease to make a scroller panel 74 """ 75 #----------------------------------------------------- 76 #
77 - def _buildcanvas(self):
78 # geometry setup - it is just a plane we stretch or shrink depending on the scale param - will be then applied a texture passed by data interface 79 geometry=loader.loadModel('data/models/menubg.egg') 80 self.settexture(geometry, self.data['texture']) 81 geomscale=(self.data['scale'][0], 0, self.data['scale'][1]) 82 geometry.setScale(geomscale) 83 b=geometry.getTightBounds() 84 w,n,h=b[1]-b[0] 85 #** 86 # making the scrolledlist control 87 self.canvas = DirectScrolledList( 88 geom=geometry, 89 geom_scale=geomscale, 90 pos=(self.data['pos'][0], -1, self.data['pos'][1]), 91 frameColor = (0, 0, 0, 0), 92 itemFrame_pos = ( 93 -(w/2)+self.data['margin'][0], 0, 94 (h/2)-self.data['margin'][1]-self.data['titlescale']-.02-self.data['itemsscale'] 95 ), 96 numItemsVisible = self.data['itemsvisible'], 97 # 98 text = self.data['title'], text_scale=self.data['titlescale'], 99 text_align = TextNode.ACenter, 100 text_pos = (0, (h/2)-self.data['margin'][1]), 101 text_fg = self.data["titlecolor"], text_font = self.data['textfont'], 102 # inc and dec buttons aren't used but looks like we can't get rid easily so we put them where not visible 103 decButton_pos= (-1000, 0, -1000), 104 incButton_pos= (-1000, 0, -1000), 105 ) 106 if not self.data['visible']: self.canvas.hide() 107 # 108 self._additems(w, h) 109 # 110 self.index=self.data['selected'] 111 self._hilightcurrent(True)
112 #----------------------------------------------------- 113 #
114 - def _setdefaultdata(self):
115 self.defaultdata={ 116 'scale':(.6,.75), 'margin':(.15,.15), 'itemsvisible':10, 117 'texture':None, 'pos':(0,0), 'title':'* TITLE *', 118 'titlescale':.07, 'titlecolor':(0,0,0,1), 'highlightcolor':(1,1,0,1), 119 'textfont':loader.loadFont("cmss12.egg"), 'itemsscale':.05, 120 'items':[], 'itemscolor':(0,0,0,1), 'roundrobin':False, 121 'callback':None, 'selected':0, 'visible':True, 'exit':None, 122 }
123 #----------------------------------------------------- 124 #
125 - def _postdatamerge(self):
126 self.defaultcallback=self.data["callback"] or self.onClick 127 self.roundrobin=self.data["roundrobin"] 128 self.highlight=self.data["highlightcolor"]
129 #----------------------------------------------------- 130 #
131 - def _additems(self): pass
132 #----------------------------------------------------- 133 #
134 - def play(self):
135 """ (re)start the menu controls """ 136 self.accept("wheel_up", self.scrollindex, [-1] ) 137 self.accept("wheel_down", self.scrollindex, [1] ) 138 self.accept("arrow_up", self.scrollindex, [-1] ) 139 self.accept("arrow_down", self.scrollindex, [1] ) 140 self.accept("enter", self._click) 141 if callable(self.data['exit']): self.accept("escape", self.data['exit']) 142 for item in self.canvas["items"]: item['state']=DGG.NORMAL
143 #----------------------------------------------------- 144 #
145 - def pause(self):
146 """ pause the menu controls """ 147 for item in self.canvas["items"]: item['state']=DGG.DISABLED 148 self.ignoreAll()
149 #----------------------------------------------------- 150 #
151 - def finish(self):
152 self.ignoreAll() 153 self.canvas.destroy()
154 #----------------------------------------------------- 155 #
156 - def _click(self):
157 """ called when click over an item is routed (i.e. via keyboard) """ 158 if hasattr(self.canvas["items"][self.index], 'commandFunc'): 159 self.canvas["items"][self.index].commandFunc(None)
160 #----------------------------------------------------- 161 #
162 - def onClick(self, *value):
163 """ Common callback for all the items with no specific callback defined (to be overriden) 164 """ 165 self.dbgprint("[CLASS CB]item clicked w/ value: %r"%(value))
166 #----------------------------------------------------- 167 #
168 - def butenex(self, evt, index, pos):
169 """ Hilight management entering and exiting w/ the mouse pointer """ 170 if evt == DGG.ENTER: 171 self._hilightcurrent(False) 172 self.index=index 173 self._hilightcurrent(True) 174 elif evt == DGG.EXIT: 175 self._hilightcurrent(False)
176 #----------------------------------------------------- 177 #
178 - def scrollindex(self, delta):
179 self._hilightcurrent(False) 180 i=self.index+delta 181 if self.roundrobin: self.index=i%len(self.canvas["items"]) 182 else: self.index=max(0, min(i, len(self.canvas["items"])-1)) 183 self._hilightcurrent(True) 184 self.canvas.scrollTo(self.index, True)
185 #----------------------------------------------------- 186 #
187 - def _hilightcurrent(self, onoff):
188 """ Set the actually selected item highlight on or off """ 189 if len(self.canvas["items"]): 190 self.canvas["items"][self.index]['frameColor']=\ 191 list(self.highlight)[:3]+[self.highlight[3] if onoff else 0]
192 193 #========================================================================= 194 #
195 -class dgmenu(dgscroll):
196 #----------------------------------------------------- 197 #
198 - def _additems(self, w,h):
199 """ Add items as buttons to the scrolling panel. 200 @note: color, textscale and font could be either assigned overall or per item 201 """ 202 for idx in range(len(self.data['items'])): 203 default={ 204 'color': self.data['itemscolor'], 205 'textscale': self.data['itemsscale'], 206 'textfont': self.data['textfont'], 207 'width': w-(self.data['margin'][0]*2.), 208 } 209 self.data['items'][idx].update(default) 210 self.addItem(idx, **self.data['items'][idx])
211 212 #----------------------------------------------------- 213 #
214 - def addItem(self, index, **keys):
215 """ An item is a clickable label that fires a callback. 216 217 There are 2 possible scenarios: 218 - 1 common callback for all (onClick) overridable (defined in the main data, see __init__) 219 - 1 custom callback carried on the item via 'callback' data element 220 for each of them will be passed the item index in the list 221 @note: textfont is mandatorily passed by the caller 222 """ 223 itemdata={ 224 'label':'label_%d'%index, 'width':.4, 'textscale':.05, 225 'color':(0,0,0,1), 'callback':self.defaultcallback, 226 } 227 # default data merge w/ custom params passed to the method 228 itemdata.update(keys) 229 # 230 w,h=(itemdata['width'], itemdata['textscale']) 231 butt = DirectButton( 232 text = tuple([itemdata['label']]*4), text_fg=itemdata['color'], 233 text_scale=itemdata['textscale'], text_align=TextNode.ALeft, 234 text_font=itemdata['textfont'], 235 relief=2, borderWidth = (0.0, 0.0), 236 frameSize = (0.0, w, (-h/2.)+.02, (h/2.)+.01), frameColor=(0,0,0,0), 237 command=itemdata['callback'], extraArgs=[index], 238 ) 239 # 240 butt.bind(DGG.ENTER, self.butenex, [DGG.ENTER, index]) 241 butt.bind(DGG.EXIT, self.butenex, [DGG.EXIT, index]) 242 self.canvas.addItem(butt, True)
243 244 #========================================================================= 245 #
246 -class dgtable(dgscroll):
247 """ Helper class to ease making of a scrolling table og columnar data. 248 """ 249 #----------------------------------------------------- 250 #
251 - def _setdefaultdata(self):
252 dgscroll._setdefaultdata(self) 253 # data interface at instancing - you define just the parameters you need to customize 254 self.defaultdata.update({'head':[], 'exit': None})
255 #----------------------------------------------------- 256 #
257 - def _postdatamerge(self):
258 # skip if there are no items 259 if not len(self.data['items']): return 260 dgscroll._postdatamerge(self) 261 # calculate the column width, where not explicitly specified, subdividing the space per columns 262 self.data['itemswidth']=self.data.get( 263 'itemswidth', 264 [ 265 self.data['scale'][1] / len(self.data['items']) 266 ]*len(self.data['items']) 267 )
268 #----------------------------------------------------- 269 #
270 - def _additems(self, w, h):
271 # add the column heading 272 for icol in range(len(self.data['head'])): 273 idata={ 274 'color': self.data['itemscolor'], 275 'textfont': self.data['textfont'], 276 'textscale': self.data['itemsscale'], 277 } 278 self.data['head'][icol]['width']=self.data['itemswidth'][icol] 279 idata.update(self.data['head'][icol]) 280 self.data['head'][icol]=idata 281 self.addHead(self.data['head'], -(w/2)+self.data['margin'][0], 282 (h/2)-self.data['margin'][1]-self.data['titlescale']-.02 283 ) 284 """ add items as buttons 285 NOTE color, textscale and font could be either assigned overall or per item 286 """ 287 for idx in range(len(self.data['items'])): 288 for icol in range(len(self.data['items'][idx])): 289 idata={ 290 'color': self.data['itemscolor'], 291 'textfont': self.data['textfont'], 292 'textscale': self.data['itemsscale'], 293 } 294 idata.update(self.data['items'][idx][icol]) 295 self.data['items'][idx][icol]=idata 296 self.data['items'][idx][icol]['width']=self.data['itemswidth'][icol] 297 298 self.addRow(idx, self.data['items'][idx])
299 #----------------------------------------------------- 300 #
301 - def addRow(self, index, rowdata):
302 """ 303 """ 304 w0=0.0 305 h0=0.0 306 l=[] 307 for col in rowdata: 308 itemdata={ 309 'label':'label_%d'%index, 'width':.4, 'textscale':.05, 310 'color':(0,0,0,1), 311 } 312 # default data merge w/ custom params passed to the method 313 itemdata.update(col) 314 # 315 w,h=(itemdata['width'], itemdata['textscale']) 316 butt = DirectButton( 317 text = itemdata['label'], text_fg=itemdata['color'], 318 text_scale=itemdata['textscale'], text_align=TextNode.ALeft, 319 text_font=itemdata['textfont'], 320 text_pos=(w0,0.01), 321 relief=2, borderWidth = (0.0, 0.0), 322 frameSize = (w0, w0+w, (-h/2.)+.03, (h/2.)+.03), frameColor=(1,0,0,0), 323 ) 324 butt.bind(DGG.ENTER, self.butenex, [DGG.ENTER, index]) 325 butt.bind(DGG.EXIT, self.butenex, [DGG.EXIT, index]) 326 l.append(butt) 327 w0+=w 328 h0=max(h0,h) 329 row=DirectFrame( 330 frameColor=(0,0,0,0) , frameSize=(0,w0,0,h), 331 ) 332 # NOTE trick to attach a callback to the frame as it was a button (click via kbd) 333 row.commandFunc=lambda foo=None: self.defaultcallback(index) 334 for c in l: c.reparentTo(row) 335 self.canvas.addItem(row, True)
336 #----------------------------------------------------- 337 #
338 - def addHead(self, rowdata, w0, h0):
339 """ 340 """ 341 l=[] 342 i=0 343 for col in rowdata: 344 itemdata={ 345 'label':'COL_%d'%i, 'width':.4, 'textscale':.05, 'color':(0,0,0,1), 346 } 347 i+=1 348 # default data merge w/ custom params passed to the method 349 itemdata.update(col) 350 # 351 w,h=(itemdata['width'], itemdata['textscale']) 352 butt = DirectLabel( 353 text = itemdata['label'], text_fg=itemdata['color'], 354 text_scale=itemdata['textscale'], text_align=TextNode.ALeft, 355 text_font=itemdata['textfont'], 356 text_pos=(w0,0.01), 357 relief=2, borderWidth = (0.0, 0.0), 358 frameSize = (w0, w0+w, (-h/2.)+.03, (h/2.)+.03), frameColor=(1,0,0,0), 359 ) 360 l.append(butt) 361 w0+=w 362 # 363 row=DirectFrame( 364 frameColor=(0,0,0,0) , frameSize=(0,w0,0,h), 365 ) 366 for c in l: c.reparentTo(row) 367 row.setZ(h0) 368 row.reparentTo(self.canvas)
369 #========================================================================= 370 #
371 -class dginput(dgstuff):
372 """ 373 @todo: aggiungere callback principale (si attiva ALLA CONFERMA dell'input) 374 """ 375 #----------------------------------------------------- 376 #
377 - def _setdefaultdata(self):
378 # overridiamo completamente 379 self.defaultdata={ 380 'bgcolor': (1,1,1,0), 'texture': None, 'margin':(0.,0.), 381 'title': "** TITLE **", 'titlescale': .08, 382 'align': 'left', 'textfont':loader.loadFont("cmss12.egg"), 383 'pos':(0,0), 'scale': (.6, .1), 'titlecolor':(0,0,0,1), 384 'inputwidth':10, 'inputscale': .07, 'initialtext': '', 'focus': 0, 385 'inputcolor':(0,0,0,1), 'autoexit': False, 386 }
387 #----------------------------------------------------- 388 #
389 - def _buildcanvas(self):
390 w,h=self.data['scale'] 391 geometry=geomscale=None 392 if self.data['texture']: 393 geometry=loader.loadModel('data/models/menubg.egg') 394 self.settexture(geometry, self.data['texture']) 395 geomscale=( 396 self.data['scale'][0]+self.data['margin'][0], 0, 397 self.data['scale'][1]+self.data['margin'][1] 398 ) 399 # 400 # by default titlepos is to the entry control left, but you can optionally set it to the top so the entry will be put to the frame center 401 self.data['align']=self.data['align'].lower() 402 if self.data['align'] == 'center': 403 textpos=(0, (h/2)-self.data['margin'][1]) 404 textalign=TextNode.ACenter 405 else: 406 textpos=(-(w/2.)+self.data['margin'][0],0) 407 textalign=TextNode.ALeft 408 # 409 self.canvas = DirectFrame( 410 geom=geometry, 411 geom_scale=geomscale, 412 pos=(self.data['pos'][0],0,self.data['pos'][1]), 413 frameSize=(-w/2.,w/2.,-h/2.,h/2), frameColor=self.data['bgcolor'], 414 text = self.data['title'], text_align = textalign, 415 text_pos = textpos, text_font = self.data['textfont'], 416 text_fg=self.data['titlecolor'], text_scale=self.data['titlescale'], 417 ) 418 self.entry = DirectEntry( 419 parent=self.canvas, pos=(0,0,0), frameColor=(1,1,1,0), 420 text_font = self.data['textfont'], text_fg=self.data['inputcolor'], 421 text_scale=self.data['inputscale'], 422 initialText=self.data['initialtext'], numLines=1, 423 width=self.data['inputwidth']/2., focus=self.data['focus'], 424 command=self._settext, focusInCommand=self._cleartext, 425 ) 426 if self.data['align'] == 'center': 427 b=self.entry.getBounds() 428 w=b[1] 429 self.entry.setPos(-(w/2.)+self.data['margin'][0],0,0)
430 #----------------------------------------------------- 431 #
432 - def _settext(self, textEntered):
433 """ Callback function entering text to the control """ 434 if textEntered.strip() == '': 435 textEntered=self.data['initialtext'] 436 self.entry.enterText(textEntered) 437 else: 438 if callable(self.data['callback']): self.data['callback'](textEntered) 439 if self.data['autoexit'] and callable(self.data['exit']): 440 # NOTE not safe to call here user callback... 441 taskMgr.doMethodLater(.5, self.data['exit'], '_ntryxt')
442 #----------------------------------------------------- 443 #
444 - def _cleartext(self):
445 text=self.entry.get(plain=True).strip() 446 if text == self.data['initialtext']: self.entry.enterText('') 447 else: self.entry.setCursorPosition(len(text))
448 #----------------------------------------------------- 449 #
450 - def play(self):
451 """ (re)start the control 452 @note: SetFocus actually won't work 453 """ 454 def focusentry(): self.entry['focus']=True 455 self.accept("tab", focusentry) 456 if callable(self.data['exit']): self.accept("escape", self.data['exit']) 457 self.entry['state']=DGG.NORMAL
458 #----------------------------------------------------- 459 #
460 - def pause(self):
461 """ pause the menu controls """ 462 self.entry['state']=DGG.DISABLED 463 self.ignoreAll()
464 #----------------------------------------------------- 465 #
466 - def finish(self):
467 self.ignoreAll() 468 self.entry.destroy() 469 self.canvas.destroy()
470 471 #========================================================================= 472 # 473 if __name__ == "__main__": 474 """ dgscrollers sample usage """ 475 import direct.directbase.DirectStart 476 import sys 477 478 # Some gui stuff 479 title="Fancy DirectGUI" 480 content="Use of gui stuff to ease to make menus, tables\nand inputs using a compact data interface" 481 infotext={} 482 infotext['title']=OnscreenText( 483 text = title, pos = (0, .92), scale = 0.08, mayChange=True, fg=(1,1,1,1), 484 bg=(0,0,1,.7) 485 ) 486 infotext['content']=OnscreenText( 487 text = content, pos = (0, 0.84), scale = 0.05, mayChange=True, fg=(1,1,0,1), 488 bg=(0,0,0,.5) 489 ) 490 infotext['message']=OnscreenText( 491 text = '', pos = (0, -0.85), scale = 0.07, mayChange=True, fg=(1,1,1,1), 492 bg=(1,0,0,.65) 493 ) 494 495 env=loader.loadModel("environment") 496 env.reparentTo(render) 497 498 #** handler called by menu_options_video
499 - def setvideo(index=None):
500 global menu_options_video 501 def _setresolution(res, fullscreen=False): 502 wp = WindowProperties() 503 wp.setSize(int(res[0]), int(res[1])) 504 wp.setFullscreen(fullscreen) 505 base.win.requestProperties(wp)
506 if index <> None: 507 video=menu_options_video['items'][index]['label'] 508 infotext['message'].setText("Video changed to %r"%video) 509 _setresolution(video.split('x')) 510 511 menulist=[] 512 #** used for the menu ovelapping mechanic to add a menu over
513 - def push_menu(menudata):
514 global menulist 515 if len(menulist): menulist[-1].pause() 516 menulist.append(dgmenu(menudata))
517 518 #** used for the menu ovelapping mechanic to add a menu over
519 - def push_table(menudata):
520 global menulist 521 if len(menulist): menulist[-1].pause() 522 menulist.append(dgtable(menudata))
523 524 #** used for the menu ovelapping mechanic to add a menu over
525 - def push_entry(menudata):
526 global menulist 527 if len(menulist): menulist[-1].pause() 528 menulist.append(dginput(menudata))
529 530 #** used for the menu ovelapping mechanic to close the overall menu
531 - def pop_menu(foo=None):
532 global menulist 533 menu=menulist.pop() 534 menu.finish() 535 if len(menulist): menulist[-1].play()
536
537 - def exit(foo=None):
538 self.dbgprint("quitting out...") 539 sys.exit(0)
540 541 menu_options_video={'title': 'Video Options', 542 'scale':(.4, .6), 'itemsvisible':10, 'titlescale':.05, 543 'texture':'data/models/textures/iphone.png', 'margin':(.12, .34), 544 'callback': setvideo, 545 'items': [ 546 {'label': '800x600'}, 547 {'label': '1024x768'}, 548 {'label': 'back', 'callback': pop_menu, }, 549 ], 550 'exit': pop_menu, 551 } 552 553 menu_options={'title': 'Options', 554 'scale':(.4, .6), 'itemsvisible':10, 'titlescale':.05, 555 'texture':'data/models/textures/iphone.png', 'margin':(.12, .34), 556 'callback': None, 557 'items': [ 558 {'label': 'video', 559 'callback': lambda foo=None: push_menu(menu_options_video), 560 }, 561 {'label': 'opponent', 'callback':None, 'choice': 1}, 562 {'label': 'back', 'callback': pop_menu, }, 563 ], 564 'exit': pop_menu, 565 } 566 menu_quitgame={'title': 'Sure to quit "game"?', 567 'scale':(.46, .34), 'itemsvisible':6, 'margin':(.25, .2), 568 'texture':'data/models/textures/round256x128.png', 'selected': 1, 569 'items': [ 570 {'label': 'Yes', 'width': .1, 'callback': exit}, 571 {'label': 'No', 'width': .1, 'callback': pop_menu, }, 572 ], 573 'itemselected': 1, 'exit': pop_menu, 574 } 575 #**
576 - def prot(foo=None): self.dbgprint(foo)
577 table0={'title': 'TOP 10', 'titlescale': .08, 578 'scale':(.62, .44), 'itemsvisible':6, 'pos':(-.5, .1), 'margin': (.25,.23), 579 'texture':'data/models/textures/menubg01.png', 580 'itemswidth': (.45,.15,.15), 581 'items': [ 582 [ {'label': 'Row0Col0',}, {'label': 'R0C1',}, {'label': 'R0C2',}, ], 583 [ {'label': 'Row1Col0',}, {'label': 'R1C1',}, {'label': 'R1C2',}, ], 584 [ {'label': 'Row2Col0',}, {'label': 'R2C1',}, {'label': 'R2C2',}, ], 585 [ {'label': 'Row3Col0',}, {'label': 'R3C1',}, {'label': 'R3C2',}, ], 586 [ {'label': 'Row4Col0',}, {'label': 'R4C1',}, {'label': 'R4C2',}, ], 587 [ {'label': 'Row5Col0',}, {'label': 'R5C1',}, {'label': 'R5C2',}, ], 588 [ {'label': 'Row6Col0',}, {'label': 'R6C1',}, {'label': 'R6C2',}, ], 589 [ {'label': 'Row7Col0',}, {'label': 'R7C1',}, {'label': 'R7C2',}, ], 590 [ {'label': 'Row8Col0',}, {'label': 'R8C1',}, {'label': 'R8C2',}, ], 591 [ {'label': 'Row9Col0',}, {'label': 'R9C1',}, {'label': 'R9C2',}, ], 592 ], 593 'head': [ 594 { 'label': 'COL0'}, 595 { 'label': 'COL1'}, 596 { 'label': 'COL2'}, 597 ], 598 'callback': prot, 'exit': pop_menu 599 } 600 #**
601 - def printv(v): infotext['message'].setText("Player Name: '%s'"%v)
602 entry0={ 603 'xpos': (-.5,.0), 'align': 'center', 604 'title': 'Player Name', 'scale': (1.2,.6), 'margin':(.07, .05), 605 'titlecolor': (0,0,1,1), 'texture':'data/models/textures/round256x128.png', 606 'initialtext': "Type Something", 'inputscale': .07, 'inputwidth': 25, 607 'inputcolor':(0,1,0,1), 608 'callback': lambda v: printv(v), 'exit': pop_menu, 'autoexit': True, 609 } 610 #** 611 menu_main={'title': 'MAIN MENU', 'titlescale': .08, 612 'scale':(.62, .6), 'itemsvisible':14, 'pos':(-.8, .2), 'margin': (.25,.23), 613 'texture':'data/models/textures/menubg01.png', 'itemsscale': .07, 614 'items': [ 615 {'label': 'Options', 616 'callback': lambda foo=None: push_menu(menu_options), 617 }, 618 {'label': 'TOP10', 619 'callback': lambda foo=None: push_table(table0), 620 }, 621 {'label': 'New Game', 622 'callback': lambda foo=None: push_entry(entry0), 623 }, 624 {'label': 'Exit', 'callback': lambda foo=None: push_menu(menu_quitgame), 625 }, 626 ], 627 'exit': lambda foo=None: push_menu(menu_quitgame), 628 } 629 630 push_menu(menu_main) 631 632 run() 633