Fix #20502: add constraint (with targets) menu has no last used memory.

The last click button memory can now deal with menus with varying amounts
of menu entries and multi column layouts.
This commit is contained in:
2010-02-01 11:13:55 +00:00
parent 53f8bbd798
commit e11f5d7d94
2 changed files with 48 additions and 19 deletions

View File

@@ -1875,6 +1875,19 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
/************************ Popup Menu Memory ****************************/
static int ui_popup_string_hash(char *str)
{
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
int hash;
char *delimit= strchr(str, '|');
if(delimit) *delimit= 0;
hash= BLI_ghashutil_strhash(str);
if(delimit) *delimit= '|';
return hash;
}
static int ui_popup_menu_hash(char *str)
{
return BLI_ghashutil_strhash(str);
@@ -1883,7 +1896,7 @@ static int ui_popup_menu_hash(char *str)
/* but == NULL read, otherwise set */
uiBut *ui_popup_menu_memory(uiBlock *block, uiBut *but)
{
static char mem[256], first=1;
static int mem[256], first=1;
int hash= block->puphash;
if(first) {
@@ -1894,12 +1907,16 @@ uiBut *ui_popup_menu_memory(uiBlock *block, uiBut *but)
if(but) {
/* set */
mem[hash & 255 ]= BLI_findindex(&block->buttons, but);
mem[hash & 255 ]= ui_popup_string_hash(but->str);
return NULL;
}
else {
/* get */
return BLI_findlink(&block->buttons, mem[hash & 255]);
for(but=block->buttons.first; but; but=but->next)
if(ui_popup_string_hash(but->str) == mem[hash & 255])
return but;
return NULL;
}
}
@@ -1924,7 +1941,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
ScrArea *sa;
ARegion *ar;
uiPopupMenu *pup= arg_pup;
int offset, direction, minwidth, flip;
int offset[2], direction, minwidth, width, height, flip;
if(pup->menu_func) {
pup->block->handle= handle;
@@ -1960,7 +1977,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
block->direction= direction;
uiBlockLayoutResolve(block, NULL, NULL);
uiBlockLayoutResolve(block, &width, &height);
uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
@@ -1969,17 +1986,27 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
uiBlockSetDirection(block, direction);
/* offset the mouse position, possibly based on earlier selection */
offset= 1.5*MENU_BUTTON_HEIGHT;
if((block->flag & UI_BLOCK_POPUP_MEMORY) &&
(bt= ui_popup_menu_memory(block, NULL))) {
/* position mouse on last clicked item, at 0.8*width of the
button, so it doesn't overlap the text too much, also note
the offset is negative because we are inverse moving the
block to be under the mouse */
offset[0]= -(bt->x1 + 0.8f*(bt->x2 - bt->x1));
offset[1]= -(bt->y1 + 0.5f*MENU_BUTTON_HEIGHT);
}
else {
/* position mouse at 0.8*width of the button and below the tile
on the first item */
offset[0]= 0;
for(bt=block->buttons.first; bt; bt=bt->next)
offset[0]= MIN2(offset[0], -(bt->x1 + 0.8f*(bt->x2 - bt->x1)));
if(block->flag & UI_BLOCK_POPUP_MEMORY) {
bt= ui_popup_menu_memory(block, NULL);
if(bt)
offset= -bt->y1 - 0.5f*MENU_BUTTON_HEIGHT;
offset[1]= 1.5*MENU_BUTTON_HEIGHT;
}
block->minbounds= minwidth;
uiMenuPopupBoundsBlock(block, 1, 20, offset);
uiMenuPopupBoundsBlock(block, 1, offset[0], offset[1]);
}
else {
/* for a header menu we set the direction automatic */