gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.26k stars 243 forks source link

[FEATURE] StackView shouldn't layout and draw hidden layers #704

Open nicklan opened 1 year ago

nicklan commented 1 year ago

Is your feature request related to a problem? Please describe. StackView lays out and draws all layers, even if they are not visible. If you have a Stack of a bunch of fullscreen layers, it doesn't make any sense to layout and draw any but the front layer. However, StackView always calls layout/draw on all layers. You need a custom view and some hacks (like checking if the printer is focused in draw) to avoid this.

Describe the solution you'd like StackView should be clever enough to not call layout/draw on layers that are not being shown.

Describe alternatives you've considered As above, custom views can hack around this.

gyscos commented 1 year ago

Hi, and thanks for the report!

Unfortunately it's not trivial to know a layer is hidden. Layers can be transparent and only draw on part of their allocated rectangle, which makes it harder to know when we can guarantee a layer is not visible.

Note that if you have a bunch of fullscreen layers, you might not actually need them all in the same stackview. For example ScreensView is meant to show one (fullscreen) view at a time (and that fullscreen view can be a StackView). One is already embedded in the Cursive root: you can call Cursive::add_screen to create new, separate screens, and then decide which one to show. This will properly skip layout and draw calls for non-active screens.

smallB007 commented 1 year ago

Probably very naive, but would adding flag is_hidden solve that issue?

gyscos commented 1 year ago

You can already wrap some view in a HideableView and toggle that on/off. You could absolutely do this for any full-screen layer you add.

But if you add a non-transparent full-screen layer to the StackView on top of other stuff, chances are a new screen is what you need.

smallB007 commented 1 year ago

I am not sure, but "I think" that hideable view blocks input to views "under" it? I remember I wasn't happy the hideableview's concepts were implemented. In my own code base I simply added flag is_hidden to a view and if view is hidden stack "skips it" completely. Simple but works.

gyscos commented 1 year ago

The post is about having a front full-screen layer, and other layers behind it. All layers behind the front one will never be seen, and drawing them is wasted.

Having a front "invisible" layer that does not grab input is a separate issue like https://github.com/gyscos/cursive/issues/558.

smallB007 commented 1 year ago

"The post is about having a front full-screen layer" - I don't think so. The OP complains about stackview calling draw/layout on all layers without checking if Layer/View is is visible or not. Anyway... As a side note, I think it would be worth mentioning Cursive::add_screen in some tutorial (if it is mentioned in any I've missed it). My point is that in the tutorials this is not the suggested way to have full screen app. Instead add_fullscreen_layer (I believe) is suggested.