UI:
* 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:
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user