Hacker News new | ask | show | jobs
by berkut 4307 days ago
Isn't using immediate mode going to make implementing more complex widgets like multi-line text-edits with selection and style, and more importantly tree controls with collapsed/expanded persistent state that lazily load children (or only display items that are visible in the active view area) more difficult?
3 comments

I was wary of this when we had first started the project. Originally I had planned to just go ahead and start a classic retained UI - the idea of trying to structure a widget lib without widget structs/classes sounded incredibly painful... however after watching some vids and actually having a go myself I'm realising just how wrong I was.

A handy breakthrough in my case was to use Rust's algebraic data type to store each individual widget state within a single container in the UIContext. This is akin to "caching" the state of every widget in one place with a process that is invisible to the user, rather than requiring the user to instantiate large number of objects and work out where they will store widgets, canvases, etc. This approach also makes it really simple to only access certain parts of the state depending on what is needed via Rust's pattern matching and destructuring. I'm yet to come across any kind of widget that is more difficult to store state for than it is in a retained UI (it's even easier for the user of the lib as they don't have to think about it) though perhaps I'm naive in my early days!

All of the widget examples that you have given are already in the plans, I might as well just implement them and do another Show HN instead of rambling in the comments :)

But "immediate mode" means you need to write code to create controls. That is the wrong idea, period. You want to be able to create tools to edit dialogs -- and you DON'T want the controls to be based on pixel positions, pretty much ever.

It's not about whether you can do it. It's whether it's useful to do it that way. You've got a cool tech demo, but you're working on something that won't ultimately be useful. Sorry.

The only reason I began development on this is because of my own use case in which this style of UI suits perfectly. It suits so well in fact I'm entirely abandoning the classical retained UI which I've been using exclusively so far. I'm not claiming that this style is perfect for every or even most use cases, however from my own humble, limited experience I'm yet to come across a use case where I'd prefer to go back (I'm well aware that these probably exist).

Re pixel positions: Tooling is planned for easier widget placement... As I mentioned in the article, the project has barely had three weeks worth of work poured into it - perhaps it's best not to try and declare the project as useless when it's barely even out of the womb ;-)

Yes.

For a good GUI library, you ideally want the layout to be data driven. This means you can draw the entire tree without writing a line of code; this also implies "retained mode" (the opposite of immediate mode).

If it's not data driven, you can't write an editor for it -- or if you do, you end up with something that can write code but that has a hard time re-reading code that you've modified.

Ideally there's more inherited and inferred information, and less parameter noise. A crucial feature of any modern GUI library is the ability to auto-position all the elements, for instance: The placement by "pixel" location is an outdated practice in an age of multiple screen resolutions, aspect ratios, and densities. And getting the layout part right is much harder than getting a few widgets up.

Sorry, but as a GUI library this is not impressing me.

Why would it? You're not constantly trashing your application state, are you?
For really simple apps, no.

But more complicated ones, with resizable widgets/layouts, selection changes, scroll view positions and widgets which display a lot of data, or layering/parenting of widgets make things a lot more complicated.