diff options
-rw-r--r-- | release/scripts/presets/keyconfig/keymap_data/blender_default.py | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 26 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 7 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 81 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 58 | ||||
-rw-r--r-- | source/blender/editors/object/object_data_transfer.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 112 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 10 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_ui_common.c | 14 |
12 files changed, 250 insertions, 71 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index dbfc9daca84..b924625b4de 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -728,6 +728,11 @@ def km_property_editor(_params): {"properties": [("direction", 'PREV'), ], },), ("screen.space_context_cycle", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("direction", 'NEXT'), ], },), + # Modifier panels + ("object.modifier_remove", {"type": 'X', "value": 'PRESS'}, {"properties": [("report", True)]}), + ("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}), + ("object.modifier_copy", {"type": 'D', "value": 'PRESS', "shift": True}, None), + ("object.modifier_apply", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("report", True)]}), ]) return keymap diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index bfc0d437994..c510b3a2dfb 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -393,6 +393,7 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb) Panel *panel = lb->first; for (; new_panel; new_panel = new_panel->next, panel = panel->next) { new_panel->activedata = NULL; + new_panel->runtime.custom_data_ptr = NULL; panel_list_copy(&new_panel->children, &panel->children); } } @@ -575,18 +576,25 @@ void BKE_region_callback_free_gizmomap_set(void (*callback)(struct wmGizmoMap *) region_free_gizmomap_callback = callback; } -void BKE_area_region_panels_free(ListBase *lb) +static void area_region_panels_free_recursive(Panel *panel) { - Panel *panel, *panel_next; - for (panel = lb->first; panel; panel = panel_next) { - panel_next = panel->next; - if (panel->activedata) { - MEM_freeN(panel->activedata); - } - BKE_area_region_panels_free(&panel->children); + MEM_SAFE_FREE(panel->activedata); + + LISTBASE_FOREACH_MUTABLE (Panel *, child_panel, &panel->children) { + area_region_panels_free_recursive(child_panel); } - BLI_freelistN(lb); + MEM_freeN(panel); +} + +void BKE_area_region_panels_free(ListBase *lb) +{ + LISTBASE_FOREACH_MUTABLE (Panel *, panel, lb) { + /* Free custom data just for parent panels to avoid a double free. */ + MEM_SAFE_FREE(panel->runtime.custom_data_ptr); + area_region_panels_free_recursive(panel); + } + BLI_listbase_clear(lb); } /* not region itself */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index e9389561b47..e4822c4cb7f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7015,6 +7015,7 @@ static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb) panel->runtime_flag = 0; panel->activedata = NULL; panel->type = NULL; + panel->runtime.custom_data_ptr = NULL; direct_link_panel_list(reader, &panel->children); } } diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index bcbee51246e..1cedd4e122f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1706,12 +1706,17 @@ void UI_panel_category_draw_all(struct ARegion *region, const char *category_id_ struct PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname); +struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContext *C, + const struct wmEvent *event); +void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data); + /* Polyinstantiated panels for representing a list of data. */ struct Panel *UI_panel_add_instanced(struct ScrArea *area, struct ARegion *region, struct ListBase *panels, char *panel_idname, - int list_index); + int list_index, + struct PointerRNA *custom_data); void UI_panels_free_instanced(struct bContext *C, struct ARegion *region); #define LIST_PANEL_UNIQUE_STR_LEN 4 diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 6aefef197df..771e9383b8a 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -5576,6 +5576,7 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, panel->layout = layout; pt->draw(C, panel); panel->layout = NULL; + BLI_assert(panel->runtime.custom_data_ptr = NULL); MEM_freeN(panel); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 9ff678df0db..4bf88c76857 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -245,20 +245,25 @@ static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_ /********* Functions for instanced panels. ***********/ -static Panel *UI_panel_add_instanced_ex( - ScrArea *area, ARegion *region, ListBase *panels, PanelType *panel_type, int list_index) +static Panel *UI_panel_add_instanced_ex(ScrArea *area, + ARegion *region, + ListBase *panels, + PanelType *panel_type, + int list_index, + PointerRNA *custom_data) { Panel *panel = MEM_callocN(sizeof(Panel), "instanced panel"); panel->type = panel_type; BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname)); panel->runtime.list_index = list_index; + panel->runtime.custom_data_ptr = custom_data; /* Add the panel's children too. Although they aren't instanced panels, we can still use this * function to create them, as UI_panel_begin does other things we don't need to do. */ LISTBASE_FOREACH (LinkData *, child, &panel_type->children) { PanelType *child_type = child->data; - UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index); + UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index, custom_data); } /* Make sure the panel is added to the end of the display-order as well. This is needed for @@ -283,8 +288,12 @@ static Panel *UI_panel_add_instanced_ex( * Called in situations where panels need to be added dynamically rather than having only one panel * corresponding to each PanelType. */ -Panel *UI_panel_add_instanced( - ScrArea *area, ARegion *region, ListBase *panels, char *panel_idname, int list_index) +Panel *UI_panel_add_instanced(ScrArea *area, + ARegion *region, + ListBase *panels, + char *panel_idname, + int list_index, + PointerRNA *custom_data) { ARegionType *region_type = region->type; @@ -296,7 +305,7 @@ Panel *UI_panel_add_instanced( return NULL; } - return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index); + return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index, custom_data); } /** @@ -332,7 +341,8 @@ static void panel_free_block(ARegion *region, Panel *panel) } /** - * Free a panel and it's children. + * Free a panel and it's children. Custom data is shared by the panel and its children + * and is freed by #UI_panels_free_instanced. * * \note The only panels that should need to be deleted at runtime are panels with the * #PNL_INSTANCED flag set. @@ -369,6 +379,13 @@ void UI_panels_free_instanced(bContext *C, ARegion *region) if (C != NULL && panel->activedata != NULL) { panel_activate_state(C, panel, PANEL_STATE_EXIT); } + + /* Free panel's custom data. */ + if (panel->runtime.custom_data_ptr != NULL) { + MEM_freeN(panel->runtime.custom_data_ptr); + } + + /* Free the panel and its subpanels. */ panel_delete(region, ®ion->panels, panel); } } @@ -2886,6 +2903,56 @@ int ui_handler_panel_region(bContext *C, return retval; } +static void ui_panel_custom_data_set_recursive(Panel *panel, PointerRNA *custom_data) +{ + panel->runtime.custom_data_ptr = custom_data; + + LISTBASE_FOREACH (Panel *, child_panel, &panel->children) { + ui_panel_custom_data_set_recursive(child_panel, custom_data); + } +} + +void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data) +{ + BLI_assert(panel->type != NULL); + + /* Free the old custom data, which should be shared among all of the panel's subpanels. */ + if (panel->runtime.custom_data_ptr != NULL) { + MEM_freeN(panel->runtime.custom_data_ptr); + } + + ui_panel_custom_data_set_recursive(panel, custom_data); +} + +PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wmEvent *event) +{ + ARegion *region = CTX_wm_region(C); + + Panel *panel = NULL; + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + panel = block->panel; + if (panel == NULL) { + continue; + } + + int mx = event->x; + int my = event->y; + ui_window_to_block(region, block, &mx, &my); + int mouse_state = ui_panel_mouse_state_get(block, panel, mx, my); + if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) { + break; + } + } + + if (panel == NULL) { + return NULL; + } + + PointerRNA *customdata = panel->runtime.custom_data_ptr; + + return customdata; +} + /**************** window level modal panel interaction **************/ /* note, this is modal handler and should not swallow events for animation */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index c22eb097761..5a5b501e21e 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1873,14 +1873,22 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C) ModifierData *md = modifiers->first; for (int i = 0; md; i++, md = md->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); - if (mti->panelRegister) { - char panel_idname[MAX_NAME]; - modifier_panel_id(md, panel_idname); + if (mti->panelRegister == NULL) { + continue; + } - Panel *new_panel = UI_panel_add_instanced(sa, region, ®ion->panels, panel_idname, i); - if (new_panel != NULL) { - UI_panel_set_expand_from_list_data(C, new_panel); - } + char panel_idname[MAX_NAME]; + modifier_panel_id(md, panel_idname); + + /* Create custom data RNA pointer. */ + PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); + RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr); + + Panel *new_panel = UI_panel_add_instanced( + sa, region, ®ion->panels, panel_idname, i, md_ptr); + + if (new_panel != NULL) { + UI_panel_set_expand_from_list_data(C, new_panel); } } } @@ -1890,6 +1898,27 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C) if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) UI_panel_set_expand_from_list_data(C, panel); } + + /* Assuming there's only one group of instanced panels, update the custom data pointers. */ + Panel *panel = region->panels.first; + LISTBASE_FOREACH (ModifierData *, md, modifiers) { + const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); + if (mti->panelRegister == NULL) { + continue; + } + + /* Move to the next instanced panel corresponding to the next modifier. */ + while ((panel->type == NULL) || !(panel->type->flag & PNL_INSTANCED)) { + panel = panel->next; + BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */ + } + + PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); + RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr); + UI_panel_custom_data_set(panel, md_ptr); + + panel = panel->next; + } } } @@ -2026,9 +2055,11 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_ char panel_idname[MAX_NAME]; panel_id_func(con, panel_idname); - Panel *new_panel = UI_panel_add_instanced(sa, region, ®ion->panels, panel_idname, i); + Panel *new_panel = UI_panel_add_instanced( + sa, region, ®ion->panels, panel_idname, i, NULL); if (new_panel) { - /* Set the list panel functionality function pointers since we don't do it with python. */ + /* Set the list panel functionality function pointers since we don't do it with + * python. */ new_panel->type->set_list_data_expand_flag = set_constraint_expand_flag; new_panel->type->get_list_data_expand_flag = get_constraint_expand_flag; new_panel->type->reorder = constraint_reorder; @@ -2082,7 +2113,8 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C) char panel_idname[MAX_NAME]; gpencil_modifier_panel_id(md, panel_idname); - Panel *new_panel = UI_panel_add_instanced(sa, region, ®ion->panels, panel_idname, i); + Panel *new_panel = UI_panel_add_instanced( + sa, region, ®ion->panels, panel_idname, i, NULL); if (new_panel != NULL) { UI_panel_set_expand_from_list_data(C, new_panel); } @@ -2107,7 +2139,8 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C) /* -------------------------------------------------------------------- */ /** \name ShaderFx Template * - * Template for building the panel layout for the active object's grease pencil shader effects. + * Template for building the panel layout for the active object's grease pencil shader + * effects. * \{ */ /** @@ -2138,7 +2171,8 @@ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C) char panel_idname[MAX_NAME]; shaderfx_panel_id(fx, panel_idname); - Panel *new_panel = UI_panel_add_instanced(sa, region, ®ion->panels, panel_idname, i); + Panel *new_panel = UI_panel_add_instanced( + sa, region, ®ion->panels, panel_idname, i, NULL); if (new_panel != NULL) { UI_panel_set_expand_from_list_data(C, new_panel); } diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 274cd31406c..77a3e194ae8 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -854,7 +854,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op) static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return datalayout_transfer_exec(C, op); } else { diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 3dbd1de123d..be1c29b0010 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -153,7 +153,9 @@ bool edit_modifier_poll_generic(struct bContext *C, const bool is_editmode_allowed); bool edit_modifier_poll(struct bContext *C); void edit_modifier_properties(struct wmOperatorType *ot); -int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op); +int edit_modifier_invoke_properties(struct bContext *C, + struct wmOperator *op, + const struct wmEvent *event); struct ModifierData *edit_modifier_property_get(struct wmOperator *op, struct Object *ob, int type); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index a6c5814e88a..adcfafb44c9 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -88,6 +88,8 @@ #include "ED_screen.h" #include "ED_sculpt.h" +#include "UI_interface.h" + #include "WM_api.h" #include "WM_types.h" @@ -1037,19 +1039,38 @@ void edit_modifier_properties(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN); } -int edit_modifier_invoke_properties(bContext *C, wmOperator *op) +static void edit_modifier_report_property(wmOperatorType *ot) { - ModifierData *md; + PropertyRNA *prop = RNA_def_boolean( + ot->srna, "report", false, "Report", "Create a notification after the operation"); + RNA_def_property_flag(prop, PROP_HIDDEN); +} + +/** + * \param event: If this isn't NULL, the operator will also look for panels underneath + * the cursor with customdata set to a modifier. + */ +int edit_modifier_invoke_properties(bContext *C, wmOperator *op, const wmEvent *event) +{ + PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); if (RNA_struct_property_is_set(op->ptr, "modifier")) { return true; } - else { - PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); - if (ptr.data) { - md = ptr.data; - RNA_string_set(op->ptr, "modifier", md->name); - return true; + else if (ctx_ptr.data != NULL) { + ModifierData *md = ctx_ptr.data; + RNA_string_set(op->ptr, "modifier", md->name); + return true; + } + else if (event != NULL) { + PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event); + + if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) { + if (RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) { + ModifierData *md = panel_ptr->data; + RNA_string_set(op->ptr, "modifier", md->name); + return true; + } } } @@ -1085,6 +1106,10 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int mode_orig = ob->mode; + /* Store name temporarily for report. */ + char name[MAX_NAME]; + strcpy(name, md->name); + if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md)) { return OPERATOR_CANCELLED; } @@ -1099,12 +1124,17 @@ static int modifier_remove_exec(bContext *C, wmOperator *op) } } } + + if (RNA_boolean_get(op->ptr, "report")) { + BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name); + } + return OPERATOR_FINISHED; } -static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_remove_exec(C, op); } else { @@ -1125,6 +1155,7 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; edit_modifier_properties(ot); + edit_modifier_report_property(ot); } /** \} */ @@ -1148,9 +1179,9 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_move_up_exec(C, op); } else { @@ -1194,9 +1225,9 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_move_down_exec(C, op); } else { @@ -1246,9 +1277,9 @@ static int modifier_move_to_index_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_move_to_index_exec(C, op); } else { @@ -1315,6 +1346,10 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int apply_as = RNA_enum_get(op->ptr, "apply_as"); + /* Store name temporarily for report. */ + char name[MAX_NAME]; + strcpy(name, md->name); + if (!md || !ED_object_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) { return OPERATOR_CANCELLED; } @@ -1323,12 +1358,16 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + if (RNA_boolean_get(op->ptr, "report")) { + BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name); + } + return OPERATOR_FINISHED; } -static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_apply_exec(C, op); } else { @@ -1366,6 +1405,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) "Apply as", "How to apply the modifier to the geometry"); edit_modifier_properties(ot); + edit_modifier_report_property(ot); } /** \} */ @@ -1396,7 +1436,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return modifier_convert_exec(C, op); } else { @@ -1440,9 +1480,9 @@ static int modifier_copy_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return modifier_copy_exec(C, op); } else { @@ -1501,7 +1541,7 @@ static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return multires_higher_levels_delete_exec(C, op); } else { @@ -1579,7 +1619,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return multires_subdivide_exec(C, op); } else { @@ -1656,7 +1696,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return multires_reshape_exec(C, op); } else { @@ -1720,7 +1760,7 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEv Mesh *me = ob->data; char path[FILE_MAX]; - if (!edit_modifier_invoke_properties(C, op)) { + if (!edit_modifier_invoke_properties(C, op, NULL)) { return OPERATOR_CANCELLED; } @@ -1835,9 +1875,9 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, event)) { return multires_base_apply_exec(C, op); } else { @@ -1891,7 +1931,7 @@ static int multires_unsubdivide_exec(bContext *C, wmOperator *op) static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return multires_unsubdivide_exec(C, op); } else { @@ -1949,7 +1989,7 @@ static int multires_rebuild_subdiv_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return multires_rebuild_subdiv_exec(C, op); } else { @@ -2327,7 +2367,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op) static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return skin_armature_create_exec(C, op); } else { @@ -2406,7 +2446,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op) static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return correctivesmooth_bind_exec(C, op); } else { @@ -2483,7 +2523,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op) static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return meshdeform_bind_exec(C, op); } else { @@ -2539,7 +2579,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op) static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return explode_refresh_exec(C, op); } else { @@ -2743,7 +2783,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return ocean_bake_exec(C, op); } else { @@ -2822,7 +2862,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return laplaciandeform_bind_exec(C, op); } else { @@ -2891,7 +2931,7 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op) static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (edit_modifier_invoke_properties(C, op)) { + if (edit_modifier_invoke_properties(C, op, NULL)) { return surfacedeform_bind_exec(C, op); } else { diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index eb9f1c1a80a..c34f1faa255 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -41,6 +41,7 @@ struct uiLayout; struct wmDrawBuffer; struct wmTimer; struct wmTooltipState; +struct PointerRNA; /* TODO Doing this is quite ugly :) * Once the top-bar is merged bScreen should be refactored to use ScrAreaMap. */ @@ -135,6 +136,15 @@ typedef struct Panel_Runtime { /* For instanced panels: Index of the list item the panel corresponds to. */ int list_index; + + /** + * Pointer for storing which data the panel corresponds to. + * Useful when there can be multiple instances of the same panel type. + * + * \note A panel and its subpanels share the same custom data pointer. + * This avoids freeing the same pointer twice when panels are removed. + */ + struct PointerRNA *custom_data_ptr; } Panel_Runtime; /** The part from uiBlock that needs saved in file. */ diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c index 88e095c549e..563aa3f091f 100644 --- a/source/blender/modifiers/intern/MOD_ui_common.c +++ b/source/blender/modifiers/intern/MOD_ui_common.c @@ -236,12 +236,15 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v) uiLayoutSetUnitsX(layout, 4.0f); /* Apply. */ - uiItemEnumO(layout, + uiItemFullO(layout, "OBJECT_OT_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"), ICON_CHECKMARK, - "apply_as", - MODIFIER_APPLY_DATA); + NULL, + WM_OP_INVOKE_DEFAULT, + 0, + &op_ptr); + RNA_boolean_set(&op_ptr, "report", true); /* Apply as shapekey. */ if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) { @@ -371,7 +374,10 @@ static void modifier_panel_header(const bContext *C, Panel *panel) if (modifier_can_delete(md) && !modifier_is_simulation(md)) { sub = uiLayoutRow(row, false); uiLayoutSetEmboss(sub, UI_EMBOSS_NONE); - uiItemO(sub, "", ICON_X, "OBJECT_OT_modifier_remove"); + PointerRNA op_ptr; + uiItemFullO( + sub, "OBJECT_OT_modifier_remove", "", ICON_X, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); + RNA_boolean_set(&op_ptr, "report", true); buttons_number++; } |