For the sake of others coming into the thread, and for the sake of completeness in it, let me start by quoting my explanation of this behaviour:
I think that there’s a caveat here: changing the frame-size doesn’t actually affect where the button thinks its “left”, “right”, and “centre” are. Instead, it’s the other way around: the frame-size seems to be specified relative to the text-anchor.
You can see this in action if you construct buttons with left- or centre- anchors, then change their frame-sizes such that they have a left-extent of zero. (Which should thus tell you where the buttons think that zero is.) You should find that in buttons with a left text-alignment, the left-hand extent of the button ends up at the left of the text, and that in buttons with a centre-alignment, the left-hand extent ends up at the centre of the text.
It’s arguably not intuitive, but it does seem to be the way that it works. ^^;
That said, I see two potential workarounds:
- You could perhaps alter the applied frame-size based on the assigned alignment.
- That is, if the widget is set to be centre-aligned, you could offset the horizontal elements of the frame-size such that they’re centred on zero. Similarly, if the widget is set to be left-aligned, you could offset the horizontal elements of the frame-size such that zero is on the left of the frame.
- You could perhaps set the “text_pos” keyword to offset the text as appropriate.
- That is, if the widget is set set to be left-aligned, you might set the horizontal element of the “text_pos” keyword to the left-most extent of the new frame-size.
Quick examples of these approaches:
(1)
(As it turns out, it seems that you can’t directly query the “text_align” keyword at the moment. I’ve opened a GitHub issue for this matter here.)
from panda3d.core import TextNode
from direct.showbase import ShowBase as showBase
from direct.gui.DirectGui import DirectButton
class Game(showBase.ShowBase):
def __init__(self):
showBase.ShowBase.__init__(self)
self.accept("escape", base.userExit)
self.accept("space", self.resize,
extraArgs = [(-2, 2, -1, 1)])
self.btn = DirectButton(text = "Kitten",
text_align = TextNode.ALeft,
scale = 0.07)
def resize(self, newFrameSize):
print ("Resizing")
textNode = self.btn.guiItem.getTextNode()
print (textNode.align == TextNode.ALeft, TextNode.ACenter)
if textNode.align == TextNode.ALeft:
width = abs(newFrameSize[1] - newFrameSize[0])
newFrameSize = (
0,
width,
newFrameSize[2],
newFrameSize[3]
)
self.btn["frameSize"] = newFrameSize
app = Game()
app.run()
(2)
from panda3d.core import TextNode
from direct.showbase import ShowBase as showBase
from direct.gui.DirectGui import DirectButton
class Game(showBase.ShowBase):
def __init__(self):
showBase.ShowBase.__init__(self)
self.accept("escape", base.userExit)
self.accept("space", self.resize)
self.btn = DirectButton(text = "Kitten",
text_align = TextNode.ALeft,
scale = 0.07)
def resize(self):
print ("Resizing")
self.btn["frameSize"] = (-2, 2, -1, 1)
self.btn["text_pos"] = (-2, 0)
app = Game()
app.run()