From 1ef163f1e0dd1c535c3c9b81670333f02c45b236 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 09:08:53 +0000 Subject: [PATCH] UI Templates: ('Any ID' Selector) Added new template for choosing to use any type of ID-block. The first combo box allows you to choose the type of ID-block that gets used, and the second box allows you to choose the ID-block of the type specified by the first one. This is currently used for setting the ID-block used for Keying Sets, but the main user for this was intended to be the Drivers UI. However, I still need to clear up a few button-event issues there before I can port this over. Additional Bugfixes: * Adding new Keying Set path was setting the active path wrong, meaning that you had to click on the list to get some response after adding * Bone Groups list was being drawn too long by default (when empty) --- release/scripts/ui/buttons_data_armature.py | 2 +- release/scripts/ui/buttons_scene.py | 2 +- source/blender/editors/animation/keyingsets.c | 2 +- source/blender/editors/include/UI_interface.h | 2 + .../editors/interface/interface_templates.c | 47 ++++++++++++++++++- source/blender/makesdna/DNA_anim_types.h | 2 + source/blender/makesrna/RNA_enum_types.h | 3 ++ source/blender/makesrna/intern/rna_ID.c | 32 +++++++++++++ .../blender/makesrna/intern/rna_animation.c | 28 ++++++++++- source/blender/makesrna/intern/rna_fcurve.c | 32 +++++++++++-- source/blender/makesrna/intern/rna_ui_api.c | 12 ++++- 11 files changed, 153 insertions(+), 11 deletions(-) diff --git a/release/scripts/ui/buttons_data_armature.py b/release/scripts/ui/buttons_data_armature.py index 9344294ff9e..bbec295a165 100644 --- a/release/scripts/ui/buttons_data_armature.py +++ b/release/scripts/ui/buttons_data_armature.py @@ -88,7 +88,7 @@ class DATA_PT_bone_groups(DataButtonsPanel): pose = ob.pose row = layout.row() - row.template_list(pose, "bone_groups", pose, "active_bone_group_index") + row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2) col = row.column(align=True) col.active = (ob.proxy == None) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 49635071342..ce4adef354d 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -527,7 +527,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): if ksp: col = layout.column() col.itemL(text="Target:") - col.itemR(ksp, "id") + col.template_any_ID(ksp, "id", "id_type") col.itemR(ksp, "rna_path") diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index a044e867d56..30eaea8b82e 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -219,7 +219,7 @@ static int add_empty_ks_path_exec (bContext *C, wmOperator *op) /* don't use the API method for this, since that checks on values... */ ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty"); BLI_addtail(&ks->paths, ksp); - ks->active_path= BLI_countlist(&ks->paths) + 1; + ks->active_path= BLI_countlist(&ks->paths); ksp->groupmode= KSP_GROUP_KSNAME; // XXX? diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index adbfd731a09..2fd870cf696 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -620,6 +620,8 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout); void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus); void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop); +void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, + char *proptypename, char *text); uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr); uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index c092b1ca68b..a7c586be42a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -152,6 +152,7 @@ static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem) } /************************ ID Template ***************************/ +/* This is for browsing and editing the ID-blocks used */ /* for new/open operators */ void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop) @@ -390,7 +391,10 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname type= RNA_property_pointer_type(ptr, prop); template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type)); - + + /* create UI elements for this template + * - template_ID makes a copy of the template data and assigns it to the relevant buttons + */ if(template->idlb) { uiLayoutRow(layout, 1); block= uiLayoutGetBlock(layout); @@ -400,6 +404,47 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname MEM_freeN(template); } +/************************ ID Chooser Template ***************************/ +/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use */ + +/* - propname: property identifier for property that ID-pointer gets stored to + * - proptypename: property identifier for property used to determine the type of ID-pointer that can be used + */ +void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *proptypename, char *text) +{ + PropertyRNA *propID, *propType; + uiLayout *row; + + /* get properties... */ + propID= RNA_struct_find_property(ptr, propname); + propType= RNA_struct_find_property(ptr, proptypename); + + if (!propID || RNA_property_type(propID) != PROP_POINTER) { + printf("uiTemplateAnyID: pointer property not found: %s\n", propname); + return; + } + if (!propType || RNA_property_type(propType) != PROP_ENUM) { + printf("uiTemplateAnyID: pointer-type property not found: %s\n", proptypename); + return; + } + + /* Start drawing UI Elements using standard defines */ + row= uiLayoutRow(layout, 1); + + /* Label - either use the provided text, or will become "ID-Block:" */ + if (text) + uiItemL(row, text, 0); + else + uiItemL(row, "ID-Block:", 0); + + /* ID-Type Selector - just have a menu of icons */ + // XXX should value really be 0? + uiItemFullR(row, "", 0, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY); + + /* ID-Block Selector - just use pointer widget... */ + uiItemFullR(row, "", 0, ptr, propID, 0, 0, 0); +} + /************************ Modifier Template *************************/ #define ERROR_LIBDATA_MESSAGE "Can't edit external libdata" diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index fedde34ae18..195d68d63ff 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -246,7 +246,9 @@ typedef struct DriverTarget { char *rna_path; /* target channel to use as driver value */ int array_index; /* if applicable, the index of the RNA-array item to use as driver */ + int idtype; /* type of ID-block that this target can use */ int flags; /* flags for the validity of the target */ + int pad; char name[64]; /* name of the variable */ } DriverTarget; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index af950c1148a..ca44e3405f6 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -29,6 +29,9 @@ /* Types */ +extern EnumPropertyItem id_type_items[]; + + extern EnumPropertyItem object_mode_items[]; extern EnumPropertyItem proportional_falloff_items[]; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 8ab5a1442c7..c52021b3a49 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -33,6 +33,38 @@ #include "rna_internal.h" +/* enum of ID-block types + * NOTE: need to keep this in line with the other defines for these + */ +EnumPropertyItem id_type_items[] = { + {ID_AC, "ACTION", ICON_ACTION, "Action", ""}, + {ID_AR, "ARMATURE", ICON_ARMATURE_DATA, "Armature", ""}, + {ID_BR, "BRUSH", ICON_BRUSH_DATA, "Brush", ""}, + {ID_CA, "CAMERA", ICON_CAMERA_DATA, "Camera", ""}, + {ID_CU, "CURVE", ICON_CURVE_DATA, "Curve", ""}, + {ID_VF, "FONT", ICON_FONT_DATA, "Font", ""}, + {ID_GD, "GREASEPENCIL", ICON_GREASEPENCIL, "Grease Pencil", ""}, + {ID_GR, "GROUP", ICON_GROUP, "Group", ""}, + {ID_IM, "IMAGE", ICON_IMAGE_DATA, "Image", ""}, + {ID_KE, "KEY", ICON_SHAPEKEY_DATA, "Key", ""}, + {ID_LA, "LAMP", ICON_LAMP_DATA, "Lamp", ""}, + {ID_LI, "LIBRARY", 0, "Library", ""}, + {ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""}, + {ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""}, + {ID_MB, "META", ICON_META_DATA, "MetaBall", ""}, + {ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""}, + {ID_NT, "NODETREE", 0, "NodeTree", ""}, + {ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""}, + {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""}, + {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""}, + {ID_SCR, "SCREEN", 0, "Screen", ""}, + {ID_SO, "SOUND", 0, "Sound", ""}, + {ID_TXT, "TEXT", ICON_TEXT, "Text", ""}, + {ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""}, + {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""}, + {ID_WM, "WINDOWMANAGER", 0, "Window Manager", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "BKE_idprop.h" diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index a62eef66cf0..23a9c48710e 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -24,6 +24,7 @@ #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" #include "RNA_enum_types.h" @@ -63,6 +64,20 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value) adt->action= value.data; } +/* ****************************** */ + +static StructRNA *rna_ksPath_id_typef(PointerRNA *ptr) +{ + KS_Path *ksp= (KS_Path*)ptr->data; + return ID_code_to_RNA_type(ksp->idtype); +} + +static int rna_ksPath_id_editable(PointerRNA *ptr) +{ + KS_Path *ksp= (KS_Path*)ptr->data; + return (ksp->idtype)? PROP_EDITABLE : 0; +} + static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value) { KS_Path *ksp= (KS_Path *)ptr->data; @@ -96,6 +111,7 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value) ksp->rna_path= NULL; } +/* ****************************** */ static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr) { @@ -153,8 +169,18 @@ static void rna_def_keyingset_path(BlenderRNA *brna) /* ID */ prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ID"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_editable_func(prop, "rna_ksPath_id_editable"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_ksPath_id_typef"); RNA_def_property_ui_text(prop, "ID-Block", "ID-Block that keyframes for Keying Set should be added to (for Absolute Keying Sets only)."); + prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "idtype"); + RNA_def_property_enum_items(prop, id_type_items); + RNA_def_property_enum_default(prop, ID_OB); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + /* Group */ prop= RNA_def_property(srna, "group", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Group Name", "Name of Action Group to assign setting(s) for this path to."); @@ -167,13 +193,11 @@ static void rna_def_keyingset_path(BlenderRNA *brna) /* Path + Array Index */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); - //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting."); RNA_def_struct_name_property(srna, prop); // XXX this is the best indicator for now... prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE); - //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific setting if applicable."); /* Flags */ diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index ba68f8e1624..12a81afa2b5 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -24,8 +24,10 @@ #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -80,6 +82,18 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) /* ****************************** */ +static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr) +{ + DriverTarget *dtar= (DriverTarget*)ptr->data; + return ID_code_to_RNA_type(dtar->idtype); +} + +static int rna_DriverTarget_id_editable(PointerRNA *ptr) +{ + DriverTarget *dtar= (DriverTarget*)ptr->data; + return (dtar->idtype)? PROP_EDITABLE : 0; +} + static void rna_DriverTarget_RnaPath_get(PointerRNA *ptr, char *value) { DriverTarget *dtar= (DriverTarget *)ptr->data; @@ -523,11 +537,21 @@ static void rna_def_drivertarget(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions."); - /* Target Properties */ - prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "id"); - RNA_def_property_ui_text(prop, "Object", "Object the specific property used can be found from"); + /* Target Properties - ID-block to Drive */ + prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ID"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_editable_func(prop, "rna_DriverTarget_id_editable"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_DriverTarget_id_typef"); + RNA_def_property_ui_text(prop, "ID", "ID-block that the specific property used can be found from"); + prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "idtype"); + RNA_def_property_enum_items(prop, id_type_items); + RNA_def_property_enum_default(prop, ID_OB); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + + /* Target Properties - Property to Drive */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used"); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 436efbcb2cf..79465f64daf 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -255,7 +255,17 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block."); RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); - + + func= RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "type_property", "", 0, "", "Identifier of property in data giving the type of the ID-blocks to use."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "text", "", 0, "", "Custom label to display in UI."); + func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); parm= RNA_def_pointer(func, "data", "Modifier", "", "Modifier data."); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);