Direct GUI workflow

Hi there

My Direct GUI workflow is rather tedious and time consuming even for very simple
GUI layouts with no real complexity. I must be missing something.
May you all please guide me in the right direction.
I have read the manual, but nothing seems efficient.
As it stands Direct GUI object are not visible in the scene graph editor, again, unless I am missing something.

Best regards.

First of all, greetings, and welcome to the forum! I hope that you find your time here to be helpful and enjoyable! :slight_smile:

That said, as to your question:

No, you’re not missing anything, I daresay: DirectGUI can be clunky to work with, at times.

For myself, I sometimes make convenience functions to generate and lay out my GUI-widgets.

However, there is a community-made tool that may well make working with DirectGUI much easier: DirectGui Designer:

Just want to chime in here and say that you can use imgui (pyimgui) as well.

from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.showbase.DirectObject import DirectObject

import imgui
from imgui.integrations.opengl import ProgrammablePipelineRenderer as ImguiRenderer


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

        imgui.create_context()
        imgui.get_io().display_size = self.get_size()
        imgui.get_io().fonts.get_tex_data_as_rgba32()
        
        self.imgui_renderer = ImguiRenderer()

        self.accept("mouse1", self.mouse_down)
        self.accept("mouse1-up", self.mouse_up)

        self.mouse_down = False

        self.taskMgr.add(self.imgui, "gui")

    def imgui(self, task):
        x, y = self.win.get_pointer(0).get_x(), self.win.get_pointer(0).get_y()
        imgui.get_io().mouse_pos = x, y
        imgui.get_io().mouse_down[0] = self.mouse_down

        imgui.new_frame()
        imgui.begin("Start Window", True)
        imgui.text("Basic imgui Window")
        imgui.button("Click Here")
        imgui.end()
        imgui.render()
        imgui.end_frame()

        self.imgui_renderer.render(imgui.get_draw_data())

        return Task.cont

    def mouse_down(self):
        self.mouse_down = True

    def mouse_up(self):
        self.mouse_down = False


app = imguiApp()
app.run()

https://pyimgui.readthedocs.io/en/latest/guide/first-steps.html

2 Likes

Hi All

Thank you for your replies.

@Thaumaturge
Thank you very much I appreciate the warm welcome.
Thank for the information and clarification as well. I appreciate it.
May you please share an example of your convenience functions, for perspective.

@ Simulan
Thank you, for the information I appreciate.

Thank you everyone, Best regards.

It’s my pleasure, and sure! :slight_smile:

The following is a very simple example, emulating a menu-class. The convenience-functions are “addButton” and “layoutButtons”.

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import DirectFrame, DirectButton

class SimpleMenu():
    def __init__(self):
        self.buttons = []
        self.backdrop = DirectFrame(frameSize = (-1, 1, -1, 1))

    def addButton(self, buttonText, buttonCommand):
        btn = DirectButton(text = buttonText,
                           frameSize = (-5, 5, -0.5, 1),
                           command = buttonCommand,
                           scale = 0.1,
                           parent = self.backdrop)
        self.buttons.append(btn)

    def layoutButtons(self):
        buttonSpacing = 0.2
        numButtons = len(self.buttons)

        topZ = (numButtons - 1) * 0.5 * buttonSpacing

        for btn in self.buttons:
            btn.setZ(topZ)

            topZ -= buttonSpacing

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

        self.menu = SimpleMenu()

        self.menu.addButton("Kittens", self.kittenMethod)
        self.menu.addButton("Meowers", self.meowerMethod)
        self.menu.addButton("Add a Button", self.addButtonMethod)
        self.menu.layoutButtons()

    def kittenMethod(self):
        print ("Kittens!")

    def meowerMethod(self):
        print ("Meowers!")

    def addButtonMethod(self):
        self.menu.addButton("Cats!", self.catMethod)
        self.menu.layoutButtons()

    def catMethod(self):
        print ("Cats!")


game = SimpleGame()
game.run()

The two convenience-functions there allow one to create multiple buttons of consistent style via a single line of code per button, and to then position them without having to manually specify those positions by hand.

(One could of course include the layout code in the button-addition code–but this way provides greater flexibility: there may be cases in which one wants to layout without creating buttons, or to make many buttons without incurring repeated layouts.)

Hi All

@ Thaumaturge
Thank you very much that helps a lot.
I really appreciate the help.

1 Like