From 5b3b0b4778a6738596cc33d933c2a2df8c4b284b Mon Sep 17 00:00:00 2001 From: raa Date: Thu, 30 Mar 2017 16:48:18 +0300 Subject: Redraw parent popup when the child popup is closed --- source/blender/editors/include/UI_interface.h | 2 +- .../blender/editors/interface/interface_handlers.c | 42 ++++++++++++++++++++-- .../blender/editors/interface/interface_intern.h | 1 + .../blender/editors/interface/interface_regions.c | 3 +- source/blender/windowmanager/intern/wm_operators.c | 24 ++----------- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 9fbce7dd203..2ce4f3e2790 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4846272b17d..259ccb60ba7 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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); } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index d8f9fdcbaae..067279777ba 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -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; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 7b6b41eeef3..534bd4278ca 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -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; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7743d4865df..d827ccafda8 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -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; } -- cgit v1.2.3