* Fix for F6 redo and similar popups closing when moving
  mouse outside of the popup while interacting with buttons.
* Simplify F6 redo popup code by using generated layout.
This commit is contained in:
2009-03-25 14:34:17 +00:00
parent 8f57a92e55
commit 8b3c2c0762
5 changed files with 70 additions and 123 deletions

View File

@@ -432,7 +432,7 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1,
void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval); void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2); uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
int uiDefAutoButsRNA(uiBlock *block, struct PointerRNA *ptr); int uiDefAutoButsRNA(const struct bContext *C, uiBlock *block, struct PointerRNA *ptr);
/* Links /* Links
* *

View File

@@ -3281,62 +3281,60 @@ static void ui_handle_button_closed_submenu(bContext *C, wmEvent *event, uiBut *
* - only for 1 second * - only for 1 second
*/ */
static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my) static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my, int force)
{ {
if(!menu->dotowards) { if(!menu->dotowards || force) {
menu->dotowards= 1; menu->dotowards= 1;
menu->towardsx= mx; menu->towardsx= mx;
menu->towardsy= my; menu->towardsy= my;
menu->towardstime= PIL_check_seconds_timer();
if(force)
menu->towardstime= DBL_MAX; /* unlimited time */
else
menu->towardstime= PIL_check_seconds_timer();
} }
} }
static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my) static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my)
{ {
int fac, dx, dy, domx, domy; float p1[2], p2[2], p3[2], p4[2], oldp[2], newp[2];
int closer;
if(!menu->dotowards) return 0; if(!menu->dotowards) return 0;
if((block->direction & UI_TOP) || (block->direction & UI_DOWN)) { if((block->direction & UI_TOP) || (block->direction & UI_DOWN)) {
menu->dotowards= 0; menu->dotowards= 0;
return menu->dotowards; return menu->dotowards;
} }
/* calculate dominant direction */
domx= (-menu->towardsx + (block->maxx+block->minx)/2);
domy= (-menu->towardsy + (block->maxy+block->miny)/2);
/* we need some accuracy */ /* verify that we are moving closer towards one of the edges
if(abs(domx) < 4) { * of the menu block, in other words, in the triangle formed
* by the initial mouse location and two edge points. */
p1[0]= block->minx;
p1[1]= block->miny;
p2[0]= block->maxx;
p2[1]= block->miny;
p3[0]= block->maxx;
p3[1]= block->maxy;
p4[0]= block->minx;
p4[1]= block->maxy;
oldp[0]= menu->towardsx;
oldp[1]= menu->towardsy;
newp[0]= mx;
newp[1]= my;
closer= 0;
closer |= (PdistVL2Dfl(newp, p1, p2) < PdistVL2Dfl(oldp, p1, p2) + 4);
closer |= (PdistVL2Dfl(newp, p2, p3) < PdistVL2Dfl(oldp, p2, p3) + 4);
closer |= (PdistVL2Dfl(newp, p3, p4) < PdistVL2Dfl(oldp, p3, p4) + 4);
closer |= (PdistVL2Dfl(newp, p4, p1) < PdistVL2Dfl(oldp, p4, p1) + 4);
if(!closer)
menu->dotowards= 0; menu->dotowards= 0;
return menu->dotowards;
}
/* check direction */
dx= mx - menu->towardsx;
dy= my - menu->towardsy;
/* threshold */
if(abs(dx)+abs(dy) > 4) {
/* menu to right */
if(domx>0) {
fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
(my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
if(fac>0) menu->dotowards= 0;
fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
(my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
if(fac<0) menu->dotowards= 0;
}
else {
fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
(my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
if(fac<0) menu->dotowards= 0;
fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
(my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
if(fac>0) menu->dotowards= 0;
}
}
/* 1 second timer */ /* 1 second timer */
if(PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) if(PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH)
@@ -3368,10 +3366,16 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
if(block->miny <= my && block->maxy >= my) if(block->miny <= my && block->maxy >= my)
inside= 1; inside= 1;
if(topmenu && event->type != TIMER) { if((but=ui_but_find_activated(ar)) && button_modal_state(but->active->state)) {
/* if a button is activated modal, always reset the start mouse
* position of the towards mechanism to avoid loosing focus,
* and don't handle events */
ui_mouse_motion_towards_init(menu, mx, my, 1);
}
else if(event->type != TIMER) {
/* for ui_mouse_motion_towards_block */ /* for ui_mouse_motion_towards_block */
if(event->type == MOUSEMOVE) if(event->type == MOUSEMOVE)
ui_mouse_motion_towards_init(menu, mx, my); ui_mouse_motion_towards_init(menu, mx, my, 0);
switch(event->type) { switch(event->type) {
/* closing sublevels of pulldowns */ /* closing sublevels of pulldowns */
@@ -3586,6 +3590,7 @@ static int ui_handle_menu_closed_submenu(bContext *C, wmEvent *event, uiPopupBlo
uiBlock *block; uiBlock *block;
uiHandleButtonData *data; uiHandleButtonData *data;
uiPopupBlockHandle *submenu; uiPopupBlockHandle *submenu;
int mx, my;
ar= menu->region; ar= menu->region;
block= ar->uiblocks.first; block= ar->uiblocks.first;
@@ -3609,6 +3614,13 @@ static int ui_handle_menu_closed_submenu(bContext *C, wmEvent *event, uiPopupBlo
ui_handle_button_closed_submenu(C, event, but); ui_handle_button_closed_submenu(C, event, but);
} }
/* for cases where close does not cascade, allow the user to
* move the mouse back towards the menu without closing */
mx= event->x;
my= event->y;
ui_window_to_block(ar, block, &mx, &my);
ui_mouse_motion_towards_init(menu, mx, my, 1);
if(menu->menuretval) if(menu->menuretval)
return WM_UI_HANDLER_CONTINUE; return WM_UI_HANDLER_CONTINUE;
else else

View File

@@ -160,7 +160,8 @@ static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, in
else else
name= (char*)RNA_property_ui_name(&rnaitem->ptr, rnaitem->prop); name= (char*)RNA_property_ui_name(&rnaitem->ptr, rnaitem->prop);
uiDefBut(block, LABEL, 0, name, x, y + h - YIC, w, YIC, NULL, 0.0, 0.0, 0, 0, ""); if(strcmp(name, "") != 0)
uiDefBut(block, LABEL, 0, name, x, y + h - YIC, w, YIC, NULL, 0.0, 0.0, 0, 0, "");
/* create buttons */ /* create buttons */
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
@@ -941,3 +942,4 @@ void uiHeaderLayout(const bContext *C, ARegion *ar, uiHeaderCreateFunc func)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
} }

View File

@@ -310,22 +310,18 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
return but; return but;
} }
int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr) int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr)
{ {
CollectionPropertyIterator iter; CollectionPropertyIterator iter;
PropertyRNA *iterprop, *prop; PropertyRNA *iterprop, *prop;
PropertySubType subtype; uiLayout *layout;
char *name, namebuf[128]; char *name;
int a= 0, length, x= 0, y= 0; int x= 0, y= 0;
x= 0; layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, DEF_BUT_WIDTH*2, 0);
y= 0;
/* create buttons */ uiTemplateColumn(layout);
uiSetCurFont(block, UI_HELVB); uiItemLabel(layout, UI_TSLOT_COLUMN_1, (char*)RNA_struct_ui_name(ptr), 0);
uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
y -= DEF_BUT_HEIGHT;
uiSetCurFont(block, UI_HELV);
iterprop= RNA_struct_iterator_property(ptr); iterprop= RNA_struct_iterator_property(ptr);
RNA_property_collection_begin(ptr, iterprop, &iter); RNA_property_collection_begin(ptr, iterprop, &iter);
@@ -336,78 +332,15 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0) if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0)
continue; continue;
if((length= RNA_property_array_length(ptr, prop))) { uiTemplateColumn(layout);
name= (char*)RNA_property_ui_name(ptr, prop);
uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
}
else
length= 1;
subtype= RNA_property_subtype(ptr, prop); name= (char*)RNA_property_ui_name(ptr, prop);
uiItemLabel(layout, UI_TSLOT_COLUMN_1, name, 0);
if(RNA_property_type(ptr, prop) != PROP_BOOLEAN) { uiItemR(layout, UI_TSLOT_COLUMN_2, "", 0, ptr, (char*)RNA_property_identifier(ptr, prop));
name= (char*)RNA_property_ui_name(ptr, prop);
uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
}
uiBlockBeginAlign(block);
if(length <= 16 && subtype == PROP_MATRIX) {
/* matrix layout */
int size, row, col, butwidth;
size= ceil(sqrt(length));
butwidth= DEF_BUT_WIDTH*2/size;
y -= DEF_BUT_HEIGHT;
for(a=0; a<length; a++) {
col= a%size;
row= a/size;
uiDefAutoButR(block, ptr, prop, a, "", 0, x+butwidth*col, y-row*DEF_BUT_HEIGHT, butwidth, DEF_BUT_HEIGHT-1);
}
y -= DEF_BUT_HEIGHT*(length/size);
}
else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
static char *quatitem[4]= {"W:", "X:", "Y:", "Z:"};
static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
int butwidth;
butwidth= DEF_BUT_WIDTH*2/length;
y -= DEF_BUT_HEIGHT;
for(a=0; a<length; a++) {
if(length == 4 && subtype == PROP_ROTATION)
name= quatitem[a];
else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
name= vectoritem[a];
else
name= coloritem[a];
uiDefAutoButR(block, ptr, prop, a, name, 0, x+butwidth*a, y, butwidth, DEF_BUT_HEIGHT-1);
}
y -= DEF_BUT_HEIGHT;
}
else {
if(RNA_property_array_length(ptr, prop)) {
sprintf(namebuf, "%d:", a+1);
name= namebuf;
}
else if(RNA_property_type(ptr, prop) == PROP_BOOLEAN)
name= (char*)RNA_property_ui_name(ptr, prop);
else
name= "";
uiDefAutoButR(block, ptr, prop, 0, name, 0, x+DEF_BUT_WIDTH, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1);
y -= DEF_BUT_HEIGHT;
}
uiBlockEndAlign(block);
} }
RNA_property_collection_end(&iter); RNA_property_collection_end(&iter);
uiLayoutEnd(C, block, layout, &x, &y);
return -y; return -y;
} }

View File

@@ -1648,7 +1648,7 @@ static uiBlock *ui_block_create_redo_last(bContext *C, ARegion *ar, void *arg_op
} }
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
height= uiDefAutoButsRNA(block, &ptr); height= uiDefAutoButsRNA(C, block, &ptr);
uiPopupBoundsBlock(block, 4.0f, 0, 0); uiPopupBoundsBlock(block, 4.0f, 0, 0);
uiEndBlock(C, block); uiEndBlock(C, block);