diff options
author | Ton Roosendaal <ton@blender.org> | 2011-03-01 15:25:55 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2011-03-01 15:25:55 +0300 |
commit | 5bf1bf645c8a0415c67b040821d6389618ca099a (patch) | |
tree | 59ebfcf4cac79268b2ee2685d7595f26f0f2c22e | |
parent | 1c0b9dfdf1f9ccae76e9c90c70d4a0ebfcd94f05 (diff) |
Bug fixes #26236 #26237
- Linking logic buttons had draw glitch, caused by reading
data from free'd buttons
- Doing an undo with mouse-over Curve Widget caused crash or
corruption.
Both related to code that tries to keep the "active" button in
memory. On each redraw of UI, buttons are re-created, which makes
it all tricky... hope we're safer now.
Also: added back undo pushes on adding links in logic editor.
-rw-r--r-- | source/blender/editors/interface/interface.c | 237 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 8 |
2 files changed, 45 insertions, 200 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 9496e75eebd..a9a7eff1685 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -507,6 +507,38 @@ static int ui_but_equals_old(uiBut *but, uiBut *oldbut) return 1; } +/* oldbut is being inserted in new block, so we use the lines from new button, and replace button pointers */ +static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut) +{ + uiLinkLine *line; + uiBut *but; + + /* if active button is LINK */ + if(but->type==LINK && but->link) { + + SWAP(uiLink *, oldbut->link, but->link); + + for(line= oldbut->link->lines.first; line; line= line->next) { + if(line->to==newbut) + line->to= oldbut; + if(line->from==newbut) + line->from= oldbut; + } + } + + /* check all other button links */ + for(but= block->buttons.first; but; but= but->next) { + if(but!=newbut && but->type==LINK && but->link) { + for(line= but->link->lines.first; line; line= line->next) { + if(line->to==newbut) + line->to= oldbut; + if(line->from==newbut) + line->from= oldbut; + } + } + } +} + static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut **butpp) { uiBlock *oldblock; @@ -555,6 +587,15 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut oldbut->x2= but->x2; oldbut->y2= but->y2; oldbut->context= but->context; /* set by Layout */ + /* typically the same pointers, but not on undo/redo */ + /* XXX some menu buttons store button itself in but->poin. Ugly */ + if(oldbut->poin != (char *)oldbut) { + SWAP(char *, oldbut->poin, but->poin) + SWAP(void *, oldbut->func_argN, but->func_argN) + } + + ui_but_update_linklines(block, oldbut, but); + BLI_remlink(&block->buttons, but); ui_free_but(C, but); @@ -933,40 +974,6 @@ static void ui_is_but_sel(uiBut *but) else but->flag &= ~UI_SELECT; } -/* XXX 2.50 no links supported yet */ -#if 0 -static int uibut_contains_pt(uiBut *UNUSED(but), short *UNUSED(mval)) -{ - return 0; - -} - -static uiBut *ui_get_valid_link_button(uiBlock *block, uiBut *but, short *mval) -{ - uiBut *bt; - - /* find button to link to */ - for (bt= block->buttons.first; bt; bt= bt->next) - if(bt!=but && uibut_contains_pt(bt, mval)) - break; - - if (bt) { - if (but->type==LINK && bt->type==INLINK) { - if( but->link->tocode == (int)bt->hardmin ) { - return bt; - } - } - else if(but->type==INLINK && bt->type==LINK) { - if( bt->link->tocode == (int)but->hardmin ) { - return bt; - } - } - } - - return NULL; -} -#endif - static uiBut *ui_find_inlink(uiBlock *block, void *poin) { uiBut *but; @@ -1086,166 +1093,6 @@ void ui_delete_linkline(uiLinkLine *line, uiBut *but) MEM_freeN(line); //REDRAW } -/* XXX 2.50 no links supported yet */ -#if 0 -static void ui_delete_active_linkline(uiBlock *block) -{ - uiBut *but; - uiLink *link; - uiLinkLine *line, *nline; - int a, b; - - but= block->buttons.first; - while(but) { - if(but->type==LINK && but->link) { - line= but->link->lines.first; - while(line) { - - nline= line->next; - - if(line->flag & UI_SELECT) { - BLI_remlink(&but->link->lines, line); - - link= line->from->link; - - /* are there more pointers allowed? */ - if(link->ppoin) { - - if(*(link->totlink)==1) { - *(link->totlink)= 0; - MEM_freeN(*(link->ppoin)); - *(link->ppoin)= NULL; - } - else { - b= 0; - for(a=0; a< (*(link->totlink)); a++) { - - if( (*(link->ppoin))[a] != line->to->poin ) { - (*(link->ppoin))[b]= (*(link->ppoin))[a]; - b++; - } - } - (*(link->totlink))--; - } - } - else { - *(link->poin)= NULL; - } - - MEM_freeN(line); - } - line= nline; - } - } - but= but->next; - } - - /* temporal! these buttons can be everywhere... */ - allqueue(REDRAWBUTSLOGIC, 0); -} - -static void ui_do_active_linklines(uiBlock *block, short *mval) -{ - uiBut *but; - uiLinkLine *line, *act= NULL; - float mindist= 12.0, fac, v1[2], v2[2], v3[3]; - int foundone= 0; - - if(mval) { - v1[0]= mval[0]; - v1[1]= mval[1]; - - /* find a line close to the mouse */ - but= block->buttons.first; - while(but) { - if(but->type==LINK && but->link) { - foundone= 1; - line= but->link->lines.first; - while(line) { - v2[0]= line->from->x2; - v2[1]= (line->from->y1+line->from->y2)/2.0; - v3[0]= line->to->x1; - v3[1]= (line->to->y1+line->to->y2)/2.0; - - fac= dist_to_line_segment_v2(v1, v2, v3); - if(fac < mindist) { - mindist= fac; - act= line; - } - line= line->next; - } - } - but= but->next; - } - } - - /* check for a 'found one' to prevent going to 'frontbuffer' mode. - this slows done gfx quite some, and at OSX the 'finish' forces a swapbuffer */ - if(foundone) { - glDrawBuffer(GL_FRONT); - - /* draw */ - but= block->buttons.first; - while(but) { - if(but->type==LINK && but->link) { - line= but->link->lines.first; - while(line) { - if(line==act) { - if((line->flag & UI_SELECT)==0) { - line->flag |= UI_SELECT; - ui_draw_linkline(line); - } - } - else if(line->flag & UI_SELECT) { - line->flag &= ~UI_SELECT; - ui_draw_linkline(line); - } - line= line->next; - } - } - but= but->next; - } - bglFlush(); - glDrawBuffer(GL_BACK); - } -} -#endif - -/* ******************************************************* */ - -/* XXX 2.50 no screendump supported yet */ - -#if 0 -/* nasty but safe way to store screendump rect */ -static int scr_x=0, scr_y=0, scr_sizex=0, scr_sizey=0; - -static void ui_set_screendump_bbox(uiBlock *block) -{ - if(block) { - scr_x= block->minx; - scr_y= block->miny; - scr_sizex= block->maxx - block->minx; - scr_sizey= block->maxy - block->miny; - } - else { - scr_sizex= scr_sizey= 0; - } -} - -/* used for making screenshots for menus, called in screendump.c */ -int uiIsMenu(int *x, int *y, int *sizex, int *sizey) -{ - if(scr_sizex!=0 && scr_sizey!=0) { - *x= scr_x; - *y= scr_y; - *sizex= scr_sizex; - *sizey= scr_sizey; - return 1; - } - - return 0; -} -#endif /* *********************** data get/set *********************** * this either works with the pointed to data, or can work with @@ -2538,7 +2385,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, /* keep track of UI_interface.h */ if(ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM)); - else if(ELEM5(but->type, SCROLL, SEPR, LINK, INLINK, FTPREVIEW)); + else if(ELEM3(but->type, SCROLL, SEPR, FTPREVIEW)); else if(but->type >= SEARCH_MENU); else but->flag |= UI_BUT_UNDO; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c0ac376f77f..1d613fd0a0e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -117,7 +117,6 @@ typedef struct uiHandleButtonData { float vec[3], origvec[3]; int togdual, togonly; ColorBand *coba; - CurveMapping *cumap; /* tooltip */ ARegion *tooltip; @@ -1874,8 +1873,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data) float softrange, softmin, softmax; if(but->type == BUT_CURVE) { - data->cumap= (CurveMapping*)but->poin; - but->editcumap= data->cumap; + but->editcumap= (CurveMapping*)but->poin; } else if(but->type == BUT_COLORBAND) { data->coba= (ColorBand*)but->poin; @@ -3375,7 +3373,7 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap, int mx, int my) { - CurveMapping *cumap= data->cumap; + CurveMapping *cumap= (CurveMapping*)but->poin; CurveMap *cuma= cumap->cm+cumap->cur; CurveMapPoint *cmp= cuma->curve; float fx, fy, zoomx, zoomy, offsx, offsy; @@ -3565,7 +3563,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt } else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) { if(data->dragsel != -1) { - CurveMapping *cumap= data->cumap; + CurveMapping *cumap= (CurveMapping*)but->poin; CurveMap *cuma= cumap->cm+cumap->cur; CurveMapPoint *cmp= cuma->curve; |