From f4e670af2ccec348378356512980554aec39ee3b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 1 Mar 2024 13:20:17 -0500 Subject: [PATCH] Refactor: UI: Use regular button callbacks for curve, color ramp templates Previously these used a special "menu func" that used an argument value passed through each menu button's a2 value. This was more complex than necessary given the existence of generic button callbacks. So use std::function in these remaining cases, and remove the now-unused `butm_func` and `butm_func_arg` values in the uiBlock. --- .../blender/editors/include/UI_interface_c.hh | 1 - source/blender/editors/interface/interface.cc | 6 - .../editors/interface/interface_handlers.cc | 17 +- .../editors/interface/interface_intern.hh | 3 - .../editors/interface/interface_templates.cc | 777 ++++++++---------- 5 files changed, 350 insertions(+), 454 deletions(-) diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh index 37b5b093a64..d6b8399c98e 100644 --- a/source/blender/editors/include/UI_interface_c.hh +++ b/source/blender/editors/include/UI_interface_c.hh @@ -1689,7 +1689,6 @@ void UI_but_number_slider_precision_set(uiBut *but, float precision); void UI_but_search_preview_grid_size_set(uiBut *but, int rows, int cols); void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg); -void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg); void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2); void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2); diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index a7c7eebdbdb..b6b8bb8d2bb 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -5840,12 +5840,6 @@ void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg) block->handle_func_arg = arg; } -void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg) -{ - block->butm_func = func; - block->butm_func_arg = arg; -} - void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2) { block->func = func; diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index b3198517951..e6ad01bc0a7 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -479,10 +479,6 @@ struct uiAfterFunc { void *handle_func_arg; int retval; - uiMenuHandleFunc butm_func; - void *butm_func_arg; - int a2; - wmOperator *popup_op; wmOperatorType *optype; wmOperatorCallContext opcontext; @@ -810,9 +806,7 @@ static void popup_check(bContext *C, wmOperator *op) static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but) { return (but->func || but->apply_func || but->funcN || but->rename_func || but->optype || - but->rnaprop || block->handle_func || - (but->type == UI_BTYPE_BUT_MENU && block->butm_func) || - (block->handle && block->handle->popup_op)); + but->rnaprop || block->handle_func || (block->handle && block->handle->popup_op)); } /** @@ -853,12 +847,6 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->handle_func_arg = block->handle_func_arg; after->retval = but->retval; - if (but->type == UI_BTYPE_BUT_MENU) { - after->butm_func = block->butm_func; - after->butm_func_arg = block->butm_func_arg; - after->a2 = but->a2; - } - if (block->handle) { after->popup_op = block->handle->popup_op; } @@ -1067,9 +1055,6 @@ static void ui_apply_but_funcs_after(bContext *C) if (after.handle_func) { after.handle_func(C, after.handle_func_arg, after.retval); } - if (after.butm_func) { - after.butm_func(C, after.butm_func_arg, after.a2); - } if (after.rename_func) { after.rename_func(C, after.rename_arg1, static_cast(after.rename_orig)); diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index d68ed4560e1..60b1eff3ae8 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -561,9 +561,6 @@ struct uiBlock { uiButHandleNFunc funcN; void *func_argN; - uiMenuHandleFunc butm_func; - void *butm_func_arg; - uiBlockHandleFunc handle_func; void *handle_func_arg; diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 93313decc34..b243e007223 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -97,6 +97,7 @@ #include "UI_string_search.hh" #include "interface_intern.hh" +using blender::StringRef; using blender::Vector; /* we may want to make this optional, disable for now. */ @@ -3390,14 +3391,7 @@ static void rna_update_cb(bContext *C, void *arg_cb, void * /*arg*/) rna_update_cb(*C, *cb); } -enum { - CB_FUNC_FLIP, - CB_FUNC_DISTRIBUTE_LR, - CB_FUNC_DISTRIBUTE_EVENLY, - CB_FUNC_RESET, -}; - -static void colorband_flip_cb(bContext *C, ColorBand *coba) +static void colorband_flip(bContext *C, ColorBand *coba) { CBData data_tmp[MAXCOLORBAND]; @@ -3415,7 +3409,7 @@ static void colorband_flip_cb(bContext *C, ColorBand *coba) ED_undo_push(C, "Flip Color Ramp"); } -static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly) +static void colorband_distribute(bContext *C, ColorBand *coba, bool evenly) { if (coba->tot > 1) { const int tot = evenly ? coba->tot - 1 : coba->tot; @@ -3429,39 +3423,16 @@ static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly) } } -static void colorband_tools_dofunc(bContext *C, void *coba_v, int event) +static uiBlock *colorband_tools_fn(bContext *C, ARegion *region, void *cb_v) { - ColorBand *coba = static_cast(coba_v); - - switch (event) { - case CB_FUNC_FLIP: - colorband_flip_cb(C, coba); - break; - case CB_FUNC_DISTRIBUTE_LR: - colorband_distribute_cb(C, coba, false); - break; - case CB_FUNC_DISTRIBUTE_EVENLY: - colorband_distribute_cb(C, coba, true); - break; - case CB_FUNC_RESET: - BKE_colorband_init(coba, true); - ED_undo_push(C, "Reset Color Ramp"); - break; - } - ED_region_tag_redraw(CTX_wm_region(C)); -} - -static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *arg_cb) -{ - RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb; + RNAUpdateCb &cb = *static_cast(cb_v); const uiStyle *style = UI_style_get_dpi(); - PointerRNA coba_ptr = RNA_property_pointer_get(&cb->ptr, cb->prop); + PointerRNA coba_ptr = RNA_property_pointer_get(&cb.ptr, cb.prop); ColorBand *coba = static_cast(coba_ptr.data); short yco = 0; const short menuwidth = 10 * UI_UNIT_X; uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS_PULLDOWN); - UI_block_func_butmenu_set(block, colorband_tools_dofunc, coba); uiLayout *layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, @@ -3480,73 +3451,100 @@ static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *arg_cb) /* We could move these to operators, * although this isn't important unless we want to assign key shortcuts to them. */ { - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_ARROW_LEFTRIGHT, - IFACE_("Flip Color Ramp"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - CB_FUNC_FLIP, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Distribute Stops from Left"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - CB_FUNC_DISTRIBUTE_LR, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Distribute Stops Evenly"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - CB_FUNC_DISTRIBUTE_EVENLY, - ""); + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_ARROW_LEFTRIGHT, + IFACE_("Flip Color Ramp"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [coba, cb](bContext &C) { + colorband_flip(&C, coba); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); + } + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Distribute Stops from Left"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [coba, cb](bContext &C) { + colorband_distribute(&C, coba, false); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); + } + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Distribute Stops Evenly"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [coba, cb](bContext &C) { + colorband_distribute(&C, coba, true); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); + } - uiItemS(layout); + uiItemS(layout); - uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp"); + uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp"); - uiItemS(layout); + uiItemS(layout); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_LOOP_BACK, - IFACE_("Reset Color Ramp"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - CB_FUNC_RESET, - ""); + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_LOOP_BACK, + IFACE_("Reset Color Ramp"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [coba, cb](bContext &C) { + BKE_colorband_init(coba, true); + ED_undo_push(&C, "Reset Color Ramp"); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); } UI_block_direction_set(block, UI_DIR_DOWN); @@ -3646,7 +3644,7 @@ static void colorband_buttons_layout(uiLayout *layout, RNAUpdateCb *tools_cb = MEM_new(__func__, cb); bt = uiDefIconBlockBut(block, - colorband_tools_func, + colorband_tools_fn, tools_cb, 0, ICON_DOWNARROW_HLT, @@ -3655,7 +3653,9 @@ static void colorband_buttons_layout(uiLayout *layout, 2.0f * unit, UI_UNIT_Y, TIP_("Tools")); - UI_but_funcN_set(bt, rna_update_cb, tools_cb, coba); + /* Pass ownership of `tools_cb` to the button. */ + UI_but_funcN_set( + bt, [](bContext *, void *, void *) {}, tools_cb, nullptr); UI_block_align_end(block); UI_block_emboss_set(block, UI_EMBOSS); @@ -4297,137 +4297,114 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap return block; } -/* only for BKE_curvemap_tools_dofunc */ -enum { - UICURVE_FUNC_RESET_NEG, - UICURVE_FUNC_RESET_POS, - UICURVE_FUNC_RESET_VIEW, - UICURVE_FUNC_HANDLE_VECTOR, - UICURVE_FUNC_HANDLE_AUTO, - UICURVE_FUNC_HANDLE_AUTO_ANIM, - UICURVE_FUNC_EXTEND_HOZ, - UICURVE_FUNC_EXTEND_EXP, -}; - -static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) -{ - CurveMapping *cumap = static_cast(cumap_v); - CurveMap *cuma = cumap->cm + cumap->cur; - - switch (event) { - case UICURVE_FUNC_RESET_NEG: - case UICURVE_FUNC_RESET_POS: /* reset */ - BKE_curvemap_reset(cuma, - &cumap->clipr, - cumap->preset, - (event == UICURVE_FUNC_RESET_NEG) ? CURVEMAP_SLOPE_NEGATIVE : - CURVEMAP_SLOPE_POSITIVE); - BKE_curvemapping_changed(cumap, false); - break; - case UICURVE_FUNC_RESET_VIEW: - BKE_curvemapping_reset_view(cumap); - break; - case UICURVE_FUNC_HANDLE_VECTOR: /* Set vector. */ - BKE_curvemap_handle_set(cuma, HD_VECT); - BKE_curvemapping_changed(cumap, false); - break; - case UICURVE_FUNC_HANDLE_AUTO: /* Set auto. */ - BKE_curvemap_handle_set(cuma, HD_AUTO); - BKE_curvemapping_changed(cumap, false); - break; - case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* Set auto-clamped. */ - BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM); - BKE_curvemapping_changed(cumap, false); - break; - case UICURVE_FUNC_EXTEND_HOZ: /* Extend horizontal. */ - cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE; - BKE_curvemapping_changed(cumap, false); - break; - case UICURVE_FUNC_EXTEND_EXP: /* Extend extrapolate. */ - cumap->flag |= CUMA_EXTEND_EXTRAPOLATE; - BKE_curvemapping_changed(cumap, false); - break; - } - ED_undo_push(C, "CurveMap tools"); - ED_region_tag_redraw(CTX_wm_region(C)); -} - static uiBlock *curvemap_tools_func( - bContext *C, ARegion *region, CurveMapping *cumap, bool show_extend, int reset_mode) + bContext *C, ARegion *region, RNAUpdateCb &cb, bool show_extend, int reset_mode) { + PointerRNA cumap_ptr = RNA_property_pointer_get(&cb.ptr, cb.prop); + CurveMapping *cumap = static_cast(cumap_ptr.data); + short yco = 0; const short menuwidth = 10 * UI_UNIT_X; uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); - UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap); { - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Reset View"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - UICURVE_FUNC_RESET_VIEW, - ""); + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Reset View"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [cumap](bContext &C) { + BKE_curvemapping_reset_view(cumap); + ED_region_tag_redraw(CTX_wm_region(&C)); + }); } if (show_extend) { - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Extend Horizontal"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - UICURVE_FUNC_EXTEND_HOZ, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Extend Extrapolated"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - UICURVE_FUNC_EXTEND_EXP, - ""); + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Extend Horizontal"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [cumap, cb](bContext &C) { + cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + ED_undo_push(&C, "CurveMap tools"); + ED_region_tag_redraw(CTX_wm_region(&C)); + }); + } + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Extend Extrapolated"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [cumap, cb](bContext &C) { + cumap->flag |= CUMA_EXTEND_EXTRAPOLATE; + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + ED_undo_push(&C, "CurveMap tools"); + ED_region_tag_redraw(CTX_wm_region(&C)); + }); + } } { - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Reset Curve"), - 0, - yco -= UI_UNIT_Y, - menuwidth, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - reset_mode, - ""); + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Reset Curve"), + 0, + yco -= UI_UNIT_Y, + menuwidth, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + reset_mode, + ""); + UI_but_func_set(but, [cumap, cb, reset_mode](bContext &C) { + CurveMap *cuma = cumap->cm + cumap->cur; + BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, reset_mode); + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + ED_undo_push(&C, "CurveMap tools"); + ED_region_tag_redraw(CTX_wm_region(&C)); + }); } UI_block_direction_set(block, UI_DIR_DOWN); @@ -4436,43 +4413,28 @@ static uiBlock *curvemap_tools_func( return block; } -static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cumap_v) +static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *region, void *cb_v) { return curvemap_tools_func( - C, region, static_cast(cumap_v), true, UICURVE_FUNC_RESET_POS); + C, region, *static_cast(cb_v), true, CURVEMAP_SLOPE_POSITIVE); } -static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v) +static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *region, void *cb_v) { return curvemap_tools_func( - C, region, static_cast(cumap_v), true, UICURVE_FUNC_RESET_NEG); + C, region, *static_cast(cb_v), true, CURVEMAP_SLOPE_NEGATIVE); } -static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *region, void *cumap_v) +static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *region, void *cb_v) { return curvemap_tools_func( - C, region, static_cast(cumap_v), false, UICURVE_FUNC_RESET_NEG); + C, region, *static_cast(cb_v), false, CURVEMAP_SLOPE_POSITIVE); } -static uiBlock *curvemap_brush_tools_negslope_func(bContext *C, ARegion *region, void *cumap_v) +static uiBlock *curvemap_brush_tools_negslope_func(bContext *C, ARegion *region, void *cb_v) { return curvemap_tools_func( - C, region, static_cast(cumap_v), false, UICURVE_FUNC_RESET_POS); -} - -static void curvemap_tools_handle_vector(bContext *C, void *cumap_v, void * /*arg*/) -{ - curvemap_tools_dofunc(C, cumap_v, UICURVE_FUNC_HANDLE_VECTOR); -} - -static void curvemap_tools_handle_auto(bContext *C, void *cumap_v, void * /*arg*/) -{ - curvemap_tools_dofunc(C, cumap_v, UICURVE_FUNC_HANDLE_AUTO); -} - -static void curvemap_tools_handle_auto_clamped(bContext *C, void *cumap_v, void * /*arg*/) -{ - curvemap_tools_dofunc(C, cumap_v, UICURVE_FUNC_HANDLE_AUTO_ANIM); + C, region, *static_cast(cb_v), false, CURVEMAP_SLOPE_POSITIVE); } static void curvemap_buttons_redraw(bContext &C) @@ -4652,10 +4614,11 @@ static void curvemap_buttons_layout(uiLayout *layout, bt->drawflag &= ~UI_BUT_ICON_LEFT; UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); }); + RNAUpdateCb *tools_cb = MEM_new(__func__, cb); if (brush && neg_slope) { bt = uiDefIconBlockBut(block, curvemap_brush_tools_negslope_func, - cumap, + tools_cb, 0, ICON_NONE, 0, @@ -4666,17 +4629,19 @@ static void curvemap_buttons_layout(uiLayout *layout, } else if (brush) { bt = uiDefIconBlockBut( - block, curvemap_brush_tools_func, cumap, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); + block, curvemap_brush_tools_func, tools_cb, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); } else if (neg_slope) { bt = uiDefIconBlockBut( - block, curvemap_tools_negslope_func, cumap, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); + block, curvemap_tools_negslope_func, tools_cb, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); } else { bt = uiDefIconBlockBut( - block, curvemap_tools_posslope_func, cumap, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); + block, curvemap_tools_posslope_func, tools_cb, 0, ICON_NONE, 0, 0, dx, dx, TIP_("Tools")); } - UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); }); + /* Pass ownership of `tools_cb` to the button. */ + UI_but_funcN_set( + bt, [](bContext *, void *, void *) {}, tools_cb, nullptr); UI_block_funcN_set(block, rna_update_cb, MEM_new(__func__, cb), nullptr); @@ -4730,7 +4695,12 @@ static void curvemap_buttons_layout(uiLayout *layout, 0.0, 0.0, TIP_("Auto Handle")); - UI_but_func_set(bt, curvemap_tools_handle_auto, cumap, nullptr); + UI_but_func_set(bt, [cumap, cb](bContext &C) { + CurveMap *cuma = cumap->cm + cumap->cur; + BKE_curvemap_handle_set(cuma, HD_AUTO); + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + }); if (((cmp->flag & CUMA_HANDLE_AUTO_ANIM) == false) && ((cmp->flag & CUMA_HANDLE_VECTOR) == false)) { @@ -4751,7 +4721,12 @@ static void curvemap_buttons_layout(uiLayout *layout, 0.0, 0.0, TIP_("Vector Handle")); - UI_but_func_set(bt, curvemap_tools_handle_vector, cumap, nullptr); + UI_but_func_set(bt, [cumap, cb](bContext &C) { + CurveMap *cuma = cumap->cm + cumap->cur; + BKE_curvemap_handle_set(cuma, HD_VECT); + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + }); if (cmp->flag & CUMA_HANDLE_VECTOR) { bt->flag |= UI_SELECT_DRAW; } @@ -4770,16 +4745,17 @@ static void curvemap_buttons_layout(uiLayout *layout, 0.0, 0.0, TIP_("Auto Clamped")); - UI_but_func_set(bt, curvemap_tools_handle_auto_clamped, cumap, nullptr); + UI_but_func_set(bt, [cumap, cb](bContext &C) { + CurveMap *cuma = cumap->cm + cumap->cur; + BKE_curvemap_handle_set(cuma, HD_AUTO_ANIM); + BKE_curvemapping_changed(cumap, false); + rna_update_cb(C, cb); + }); if (cmp->flag & CUMA_HANDLE_AUTO_ANIM) { bt->flag |= UI_SELECT_DRAW; } /* Curve handle position */ - UI_but_func_set(bt, [cumap, cb](bContext &C) { - BKE_curvemapping_changed(cumap, true); - rna_update_cb(C, cb); - }); bt = uiDefButF(block, UI_BTYPE_NUM, 0, @@ -4794,6 +4770,11 @@ static void curvemap_buttons_layout(uiLayout *layout, ""); UI_but_number_step_size_set(bt, 1); UI_but_number_precision_set(bt, 5); + UI_but_func_set(bt, [cumap, cb](bContext &C) { + BKE_curvemapping_changed(cumap, true); + rna_update_cb(C, cb); + }); + bt = uiDefButF(block, UI_BTYPE_NUM, 0, @@ -4808,6 +4789,10 @@ static void curvemap_buttons_layout(uiLayout *layout, ""); UI_but_number_step_size_set(bt, 1); UI_but_number_precision_set(bt, 5); + UI_but_func_set(bt, [cumap, cb](bContext &C) { + BKE_curvemapping_changed(cumap, true); + rna_update_cb(C, cb); + }); /* Curve handle delete point */ bt = uiDefIconBut(block, @@ -4917,172 +4902,46 @@ void uiTemplateCurveMapping(uiLayout *layout, /** \name Curve Profile Template * \{ */ -static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event) -{ - CurveProfile *profile = static_cast(profile_v); - - profile->preset = event; - BKE_curveprofile_reset(profile); - BKE_curveprofile_update(profile, PROF_UPDATE_NONE); - - ED_undo_push(C, "CurveProfile tools"); - ED_region_tag_redraw(CTX_wm_region(C)); -} - -static uiBlock *CurveProfile_presets_func(bContext *C, ARegion *region, CurveProfile *profile) +static uiBlock *curve_profile_presets_fn(bContext *C, ARegion *region, void *cb_v) { + RNAUpdateCb &cb = *static_cast(cb_v); + PointerRNA profile_ptr = RNA_property_pointer_get(&cb.ptr, cb.prop); + CurveProfile *profile = static_cast(profile_ptr.data); short yco = 0; uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); - UI_block_func_butmenu_set(block, CurveProfile_presets_dofunc, profile); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Default"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - PROF_PRESET_LINE, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Support Loops"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - PROF_PRESET_SUPPORTS, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Cornice Molding"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - PROF_PRESET_CORNICE, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Crown Molding"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - PROF_PRESET_CROWN, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Steps"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - PROF_PRESET_STEPS, - ""); - - UI_block_direction_set(block, UI_DIR_DOWN); - UI_block_bounds_set_text(block, int(3.0f * UI_UNIT_X)); - - return block; -} - -static uiBlock *CurveProfile_buttons_presets(bContext *C, ARegion *region, void *profile_v) -{ - return CurveProfile_presets_func(C, region, (CurveProfile *)profile_v); -} - -/* Only for CurveProfile tools block */ -enum { - UIPROFILE_FUNC_RESET, - UIPROFILE_FUNC_RESET_VIEW, -}; - -static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event) -{ - CurveProfile *profile = static_cast(profile_v); - - switch (event) { - case UIPROFILE_FUNC_RESET: /* reset */ + for (const auto &[name, preset] : + {std::pair(IFACE_("Default"), PROF_PRESET_LINE), + std::pair(IFACE_("Support Loops"), PROF_PRESET_SUPPORTS), + std::pair(IFACE_("Cornice Molding"), PROF_PRESET_CORNICE), + std::pair(IFACE_("Crown Molding"), PROF_PRESET_CROWN), + std::pair(IFACE_("Steps"), PROF_PRESET_STEPS)}) + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + name, + 0, + yco -= UI_UNIT_Y, + 0, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [profile, cb, preset](bContext &C) { + profile->preset = preset; BKE_curveprofile_reset(profile); BKE_curveprofile_update(profile, PROF_UPDATE_NONE); - break; - case UIPROFILE_FUNC_RESET_VIEW: /* reset view to clipping rect */ - BKE_curveprofile_reset_view(profile); - break; + ED_undo_push(&C, "Reset Curve Profile"); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); } - ED_undo_push(C, "CurveProfile tools"); - ED_region_tag_redraw(CTX_wm_region(C)); -} - -static uiBlock *CurveProfile_tools_func(bContext *C, ARegion *region, CurveProfile *profile) -{ - short yco = 0; - - uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); - UI_block_func_butmenu_set(block, CurveProfile_tools_dofunc, profile); - - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Reset View"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - UIPROFILE_FUNC_RESET_VIEW, - ""); - uiDefIconTextBut(block, - UI_BTYPE_BUT_MENU, - 1, - ICON_BLANK1, - IFACE_("Reset Curve"), - 0, - yco -= UI_UNIT_Y, - 0, - UI_UNIT_Y, - nullptr, - 0.0, - 0.0, - 0, - UIPROFILE_FUNC_RESET, - ""); UI_block_direction_set(block, UI_DIR_DOWN); UI_block_bounds_set_text(block, int(3.0f * UI_UNIT_X)); @@ -5090,25 +4949,81 @@ static uiBlock *CurveProfile_tools_func(bContext *C, ARegion *region, CurveProfi return block; } -static uiBlock *CurveProfile_buttons_tools(bContext *C, ARegion *region, void *profile_v) +static uiBlock *curve_profile_tools_fn(bContext *C, ARegion *region, void *cb_v) { - return CurveProfile_tools_func(C, region, (CurveProfile *)profile_v); + RNAUpdateCb &cb = *static_cast(cb_v); + PointerRNA profile_ptr = RNA_property_pointer_get(&cb.ptr, cb.prop); + CurveProfile *profile = static_cast(profile_ptr.data); + short yco = 0; + + uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS); + + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Reset View"), + 0, + yco -= UI_UNIT_Y, + 0, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [profile](bContext &C) { + BKE_curveprofile_reset_view(profile); + ED_region_tag_redraw(CTX_wm_region(&C)); + }); + } + { + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT_MENU, + 1, + ICON_BLANK1, + IFACE_("Reset Curve"), + 0, + yco -= UI_UNIT_Y, + 0, + UI_UNIT_Y, + nullptr, + 0.0, + 0.0, + 0, + 0, + ""); + UI_but_func_set(but, [profile, cb](bContext &C) { + BKE_curveprofile_reset(profile); + BKE_curveprofile_update(profile, PROF_UPDATE_NONE); + ED_undo_push(&C, "Reset Profile"); + ED_region_tag_redraw(CTX_wm_region(&C)); + rna_update_cb(C, cb); + }); + } + + UI_block_direction_set(block, UI_DIR_DOWN); + UI_block_bounds_set_text(block, int(3.0f * UI_UNIT_X)); + + return block; } -static bool CurveProfile_can_zoom_in(CurveProfile *profile) +static bool curve_profile_can_zoom_in(CurveProfile *profile) { return BLI_rctf_size_x(&profile->view_rect) > CURVE_ZOOM_MAX * BLI_rctf_size_x(&profile->clip_rect); } -static bool CurveProfile_can_zoom_out(CurveProfile *profile) +static bool curve_profile_can_zoom_out(CurveProfile *profile) { return BLI_rctf_size_x(&profile->view_rect) < BLI_rctf_size_x(&profile->clip_rect); } -static void CurveProfile_buttons_zoom_in(bContext *C, CurveProfile *profile) +static void curve_profile_zoom_in(bContext *C, CurveProfile *profile) { - if (CurveProfile_can_zoom_in(profile)) { + if (curve_profile_can_zoom_in(profile)) { const float dx = 0.1154f * BLI_rctf_size_x(&profile->view_rect); profile->view_rect.xmin += dx; profile->view_rect.xmax -= dx; @@ -5120,9 +5035,9 @@ static void CurveProfile_buttons_zoom_in(bContext *C, CurveProfile *profile) ED_region_tag_redraw(CTX_wm_region(C)); } -static void CurveProfile_buttons_zoom_out(bContext *C, CurveProfile *profile) +static void curve_profile_zoom_out(bContext *C, CurveProfile *profile) { - if (CurveProfile_can_zoom_out(profile)) { + if (curve_profile_can_zoom_out(profile)) { float d = 0.15f * BLI_rctf_size_x(&profile->view_rect); float d1 = d; @@ -5177,16 +5092,19 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const /* There is probably potential to use simpler "uiItemR" functions here, but automatic updating * after a preset is selected would be more complicated. */ uiLayout *row = uiLayoutRow(layout, true); + RNAUpdateCb *presets_cb = MEM_new(__func__, cb); bt = uiDefBlockBut(block, - CurveProfile_buttons_presets, - profile, + curve_profile_presets_fn, + presets_cb, IFACE_("Preset"), 0, 0, UI_UNIT_X, UI_UNIT_X, ""); - UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); }); + /* Pass ownership of `presets_cb` to the button. */ + UI_but_funcN_set( + bt, [](bContext *, void *, void *) {}, presets_cb, nullptr); /* Show a "re-apply" preset button when it has been changed from the preset. */ if (profile->flag & PROF_DIRTY_PRESET) { @@ -5236,8 +5154,8 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const 0.0, 0.0, TIP_("Zoom in")); - UI_but_func_set(bt, [profile](bContext &C) { CurveProfile_buttons_zoom_in(&C, profile); }); - if (!CurveProfile_can_zoom_in(profile)) { + UI_but_func_set(bt, [profile](bContext &C) { curve_profile_zoom_in(&C, profile); }); + if (!curve_profile_can_zoom_in(profile)) { UI_but_disable(bt, ""); } @@ -5256,8 +5174,8 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const 0.0, 0.0, TIP_("Zoom out")); - UI_but_func_set(bt, [profile](bContext &C) { CurveProfile_buttons_zoom_out(&C, profile); }); - if (!CurveProfile_can_zoom_out(profile)) { + UI_but_func_set(bt, [profile](bContext &C) { curve_profile_zoom_out(&C, profile); }); + if (!curve_profile_can_zoom_out(profile)) { UI_but_disable(bt, ""); } @@ -5309,9 +5227,10 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const }); /* Reset view, reset curve */ + RNAUpdateCb *tools_cb = MEM_new(__func__, cb); bt = uiDefIconBlockBut(block, - CurveProfile_buttons_tools, - profile, + curve_profile_tools_fn, + tools_cb, 0, ICON_NONE, 0, @@ -5319,7 +5238,9 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, const UI_UNIT_X, UI_UNIT_X, TIP_("Tools")); - UI_but_func_set(bt, [cb](bContext &C) { rna_update_cb(C, cb); }); + /* Pass ownership of `presets_cb` to the button. */ + UI_but_funcN_set( + bt, [](bContext *, void *, void *) {}, tools_cb, nullptr); UI_block_funcN_set(block, rna_update_cb, MEM_new(__func__, cb), nullptr);