Here’s some bonus chatter after my web talk postmortem at GDC 2017. I’ll try to answer a bunch of FAQs here so I can refer people to them rather than answering everyone individually 🙂
Why didn’t you chose IMGUI for the client reboot?
I think IMGUI is great for in-game UI and read-only presentation of stuff, but it is not attractive for a small team working on desktop tools. We did consider switching to an immediate approach, but were a few strong reasons we didn’t.
First of all, there are no off the shelf IMGUI libraries that can compete with traditional GUI frameworks like Qt when it comes to features and completeness. People at Insomniac expect a robust familiar looking UI with good performance. But they also expect a lot of power tools to come with that. Things like:
- Filtering and sorting every list and tree view
- Copy and paste
- Multi-selection logic with order preservation
- Drag and drop with preview and animation
- Full unicode support (i.e. localization)
Yes, you can totally do all that in IMGUI. But it’s a lot of code to write and maintain, and before you have written it you have nothing. And we had just escaped the hell of writing every control ourselves in the web space, so that was not something we wanted to start this project off by doing.
Second, we only have 5 programmers on the tool side. Starting an IMGUI reboot of the level editor would involve fun decisions like:
- How are we going to render fonts?
- How are we going to load icons?
- How do we handle resizing layouts?
- How do we handle high DPI?
Bikeshedding opportunities for all! Using a framework that has reasonable answers to all those questions already means you can start doing what’s important from day one, which is make the damn tool, instead of inventing yet another font renderer.
But I’ve heard that traditional frameworks suck?
Well, they have a lot of baggage, sure. And you definitely don’t want to be using anything like MFC or classic Win32 where the widgets take ownership of the data. Qt’s model-view architecture however is pretty sane.
You implement a model interface, telling the library how to access (and edit) your data and then it handles input and rendering for the views. The views are completely stock and run unmodified, with standard look and feel, sane multi-selection and keyboard behavior, editing support etc etc. The cost is that you have to express your data access using a framework-defined interface. That’s a pretty small price to pay for the massive leapfrogging you get by relying on those stock views.
The above is true for all “multiple things” widgets, like combo boxes, list and tree views. What remains are the “scalar” widgets, like a single string, checkbox etc. Yes, they retain state so they can repaint themselves without involving your code. And yes, you need to keep them in sync with your data by connecting signals to slots. But it also means that the data is not committed automatically as soon as the checkbox changes. You can actually complain and have the user correct their settings before committing. Tradeoffs.
Are you using Qt Quick?
No, we’re sticking with traditional Qt widgets only. The reasons are:
- We want perfect Win32 interop for our native 3D view
But don’t custom widgets in Qt suck?
No, they’re in fact just like IMGUI if you do things correctly! The differences are:
- You’re painting using a traditional pixel-oriented API rather than a 3D API
- Mostly the framework decides when you need to repaint, not you
- But if your data changes, you’ll need to schedule a repaint yourself (which is easily accomplished in a decoupled fashion using signals and slots)
But other than that, you’re painting a view of your app’s data directly to a drawing surface. So in fact, it’s more like IMGUI than you might think.