DGUI DirectLabel: setText and text w/h

Actually ran into an issue with TextPropertiesManager and maybe it’s because I am either doing things wrong or thought it should work and it doesn’t.

Code that I use is as follows:

        n = DirectLabel(text = text_setText(txt), text_fg = txtColor,
                        text_scale = (scX, scY) ,
                        text_mayChange = True,
                        text_wordwrap = wwX,
                        relief = None,
                        state = DGG.NORMAL )

First Issue: Embedded Text Properties
Figured since text.setText() in the manual referredto text nodes and onscreen text that text_setText() would work inside the DirectLabel. Aren’t many posts about embedded text properties and the DGUI system so I think I am the first to do this wrong.

Normally don’t like just copy/pasting other people’s work but I am at a loss for how to get this to work. Spent an inordinate amount of time trying to get this stuff up and running to no avail.

Before someone asks, making it a direct labelinstead of a text node so I can bind events (such as linking in-game items, etc.).

Second Issue: Text W/H
Been noticing that text w/h is scaling with the sixe of the scale of the direct label frame. For instance I have a node that is parented to pixel2d based on data collected from a layout file. When the gui item is opened all elements are parented to this node so moving the entire widget is much easier. Since the node doesn’t have a defined width, height, I pass along either individual w/h or main frame w/h when defining the method. The larger the width, the more stretched the text on a vertical scale (not horizontal).

The workaround I am using is converting current frame scale to the actual size of the text that I am looking for.

Such as this:

    def retScale(self, w=40, h=40, scaleX=DESIREDTXTSZX, scaleY=DESIREDTXTSZY): # returns the desired scale based on current w/h
        scX = (scaleX[1] / w) * scaleX[0]
        scY = (scaleY[1] / h) * scaleY[0]
        wwX = scX * w
        return scX, scY, wwX

The all cap variables are globals in the module. Only thing I found for absolute text size was defining the amount of pixels per character which I read was to be used for the blurring that may take place with larger text sizes.

Trying to make this part of the code a bit versatile so users can change text size with a GUI slider bar.

As always appreciate people reading/responding. Pardon the lack of correct coding vocabulary and any spelling errors; seems I have been looking at code every hour I haven’t been in the office for the last month.

text = text_setText(txt)

What is “text_setText(txt)”? Is it some function you defined yourself? If not, then it doesn’t make any sense :wink:.

“text” is a regular attribute. If you want to set text, all you need to do is:

myWidget = Direct<Widget>(text = "my fancy text")

If you want to change the text later, you do this:

myWidget["text"] = "my new, more fancy text"

DGUI uses that dictionary notation which might be a little counter-intuitive at first, but it doesn’t make much difference.

If you want to set the size of any DirectGUI widget’s you can do it using the “frameSize” attribute. This will only change the size of the widget’s frame (the widget’s “background”, “canvas” or whatever you want to call it) leaving everything else unchanged.

myWidget = Direct<Widget>(frameSize = [left, right, bottom, top]) # at creation
myWidget["frameSize"] = [left, right, bottom, top] # change later

left, right, bottom and top are floats. This is yet another thing that might seem strange when beginning to work with DGUI, because there’s 4 values instead of just width/height. But you will find this gives you a lot more control (allowing to set the center of the widget wherever you like it, even outside of the widget’s frame).

Obviously, there’s also scale (text_scale and general, frame’s scale). This is also useful, but only if you want to shrink or extend the frame, the text and all the widget’s child nodes (usually being other direct gui widgets). This is most useful for animations and stuff.

Not worried about setting text. Trying to get the embedded text properties to work within the DGUI DirectLabel. Assumed the text.setText(string) method was specific to embedded properties since node[‘text’] = string would set the text on the DGUI. So the assumption was then that text_setText(string) would point to the text node’s setText method.

I either failed in the beginning embedding the ASCII character into the strings or I am failing when constructing the text/DirectLabel; don’t know which.

Will have to post some pics of the before and after vertical stretching of the text. I guess a follow up question is how do most people set absolute sizes for text when their frames can all vary in width and height?

Thanks for the response.

Nope, that’s not the case. You can’t get into the text node that way. I wonder why you want to do it. I still don’t understand what you mean by “embedded text”.

There’s just one kind of text on any DirectGUI thing, and that’s what you set by “text”, while it’s properties are set by “text_” (but, as I said, you can’t get to methods that way).

That’s IIRC an OnscreenText (parented to the DirectGUI widget) which, in turn, is just a convenience wrapper around a TextNode, as the manual points out. So, my point is that what you’re trying to get to simply doesn’t exist, and what you’re trying to achieve is done by passing the text attribute. It’s just your expectations regarding the resulting behavior that seem to be deceiving you.

That’s seems to be where you confuse stuff.

I guess your problem is that when you change the frame’s scale, your text’s scale changes as well, probably loosing proportions (assuming you scale the frame by different values in x and y). Is that the case?

If so, you’re just using scaling incorrectly (technically that can be useful, just not in your case).

This is actually expected behavior. The frame’s text is a child of the frame itself, and thus will scale with it, just like any node.

Scale is, simply, not for setting the size of your frames. You do this using the “frameSize” attribute/dictionary key. And that does not affect your text in any way but it’s default placement relative to the frame’s boundaries.

You should leave your frame’s scale as 1.0, set the frameSize to whatever you need, and set your text scale to some reasonable value, because by default it’s extremely big. That’s all.

Just then if you need to scale the Frame for whatever reason, then you should just compensate with reverse scale on your text, or the text will scale with the frame. But usually that’s just not needed, because you shouldn’t need to touch the frame’s scale (unless in animation).

There’s one thing I think scaling the whole frame can be useful for, and that’s default reliefs, which (except for FLAT, obviously) look quite ugly with frame’s scale set to 1.0 and the frameSize being small. But then you usually just scale the frame proportionally, so the text shrinks too, but it doesn’t get stretched in any direction. Additionally, the reliefs are not very nice looking anyway, so I usually stick to “DGG.FLAT” and just put a texture on the button with frameTexture.

I hope I understood your problem.

Embedded text properties comes from the manual.

And I think it was an error on my end. Changed the DB item and effect construction method and now receiving the following error when the DirectLabel posts the text:

Is this not the correct way to implement embedded properties (push first then close second)?

spChr = "".join(chr(0x01))
stP = spChr+"1stat+spChr+"1"
stC = spChr+"2"

And thanks for the heads-up on the framesize; was always using setScale for the individual widgets within a GUI component (my definition) being parented to that component’s node.

Have a question though about framesize before I try it …

Does the text stretch to fill the frame like it does when you use .setScale? That’s the reason I came up with the DESIREDTXTSZ globals in my node class. Wanted control over panda’s process of filling in the space and thus distorting the desired scale.

Sorry if the presentation of my question is frustrating … I just lack the appropriate words most of the time.

Oh, you mean that. Ok, I just got completely lost because there were two issues which are not very much related (text properties and scaling).

Anyway, what you were trying to do with text_setText was wrong anyway :wink:. You overcomplicated. The text attribute is actually the only thing you need.

You seem to have solved the problem, but just in case someone else gets in here, I’ll paste a piece of code (made from the manual stuff):

tpRed = TextProperties()
tpRed.setTextColor(1, 0, 0, 1)
tpSlant = TextProperties()
tpSlant.setSlant(0.3)

tpMgr = TextPropertiesManager.getGlobalPtr()
tpMgr.setProperties("red", tpRed)
tpMgr.setProperties("slant", tpSlant)

DirectFrame(
	frameColor = transparent,
	
	parent = aspect2d,
	
	text_align = TextNode.ALeft,
	text = "Every day in \1slant\1every way\2 I'm \1red\1getting",
	text_font = sansFont,
	text_scale = 0.1,
	)

If you’re getting that error that means, in your string, you’ve used a text property that you either did not define or did not register. Start with checking the spelling.

EDIT:

Nope, that’s completely unrelated. It works in a completely different way and does not affect the text nor the image you set to the frame (that’s why if you want to have the whole frame textured nicely with no fuss I recommend befriending the frameTexture attribute).

That’s ok. All once have, and all sometimes do :wink:.

Thanks, mate!

Do appreciate the help and I do have a tendency to take about 4 steps when only 1 would do and typically steps 2, 3 and 4 are wrong.

Cheers!

Oh my, tell me about it ;D.