Developers: Favorite GUI framework?

I’m largely posting this thread to move discussion away from this GitHub issue and to gain some input from the userbase.

We’re looking to deprecate libRocket, which is (was) great in that it’s a resource-based GUI framework - it runs (ran) on the HTML-derived RML language for expressing a GUI independently of programmer assistance. Unfortunately, it’s abandonware and not compatible with Python 3.x, so unless someone’s willing to step forward and maintain it, we’re not going to be able to continue supporting it.

There are far better options out there these days; so rather than trying to add yet-another-directgui-alternative, we should probably try to pick something that would fit most use cases for Panda app developers, and thus can be a more “standard” Panda GUI toolkit.

I’m probably heavily biased by my own perspective, but the way I see it, what’s important here is:

  • Lightweight: Should not add more than about a dozen or so MB to the built binary size.
  • Resource-based: Your team’s GUI designer should be able to edit the GUI with minimal/no coordination with your team’s programmer.
  • Procedurally-friendly: Not every app developer cares to put special attention into creating GUI resources; sometimes one simply wishes to hammer out a quick “setup_gui()” function that places all of the widgets. A procedurally-friendly interface would be nice - but note that any resource-based framework is necessarily procedurally-usable, since an app can always create the necessary resources on-the-fly.
  • Performant: We’d like the GUI toolkit to generate as few draw calls as possible - pgui, for instance, is heavily dependent on the Panda scenegraph, which means full transform changes and primitive batches for each widget.
  • Portable: Should run equally well on desktop and mobile (and other) platforms; should not assume a single rendering API (e.g. so it can target GL, Direct3D, Vulkan, etc.)
  • Flexible: Ideally, it’d be nice if the toolkit didn’t assume it was a 2D overlay running in screen-space. This allows for widgets to be spatially positioned in the scene, with GUI interactions driven by ray-casting and/or VR controller point-and-click.
  • Embedded+standalone?: A nice-to-have feature would be a GUI toolkit that supports rendering both within a 3D framebuffer, and onto a desktop using the platform’s native windowing system. This means that teams familiar with the in-app GUI toolkit can easily use it to create out-of-app GUIs as well, or perhaps create interfaces in which the Panda viewport is yet another widget itself.
  • Usable both from C++ and from Python: As many developers prefer the C++ interface to the engine; it should be easy to set up a GUI using pure C++ code.
  • Permissively licensed: Ideally under BSD/MIT license so that the terms of using the GUI toolkit don’t differ substantially from the terms of using Panda3D itself.

To that end, I tried to narrow this down and find some options myself. We can effectively split the choice here between HTML-based and non-HTML, so I’ll list each:

HTML-based:

  • Chromium Embedded Framework

    • Pro: Permissively licensed under BSD.
    • Pro: Includes its own JavaScript scripting engine, independent/isolated from the game scripting engine, resulting in a minimum attack surface if the HTML is modified.
    • Pro: Works either embedded or standalone
    • Con: Heavy! It’s about 100MB in size.
    • Con: May not be very portable, as Chromium itself has a lot of OS-dependent code.
    • Con: Although it does work standalone, it’s an odd choice that can’t easily be made to resemble the desktop’s native GUI framework.
  • litehtml

    • Pro: Much lighter weight than Chromium
    • Pro: Permissively-licensed
    • Con: Does not include its own JavaScript implementation
    • Con: Not a full HTML implementation
  • Ultralig.ht

    • Pro: Developed by the Awesomium author
    • Pro: Purpose-built for this exact use case
    • Con: Not open source. Trying to support non-x86 platforms? You’re completely out of luck.
    • Con: Very restrictive license, of the “we want to know how much revenue you’re making” sort.

Non-HTML:

  • Kivy

    • Pro: Multitouch is a first-class feature
    • Pro: Includes the Kv design language, making it somewhat resource-based
    • Pro: Implemented primarily in Python, making the interface very comfortable for Python users
    • Pro: Mobile support is a primary objective
    • Con: Not usable from pure C++
  • Qt/QML

    • Pro: A very popular framework, with which many F/OSS developers are already quite familiar.
    • Pro: QML is a great, resource-based approach to GUI design
    • Pro: Very usable from pure C++
    • Con: Not very usable from Python - bindings for Qt5 are available, but as yet somewhat immature.
    • Con: Might be too heavy.
    • Con: LGPL license may be too restrictive for some use cases.
  • Dear ImGui

    • Pro: Lightweight
    • Pro: Popular
    • Pro: Good license
    • Pro: Easy to use from C++
    • Con: Not resource-based; GUI must be implemented in code
    • Con: Immediate-mode operation means the GUI code must run in the draw thread - if Python-based, means the Python GIL will be held while drawing and block the app thread

What are everyone else’s thoughts?

1 Like

Coming at this from a front-end design standpoint: We recently released a GUI-heavy update to our game where we built a custom Options Panel. These are the main two issues that made it a very tedious task for us:

  1. Many DirectGui elements don’t follow modern interface standards.
    The most plain example of this is DirectOptionMenu, which isn’t intuitive to the general user who is used to web drop-down forms. (You have to click and hold to select a new option, there’s no scroll bar to sort through the options, etc.)

  2. There was no easy way for us to adjust the GUI position or try different layouts.
    At least half of the front-end work is plugging in a position, open the game, open the GUI, close the game, rinse and repeat. This can get especially daunting if the GUI you’re tweaking is buried deep and takes a few minutes to reach in-game.

I’ve only briefly looked through Kivy, but I like that most of the options presented so far. The Kv Design Language would be neat for artists so that they can play with the appearance GUI elements easily.

Whatever the library, Panda could really use some investment in GUI tools. Having some sort of editor to eliminate the rinse-and-repeat method would significantly reduce development time for our team.

Hey, how about CEGUI? It’s liberally (MIT) licensed, supports scripting, extremely reskinnable, comes with its own editor and tooling, and is pluggable enough that we can write our own “Panda” backend for it (so it supports any rendering API that Panda would support).

So far I can’t think of any cons to this option - although I don’t know if it supports multitouch like Kivy and probably can’t operate standalone. Might need to research this option a bit better.

DirectGUI is not that bad, you can hack the hell out off it and do really nice things … but the draw call per widget is the killer here. A rpg style inventory or character screen can have 50, 100, 200 or more buttons, fields, slots, things and using DirectGUI for that means you can kiss 60fps goodbye without even rendering a 3D object.

CEF looks like an overkill, and with +100MB added - that’s a ‘no’ from me. I don’t care that much for HTML, and C++, so for my own use Kivy looks like a good choice, but CEGUI also looks ok. But to be honest I have no idea how any of these perform.

What about LUI? I never got it compiled (cursed PC, allergic to building anything, don’t arsk…), but I remember people on irc telling me it’s good.

Personally id vote for CEF to at be an available option though having it as the primary is slightly overkill for most people. My vote would be for a solution that is both available from C++ and Python.

I think the main problems with DirectGUI are its non-usability for apps that don’t make use of direct, programmer-centrism (the few UX people I’ve known hate having to touch code), and yeah, the performance. As a programmer, I love toolkits and platforms that are super hackable, but it’s something of a kiss of death for diverse teams that don’t have a programmer available for every artistic task. If there’s one thing overworked programmers like, it’s being handed ready-made drop-in assets and not more specifications/wireframes.

I’ll need to pro/con this one too. I only saw it in passing, so I don’t know about it. Are you suggesting it as the “standard Panda GUI system” to be included as part of Panda? Or just suggesting that we understand its approach to help us in our decision here?

So, vote for CEF as an HTML rendering add-on, but against CEF as “the” GUI toolkit.

I think that’s roughly where I stand as well. There’s many, many cases where an app developer would want to be able to show web content within their app, and if their assets are already a few dozen GBs anyway, an extra 100MB would increase the size by less than half-a-percent. CEF just shouldn’t be required to use Panda.

I mentioned this on the GitHub page, but those who are interested in using CEF, there is the cefpanda project. I can work on cleaning it up some more if there is interest. Unfortunately, this is Python only as it relies on cefpython.

if I was going to throw my vote in for a framework for general use Id actually consider CEGui. The idea of having external files and editors for the GUI makes it a lot easier for content patches in something large scale then direct GUI ever was. Especially when you consider how we personally compile our games. Its Cython based so having to go through the whole process of compiling the executable again to make a GUI change is annoying. It would be a lot easier to just modify something in the resources and push a patch for that.

What I do think is that Panda3D itself should not implement any GUI system at all. GUI systems often become abandoned because almost every user has its own set of requirements. I don’t think that Panda3D team is able to support a monster GUI framework like Qt or GTK to satisfy needs of all customers.

But I do think than Panda3D should implement a nice and clean interface, so users can interact with their own favorite GUI system, or write their own wrappers, like Flask users do. Once implemented, this interface would be relatively easy to maintain and it will give users great freedom to choose.

Conversely, I think that it’s really handy to have a built-in (or at least “out-of-the-box” third-party) GUI provided. It allows users who don’t have a preferred GUI framework to quickly build something with Panda3D.

(I don’t think that I’ve used anything but DirectGUI for ages now. It may be clunky, but it works, and it’s convenient.)

DirectGUI is evil, I was angry when I could not set it up as I wanted it. But I began to use lower levels of TextNode and DirectFrame classes. And I was able to realize what I wanted, I think manual should start with them, instead of DirectGUI. Inference panda should teach to create GUI based on its classes.

2 Likes

I’m curious, if I may: what were you attempting to implement that DirectGUI didn’t allow?

(I do know that it’s missing a few widgets, like numeric spinners, for one thing!)

I’m enjoying tobspr’s LUI personally, it would certainly be the easiest to integrate into the engine since it was written for it. From a designer’s standpoint, it would definitely benefit from some sort of markup language, however.

1 Like

Pay attention to the same digressions in the menu between the points. The distance between the names are recalculated upon request. Example when needed, for example localization in real time. I do not think that it can be done by DirectGUI. Also on the video you can see that I could not do with the list of DirectGUI - language selection, I could not turn off the background of the elements. How can I set transparency for elements?

I’m not sure of what you mean by this–unless you mean the distance between names that you mention in your next sentence! ^^;

For that, indeed, TextNodes might be better than simple labels; I agree. But then again, TextNodes seem to me to work well within or alongside DirectGUI.

What I’ve done for localisation of things like DirectLabels and DirectButtons, I believe, is to assign the “text” value of the object, then call “setText” and “resetFrameSize”. That said, it’s possible that I’ve missed some issue with this! For example, I might have code something like this:

myDirectButton["text"] = getSomeLocalisedText("textID")
myDirectButton.setText()
myDirectButton.resetFrameSize()

(It’s possible that some of that is superfluous for DirectButtons or DirectLabels–it’s very possible that I just applied the same logic to all such widgets, given that I have a fair few objects to localise. ^^; )

In all fairness, I don’t think that I’ve had a layout that called for the objects in question to be re-located when localised.

As to the background of the elements, I take it that you want to make the items show up with no surrounding panel? That should, I think, be possible with a bit of work. Looking at the code for “DirectOptionMenu”, I see that it creates a popup-menu object. It might be possible to set the “frameColor” for that object to be transparent (see the next section below for notes on that). If so, note that you may find that the items themselves will be similarly transparent unless you additionally specify a non-transparent “frameColor” for them.

As to transparency in general, I think that you do that in much the same way as any other node: “myNodePath.setTransparency(True)” (or whatever specific transparency mode you want), perhaps followed by re-binning it as called for.

[edit]
Ah, I’ve just realised that you probably mean that you want to set transparency for the items in a DirectOptionMenu. You can pass DirectGUI keyword-arguments for them by passing in an argument starting with “item_”, I believe. So, for example, if you want the items of such a menu to be green, when constructing the menu you might pass in the keyword argument “item_frameColor = (0, 1, 0, 1)”. If you want to access them later, I think that it an be done, but I’d have to look up how to do it, I think.
[/edit]

Don’t misunderstand me: DirectGUI is a clunky thing, and makes a number of tasks more difficult than I might like. I’m not opposed to replacing it with something better!

Indeed, I’ve created at least one sub-class of a DirectGUI widget in order to adjust the behaviour of that widget: I found that DirectOptionsMenu could easily end up placing its popup menu outside of the bounds of a parent DirectScrolledFrame, so I made a version that checks for this case.

Let’s keep this discussion focused on consideration of other GUI frameworks, and not get distracted by discussing the intricacies of DirectGUI.

1 Like

@JoeyZio I feel the pain, much of the work i did for former projects were GUI based. Simple things were just really tedious. Especially the DirectOptionMenu as you stated, I just wrote my own really simple menu that is just a couple of buttons with a faded background. Terrible solution, but i was just sick of dealing with drop downs. Even the guis i put the most effort into look relatively terrible compared to interfaces i make for websites, and other game engines.

About Chromium, not only is it heavy in size, it also has a good amount of overhead, so for games like Toontown, where lower end devices are already kind of starving of CPU power, it is not a good solution.

However, an HTML-Based would be REALLY preferred.

It would also allow game devs to easily implement a feature where they can customize the ui, much like in minecraft: bedrock edition. This was a feature i started to implement into a project i formerly developed for, however, since it was using the DirectGUI, it was really rudimentary, and I never ended up doing much with it due to having to focus on other parts of the game at the time.

Most game engines now a days either use an HTML (or xml, but thats basically the same thing) based system, or just a fully visual designer (like Unreal / Unity), so having the HTML would be the easiest to use, as its very widely used.

As someone who does a TON of UI stuff, I really am excited to see a conversation finally coming up./

Alongside with clean API for any GUI system, we can go with LUI. It seems to be fast, light-weight and convenient.

I would like to vote for any GUI, that brings some type of markup language with it. Extra points for lightweight, both in render performance and overall overhead.

1 Like

Ah, my apologies if I went overboard on that! ^^;