Class to translate gui coordinates

I made a class to help translate gui coordinates to panda gui coordinates. Here’s the code if someone is interested in using it.

from math import *
class GuiSpace:
    def __init__(self,left=0,bottom=0,right=1,top=1):
        self.pscale = (2.0,2.0)
        self.ptransl = (-1.0, -1.0)
        self.scale = (right-left, top-bottom)
        self.sfactor = (self.pscale[0]/self.scale[0],
                        self.pscale[1]/self.scale[1])
        self.transl = (left, bottom)
    def pos(self,x,y):
        return (self.posx(x), self.posy(y))
    def posx(self,x):
        return (x - self.transl[0]) * self.sfactor[0] + self.ptransl[0]
    def posy(self,y):
        return (y - self.transl[1]) * self.sfactor[1] + self.ptransl[1]
    def dim(self,x,y):
        return (self.dimx(x), self.dimy(y))
    def dimx(self,x):
        return fabs(x * self.sfactor[0])
    def dimy(self,y):
        return fabs(y * self.sfactor[1])

First you have to specify a gui coordinate system, for example, 800x600 with screen coordinates where y is upside down.

gsp = GuiSpace(left=0,bottom=600,right=800,top=0)

Notice that top < bottom which will result in y being inverted.

To use this object, whenever you have to pass panda gui coordinates you can now reason logically in terms of a familiar coordinate system (800x600 screen). Like this:

return OnscreenText(
text=msg,
style=1,
fg=(1,1,1,1),
pos=gsp.pos(10, 10),
align=TextNode.ALeft,
scale = gsp.dimy(16))

Great! I think this will help me a lot.

But will it still look good an machines with different screen resolutions?

Different resolution doesn’t always mean different ratio.
[] 800 x 600 and 1024 x 768 are different, but same ratio
[
] 800 x 600 and 1280 x 768 are different, and the ratio is different too

If what you really meant is resolution, yes it will work, but still pscale and ptransl are wrong. They’re bound to render2d’s coord space, which should use aspect2d’s instead.

But if what you meant is ratio, no it won’t work. Your GUI will be stretched or squashed.
Unless you fix it this way :
tfactor is for translation, and sfactor is for scale.

from math import *
class GuiSpace:
    def __init__(self,left=0,bottom=0,right=1,top=1):
        self.pscale = (2.0*base.getAspectRatio(),2.0)
        self.ptransl = (-base.getAspectRatio(), -1.0)
        self.scale = (right-left, top-bottom)
        self.ratio = float(self.scale[0])/self.scale[1]
        self.tfactor = (self.pscale[0]/self.scale[0],
                        self.pscale[1]/self.scale[1])
        self.sfactor = (2.0*self.ratio/self.scale[0],
                        self.pscale[1]/self.scale[1])
        self.transl = (left, bottom)
    def pos(self,x,y):
        return (self.posx(x), self.posy(y))
    def pos3(self,x,y):
        return (self.posx(x), 0, self.posy(y))
    def posx(self,x):
        return (x - self.transl[0]) * self.tfactor[0] + self.ptransl[0]
    def posy(self,y):
        return (y - self.transl[1]) * self.tfactor[1] + self.ptransl[1]
    def dim(self,x,y):
        return (self.dimx(x), self.dimy(y))
    def dim3(self,x,y):
        return (self.dimx(x), 1, self.dimy(y))
    def dimx(self,x):
        return fabs(x * self.sfactor[0])
    def dimy(self,y):
        return fabs(y * self.sfactor[1])

Added pos3 and dim3 too.

Thanks ynjh_jo. I knew there would be something missing somewhere. :slight_smile: