Recommended way to build a DirectButton hierarchy

Hello,

I want to build a complex button which combines multiple texts and images for each of the states. I’ve figured out that the “geom” attribute can be used for this, however I’d like to know the best approaches…

Should I use OnScreenText/OnScreenImages reparented to a DirectFrame, for each state?
Or parented just to a regular NodePath?
Or should I avoid OnScreenText/OnScreenImages and use DirectFrames or other DirectGUI objects for each sub element, setting their “image” and “text” attributes?

Which of these approaches fits best with the GUI system?

At the moment I’ve been attempting as shown below, and it kind of works, however the items I create seem to get duplicated for the button. (So there are double the images/texts overlaying each other).

		highLightedButtonGeom = DirectFrame()
		obj = OnscreenText(text = "Example", font = fontBlurred, fg = Vec4(0.75,1,0,1), pos = (0,0.25), scale = 0.15)
		obj.reparentTo(highLightedButtonGeom)
		obj = OnscreenText(text = "Example", font = font, fg = Vec4(0.5,0.75,0,1), pos = (0,0.25), scale = 0.15)
		obj.reparentTo(highLightedButtonGeom)
		obj = OnscreenImage("menuitem-highlighted.png", scale = (scale_y,1,scale_y))
		obj.reparentTo(highLightedButtonGeom)
		
		regularButtonGeom = DirectFrame()
		obj = OnscreenText(text = "Example", font = font, fg = Vec4(0.5,0.75,0,1), pos = (0,0.25), scale = 0.15)
		obj.reparentTo(regularButtonGeom)
		obj = OnscreenImage("menuitem-regular.png", scale = (scale_y,1,scale_y))
		obj.reparentTo(regularButtonGeom)
		
		button = DirectButton(relief = None, pressEffect = 0, geom = (regularButtonGeom,highLightedButtonGeom,highLightedButtonGeom,regularButtonGeom))

Hello,

If you do not wish to change the text dynamic it is much more easier to use the code explained in the manual:
http://www.panda3d.org/manual/index.php/DirectButton :

egg-texture-cards -o button_maps.egg -p 240,240 button_ready.png button_click.png button_rollover.png button_disabled.png

and

maps = loader.loadModel('button_maps.egg')
b = DirectButton(geom = (maps.find('**/button_ready'),
                         maps.find('**/button_click'),
                         maps.find('**/button_rollover'),
                         maps.find('**/button_disabled')))

This way you can make a really nice looking gui which will have the feature with multiple texts and images for each of the states.

yes, I wanted to use multiple (dynamic) fonts/texts and stuff too which I don’t think that supports,

(I’m actually dynamically generating the button images too, though not in my example)

Anyway, I finally got it working using pure NodePaths for the “geoms” rather than any OnScreenImage/OnScreenText stuff:

		cm = CardMaker('OnscreenImage')
		cm.setFrame(-1, 1, -1, 1)
		
		# normal button
		buttonNorm = NodePath(cm.generate())
		buttonNorm.setTexture( loader.loadTexture("button.png") )
		buttonNorm.setTransparency(TransparencyAttrib.MAlpha)
		
		# normal button text 1
		text = TextNode("test")
		text.setText("Example")
		text.setFont(font)
		text.setTextColor(Vec4(0.5,0.75,0,1))
		buttonNorm.attachNewNode(text)
		
		# highlighted button
		buttonHigh = NodePath(cm.generate())
		buttonHigh.setTexture( loader.loadTexture("button-highlighted.png") )
		buttonHigh.setTransparency(TransparencyAttrib.MAlpha)
		
		# highlighted button text 1 (blurred background for font)
		text = TextNode("test")
		text.setText("Example")
		text.setFont(fontBlurred)
		text.setTextColor(Vec4(0.75,1,0,1))
		buttonHigh.attachNewNode(text)
		
		# highlighted button text 2 (standard font)
		text = TextNode("test")
		text.setText("Example")
		text.setFont(font)
		text.setTextColor(Vec4(0.5,0.75,0,1))
		buttonHigh.attachNewNode(text)
		
		# actual gui button
		button = DirectButton(relief = None, pressEffect = 0, geom = (buttonNorm,buttonHigh,buttonHigh,buttonNorm), scale = 0.2)