Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide() / show() functionality of GUI elements #115

Closed
ylenard opened this issue Jun 1, 2020 · 9 comments · Fixed by #136
Closed

hide() / show() functionality of GUI elements #115

ylenard opened this issue Jun 1, 2020 · 9 comments · Fixed by #136
Labels
enhancement New feature or request

Comments

@ylenard
Copy link

ylenard commented Jun 1, 2020

Is your feature request related to a problem? Please describe.
Currently I have to constantly create and kill a lot of GUI elements when using them in a dynamic GUI.

Describe the solution you'd like
I'd like to be able to keep the GUI elements in memory and control whether they should be drawn and taken into account during event processing by using show() / hide() methods.

Describe alternatives you've considered
Creating and killing GUI elements works, but leads to bad design and can be a bit costly performance-wise in some cases.

@ylenard ylenard added the enhancement New feature or request label Jun 1, 2020
@MyreMylar
Copy link
Owner

Related: #108

@ylenard
Copy link
Author

ylenard commented Jun 2, 2020

I have implemented the basis for the feature and it seems to work. I did it in a different way than what you mentioned in # 108 though.

At the very least all the tests pass and everything still works in my application. I also wrote some new tests. If you're interested, you could create a new branch so I can commit to it.

Also, I have a slightly related question - what was the rationale for UIPanel implementing IContainerLikeInterface instead of inheriting from UIContainer?

@MyreMylar
Copy link
Owner

I have implemented the basis for the feature and it seems to work. I did it in a different way than what you mentioned in # 108 though.

I'm curious what approach you took.

At the very least all the tests pass and everything still works in my application. I also wrote some new tests. If you're interested, you could create a new branch so I can commit to it.

Usually the way this is done on GitHub is for you to make a fork of pygame_gui, then make a branch of that and submit that branch as a pull request then we can take it from there. It's a bit of a round about way but it seems to be the accepted process.

Also, I have a slightly related question - what was the rationale for UIPanel implementing IContainerLikeInterface instead of inheriting from UIContainer?

Well I usually try to steer away from inheritance chains that are too deep as it can lead to a confusing mess of trying to figure out which variables belong to which thing in the inherited stack. passing off the container functionality to the otherwise invisible container and keeping the drawing functionality in the Panel class seemed to make sense, likewise for the window. The ContainerLike thing came about as a way to make panels and windows easier to treat like they were containers for users of pygame_gui. So you can just pass a window or panel in to the 'container' parameter of elements and it will behave how you expect without having to worry about the fact that behind the scenes the window and the panel are passing the container handling over to the container.

I'm not sure it's worked flawlessly as some people still seem a little confused by it.

@ylenard
Copy link
Author

ylenard commented Jun 2, 2020

I'm curious what approach you took.

This is the gist of it:

  1. I added a flag is_visible to UIElement (the name might not be the best, because it can be understood that the element is obscured) along with the show()/hide() methods
  2. I implemented a new class: UILayeredUpdates inheriting from pygame.sprite.LayeredUpdates. Made the UIManager use the new class instead as ui_group. The new class overrides the draw() method in a way, that UIElements with is_visible=False are omitted
  3. Changed the UIManager process_events() and update() methods to ignore the hidden UI elements. (this I may have to change. If I understand correctly, the hidden UIButtons for example still create hover events, they are just ignored, which is far from ideal)
  4. Changed the UIContainer to make the show() / hide() methods propagate to children UIElements
  5. Changed the init() methods of UIButton and UIPanel so that I can test everything easily

Usually the way this is done on GitHub is for you to make a fork of pygame_gui, then make a branch of that and submit that branch as a pull request then we can take it from there. It's a bit of a round about way but it seems to be the accepted process.

Thanks. I created the fork and created a new branch, but I have to write more tests and make changes to all the UIElements before I make the pull request.

@MyreMylar
Copy link
Owner

On thing to be aware of is that I have a branch that I may merge into master shortly now that pygame 2.0.0.dev10 is out, that in the process of solving an entirely different issue, changes pygame_gui over to using pygame's DirtySprite class as the base for UIElements instead of pygame's regular Sprite class.

https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.DirtySprite

I mention this because, DirtySprite has an attribute called 'visible' that might be useful for the first two parts of your described solution.

@ylenard
Copy link
Author

ylenard commented Jun 2, 2020

Thanks for the heads up. This will remove the need for the UILayeredUpdates class, so it's even better.

I'll focus on the events for now. And I have to learn how to make rendering tests.

@ylenard
Copy link
Author

ylenard commented Jun 4, 2020

I have already implemented the feature for a lot of UIElements (up to date with your master, so pygame 2 dev 10 ready) - you can check it out on my fork - show_hide_feature branch. If you have any suggestions or envisioned something differently, please tell me.

I don't know what to do with the UITooltip though.

Should I reimplement it, so that it's always there and is only shown / hidden when appropriate, or leave it be and ignore the new functionality?

@MyreMylar
Copy link
Owner

MyreMylar commented Jun 4, 2020

I think they should probably stay the way they are by default - mainly because I'm imagining a future with screen full of elements with nested tool tips like a Civilopedia entry or something, and if they were all pre-loaded by default we might run out of RAM before anyone even gets to hover one. I mean its fairly unlikely but you never know what constrained platforms people will be running pygame apps on.

There was a chap the other day using it for embedded displays such as you might get on the side of photocopiers - I mean they probably aren't also using pygame_gui tooltips with that, but you never know.

I would probably leave them for now for simplicity of purpose in this PR. Though perhaps we could have a 'preload' flag eventually? And then maybe pre-loading the tooltips (or not) could be a theming option for other elements and then it would use show/hide.

I mean the trade-off with show/hide versus create-on-the-spot is memory usage versus UI responsiveness and I'd like to put that choice in the hands of the users as much as possible so they can tailor the GUI to their application if they know exactly what they want. That's the libraries general stance. A sort of 'works well' middle-ground by default and options to tweak from there.

Anyway good work on the branch, I had a glance over it and it seems pretty comprehensive (with tests and everything!). Feel free to open a pull request when you are done.

@MyreMylar MyreMylar linked a pull request Jun 10, 2020 that will close this issue
@MyreMylar
Copy link
Owner

This is now merged to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants