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:
Julian Eisel 2016-09-22 00:10:53 +02:00
parent 9493e3b2d6
commit 6f80604509
20 changed files with 80 additions and 33 deletions

View File

@ -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;

View File

@ -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]) {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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! */

View File

@ -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;

View File

@ -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)) {