/**
 * \a check_prop callback filters functions to avoid drawing certain properties,
 * in cases where PROP_HIDDEN flag can't be used for a property.
 */
int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr,
                     int (*check_prop)(PointerRNA *, PropertyRNA *),
                     const char label_align)
{
	uiLayout *split, *col;
	int flag;
	const char *name;
	int tot = 0;

	assert(ELEM3(label_align, '\0', 'H', 'V'));

	RNA_STRUCT_BEGIN (ptr, prop)
	{
		flag = RNA_property_flag(prop);
		if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop) == FALSE))
			continue;

		if (label_align != '\0') {
			PropertyType type = RNA_property_type(prop);
			int is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));

			name = RNA_property_ui_name(prop);

			if (label_align == 'V') {
				col = uiLayoutColumn(layout, TRUE);

				if (!is_boolean)
					uiItemL(col, name, ICON_NONE);
			}
			else if (label_align == 'H') {
				split = uiLayoutSplit(layout, 0.5f, FALSE);

				col = uiLayoutColumn(split, FALSE);
				uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
				col = uiLayoutColumn(split, FALSE);
			}
			else {
				col = NULL;
			}

			/* may meed to add more cases here.
			 * don't override enum flag names */

			/* name is shown above, empty name for button below */
			name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
		}
		else {
			col = layout;
			name = NULL; /* no smart label alignment, show default name with button */
		}

		uiItemFullR(col, ptr, prop, -1, 0, 0, name, ICON_NONE);
		tot++;
	}
Exemple #2
0
/* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings),
 * and return the icon used for the struct that this property refers to 
 * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details)
 */
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
	int icon = 0;
	
	/* sanity checks */
	if (name == NULL)
		return icon;
	else if (ELEM3(NULL, id, fcu, fcu->rna_path)) {
		if (fcu == NULL)
			strcpy(name, "<invalid>");
		else if (fcu->rna_path == NULL)
			strcpy(name, "<no path>");
		else /* id == NULL */
			BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
	}
	else {
		PointerRNA id_ptr, ptr;
		PropertyRNA *prop;
		
		/* get RNA pointer, and resolve the path */
		RNA_id_pointer_create(id, &id_ptr);
		
		/* try to resolve the path */
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
			const char *structname = NULL, *propname = NULL;
			char arrayindbuf[16];
			const char *arrayname = NULL;
			short free_structname = 0;
			
			/* For now, name will consist of 3 parts: struct-name, property name, array index
			 * There are several options possible:
			 *	1) <struct-name>.<property-name>.<array-index>
			 *		i.e. Bone1.Location.X, or Object.Location.X
			 *	2) <array-index> <property-name> (<struct name>)
			 *		i.e. X Location (Bone1), or X Location (Object)
			 *	
			 * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
			 * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of 
			 * hierarchy though, which isn't so clear with option 2.
			 */
			
			/* for structname
			 *	- as base, we use a custom name from the structs if one is available 
			 *	- however, if we're showing subdata of bones (probably there will be other exceptions later)
			 *	  need to include that info too since it gets confusing otherwise
			 *	- if a pointer just refers to the ID-block, then don't repeat this info
			 *	  since this just introduces clutter
			 */
			if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
				/* perform string 'chopping' to get "Bone Name : Constraint Name" */
				char *pchanName = BLI_getQuotedStr(fcu->rna_path, "bones[");
				char *constName = BLI_getQuotedStr(fcu->rna_path, "constraints[");
				
				/* assemble the string to display in the UI... */
				structname = BLI_sprintfN("%s : %s", pchanName, constName);
				free_structname = 1;
				
				/* free the temp names */
				if (pchanName) MEM_freeN(pchanName);
				if (constName) MEM_freeN(constName);
			}
			else if (ptr.data != ptr.id.data) {
				PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
				if (nameprop) {
					/* this gets a string which will need to be freed */
					structname = RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
					free_structname = 1;
				}
				else
					structname = RNA_struct_ui_name(ptr.type);
			}
			
			/* Property Name is straightforward */
			propname = RNA_property_ui_name(prop);
			
			/* Array Index - only if applicable */
			if (RNA_property_array_length(&ptr, prop)) {
				char c = RNA_property_array_item_char(prop, fcu->array_index);
				
				/* we need to write the index to a temp buffer (in py syntax) */
				if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
				else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
				
				arrayname = &arrayindbuf[0];
			}
			else {
				/* no array index */
				arrayname = "";
			}
			
			/* putting this all together into the buffer */
			// XXX we need to check for invalid names...
			// XXX the name length limit needs to be passed in or as some define
			if (structname)
				BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname); 
			else
				BLI_snprintf(name, 256, "%s%s", arrayname, propname); 
			
			/* free temp name if nameprop is set */
			if (free_structname)
				MEM_freeN((void *)structname);
			
			
			/* Icon for this property's owner:
			 *	use the struct's icon if it is set
			 */
			icon = RNA_struct_ui_icon(ptr.type);
			
			/* valid path - remove the invalid tag since we now know how to use it saving
			 * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
			 */
			fcu->flag &= ~FCURVE_DISABLED;
		}
		else {
			/* invalid path */
			BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
			
			/* icon for this should be the icon for the base ID */
			// TODO: or should we just use the error icon?
			icon = RNA_struct_ui_icon(id_ptr.type);
			
			/* tag F-Curve as disabled - as not usable path */
			fcu->flag |= FCURVE_DISABLED;
		}
	}
	
	/* return the icon that the active data had */
	return icon;
}