3 ms·
You should look at modern UI libraries like Flutter or SwiftUI. It's a lot like immediate UI, but: - it is capable of storing state: storing position in scroll
by krzat 6y ago
You should look at modern UI libraries like Flutter or SwiftUI. It's a lot like immediate UI, but:
- it is capable of storing state: storing position in scroll view, which page is currently visible, etc.
- it tracks dependencies, so ideally UI building code is executed again only if something changed that would affect it's output.
- jstimpfle 6y agoThe approach I currently take is I just re-layout on each frame. If you have <1000 elements visible on the screen, I don't think that will ever be a problem. I currently have only about 20 though, so I don't really know. The important point is that I don't allocate and re-initialize the state of all controls. It's enough if you do from scratch the layout - that gets much simpler if you don't have to code a diff against the previous state. So I basically have a simple Widget abstraction - a draw function and a process-input function + some identification data (implemented as a union of void-ptr and int). I can then make lists of these abstract Widgets, and each list represents the set of childs of a superordinate element. This abstraction allows me to construct hierarchies and to have unabstracted and very flexible code for the layout, while the layout and input processing code can be generic - it's a simple loop over the list, calling the callback with the abstract handle. If there are ever performance problems you can still fluidly move more towards some retained layout state. This for sure will require more complex code, but if you just do it for complex layouts with lots of elements, I figure you get the best of both worlds. Mouse and drag handling is a little bit tricky as well - how to keep sending events to the slider control widget for example even if the mouse is temporarily outside the widget? The important realization is that dragging needs global state. You set the mouse globally as "grabbed" and provide a callback to execute when there are more mouse events.