panda3d / panda3d

Powerful, mature open-source cross-platform game engine for Python and C++, developed by Disney and CMU
https://www.panda3d.org/
Other
4.46k stars 781 forks source link

Improving the UI #317

Open BMaxV opened 6 years ago

BMaxV commented 6 years ago

Hello everyone,

I recently switched from the blender game engine to panda and I want to contribute code and help to improve it where I can. The most obvious thing is the UI, because there is something I want the UI to do, which it currently can't. That's drag drop functionality to build an RPG like inventory as an example, but I imagine there would be numerous use cases for that.

So I looked at the various bits of code and the development doesn't seem to be that active at the moment, so I'm opening this issue, for people to collect suggestions and requests, things they would like added or improved or maybe even removed or done differently.

I can read&write python and I can read c++, but not very confident in my ability to write good c++, so I'll need a bit of help for that.

To start out with some suggestions or critique:

I think the drag drop functionality I want is already present in the PGSlider and DirectSlider, it's just not exposed enough to be useable outside of that class. So that should be doable without too much trouble by moving some code around.

I also noticed that the Direct GUI elements do some things I would consider a bit strange: mostly the use of imo unneeded globals, the use kw** to handle arguments and offloading the actual construction and initializing of objects to other places than the classes __init__. The DirectGUIBase has an in depth __init__that is then overloaded and called withsuper(self).__init__ in the child classes.

I'm sure there are a reasons for these, they're just not obvious to me. There are lots of commets (+1) but unfortunately they don't explain why it's this way, just how it's done.

One of the biggest questions I have that isn't answered by the code, comments or the manual is whether the functionality should be available from python or c++ or both equally.

It'd also be very nice to know if there are some kind of target tests that shouldn't be broken or some common use cases that should be considered.

wezu commented 6 years ago

DirectGui is surprisingly flexible, and I've yet to see something it can't do. You can drag&drop any DirectGui widget. You need to make a task tracking the mouse cursor position and updating the position of the dragged widget, and bind some events to know where the widget got dragged to. It's not out-of-the-box functionality, but not too hard to code (I can post some Python code if you want me to).

Having said that - DirectGui is kind of horrible, slow(-ish), strange, quirky and forces you to write miles of spagetti code.

BMaxV commented 6 years ago

I can post some Python code if you want me to

Please do, sounds like it can be improved either way, at least by adding this to the module.

wezu commented 6 years ago

Here's a drag&drop demo: https://gist.github.com/wezu/17c8021fe2bcbff3e0ef7d3a8460ab90

Moguri commented 6 years ago

@BMaxV was @wezu's demo sufficient for your use case? If so, we should add a Manual page on drag and drop with DirectGUI based on the demo.

BMaxV commented 6 years ago

The demo is nice, most drag and drop systems have some form of lock or snap though, I'm sure I can do something like that and then we/I can create a manual page for it.

montreal91 commented 6 years ago

Here's a drag&drop demo:

Maybe we should do a page or repo (or both) with such code snippets written by users?

BMaxV commented 6 years ago

Isn't that what the "samples" directory is supposed to be? I am almost done with my sample by the way, I'll probably upload it today or tomorrow.

BMaxV commented 2 years ago

Since I fell over some non explained issues with direct again, I'd like to reactive this issue and would like people to voice wishes and requests, for an eventual rewrite.

It would be necessary to collect and understand people's requirements, E.g. @fireclawthefox has done a lot of things with it and I think @ArsThaumaturgis has some experience with it? Simulan on discord mentioned he did the UI. Everyone else please speak up.

It would be cool/required for a rewrite to be minimally invasive and at best provide opportunities to improve code in other projects as well.

@rdb @Moguri I would appreciate if we could set up some kind of weekly thing were we look at progress for a few minutes, must haves/must avoids. Also your stance on when/how to do a breaking version and deprecate functions.

I really like panda and you guys, but asking around for help and trying to read source is not "viable" if anyone is supposed to build any "real" game with panda. Especially when it's about "simple" things like setting a texture for a button or trying to link multiple functions to the same button or slider.

The key problem with DirectUI is that nobody understands it. (counter point, if you do, please speak up and explain it)

I tried diving deeper into how DirectUI assembles itself, it's a nightmare, (no offense).

The original idea of it isn't so bad:

The problem is that it's completely in-transparent where and how values and functions are actually set in the end:

class DirectScrolledFrame(DirectFrame):
    def __init__(self, parent = None, **kw):
        optiondefs = (           
            ('pgFunc',         PGScrollFrame,      None),
            ('frameSize',      (-0.5, 0.5, -0.5, 0.5), None),

            ('canvasSize',     (-1, 1, -1, 1),        self.setCanvasSize),
            ('manageScrollBars', 1,                self.setManageScrollBars),
            ('autoHideScrollBars', 1,              self.setAutoHideScrollBars),
            ('scrollBarWidth', 0.08,               self.setScrollBarWidth),
            ('borderWidth',    (0.01, 0.01),       self.setBorderWidth),
            )
        #...
        self.defineoptions(kw, optiondefs)
        #...
        # Call option initialization functions
        self.initialiseoptions(DirectScrolledFrame)

Also this:

    def commandFunc(self):
        if self['command']:
            self['command'](*self['extraArgs'])

my example problem

In the problem I have right now, I want to bind this function to control two scrolledFrames at once.

I can't find the function that's sitting between the scroll bar and the scrolled frame. Doesn't really matter though, the problem should be similar to wanting to control or understand any controlling of things with scrollbars or UI elements of things in general.

When ScrolledFrame is created, it's not explicitly stating which function it is, but it is creating ScrollBars.

https://github.com/panda3d/panda3d/blob/dd3510eea743702400fe9aeb359d47bd2f5914ed/direct/src/gui/DirectScrolledFrame.py https://github.com/panda3d/panda3d/blob/dd3510eea743702400fe9aeb359d47bd2f5914ed/direct/src/gui/DirectScrollBar.py

The scroll bar sets up this, which is possibly some function and then no additional command function that's being called, so whatever self.commandFunc is when .bind is being called, it has to be some default.

    def __init__(self, parent = None, **kw):
        optiondefs = (
            # Define type of DirectGuiWidget
            ('pgFunc',         PGSliderBar,        None),
            # ...
            # Function to be called repeatedly as the bar is scrolled
            ('command',        None,               None),
           )

        # Bind command function
        self.bind(DGG.ADJUST, self.commandFunc)

It has to exist somewhere. There has to be an onclick onmove trigger or something. From .bind exists and ADJUST = PGSliderBar.getAdjustPrefix() we know at least the event name gEvent = event + self.guiId an event being defined in DirectGuiGlobals.

.bind does not much more than doing this:

self.accept(gEvent, command, extraArgs = extraArgs)

Logically, I should be able to find this entry in some event listener and find which function is being called but I don't know where I would look for that.

The docs don't explain that part, only how to create new events or how to ignore events from/for an object. Looking at the events docs page mentioned importing messenger, so messenger...

from direct.showbase.MessengerGlobal import messenger
print(messenger)

can show me the events, but

The messenger is currently handling:
================================================================
adjust-pg11                         DirectScrollBar.commandFunc 
adjust-pg7                                  DirectScrollBar.commandFunc 
async_loader_0                      Loader.__gotAsyncObject 
click-mouse1-pg1                    DirectButton.commandFunc 
click-mouse1-pg10                   DirectButton.commandFunc 

This just tells me it's .commandFunc which I mentioned above and actually tells me nothing. Interestingly, when I try to access self['command'] I'm told by the interpreter that that doesn't exist.

ArsThaumaturgis commented 2 years ago

There has been some discussion of replacing DirectGUI, as I recall. See the following thread, for example: https://discourse.panda3d.org/t/developers-favorite-gui-framework/24207

I do agree that DirectGUI can be a little opaque at times, and there are cases in which properties cannot be set after construction--or, worse to my mind, are lost after some change is applied.

Still, I've generally found it reasonably powerful and flexible--not perfect, and with some frustrations, but overall effective.

... but asking around for help ... is not "viable" if anyone is supposed to build any "real" game with panda.

I mean, unless such asking is occurring to a problematic degree, or answers are not forthcoming, I think that asking for help (or searching for answers already available) is actually pretty normal in game development.

In the problem I have right now, I want to bind this function to control two scrolledFrames at once.

It has to exist somewhere.

It looks like this is in part handled in the C++ side of the widget (i.e. within pgScrollFrame).

Unfortunately, if the events are handled via something lower-level than the command-functions of the component widgets--which I think might be the case here--then finding the command might take some digging.

However, since the command-func isn't being used, there's little to stop you from using it. Something like this:


from direct.showbase.ShowBase import ShowBase

from direct.gui.DirectGui import *

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

        self.frame1 = DirectScrolledFrame(frameSize = (-1, -0.2, -1, 1),
                                          canvasSize = (-1, -0.2, -10, 1))
        self.frame2 = DirectScrolledFrame(frameSize = (0.2, 1, -1, 1),
                                          canvasSize = (0.2, 1, -10, 1),
                                          verticalScroll_command = self.controlOtherFrame)

    def controlOtherFrame(self):
        val = self.frame2.verticalScroll.getValue()

        self.frame1.verticalScroll["value"] = val

app = Game()
app.run()
BMaxV commented 2 years ago

Ok that works, thank you. It has taken "me" the better part of two days to accomplish this now. It's frustrating.

It doesn't resolve the general problem with DirectGui. (will read that thread now)

I think that asking for help (or searching for answers already available) is actually pretty normal in game development.

Sure, I'm not leaving in frustration after all, and some asking will inevitably happen anyway.

But the solution you just gave me is not documented:

verticalScroll_command and horizontalScroll_command are probably set up somehow from the self.createcomponent part in DirectScrolledFrame. And it doesn't even show up in the messenger printout in the end. This is purely something DirectGui does for itself. Why is it is necessary to do it this complicated way?

it's not in the docs

https://docs.panda3d.org/1.10/python/programming/gui/directgui/directscrolledframe https://docs.panda3d.org/1.10/python/programming/gui/directgui/directscrollbar

and it's not in the source either. The only way I can see anyone do this is to ask.

So far, most of the things I wanted to do were doable in some way, mostly in the sense that others have found them. I agree that there are parts of it that work well and keeping those should be a requirement. I strongly suspect the parts that are weird about DirectGui are not the things that reach into C++ territory.

E.g. as I/we have learned today, having a .bind is completely redundant. And I don't think the DirectGuiGlobals does anything more than obfuscate that it's very simple strings and numeric values being passed.

If it's literally as simple as

  1. create geometry/text on screen, which we don't need DirectGui for as far as I can tell
  2. create an accept with the correct keywords (which are document in DirectGuiGlobals) but they just translate to strings and ints
  3. tie to that whatever function is necessary

Then we don't need the rest? That's kind of my question.

ArsThaumaturgis commented 2 years ago

But the solution you just gave me is not documented:

Yeah, it's somewhat implicit:

Hence the arguments that I used above.

Why is it is necessary to do it this complicated way?

That, I'm afraid, you might have to ask the original developers of the system!

I will say that in designing software it's quite easy to have an idea that seems good, but that much further down the line turns out to incur complication. That may be the case here.

E.g. as I/we have learned today, having a .bind is completely redundant.

Eh, "bind" has its uses. There are things that one might want to do that aren't covered by the command-func, or the default behaviour.

For example, one might want a secondary widget to change colour when the mouse hovers over a particular button. I don't think that DirectGUI provides any sort of "hoverCommand" parameter, so binding fills in.

In short, "bind" provides a more-complex by more-flexible system for registering for UI-events.

And I don't think the DirectGuiGlobals does anything more than obfuscate that it's very simple strings and numeric values being passed.

Where would you suggest keeping those values, then?

If it's literally as simple as

  1. create geometry/text on screen, which we don't need DirectGui for as far as I can tell
  2. create an accept with the correct keywords (which are document in DirectGuiGlobals) but they just translate to strings and ints
  3. tie to that whatever function is necessary

Then we don't need the rest? That's kind of my question.

I suspect that creating a functional and reasonably-flexible UI system would be a bit more complex than that suggests.

In particular, widgets that have sub-components--like DirectScrolledFrame--introduce some complexity. I'm not a huge fan of DirectGUI's solution, let me note, but it is something that seems likely to be called for. (Presuming that one wanted to avoid replicating code by re-implementing things like scroll-bars.)

And conversely, you could make your own UI much as you describe, if you so desired. There's little to stop you.

Another thought: you might perhaps look at tobspr's "LUI". I don't know whether it works with the current version of Panda, but you could try: https://github.com/tobspr/LUI

BMaxV commented 2 years ago

Another thought: you might perhaps look at tobspr's "LUI". I don't know whether it works with the current version of Panda, but you could try:

Currently not working, but not because of the build. There is an import error.

DirectGuiGlobals

Where would you suggest keeping those values, then?

In a doc page relating to event handling.

ArsThaumaturgis commented 2 years ago

In a doc page relating to event handling.

No, I mean in the code: where would you make those values available for the programmer?

BMaxV commented 2 years ago

What do you mean. Not at all. It's meta knowledge, all you need to know is that the value triggers the thing?

Why do you need to import that?

What you need is accept(event, function, argument) and you need to know that "0" code for the event you mean.

This below should be in a table in the docs with a proper name : 0

# DirectButton States:
BUTTON_READY_STATE     = PGButton.SReady       # 0
BUTTON_DEPRESSED_STATE = PGButton.SDepressed   # 1
BUTTON_ROLLOVER_STATE  = PGButton.SRollover    # 2
BUTTON_INACTIVE_STATE  = PGButton.SInactive    # 3

It's like accept("mouse1",function,argument) "mouse1" isn't in the code either.

ArsThaumaturgis commented 2 years ago

What do you mean. Not at all. It's meta knowledge, all you need to know is that the value triggers the thing?

Why do you need to import that?

What you need is accept(event, function, argument) and you need to know that "0" code for the event you mean.

That way is error-prone, however.

After all, if a constant is stored in a variable, then the interpreter can warn you of a typo: if you type "DGG.BUTTON_DEPRESSED_STATE0" (accidentally appending a "0" to the name), then you'll likely get an error pointing at exactly the mistake that you made.

Conversely, if the constant is "hard coded", then the same typo--"10"--yields no helpful error, but does potentially cause the program to break, perhaps in unexpected and hard-to-find ways.

Further, if the constant ever needs to be changed, then code that relies on it updates "automatically"--there's no need for people to hunt through potentially-huge code-bases to find values that may or may not refer to the constant that has been changed--and all too likely miss some.

Storage in variables is much safer.

Not to mention that it's far more convenient: it's easier to start typing "DGG.BUTTON_" and then let the IDE suggest values for you than to memorise or tab over to the docs to find the relevant number. (And even if you don't have code-completion in your IDE, names will tend to be more memorable than numbers, I daresay.)

It's like accept("mouse1",function,argument) "mouse1" isn't in the code either.

Sure--but it might be better if it were.

fireclawthefox commented 2 years ago

I'd like to reactive this issue and would like people to voice wishes and requests, for an eventual rewrite.

Actually the way directGUI is set up is really flexible and blends in just nice with how Panda3D works in general. It does has its shortcomings but I wouldn't say it requires a full rewrite except if things can't be solved with the current structure.

The major points that I see would need improvement after using this system for years and in larger scale projects would be (in no particular order):

  1. Ensure all properties can be set and gathered from index style referencing
  2. Return predictable values and enforce sane defaults, for example sometimes things like frameSize can be None while the element still has a size or some properties can be set using a simple string path but return a model or texture after creation.
  3. Change setup of some widgets to not have options that are only able to be set during initialization (all properties should be able to be changed after creation)
  4. Simple ways to increase performance of large UIs (multiple hundred elements)
  5. Enhancements for layout systems
  6. Non-mouse input navigation (e.g. a simple way to map tab, arrow keys or gamepad d-pad keys to jump between interactive controls, activate a button by hitting enter, etc)
  7. Simple themeability
  8. Some way to set up a UI from a Designers point of view. Currently creating a GUI requires knowledge of python but something like a markup language (xml, html, json for example) would be more in line what designers know from other toolkits. This may also help other endeavors like my DirectGUI Designer to become more standardized.

None of that would require a full rewrite nor replacing it with a whole different GUI system which will probably brings its own drawbacks. On the other hand it would greatly improve how DirectGUI can be used.

And yes, some special things are not documented, but that again is another topic, if something is not documented, there should be an issue opened on the manual proposing its inclusion.

ArsThaumaturgis commented 2 years ago

One point that I might add to the above is that there is at least one class that resets certain elements of theming after particular changes are made to it. That issue I'd like to see fixed. (And in other classes that have the same issue too, if any.)

(That said, I think that I do actually have a pull request open for the issue in the class in question.)

Change setup of some widgets to not have options that are only able to be set during initialization (all properties should be able to be changed after creation)

This is a point that I'd particularly like to have fixed!

Non-mouse input navigation (e.g. a simple way to map tab, arrow keys or gamepad d-pad keys to jump between interactive controls, activate a button by hitting enter, etc)

The main problem that I see here is that whatever is put in place might then clash with the developer's control-scheme. :/

Simple themeability

This would be nice, indeed!

Theming can, of course, be done--but it's a by-hand system at the moment, which can get quite tedious, especially if one doesn't set up one's own custom theming functions.

This may also help other endeavors like my DirectGUI Designer to become more standardized.

I would actually really like to see DirectGUI Designer become the standard tool for setting up Panda3D GUIs, myself.

fireclawthefox commented 2 years ago

The main problem that I see here is that whatever is put in place might then clash with the developer's control-scheme. :/

Right, it could of course be enabled explicitly by the developers or for example be enabled if the focus is already within a control like the DirectEntry which already grabs most keyboard input and otherwise doesn't really has a way to actively loos its focus again.

Theming can, of course, be done--but it's a by-hand system at the moment

There are also very minor theming thing available like the default font or background image of dialogs, which can all be set via the DirectGuiGlobals, but it'd be nice to have a little more for elements that get used more often like buttons and entries. Though, that would require the theming engine to be reasonable complex to handle different types of buttons and entries and whatnot. But that's a discussion better held in its own request issue.

ArsThaumaturgis commented 2 years ago

Right, it could of course be enabled explicitly by the developers or for example be enabled if the focus is already within a control like the DirectEntry which already grabs most keyboard input and otherwise doesn't really has a way to actively loos its focus again.

Even then, if the developer has, say, movement mapped to the numpad and DirectGUI responds to the arrow keys, but not to the numpad, then the developer may end up with an inconsistent UI.

This might be alleviated by allowing customisation (such as by specifying which keys are used to navigate--my own home-made menu-navigation system does this)--but even then, it may be inconsistent with some unusual UI schemes...

... it'd be nice to have a little more for elements that get used more often like buttons and entries. Though, that would require the theming engine to be reasonable complex to handle different types of buttons and entries and whatnot. But that's a discussion better held in its own request issue.

Indeed, on all counts!

(And I didn't know about the default font and dialogue-backgrounds! ^_^)

fireclawthefox commented 2 years ago

Even then, if the developer has, say, movement mapped to the numpad and DirectGUI responds to the arrow keys, but not to the numpad, then the developer may end up with an inconsistent UI.

Yeah, that's why it should be configurable by the developer. There are plenty of input methods one may use. Regarding the UI scheme, I'm not 100% sure what you mean there, is it regarding how the UI should behave when navigating, like where to jump next? If so, that could easily be handled by creating a dedicated jump index on the controls, something like the draw order but for navigation. And for real complex UIs maybe have an option to override the "jump to" method to extend the logic to the users desire.

But I also think this is going to much into the implementation specifics and we should create extra issues for those topics to be discussed in detail and finally get implemented. I'd also gladly implement some of these things on my own.

janEntikan commented 2 years ago

https://github.com/panda3d/panda3d/issues/1242

I'll also mention this issue here for prosperity.

ArsThaumaturgis commented 2 years ago

Yeah, that's why it should be configurable by the developer. There are plenty of input methods one may use.

That is fair.

Regarding the UI scheme, I'm not 100% sure what you mean there, is it regarding how the UI should behave when navigating, like where to jump next?

I suppose that I'm thinking that a developer might come up with some way of controller the UI that's very different. For example, perhaps the developer has come up with a three-dimensional UI, one that uses buttons to rotate the entire UI around the vertical and horizontal, with selection between widgets then being dependant on view.

That said, perhaps you're right that even strange cases might be handled by clever setting of custom widget-connections.

But I also think this is going to much into the implementation specifics and we should create extra issues for those topics to be discussed in detail and finally get implemented.

That is a good point.

I'd also gladly implement some of these things on my own.

I have some code myself that handles non-mouse navigation (amongst other things)--but that's not really up to being made available for public use, I fear.

fireclawthefox commented 2 years ago

a developer might come up with some way of controller the UI that's very different.

Yes, that's what I thought too and indeed there do exist very exotic UIs but there probably will never be a UI that doesn't work like a tree structure, no matter how flat or deep it may be since that's how it'll look behind the scenes in Panda3D anyways. Even if it's some fancy spinning 3D model with UI elements spread across it. It probably requires a custom setup for moving from one element to the other, but even that should be doable the way I proposed it.

That is a good point.

I guess I'll start writing up some things and create issues later today so things won't be forgotten and can be assigned to work on.

I have some code myself that handles non-mouse navigation (amongst other things)--but that's not really up to being made available for public use, I fear.

That's not a problem, if something will be integrated into the engine, it should be done for all elements and I guess best be somewhere in the core, the pg elements if possible.

fireclawthefox commented 2 years ago

Alright, most of the topics should be covered with dedicated issues now:

1 & 2 Property usage - #1350 3 Property return values - #1353 6 UI Navigation - #1351 7 Theming support - #1242 (thanks @janEntikan ) 8 GUI designer language - #1352

topics 4 and 5 require some more investigation and exact details before issues can be created.

ArsThaumaturgis commented 2 years ago

Thank you for doing that! ^_^

BMaxV commented 2 years ago

Something else we can hopefully agree on is the topic of spacing. I ran into an issue today where the position value worked out in an unexpected way.

OnScreenText uses of course the relative 2d coordinates from -1 to 1 representing x space on screen left to right and the same deal for y -1 being the bottom of the screen.

It turns out that that's not quite true. In other words, and the issue I ran into today, is that this:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import TextNode
from vector import vector
from direct.gui.OnscreenText import OnscreenText

class Wrapper:    
    def __init__(self):

        self.b = ShowBase()

        text="default"
        pos=(1,0)
        align="right"
        scale=0.07
        #scale=1
        if align=="right":
            align=TextNode.ARight
        elif align=="left":
            align=TextNode.ALeft
        else:
            raise TypeError

        o=OnscreenText(text=text, scale=scale,
        align=align, pos=pos,
        fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5))

def main():
    W = Wrapper()
    while True:
        W.b.taskMgr.step()

if __name__=="__main__":
    main()

does not result in text that's really hugging the right side of the screen. I can probably whip something up to move it there anyway, but the entire point of having a relative 2d coordinate system is that I should have to deal with this.

It looks like it instead uses the aspect 2d relation, if I use that it works out, but it's weird.

So when it comes to laying out UI, here are some points:

ArsThaumaturgis commented 2 years ago

It looks like it instead uses the aspect 2d relation ...

That's what most DirectGUI widgets used, I believe.

(And I would argue in favour of it, as that provides coordinates that are normalised for the window-resolution.)

Of course, I believe that you can always place things "manually" as you please, like so:

myOnscreenTextObject.setPos(render2d, 1, 0)

I can probably whip something up to move it there anyway, but the entire point of having a relative 2d coordinate system is that I should have to deal with this.

For what it's worth, you can do this via Panda's "a2d" nodes--there's a whole set of nodes that automatically keep their place relative to the window, allowing for reliable placement at such positions as the edge of the screen.

This is, alas, one of those things that does seem to be poorly-documented. But in short, the nodes are named along the lines of "a2dTopRight" and "a2dBottomCenter".

I find that my IDE picks them up, and you should find a list of them in the source-code, at least, starting here: https://github.com/panda3d/panda3d/blob/0a3733ccb9fe15a9c00838a78b062958674ed3a3/direct/src/showbase/ShowBase.py#L1216

it would be cool if we have html like fillable containers that automatically readjust the contents based on the size of the element. possibly converting to scrollable things when needed.

That would indeed be cool!

I think that a community-member (perhaps fireclawthefox?) created some such widget(s)--but I don't know whether whatever was created there is available, or suitable for broad use.

absolute offsets to relative points

Something like this could indeed be useful, I think. While, again, "manual" placement can provide this, it might be handy to have the option to have DirectGUI "pos"-parameters not be affected by things like scaling.

Moguri commented 2 years ago

Sounds like we could also use some doc improvements and some samples.

fireclawthefox commented 2 years ago

Sounds like we could also use some doc improvements and some samples.

I totally agree on that, those things are probably somewhere in the manual but I also sometimes struggle to find the correct details for those.

A new dedicated page with guides on how to create different types of layouts and useful information on placing GUI widgets would indeed be a nice addition.

Regarding

  • it would be cool if we have html like fillable containers that automatically readjust the contents based on the size of the element

and

I think that a community-member (perhaps fireclawthefox?) created some such widget(s)

I actually created some widgets that can aid in placing DirectGUI widgets similarly to other GUI toolkits like GTK, Qt or WPF. They may not be as fully featured yet but they will grow over time and dependent on what users wish for. The widgets and documentation for how to install and use them can be found here:

https://github.com/fireclawthefox/DirectGuiExtension

ArsThaumaturgis commented 2 years ago

Sounds like we could also use some doc improvements and some samples.

I totally agree on that, those things are probably somewhere in the manual but I also sometimes struggle to find the correct details for those.

A new dedicated page with guides on how to create different types of layouts and useful information on placing GUI widgets would indeed be a nice addition.

Agreed indeed! Those could prove very helpful in working with DirectGUI! ^_^

I actually created some widgets that can aid in placing DirectGUI widgets similarly to other GUI toolkits like GTK, Qt or WPF. They may not be as fully featured yet but they will grow over time and dependent on what users wish for. The widgets and documentation for how to install and use them can be found here:

Ah, excellent! I thought that I remembered some such thing. Thank you for linking to that--and indeed, for making it! ^_^

xxxshelby commented 1 year ago

How to convert 2D to 3D through panda3D?

ArsThaumaturgis commented 1 year ago

@xxxshelby: That... doesn't seem terribly related to the topic of this issue, that I see. However, you might perhaps create a thread for your question on the forum (see the link below).

https://discourse.panda3d.org