Hello Everyone,
I’m not sure how many guys here would like to discuss the Blender user interface.
I started to learn how to use Blender 2 years ago. At the first time I opened the application, I was attracted by the simple, fast user interface.
When I read the source code, I was surprised that all the UI elements were drawn in OpenGL directly, and until now Blender is still using OpenGL APIs prior to 2.1. (Which is called legacy APIs now and they are removed from OpenGL 3.3).
Besides, the user interface is written in C and embedded in Blender editor, it's hard for a beginner to reuse the code, there're only Python APIs to extend the UI.
From my experience with some GUI toolkits such as Qt,Gtkmm, I think it's better to use an object-oriented language (e.g. C++) for user interface.
So 1 year ago I started to try to develop a Blender-like GUI toolkit in my spare time, just for fun!
Here're some highlight features I plan to complete:
I use C++ to develop this toolkit, and some concepts from Qt and Gtkmm, so every UI element is an object: a button, a slider, an imageview, a listview etc.
For example, a button can be created by just 1 line:
Button* btn = new Button("Hello World!);
There’s container to hold a sub widget or sub container, for example, a button can be added in a Expander:
Expander* expander = new Expander;
expander->Setup(btn);
You can use a smart pointer which support reference counting, so that you don’t need to release an object manually:
RefPtr<Button> btn(new Button("Hello World"));
And an sub widget which is set managed, can be release automatically when its container destroyed:
Button* btn = Manage(new Button);
Expander* expander = new Expander;
expander->Setup(btn);
delete expander; // this will delete btn too.
I use modern OpenGL (OpenGL 3.3+), there’re predefined and simple shaders to draw a widget and you can use your own in your subclasses.
For example, I use a geometry shader to generate the effect of jitter, which makes the outline of a widget looks anti-aliased.
I use CppEvent to provide a fast Event/Delegate (signal/slot) mechanism. For example, if you need to do something when a button click:
events()->connect(btn->clicked(), this, &ClassName::OnButtonClick);
and disconnect when you don’t need it:
btn->clicked().disconnect(this, &ClassName::OnButtonClick);
A GUI toolkit should never waste resources to redraw widgets each time.
With OpenGL 3.3+, you could use Framebuffer Object for off-screen rendering. In this toolkit, partial redraws can be done by overriding some virtual functions and draw some regions only once when needed.
So, put all together, you could reuse preset widgets, for example, a FileSelector:<img src="/uploads/default/original/4X/9/8/9/989034c36525a992b5de1145cb4e1c9ee3ec36b2.png" width="654" height="500"><br/>
, and build your own Blend-like application quickly,<img src="/uploads/default/original/4X/7/8/9/7890b4e9b6e134552ac893cf742ed520f0138c91.png" width="690" height="446"><br/>
The weakness of such C++ toolkit is that it cause difficulty to write python binding, I'm learning SWIG (http://www.swig.org) to figure it out.
Finally, please notice this toolkit is not finished, it's still under development, very very buggy, not fine-tuned. Above all, this toolkit actually has nothing to do with Blender.
I just want feedback from you if it's worth to continue to develop such toolkit. The progress is not as fast as I expected, and sometimes I doubt what I've done is useless.
I'd appreciate any comments.
The source code is hosted on https://bitbucket.org/zhanggyb/blendint