Window size independent GUI

Hey guys, I’m building an application which I don’t what resolution the client will use. Is there a way to use a widget such as DirectOptionMenu and keep at exactly the same place for all resolutions? It also affects my camera.

Here if I put on 800x600 (all wrong)


Here if I put on maximized (my screen resolution is 1366x768, everything on the right spot)

I appreciate code examples since I’m new to panda3d.

Thanks in advance

You can get the window size with

window_x = base.win.getXSize()
window_y = base.win.getYSize()

Then, I would suggest (there are a number of ways to do this) to normalize that resolution data and then set your UI positions and scales that way (assuming you’re using the built-in Panda3D gui system in render 2D).

I guess I’ll just force a fullscreen mode in 1366x768 and that’s it.

How are you attaching your DirectGUI widgets to the window? If you parent them below “aspect2d” (the default), then they should retain their size and position, I believe.

There is one catch, however: Their positions are held relative to the centre of the window. As a result, while a change to the size of the window should have little effect, a change to the aspect-ratio of the window may result in objects being shunted off-screen, or left adrift in empty screen-space.

Now, if your widgets are near the edge of the screen, then you can potentially remedy this by parenting them below a special set of anchors that Panda provides. These are located around the edge of the screen–one for the middle-left, one for the top-left, and so on. And, importantly, they automatically update their positions as the window is resized.

(These anchors are themselves children of “aspect2d”).

You can see a listing of the anchors here, I believe:

And to demonstrate, here is a simple example program:

from direct.showbase.ShowBase import ShowBase

from panda3d.core import TextNode
from direct.gui.DirectGui import *

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.disableMouse()

        self.accept("escape", base.userExit)

        self.mew = DirectButton(scale = 0.1,
                                text = "Kitten",
                                parent = base.a2dTopLeft,
                                pos = (0, 0, -0.1),
                                text_align = TextNode.ALeft)

        self.mew2 = DirectButton(scale = 0.1,
                                text = "Cat",
                                parent = base.a2dRightCenter,
                                pos = (0, 0, -0.1),
                                text_align = TextNode.ARight)

app = Game()
app.run()
1 Like

Please don’t do this; it would make multitasking with your editor (e.g. switching between it and a text editor or modeling program) unnecessarily difficult. In addition, if the user’s native monitor resolution is higher than the forced resolution, their carefully placed desktop icons and open windows might get repositioned/resized, which can be quite annoying.

As an alternative to Thaumaturge’s suggestion, if your GUI becomes more complex you may want to take a look at my layout system. It will preserve your layout however you resize the window, while you never have to set any explicit positions; everything is laid out based on borders, proportions and alignments.
It may be a bit overkill for now, but as the complexity of your interface grows, it might become more useful to you :slight_smile: .

1 Like

Conversely, if they don’t have a monitor that offers that resolution, they might end up with being forced into a lower resolution, which again could mess up the UI.

I’ll surely take a look on it, thanks for being so kind.

How to independently of the operating system, maximize window on startup?

See here for an answer:

The short version, if I have it correctly, is: “Not in the current release, but it’s intended for a later one. Workarounds of various degrees of efficacy and cross-platformness may be feasible.”