Redraw parent popup when the child popup is closed

This commit is contained in:
Aleksandr Zinovev 2017-03-30 16:48:18 +03:00
parent 843be91002
commit 5b3b0b4778
5 changed files with 47 additions and 25 deletions

View File

@ -421,7 +421,7 @@ typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1);
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg);
void UI_popup_block_invoke_ex(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg);
void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg, struct wmOperator *op);
/* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */
void UI_popup_block_close(struct bContext *C, struct wmWindow *win, uiBlock *block);

View File

@ -87,6 +87,7 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
#ifdef WITH_INPUT_IME
# include "wm_window.h"
@ -380,6 +381,7 @@ typedef struct uiAfterFunc {
void *butm_func_arg;
int a2;
wmOperator *popup_op;
wmOperatorType *optype;
int opcontext;
PointerRNA *opptr;
@ -635,13 +637,24 @@ PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext,
return ptr;
}
static void popup_check(bContext *C, const wmOperator *op)
{
if (op && op->type->check && op->type->check(C, op)) {
/* check for popup and re-layout buttons */
ARegion *ar_menu = CTX_wm_menu(C);
if (ar_menu)
ED_region_tag_refresh_ui(ar_menu);
}
}
/**
* Check if a #uiAfterFunc is needed for this button.
*/
static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
{
return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop || block->handle_func ||
(but->type == UI_BTYPE_BUT_MENU && block->butm_func));
(but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
block->handle && block->handle->popup_op);
}
static void ui_apply_but_func(bContext *C, uiBut *but)
@ -682,6 +695,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->butm_func_arg = block->butm_func_arg;
after->a2 = but->a2;
}
if (block->handle)
after->popup_op = block->handle->popup_op;
after->optype = but->optype;
after->opcontext = but->opcontext;
@ -766,6 +782,9 @@ static void ui_apply_but_funcs_after(bContext *C)
if (after.context)
CTX_store_set(C, after.context);
if (after.popup_op)
popup_check(C, after.popup_op);
if (after.opptr) {
/* free in advance to avoid leak on exit */
opptr = *after.opptr;
@ -6665,7 +6684,7 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
}
/**
@ -10179,6 +10198,25 @@ void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *
void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
{
wmEventHandler *handler;
for (handler = handlers->first; handler; handler = handler->next) {
if (handler->ui_handle == ui_popup_handler &&
handler->ui_remove == ui_popup_handler_remove &&
handler->ui_userdata == popup)
{
/* tag refresh parent popup */
if (handler->next &&
handler->next->ui_handle == ui_popup_handler &&
handler->next->ui_remove == ui_popup_handler_remove)
{
uiPopupBlockHandle *parent_popup = handler->next->ui_userdata;
ED_region_tag_refresh_ui(parent_popup->region);
}
break;
}
}
WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false);
}

View File

@ -556,6 +556,7 @@ struct uiPopupBlockHandle {
struct uiKeyNavLock keynav_state;
/* for operator popups */
struct wmOperator *popup_op;
struct wmOperatorType *optype;
ScrArea *ctx_area;
ARegion *ctx_region;

View File

@ -3312,7 +3312,7 @@ void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg)
UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
}
void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg, wmOperator *op)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
@ -3321,6 +3321,7 @@ void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc po
handle->popup = true;
handle->retvalue = 1;
handle->popup_op = op;
handle->popup_arg = arg;
handle->popup_func = popup_func;
handle->cancel_func = cancel_func;

View File

@ -1403,20 +1403,6 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
}
}
static void popup_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
{
wmOperator *op = op_ptr;
if (op->type->check) {
if (op->type->check(C, op)) {
/* check for popup and re-layout buttons */
ARegion *ar_menu = CTX_wm_menu(C);
if (ar_menu) {
ED_region_tag_refresh_ui(ar_menu);
}
}
}
}
/* Dialogs are popups that require user verification (click OK) before exec */
static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
{
@ -1435,8 +1421,6 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
UI_block_func_set(block, popup_check_cb, op, NULL);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
/* clear so the OK button is left alone */
@ -1475,8 +1459,6 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
UI_block_func_set(block, popup_check_cb, op, NULL);
/* since ui is defined the auto-layout args are not used */
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
@ -1523,7 +1505,7 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
data->width = width;
data->height = height;
data->free_op = true; /* if this runs and gets registered we may want not to free it */
UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data, op);
return OPERATOR_RUNNING_MODAL;
}
@ -1553,7 +1535,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op, op);
if (do_call)
wm_block_redo_cb(C, op, 0);
@ -1595,7 +1577,7 @@ int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int h
data->free_op = true; /* if this runs and gets registered we may want not to free it */
/* op is not executed until popup OK but is clicked */
UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data, op);
return OPERATOR_RUNNING_MODAL;
}