BlenderDev/button

Wikipedia,自由的百科全书

前面有一篇文章讲到了Blender中的Space Window,其实Space Window应该是UI Framework中最高的一层,Space Window中有Panel,Panel中有按钮。


按照我前面的那篇文章,我定义了一个CAVS_WINDOW,下面我讲一下如何在这个Space Window中定义面板


在blender/doc/interface_API.txt文件中详细讲了User interface 中的主要的API函数,下面我调用的函数中有不清的可以参考这篇文档(我前面部分翻译过这个文档,大家也可以参考一下)。


对于一个Space Window我们至少要为他增加三个.C文件,对于Cavs Window,我为其增加了editcavs.c,drawcavs.c,header_cavs.c。其中,editcavs.c 主要用于处理这个窗口中的事件,drawcavs.c主要用于画出这个窗口,header_cavs.c主要用于事件响应函数的编写。


在我前面贴的那张图中,有一个Progressive Mesh的面板,这个面板是在drawcavs.c中画出的。代码如下:

void cavs_pm_panel()

{

uiBlock * pmblock;

pmblock = uiNewBlock(&curarea->uiblocks, "progressive mesh panel",

UI_EMBOSS, UI_HELV, curarea->win);

if(uiNewPanel(curarea, pmblock, "Progressive Mesh", "Editing", 0, 0, 318, 204)==0)

return;

uiBlockBeginAlign(pmblock);

uiDefBut(pmblock, BUT,B_CAVS_PM_SEL,

"Select a Edge",292,98,120,20, 0, 0, 0, 0, 0, "Select a Edge with minWeight");

uiDefButI(pmblock, NUM,B_CAVS_PM_EV, "End vnum : ",292,76,200,20,

&pm_endvnum,0.0,5000.0,0,0,"Input the End Vertex Number");

uiDrawBlock(pmblock);

uiBlockEndAlign(pmblock);

}

然后我们只需要在画Space Window的函数中调用这个函就就OK了。


我们可以看到,上面那个uiDefBut函数中的第三个参数就对应着事件,也就是说按了“Select a Edge”按钮后,相应事件B_CAVS_PM_SEL。

这个事件被定义在butspace.h中,我在这个文件的最后加了几行如下:

/* BUTTON BUT: > 4000 */

  1. define B_CAVS_PM_SEL 4000
  1. define B_CAVS_PM_EV 4001

而响应这个事件的函数也得定义在这个头文件中,我在上面这两行后面加上了一个函数:

extern void do_cavs_pm(short event);

理论上讲,这个函数处理Cavs Space的Progressive Mesh Panel中的所有按钮事件,这个函数的代码如下:

void do_cavs_pm(short event)

{

switch(event){

case B_CAVS_PM_SEL:

//处理函数

printf(" you have click select button\n");

break;

default:

break;

}

}

当然我们可以为每个事件单独编一个处理函数,为了理解方便,我这里的响应动作很简单,就是输出一段话。

然后我们在整个Space Window的响应函数(在前面一篇文章中已经讲过这个函数如何加到代码中)中调用这个函数,如下:

void do_cavs_buttons(short event)

{

if(event == B_CAVS_PM_SEL)

do_cavs_pm(event);

}


最后一步,也是最重要的,就是在一个我们已经为Cavs Space加入的Space的消息响应函数中,调用上面这个函数:

void winqreadcavsspace(ScrArea *sa, void *spacedata,

BWinEvent *evt)

{

unsigned short event = evt->event;

short val = evt->val;

if(val){

if(uiDoBlocks(&sa->uiblocks,event)!=UI_NOTHING)

evt->event = 0;

switch(event){

case UI_BUT_EVENT:

do_cavs_buttons(val);

break;

default:

break;

}

}

scrarea_queue_winredraw(sa);

}

上面这个函数响应在这个Space Window中的所有事件,包括鼠标和键盘事件

做完上面的,就基本OK了。由于事件响应这一块牵涉甚广,很难说清楚,上面也只是一个大概。

Personal tools