本文的写作得益于Blender maillist 给我发的一份邮件,告诉我Blender的user interface方面的文档都在/doc/interface.txt中,我看了这个文档,决定把我了解得内容写出来。
1. 窗口(window)和模块(block)
所有的Blender的GUI元素都被存放在uiBlock结构中,而所有的uiBlock构成一个链表,最终显示在一个窗口中。
uiBlock通过以下函数生成:
uiBlock *block= uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win);
下面的代码生成一个新的模块,然后将模块放入一个窗口区域的uiBlock链表中:
uiDoBlocks(&curarea->uiblocks, event);
1.1内存分配
在这个工具箱中,创建新的uiBlock和在界面上画出uiBlock没有任何区别,在任何一个窗口中,重画所有的uiBlock就是重新创建了所有的uiBlock。
内存分配主要处理以下事件:
- 如果在同一个窗口中有同名的uiBlock,他们将被释放
- 当你关闭一个窗口时,这个窗口中的所有uiBlock将会被释放
- 当你复制一个窗口时,这个窗口中所有的uiBlock将会被复制
1.2内部工作机制
当调用uiDoBlock函数时,当前活动窗口中的所有模块将被重新评价,这时在链表中将进行一系列复杂的过程:
- while(looping)
/* the normal buttons handling */
- for each block
- call uiDoBlock (handles buttons for single block)
- (end for)
/* at this moment, a new block can be created, for a menu */
/* so we create a 2nd loop for it */
- while first block is a menu
- if block is a menu and not initialized:
- initalize 'saveunder'
- draw it
- get event from queue
- call uiDoBlock (handles buttons for single block)
/* here, a new block again can be created, for a sub menu */
- if return "end" from uiDoBlock
restore 'saveunder's
free all menu blocks
exit from loop
- do tooltip if nothing has happened
- (end while)
- if there was menu, it does this loop once more
(when you click outside a menu, at another button)
- (end while)
- do tooltip if nothing has happened