UI: Add support for popups to refresh their layput (D578)

This is needed for popups to chance state once activated,
currently it makes use of operators `check` callback, after values are modified,
as the file selector does already.
This commit is contained in:
2014-06-15 01:40:15 +10:00
parent 5713d80804
commit ea2043eb3a
13 changed files with 203 additions and 77 deletions

View File

@@ -295,9 +295,8 @@ void ui_bounds_block(uiBlock *block)
block->safety.ymax = block->rect.ymax + xof;
}
static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
static void ui_centered_bounds_block(wmWindow *window, uiBlock *block)
{
wmWindow *window = CTX_wm_window(C);
int xmax, ymax;
int startx, starty;
int width, height;
@@ -322,9 +321,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
ui_bounds_block(block);
}
static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBoundsCalc bounds_calc)
static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
eBlockBoundsCalc bounds_calc, const int xy[2])
{
wmWindow *window = CTX_wm_window(C);
int startx, starty, endx, endy, width, height, oldwidth, oldheight;
int oldbounds, xmax, ymax;
const int margin = UI_SCREEN_MARGIN;
@@ -362,8 +361,8 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
/* offset block based on mouse position, user offset is scaled
* along in case we resized the block in ui_text_bounds_block */
startx = window->eventstate->x + block->rect.xmin + (block->mx * width) / oldwidth;
starty = window->eventstate->y + block->rect.ymin + (block->my * height) / oldheight;
startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
if (startx < margin)
startx = margin;
@@ -1083,29 +1082,50 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
}
void uiEndBlock(const bContext *C, uiBlock *block)
void uiBlockUpdateFromOld(const bContext *C, uiBlock *block)
{
const bool has_old = (block->oldblock != NULL);
/* avoid searches when old/new lists align */
uiBut *but_old = has_old ? block->oldblock->buttons.first : NULL;
uiBut *but_old;
uiBut *but;
Scene *scene = CTX_data_scene(C);
if (!block->oldblock)
return;
if (has_old && BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
but_old = block->oldblock->buttons.first;
if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
UI_butstore_update(block);
}
for (but = block->buttons.first; but; but = but->next) {
if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
ui_check_but(but);
}
}
block->auto_open = block->oldblock->auto_open;
block->auto_open_last = block->oldblock->auto_open_last;
block->tooltipdisabled = block->oldblock->tooltipdisabled;
copy_v3_v3(ui_block_hsv_get(block),
ui_block_hsv_get(block->oldblock));
block->oldblock = NULL;
}
void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
{
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
uiBut *but;
BLI_assert(block->active);
uiBlockUpdateFromOld(C, block);
/* inherit flags from 'old' buttons that was drawn here previous, based
* on matching buttons, we need this to make button event handling non
* blocking, while still allowing buttons to be remade each redraw as it
* is expected by blender code */
for (but = block->buttons.first; but; but = but->next) {
if (has_old && ui_but_update_from_old_block(C, block, &but, &but_old)) {
ui_check_but(but);
}
/* temp? Proper check for graying out */
if (but->optype) {
wmOperatorType *ot = but->optype;
@@ -1125,15 +1145,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
}
if (block->oldblock) {
block->auto_open = block->oldblock->auto_open;
block->auto_open_last = block->oldblock->auto_open_last;
block->tooltipdisabled = block->oldblock->tooltipdisabled;
copy_v3_v3(ui_block_hsv_get(block),
ui_block_hsv_get(block->oldblock));
block->oldblock = NULL;
}
/* handle pending stuff */
if (block->layouts.first) {
@@ -1159,13 +1171,13 @@ void uiEndBlock(const bContext *C, uiBlock *block)
ui_text_bounds_block(block, 0.0f);
break;
case UI_BLOCK_BOUNDS_POPUP_CENTER:
ui_centered_bounds_block(C, block);
ui_centered_bounds_block(window, block);
break;
/* fallback */
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
case UI_BLOCK_BOUNDS_POPUP_MENU:
ui_popup_bounds_block(C, block, block->bounds_type);
ui_popup_bounds_block(window, block, block->bounds_type, xy);
break;
}
@@ -1179,6 +1191,13 @@ void uiEndBlock(const bContext *C, uiBlock *block)
block->endblock = 1;
}
void uiEndBlock(const bContext *C, uiBlock *block)
{
wmWindow *window = CTX_wm_window(C);
uiEndBlock_ex(C, block, &window->eventstate->x);
}
/* ************** BLOCK DRAWING FUNCTION ************* */
void ui_fontscale(short *points, float aspect)
@@ -2418,6 +2437,7 @@ void uiBlockSetRegion(uiBlock *block, ARegion *region)
if (oldblock) {
oldblock->active = 0;
oldblock->panel = NULL;
oldblock->handle = NULL;
}
/* at the beginning of the list! for dynamical menus/blocks */