diff options
-rw-r--r-- | source/blender/editors/interface/interface.c | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_region_tooltip.c | 14 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_wm.c | 36 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_wm_api.c | 12 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 21 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operator_type.c | 31 |
8 files changed, 114 insertions, 14 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 78b190a59e0..7bfd0200362 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -4250,7 +4250,7 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, } } - if ((!tip || tip[0] == '\0') && ot && ot->srna) { + if ((!tip || tip[0] == '\0') && ot && ot->srna && !ot->get_description) { tip = RNA_struct_ui_description(ot->srna); } @@ -6350,6 +6350,9 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) else if (but->tip && but->tip[0]) { tmp = BLI_strdup(but->tip); } + else if (but->optype && but->optype->get_description) { + tmp = WM_operatortype_description(C, but->optype, but->opptr); + } else { type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ } diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 7387fe5eb1c..3f20e8247b9 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -932,18 +932,14 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) NULL; if (gzop != NULL) { /* Description */ - const char *info = RNA_struct_ui_description(gzop->type->srna); - if (!(info && info[0])) { - info = RNA_struct_ui_name(gzop->type->srna); - } + char *info = WM_operatortype_description(C, gzop->type, &gzop->ptr); + + if (info != NULL) { + char *text = info; - if (info && info[0]) { - char *text = NULL; if (gzop_actions[i].prefix != NULL) { text = BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info); - } - else { - text = BLI_strdup(info); + MEM_freeN(info); } if (text != NULL) { diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index c3ffeaf6f6f..5f60ecf449b 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1420,6 +1420,39 @@ static void rna_operator_cancel_cb(bContext *C, wmOperator *op) RNA_parameter_list_free(&list); } +static char *rna_operator_description_cb(bContext *C, wmOperatorType *ot, PointerRNA *prop_ptr) +{ + extern FunctionRNA rna_Operator_description_func; + + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + void *ret; + char *result; + + RNA_pointer_create(NULL, ot->ext.srna, NULL, &ptr); /* dummy */ + func = &rna_Operator_description_func; /* RNA_struct_find_function(&ptr, "description"); */ + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &C); + RNA_parameter_set_lookup(&list, "properties", prop_ptr); + ot->ext.call(C, &ptr, func, &list); + + RNA_parameter_get_lookup(&list, "result", &ret); + result = (char *)ret; + + if (result && result[0]) { + result = BLI_strdup(result); + } + else { + result = NULL; + } + + RNA_parameter_list_free(&list); + + return result; +} + static void rna_Operator_unregister(struct Main *bmain, StructRNA *type); /* bpy_operator_wrap.c */ @@ -1437,7 +1470,7 @@ static StructRNA *rna_Operator_register(Main *bmain, wmOperatorType dummyot = {NULL}; wmOperator dummyop = {NULL}; PointerRNA dummyotr; - int have_function[7]; + int have_function[8]; struct { char idname[OP_MAX_TYPENAME]; @@ -1531,6 +1564,7 @@ static StructRNA *rna_Operator_register(Main *bmain, dummyot.modal = (have_function[4]) ? rna_operator_modal_cb : NULL; dummyot.ui = (have_function[5]) ? rna_operator_draw_cb : NULL; dummyot.cancel = (have_function[6]) ? rna_operator_cancel_cb : NULL; + dummyot.get_description = (have_function[7]) ? rna_operator_description_cb : NULL; WM_operatortype_append_ptr(BPY_RNA_operator_wrapper, (void *)&dummyot); /* update while blender is running */ diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index d9306ba7a65..650d410091e 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -957,6 +957,18 @@ void RNA_api_operator(StructRNA *srna) RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + + /* description */ + func = RNA_def_function(srna, "description", NULL); + RNA_def_function_ui_description(func, "Compute a description string that depends on parameters"); + RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); + parm = RNA_def_string(func, "result", NULL, 4096, "result", ""); + RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0); + RNA_def_function_output(func, parm); + parm = RNA_def_pointer(func, "context", "Context", "", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); } void RNA_api_macro(StructRNA *srna) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 12005b92388..c5424ca6ffb 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1768,7 +1768,12 @@ static int pyrna_py_to_prop( if (value == Py_None) { if ((RNA_property_flag(prop) & PROP_NEVER_NULL) == 0) { if (data) { - *((char **)data) = (char *)NULL; + if (RNA_property_flag(prop) & PROP_THICK_WRAP) { + *(char *)data = 0; + } + else { + *((char **)data) = (char *)NULL; + } } else { RNA_property_string_set(ptr, prop, NULL); @@ -1813,7 +1818,12 @@ static int pyrna_py_to_prop( } else { if (data) { - *((char **)data) = (char *)param; + if (RNA_property_flag(prop) & PROP_THICK_WRAP) { + BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); + } + else { + *((char **)data) = (char *)param; + } } else { RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value)); @@ -1862,7 +1872,12 @@ static int pyrna_py_to_prop( /* XXX, this is suspect, but needed for function calls, * need to see if there's a better way. */ if (data) { - *((char **)data) = (char *)param; + if (RNA_property_flag(prop) & PROP_THICK_WRAP) { + BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop)); + } + else { + *((char **)data) = (char *)param; + } } else { RNA_property_string_set(ptr, prop, param); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c7b18adf9b1..b933448d0bd 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -547,6 +547,9 @@ struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType * const char *idname); const char *WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties); +char *WM_operatortype_description(struct bContext *C, + struct wmOperatorType *ot, + struct PointerRNA *properties); /* wm_uilist_type.c */ void WM_uilisttype_init(void); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 7fdbf79248b..b3507c7e57e 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -737,6 +737,12 @@ typedef struct wmOperatorType { */ const char *(*get_name)(struct wmOperatorType *, struct PointerRNA *); + /** + * Return a different description to use in the user interface, based on property values. + * The returned string must be freed by the caller, unless NULL. + */ + char *(*get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *); + /** rna for properties */ struct StructRNA *srna; diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index 8f3052ace5e..96fbac3aecc 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -595,4 +595,35 @@ const char *WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *p return (name && name[0]) ? name : RNA_struct_ui_name(ot->srna); } +char *WM_operatortype_description(struct bContext *C, + struct wmOperatorType *ot, + struct PointerRNA *properties) +{ + if (ot->get_description && properties) { + char *description = ot->get_description(C, ot, properties); + + if (description) { + if (description[0]) { + return description; + } + else { + MEM_freeN(description); + } + } + } + + const char *info = RNA_struct_ui_description(ot->srna); + + if (!(info && info[0])) { + info = RNA_struct_ui_name(ot->srna); + } + + if (info && info[0]) { + return BLI_strdup(info); + } + else { + return NULL; + } +} + /** \} */ |