First commit of a new toolbox system.

Aim was to find a simple & easy system, script alike, to add and configure
a toolbox system, so that others can experiment, but also of course Python.

Summary:
- spacebar calls it up. SHIFT+A still does old toolbox
- hold left or rightmouse for 0.4 second, and it pops up as well
  this is experimental! Can be tweaked with Userdef var "ThresA"
- it is a little bit complete for Object mode only. Needs still work
  at information desing/structure level
- the code works like an engine, interpreting structs like this:

static TBitem addmenu_curve[]= {
{	0, "Bezier Curve", 	0, NULL},
{	0, "Bezier Circle", 1, NULL},
{	0, "NURBS Curve", 	2, NULL},
{	0, "NURBS Circle", 	3, NULL},
{	0, "Path", 			4, NULL},
{  -1, "", 			0, do_info_add_curvemenu}};

- first value is ICON code,
- then name
- return value
- pointer to optional child

last row has -1 to indicate its the last...
plus a callback to event function.

I also built an old toolbox style callback for this:

static TBitem tb_object_select[]= {
{	0, "Border Select|B", 	'b', NULL},
{	0, "(De)select All|A", 	'a', NULL},
{	0, "Linked...|Shift L", 	'L', NULL},
{	0, "Grouped...|Shift G", 	'G', NULL},
{  -1, "", 			0, tb_do_hotkey}};

here the return values are put back as hotkeys in mainqueue.

A mainloop can do all context switching, and build menus on the fly.
Meaning, it also allows other designs such as radials...
This commit is contained in:
2003-10-25 00:08:12 +00:00
parent 5f26e16c51
commit 513ae61f2b
13 changed files with 546 additions and 147 deletions

View File

@@ -343,8 +343,21 @@ static void ui_positionblock(uiBlock *block, uiBut *but)
{
/* position block relative to but */
uiBut *bt;
int xsize, ysize, xof=0, yof=0;
rctf butrct;
int xsize, ysize, xof=0, yof=0, centre;
short dir1= 0, dir2=0;
/* first transform to screen coords, assuming matrix is stil OK */
/* the UIwinmat is in panelspace */
butrct.xmin= but->x1; butrct.xmax= but->x2;
butrct.ymin= but->y1; butrct.ymax= but->y2;
ui_graphics_to_window(block->win, &butrct.xmin, &butrct.ymin);
ui_graphics_to_window(block->win, &butrct.xmax, &butrct.ymax);
block->parentrct= butrct; // will use that for pulldowns later
/* calc block rect */
block->minx= block->miny= 10000;
block->maxx= block->maxy= -10000;
@@ -359,42 +372,37 @@ static void ui_positionblock(uiBlock *block, uiBut *but)
bt= bt->next;
}
ui_graphics_to_window(block->win, &block->minx, &block->miny);
ui_graphics_to_window(block->win, &block->maxx, &block->maxy);
block->minx-= 2.0; block->miny-= 2.0;
block->maxx+= 2.0; block->maxy+= 2.0;
xsize= block->maxx - block->minx+4; // 4 for shadow
ysize= block->maxy - block->miny+4;
if(but) {
rctf butrct;
short left=0, right=0, top=0, down=0;
short dir1, dir2 = 0;
butrct.xmin= but->x1; butrct.xmax= but->x2;
butrct.ymin= but->y1; butrct.ymax= but->y2;
if(but->block->panel) {
butrct.xmin += but->block->panel->ofsx;
butrct.ymin += but->block->panel->ofsy;
butrct.xmax += but->block->panel->ofsx;
butrct.ymax += but->block->panel->ofsy;
}
/* added this for submenu's... */
Mat4CpyMat4(UIwinmat, block->winmat);
ui_graphics_to_window(block->win, &butrct.xmin, &butrct.ymin);
ui_graphics_to_window(block->win, &butrct.xmax, &butrct.ymax);
block->parentrct= butrct; // will use that for pulldowns later
if(block->direction & UI_CENTRE) centre= ysize/2;
else centre= 0;
if( butrct.xmin-xsize > 0.0) left= 1;
if( butrct.xmax+xsize < G.curscreen->sizex) right= 1;
if( butrct.ymin-ysize > 0.0) down= 1;
if( butrct.ymax+ysize < G.curscreen->sizey) top= 1;
if( butrct.ymin-ysize+centre > 0.0) down= 1;
if( butrct.ymax+ysize-centre < G.curscreen->sizey) top= 1;
dir1= block->direction;
if(dir1==UI_LEFT || dir1==UI_RIGHT) dir2= UI_DOWN;
if(dir1==UI_TOP || dir1==UI_DOWN) dir2= UI_LEFT;
dir1= block->direction & UI_DIRECTION;
/* secundary directions */
if(dir1 & (UI_TOP|UI_DOWN)) {
if(dir1 & UI_LEFT) dir2= UI_LEFT;
else if(dir1 & UI_RIGHT) dir2= UI_RIGHT;
dir1 &= (UI_TOP|UI_DOWN);
}
if(dir2==0) if(dir1==UI_LEFT || dir1==UI_RIGHT) dir2= UI_DOWN;
if(dir2==0) if(dir1==UI_TOP || dir1==UI_DOWN) dir2= UI_LEFT;
/* no space at all? dont change */
if(left || right) {
@@ -412,47 +420,55 @@ static void ui_positionblock(uiBlock *block, uiBut *but)
}
if(dir1==UI_LEFT) {
xof= but->x1 - block->maxx;
if(dir2==UI_TOP) yof= but->y1 - block->miny;
else yof= but->y2 - block->maxy;
xof= butrct.xmin - block->maxx;
if(dir2==UI_TOP) yof= butrct.ymin - block->miny-centre;
else yof= butrct.ymax - block->maxy+centre;
}
else if(dir1==UI_RIGHT) {
xof= but->x2 - block->minx;
if(dir2==UI_TOP) yof= but->y1 - block->miny;
else yof= but->y2 - block->maxy;
xof= butrct.xmax - block->minx;
if(dir2==UI_TOP) yof= butrct.ymin - block->miny-centre;
else yof= butrct.ymax - block->maxy+centre;
}
else if(dir1==UI_TOP) {
yof= but->y2 - block->miny+1;
if(dir2==UI_RIGHT) xof= but->x2 - block->maxx;
else xof= but->x1 - block->minx;
yof= butrct.ymax - block->miny-1;
if(dir2==UI_RIGHT) xof= butrct.xmax - block->maxx;
else xof= butrct.xmin - block->minx;
// changed direction?
if((dir1 & block->direction)==0) {
if(block->direction & UI_SHIFT_FLIPPED)
xof+= dir2==UI_LEFT?25:-25;
uiBlockFlipOrder(block);
}
}
else if(dir1==UI_DOWN) {
yof= but->y1 - block->maxy-1;
if(dir2==UI_RIGHT) xof= but->x2 - block->maxx;
else xof= but->x1 - block->minx;
yof= butrct.ymin - block->maxy+1;
if(dir2==UI_RIGHT) xof= butrct.xmax - block->maxx;
else xof= butrct.xmin - block->minx;
// changed direction?
if((dir1 & block->direction)==0) {
if(block->direction & UI_SHIFT_FLIPPED)
xof+= dir2==UI_LEFT?25:-25;
uiBlockFlipOrder(block);
}
}
// apply requested offset in the block
xof += block->xofs;
yof += block->yofs;
xof += block->xofs/block->aspect;
yof += block->yofs/block->aspect;
if(but->block->panel) {
xof += but->block->panel->ofsx;
yof += but->block->panel->ofsy;
}
}
/* apply */
bt= block->buttons.first;
while(bt) {
ui_graphics_to_window(block->win, &bt->x1, &bt->y1);
ui_graphics_to_window(block->win, &bt->x2, &bt->y2);
bt->x1 += xof;
bt->x2 += xof;
bt->y1 += yof;
bt->y2 += yof;
ui_graphics_to_window(block->win, &bt->x1, &bt->y1);
ui_graphics_to_window(block->win, &bt->x2, &bt->y2);
bt->aspect= 1.0;
@@ -464,8 +480,40 @@ static void ui_positionblock(uiBlock *block, uiBut *but)
block->maxx += xof;
block->maxy += yof;
ui_graphics_to_window(block->win, &block->minx, &block->miny);
ui_graphics_to_window(block->win, &block->maxx, &block->maxy);
/* safety calculus */
if(but) {
float midx= (block->parentrct.xmin+block->parentrct.xmax)/2.0;
float midy= (block->parentrct.ymin+block->parentrct.ymax)/2.0;
/* when you are outside parent button, safety there should be smaller */
// parent button to left
if( midx < block->minx ) block->safety.xmin= block->minx-3;
else block->safety.xmin= block->minx-40;
// parent button to right
if( midx > block->maxx ) block->safety.xmax= block->maxx+3;
else block->safety.xmax= block->maxx+40;
// parent button on bottom
if( midy < block->miny ) block->safety.ymin= block->miny-3;
else block->safety.ymin= block->miny-40;
// parent button on top
if( midy > block->maxy ) block->safety.ymax= block->maxy+3;
else block->safety.ymax= block->maxy+40;
// exception for switched pulldowns...
if(dir1 && (dir1 & block->direction)==0) {
if(dir2==UI_RIGHT) block->safety.xmax= block->maxx+3;
if(dir2==UI_LEFT) block->safety.xmin= block->minx-3;
}
}
else {
block->safety.xmin= block->minx-40;
block->safety.ymin= block->miny-40;
block->safety.xmax= block->maxx+40;
block->safety.ymax= block->maxy+40;
}
}
@@ -823,22 +871,19 @@ static int ui_do_but_MENU(uiBut *but)
for(a=0; a<md->nitems; a++) {
x1= but->x1 + width*((int)a/rows);
x1= but->x1 + width*((int)(md->nitems-a-1)/rows);
y1= but->y1 - boxh*(a%rows) + (rows-1)*boxh;
if (strcmp(md->items[a].str, "%l")==0) {
if (strcmp(md->items[md->nitems-a-1].str, "%l")==0) {
uiDefBut(block, SEPR, B_NOP, "", x1, y1,(short)(width-(rows>1)), (short)(boxh-1), NULL, 0.0, 0.0, 0, 0, "");
}
else {
uiBut *bt= uiDefBut(block, BUTM|but->pointype, but->retval, md->items[a].str, x1, y1,(short)(width-(rows>1)), (short)(boxh-1), but->poin, (float) md->items[a].retval, 0.0, 0, 0, "");
uiBut *bt= uiDefBut(block, BUTM|but->pointype, but->retval, md->items[md->nitems-a-1].str, x1, y1,(short)(width-(rows>1)), (short)(boxh-1), but->poin, (float) md->items[md->nitems-a-1].retval, 0.0, 0, 0, "");
if(active==a) bt->flag |= UI_ACTIVE;
}
}
/* fix alignment because of the shadow, etc */
block->xofs = -2;
block->yofs = -2;
block->direction= UI_TOP;
ui_positionblock(block, but);
block->win= G.curscreen->mainwin;
event= uiDoBlocks(&listb, 0);
@@ -1690,6 +1735,7 @@ static int ui_do_but_NUMSLI(uiBut *but)
static int ui_do_but_BLOCK(uiBut *but)
{
uiBlock *block;
uiBut *bt;
but->flag |= UI_SELECT;
ui_draw_but(but);
@@ -1697,15 +1743,30 @@ static int ui_do_but_BLOCK(uiBut *but)
block= but->block_func(but->poin);
block->xofs = -2; /* for proper alignment */
/* only used for automatic toolbox, so can set the shift flag */
if(but->flag & UI_MAKE_TOP) {
block->direction= UI_TOP|UI_SHIFT_FLIPPED;
uiBlockFlipOrder(block);
}
if(but->flag & UI_MAKE_DOWN) block->direction= UI_DOWN|UI_SHIFT_FLIPPED;
if(but->flag & UI_MAKE_LEFT) block->direction |= UI_LEFT;
if(but->flag & UI_MAKE_RIGHT) block->direction |= UI_RIGHT;
ui_positionblock(block, but);
block->flag |= UI_BLOCK_LOOP;
/* blocks can come from a normal window, but we go to screenspace */
block->win= G.curscreen->mainwin;
for(bt= block->buttons.first; bt; bt= bt->next) bt->win= block->win;
bwin_getsinglematrix(block->win, block->winmat);
/* postpone draw, this will cause a new window matrix, first finish all other buttons */
block->flag |= UI_BLOCK_REDRAW;
but->flag &= ~UI_SELECT;
uibut_do_func(but);
return 0;
}
@@ -2136,7 +2197,7 @@ static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent)
case BLOCK:
if(uevent->val) {
retval= ui_do_but_BLOCK(but);
block->auto_open= 1;
if(block->auto_open==0) block->auto_open= 1;
}
break;
@@ -2288,7 +2349,7 @@ static int ui_mouse_motion_towards_block(uiBlock *block, uiEvent *uevent)
short mvalo[2], dx, dy, domx, domy, x1, y1;
int disto, dist, counter=0;
if(block->direction==UI_TOP || block->direction==UI_DOWN) return 0;
if((block->direction & UI_TOP) || (block->direction & UI_DOWN)) return 0;
if(uevent->event!= MOUSEX && uevent->event!= MOUSEY) return 0;
/* calculate dominant direction */
@@ -2576,15 +2637,20 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
else if(but->type==BLOCK || but->type==MENU) { // automatic opens block button (pulldown)
int time;
if(uevent->event!=LEFTMOUSE ) {
if(block->auto_open) time= 5*U.menuthreshold2;
if(block->auto_open==2) time= 2; // test for toolbox
else if(block->auto_open) time= 5*U.menuthreshold2;
else if(U.uiflag & MENUOPENAUTO) time= 5*U.menuthreshold1;
else time= -1;
for (; time>0; time--) {
if (anyqtest()) break;
if (qtest()) break;
else PIL_sleep_ms(20);
}
if(time==0) ui_do_button(block, but, uevent);
if(time==0) {
uevent->val= 1; // otherwise buttons dont react
ui_do_button(block, but, uevent);
}
}
}
if(but->flag & UI_ACTIVE) active= 1;
@@ -2640,8 +2706,10 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
if(block->flag & UI_BLOCK_LOOP) {
if(inside==0 && uevent->val==1) {
if ELEM3(uevent->event, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)
return UI_RETURN_OUT;
if ELEM3(uevent->event, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) {
if(BLI_in_rctf(&block->parentrct, (float)uevent->mval[0], (float)uevent->mval[1]));
else return UI_RETURN_OUT;
}
}
if(uevent->event==ESCKEY && uevent->val==1) return UI_RETURN_CANCEL;
@@ -2649,37 +2717,12 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
if((uevent->event==RETKEY || uevent->event==PADENTER) && uevent->val==1) return UI_RETURN_OK;
/* check outside */
if(inside==0 && block->parentrct.xmax != 0.0) {
if(inside==0) {
/* strict check, and include the parent rect */
if( BLI_in_rctf(&block->parentrct, (float)uevent->mval[0], (float)uevent->mval[1]));
else if( ui_mouse_motion_towards_block(block, uevent));
else {
float midx, midy;
int safety;
midx= (block->parentrct.xmin+block->parentrct.xmax)/2.0;
midy= (block->parentrct.ymin+block->parentrct.ymax)/2.0;
if( midx < block->minx ) safety = 3; else safety= 40;
if(uevent->mval[0]<block->minx-safety) return UI_RETURN_OUT;
if( midy < block->miny ) safety = 3; else safety= 40;
if(uevent->mval[1]<block->miny-safety) return UI_RETURN_OUT;
if( midx > block->maxx ) safety = 3; else safety= 40;
if(uevent->mval[0]>block->maxx+safety) return UI_RETURN_OUT;
if( midy > block->maxy ) safety = 3; else safety= 40;
if(uevent->mval[1]>block->maxy+safety) return UI_RETURN_OUT;
}
}
else {
/* for popups without parent button */
if(uevent->mval[0]<block->minx-40) return UI_RETURN_OUT;
if(uevent->mval[1]<block->miny-40) return UI_RETURN_OUT;
if(uevent->mval[0]>block->maxx+40) return UI_RETURN_OUT;
if(uevent->mval[1]>block->maxy+40) return UI_RETURN_OUT;
else if( BLI_in_rctf(&block->safety, (float)uevent->mval[0], (float)uevent->mval[1]));
else return UI_RETURN_OUT;
}
}
@@ -2740,24 +2783,10 @@ static uiSaveUnder *ui_draw_but_tip(uiBut *but)
su= ui_bgnpupdraw((int)(x1-1), (int)(y1-1), (int)(x2+4), (int)(y2+4), 0);
/* bottom */
//glColor3ub(0,0,0);
//fdrawline(x1, y1, x2, y1);
/* right */
//fdrawline(x2, y1, x2, y2);
/* top */
//glColor3ub(255,255,255);
//fdrawline(x1, y2, x2, y2);
/* left */
//fdrawline(x1, y1, x1, y2);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/*glColor4ub(0, 0, 0, 100);
fdrawline(x1+4, y1, x2+1, y1);
fdrawline(x2+1, y1, x2+1, y2-4);
*/
glColor4ub(0, 0, 0, 60);
fdrawline(x1+3, y1-1, x2, y1-1);
fdrawline(x2+1, y1, x2+1, y2-3);
@@ -2914,7 +2943,7 @@ int uiDoBlocks(ListBase *lb, int event)
if(block==NULL || (block->flag & UI_BLOCK_LOOP)==0) cont= 0;
while( (block= lb->first) && (block->flag & UI_BLOCK_LOOP)) {
block->auto_open= 1;
if(block->auto_open==0) block->auto_open= 1;
/* this here, for menu buts */
if(block->flag & UI_BLOCK_REDRAW) {
@@ -2946,7 +2975,7 @@ int uiDoBlocks(ListBase *lb, int event)
BLI_remlink(lb, block);
uiFreeBlock(block);
}
if(retval==UI_RETURN_OK) {
if(retval & (UI_RETURN_OK|UI_RETURN_CANCEL)) {
/* free other menus */
while( (block= lb->first) && (block->flag & UI_BLOCK_LOOP)) {
ui_endpupdraw(block->saveunder);
@@ -3197,6 +3226,7 @@ uiBlock *uiNewBlock(ListBase *lb, char *name, short dt, short font, short win)
if (win==G.curscreen->mainwin) {
block->aspect= 1.0;
block->auto_open= 2;
} else {
int getsizex, getsizey;