RNA/UI: Allow displaying in tooltip why RNA property isn't editable
This commit allows RNA properties to return additional info on their editable state which may then be displayed in tooltips. To show how it works, it also adds some info for the editable check of proxies. For generally un-editable properties or properties of a linked data-block, RNA returns default strings. | {F362785} | {F362786} | {F362787} | Reviewed by brecht, thanks! Differential Revision: https://developer.blender.org/D2243
This commit is contained in:
parent
9493e3b2d6
commit
6f80604509
|
@ -3215,10 +3215,10 @@ void ui_def_but_icon(uiBut *but, const int icon, const int flag)
|
|||
}
|
||||
}
|
||||
|
||||
static void ui_def_but_rna__disable(uiBut *but)
|
||||
static void ui_def_but_rna__disable(uiBut *but, const char *info)
|
||||
{
|
||||
but->flag |= UI_BUT_DISABLED;
|
||||
but->disabled_info = "";
|
||||
but->disabled_info = info;
|
||||
}
|
||||
|
||||
static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
|
||||
|
@ -3483,8 +3483,9 @@ static uiBut *ui_def_but_rna(
|
|||
but->flag |= UI_BUT_ICON_SUBMENU;
|
||||
}
|
||||
|
||||
if (!RNA_property_editable(&but->rnapoin, prop)) {
|
||||
ui_def_but_rna__disable(but);
|
||||
const char *info;
|
||||
if (!RNA_property_editable_info(&but->rnapoin, prop, &info)) {
|
||||
ui_def_but_rna__disable(but, info);
|
||||
}
|
||||
|
||||
if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
|
||||
|
@ -3515,7 +3516,7 @@ static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, cons
|
|||
else {
|
||||
but = ui_def_but(block, type, retval, propname, x, y, width, height, NULL, min, max, a1, a2, tip);
|
||||
|
||||
ui_def_but_rna__disable(but);
|
||||
ui_def_but_rna__disable(but, "Unknown Property.");
|
||||
}
|
||||
|
||||
return but;
|
||||
|
|
|
@ -467,7 +467,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
|
|||
}
|
||||
/* alternatively, buttons can store some reasoning too */
|
||||
else if (but->disabled_info) {
|
||||
disabled_msg = but->disabled_info;
|
||||
disabled_msg = TIP_(but->disabled_info);
|
||||
}
|
||||
|
||||
if (disabled_msg && disabled_msg[0]) {
|
||||
|
|
|
@ -856,6 +856,7 @@ StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
|
|||
int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value);
|
||||
|
||||
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
|
||||
bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info);
|
||||
bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
|
||||
bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
|
||||
bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
|
||||
|
|
|
@ -122,7 +122,7 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value)
|
|||
BLI_libblock_ensure_unique_name(G.main, id->name);
|
||||
}
|
||||
|
||||
static int rna_ID_name_editable(PointerRNA *ptr)
|
||||
static int rna_ID_name_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
ID *id = (ID *)ptr->data;
|
||||
|
||||
|
|
|
@ -1619,20 +1619,56 @@ bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
|
|||
{
|
||||
ID *id = ptr->id.data;
|
||||
int flag;
|
||||
const char *dummy_info;
|
||||
|
||||
prop = rna_ensure_property(prop);
|
||||
flag = prop->editable ? prop->editable(ptr) : prop->flag;
|
||||
flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
|
||||
|
||||
return ((flag & PROP_EDITABLE) &&
|
||||
(flag & PROP_REGISTER) == 0 &&
|
||||
(!id || !ID_IS_LINKED_DATABLOCK(id) || (prop->flag & PROP_LIB_EXCEPTION)));
|
||||
}
|
||||
|
||||
bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
|
||||
/**
|
||||
* Version of #RNA_property_editable that tries to return additional info in \a r_info that can be exposed in UI.
|
||||
*/
|
||||
bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
|
||||
{
|
||||
ID *id = ptr->id.data;
|
||||
int flag;
|
||||
|
||||
prop = rna_ensure_property(prop);
|
||||
flag = prop->editable ? prop->editable(ptr) : prop->flag;
|
||||
*r_info = "";
|
||||
|
||||
/* get flag */
|
||||
if (prop->editable) {
|
||||
flag = prop->editable(ptr, r_info);
|
||||
}
|
||||
else {
|
||||
flag = prop->flag;
|
||||
if ((flag & PROP_EDITABLE) == 0 || (flag & PROP_REGISTER)) {
|
||||
*r_info = "This property is for internal use only and can't be edited.";
|
||||
}
|
||||
}
|
||||
|
||||
/* property from linked data-block */
|
||||
if (id && ID_IS_LINKED_DATABLOCK(id) && (prop->flag & PROP_LIB_EXCEPTION) == 0) {
|
||||
if (!(*r_info)[0]) {
|
||||
*r_info = "Can't edit this property from a linked data-block.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0);
|
||||
}
|
||||
|
||||
bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
int flag;
|
||||
const char *dummy_info;
|
||||
|
||||
prop = rna_ensure_property(prop);
|
||||
flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
|
||||
return (flag & PROP_EDITABLE) != 0;
|
||||
}
|
||||
|
||||
|
@ -1647,9 +1683,11 @@ bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
|
|||
prop = rna_ensure_property(prop);
|
||||
|
||||
flag = prop->flag;
|
||||
|
||||
if (prop->editable)
|
||||
flag &= prop->editable(ptr);
|
||||
|
||||
if (prop->editable) {
|
||||
const char *dummy_info;
|
||||
flag &= prop->editable(ptr, &dummy_info);
|
||||
}
|
||||
|
||||
if (prop->itemeditable)
|
||||
flag &= prop->itemeditable(ptr, index);
|
||||
|
|
|
@ -89,7 +89,7 @@ static void rna_AnimData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
|
|||
DAG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
static int rna_AnimData_action_editable(PointerRNA *ptr)
|
||||
static int rna_AnimData_action_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
AnimData *adt = (AnimData *)ptr->data;
|
||||
|
||||
|
@ -305,7 +305,7 @@ static StructRNA *rna_ksPath_id_typef(PointerRNA *ptr)
|
|||
return ID_code_to_RNA_type(ksp->idtype);
|
||||
}
|
||||
|
||||
static int rna_ksPath_id_editable(PointerRNA *ptr)
|
||||
static int rna_ksPath_id_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
KS_Path *ksp = (KS_Path *)ptr->data;
|
||||
return (ksp->idtype) ? PROP_EDITABLE : 0;
|
||||
|
@ -393,7 +393,7 @@ static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
|
|||
}
|
||||
|
||||
|
||||
static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr)
|
||||
static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
KeyingSet *ks = (KeyingSet *)ptr->data;
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ static void rna_Curve_texspace_set(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
|
|||
BKE_curve_texspace_calc(cu);
|
||||
}
|
||||
|
||||
static int rna_Curve_texspace_editable(PointerRNA *ptr)
|
||||
static int rna_Curve_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Curve *cu = (Curve *)ptr->data;
|
||||
return (cu->texflag & CU_AUTOSPACE) ? 0 : PROP_EDITABLE;
|
||||
|
|
|
@ -199,13 +199,13 @@ static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr)
|
|||
return ID_code_to_RNA_type(dtar->idtype);
|
||||
}
|
||||
|
||||
static int rna_DriverTarget_id_editable(PointerRNA *ptr)
|
||||
static int rna_DriverTarget_id_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
DriverTarget *dtar = (DriverTarget *)ptr->data;
|
||||
return (dtar->idtype) ? PROP_EDITABLE : 0;
|
||||
}
|
||||
|
||||
static int rna_DriverTarget_id_type_editable(PointerRNA *ptr)
|
||||
static int rna_DriverTarget_id_type_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
DriverTarget *dtar = (DriverTarget *)ptr->data;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ static char *rna_GPencilLayer_path(PointerRNA *ptr)
|
|||
return BLI_sprintfN("layers[\"%s\"]", name_esc);
|
||||
}
|
||||
|
||||
static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr)
|
||||
static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ struct Scene;
|
|||
typedef void (*UpdateFunc)(struct Main *main, struct Scene *scene, struct PointerRNA *ptr);
|
||||
typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop);
|
||||
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
|
||||
typedef int (*EditableFunc)(struct PointerRNA *ptr);
|
||||
typedef int (*EditableFunc)(struct PointerRNA *ptr, const char **r_info);
|
||||
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
|
||||
typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, bool create);
|
||||
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
|
||||
|
@ -188,7 +188,9 @@ struct PropertyRNA {
|
|||
UpdateFunc update;
|
||||
int noteflag;
|
||||
|
||||
/* callback for testing if editable */
|
||||
/* Callback for testing if editable. Its r_info parameter can be used to
|
||||
* return info on editable state that might be shown to user. E.g. tooltips
|
||||
* of disabled buttons can show reason why button is disabled using this. */
|
||||
EditableFunc editable;
|
||||
/* callback for testing if array-item editable (if applicable) */
|
||||
ItemEditableFunc itemeditable;
|
||||
|
|
|
@ -171,7 +171,7 @@ static void rna_Lattice_use_outside_set(PointerRNA *ptr, int value)
|
|||
}
|
||||
}
|
||||
|
||||
static int rna_Lattice_size_editable(PointerRNA *ptr)
|
||||
static int rna_Lattice_size_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Lattice *lt = (Lattice *)ptr->data;
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ static void rna_Material_active_texture_set(PointerRNA *ptr, PointerRNA value)
|
|||
set_current_material_texture(ma, value.data);
|
||||
}
|
||||
|
||||
static int rna_Material_active_texture_editable(PointerRNA *ptr)
|
||||
static int rna_Material_active_texture_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Material *ma = (Material *)ptr->id.data;
|
||||
|
||||
|
|
|
@ -662,7 +662,7 @@ static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values)
|
|||
(&mcol->r)[2] = (char)(CLAMPIS(values[2] * 255.0f, 0, 255));
|
||||
}
|
||||
|
||||
static int rna_Mesh_texspace_editable(PointerRNA *ptr)
|
||||
static int rna_Mesh_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Mesh *me = (Mesh *)ptr->data;
|
||||
return (me->texflag & ME_AUTOSPACE) ? 0 : PROP_EDITABLE;
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
static int rna_Meta_texspace_editable(PointerRNA *ptr)
|
||||
static int rna_Meta_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
MetaBall *mb = (MetaBall *)ptr->data;
|
||||
return (mb->texflag & MB_AUTOSPACE) ? 0 : PROP_EDITABLE;
|
||||
|
|
|
@ -282,7 +282,7 @@ static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
|
|||
}
|
||||
}
|
||||
|
||||
static int rna_NlaStrip_action_editable(PointerRNA *ptr)
|
||||
static int rna_NlaStrip_action_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
NlaStrip *strip = (NlaStrip *)ptr->data;
|
||||
|
||||
|
|
|
@ -712,7 +712,7 @@ static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
|
|||
assign_material(ob, value.data, ob->actcol, BKE_MAT_ASSIGN_EXISTING);
|
||||
}
|
||||
|
||||
static int rna_Object_active_material_editable(PointerRNA *ptr)
|
||||
static int rna_Object_active_material_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Object *ob = (Object *)ptr->id.data;
|
||||
bool is_editable;
|
||||
|
|
|
@ -556,13 +556,18 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo
|
|||
}
|
||||
}
|
||||
|
||||
static int rna_PoseChannel_proxy_editable(PointerRNA *ptr)
|
||||
static int rna_PoseChannel_proxy_editable(PointerRNA *ptr, const char **r_info)
|
||||
{
|
||||
Object *ob = (Object *)ptr->id.data;
|
||||
bArmature *arm = ob->data;
|
||||
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
|
||||
|
||||
return (ob->proxy && pchan->bone && (pchan->bone->layer & arm->layer_protected)) ? 0 : PROP_EDITABLE;
|
||||
if (ob->proxy && pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
|
||||
*r_info = "Can't edit property of a proxy on a protected layer";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PROP_EDITABLE;
|
||||
}
|
||||
|
||||
static int rna_PoseChannel_location_editable(PointerRNA *ptr, int index)
|
||||
|
|
|
@ -292,7 +292,7 @@ static int rna_Sequence_frame_length_get(PointerRNA *ptr)
|
|||
return BKE_sequence_tx_get_final_right(seq, false) - BKE_sequence_tx_get_final_left(seq, false);
|
||||
}
|
||||
|
||||
static int rna_Sequence_frame_editable(PointerRNA *ptr)
|
||||
static int rna_Sequence_frame_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
Sequence *seq = (Sequence *)ptr->data;
|
||||
/* Effect sequences' start frame and length must be readonly! */
|
||||
|
|
|
@ -1645,7 +1645,7 @@ static void rna_FileBrowser_FSMenuEntry_name_set(PointerRNA *ptr, const char *va
|
|||
ED_fsmenu_entry_set_name(fsm, value);
|
||||
}
|
||||
|
||||
static int rna_FileBrowser_FSMenuEntry_name_get_editable(PointerRNA *ptr)
|
||||
static int rna_FileBrowser_FSMenuEntry_name_get_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
FSMenuEntry *fsm = ptr->data;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "WM_api.h"
|
||||
|
||||
/* matching fnction in rna_ID.c */
|
||||
static int rna_VectorFont_filepath_editable(PointerRNA *ptr)
|
||||
static int rna_VectorFont_filepath_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
VFont *vfont = ptr->id.data;
|
||||
if (BKE_vfont_is_builtin(vfont)) {
|
||||
|
|
Loading…
Reference in New Issue