Open keithkml opened 4 years ago
I've avoided to add a visible flag on components so far because it makes the layout manager / focus / input handling more complicated and it would take time to go through all components and test. For LinearLayout/BorderLayout, I think it's easy to just remove/re-add the component you want to hide. GridLayout is possibly more complicated as it maintains the order. You could create a wrapper panel and remove/re-add the actual component from there.
It's not that easy to re-add the component in the right spot (requires some ugly code IMO).
Creating a wrapper panel doesn't work if the layout has spacing between components.
I’m working on a PR for this. I think full support would be a very large PR, so I’m wondering what you guys would consider acceptable at first. Which of these features do you consider mandatory?
LinearLayout
flex mode
1b. LinearLayout
legacy mode
1c. GridLayout
1d. BorderLayout
1e. (I think there’s one more layout manager but I’m on my phone right now and can’t look it up :)Are there any other areas that I’d need to address in an initial PR? Note that I personally don’t need mouse support and I only use LinearLayout and GridLayout, so I’d be happy with only implementing 1a, 1c, and 2 🙂
Well, unfortunately, I think we'll need to support it in all layout managers. Could split it up into multiple PRs. Focus will be a problem so that needs to be addressed too. Don't think mouse is that important, but you'll need probably need to set the component size to zero as well so the InteractableLookupMap still works and doesn't add the invisible component.
I think that if you make a builder component or utility method which solves this, the PR will not be too involved, it can leverage some object which applications can use in building their screens.
When the event occurs, they just update the Map<Component, Boolean> and re-call this utility.
Unless I misunderstand, you are talking about objects taking up zero space on screen and not receiving input unless they are visible, which is really that they are not there at all, they only reside there in the sense that there is some marker to spring them back into existence upon some event.
Instead of broad sweeping changes, a utility method which builds the screen can take all the components and a mapping of booleans of those components which are invisible. (these names not much thought out)
// or this may be utility method in AbstractComponent
public class SomeUtilityClassThing {
// generally base pane
public Component constructUi(UserUiBuilder lambda, Map<Component, Boolean> userManaged) {
Component full = lambda.adhocUiLayoutStuff(userManaged);
Component swiss = visitComponentTreeAndRemoveSome(full, userManaged);
return swiss;
}
}
// user applications will create a lambda which is their meat and potatoes
@Interface UserUiBuilder {
Component adhocUiLayoutStuff()
}
Users can make use of the utility method by passing in a lambda of the above which does the construction of the screen, the user will manage the booleans in the map and provide it.
Upon relevant events, users just need to resubmit their lambda and their map to the utiltiy method and replace the base pane or whatever correlating part this comp tree is for.
Since it is the same comps being sent to adHocUiiLayoutStuff, any state of selection etc will be preserved.
This utility could reside in the container and then the components setVisibile() method can just turn around and call upwards to the container until the top and it can have the mapping and re-call the lambda.
In this way, no layout manager changes are needed.
Hmm, yes, maybe that would work. I'll take a look today.
@keithkml @ginkoblongata I've pushed to 3.1 and master the "visible" flag on Component and implemented it in each of the four available layout managers. Let's see if this works for everyone.
An invisible component would have no height/width, and would not have any inter-component border/spacing applied by the layout manager. This would be useful for components which are only relevant in some contexts.