Esempio n. 1
0
StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports, void *data, const char *identifier,
                                      StructValidateFunc validate, StructCallbackFunc UNUSED(call),
                                      StructFreeFunc UNUSED(free))
{
	PointerRNA dummyptr;

	/* create dummy pointer */
	RNA_pointer_create(NULL, &RNA_PropertyGroup, NULL, &dummyptr);

	/* validate the python class */
	if (validate(&dummyptr, data, NULL) != 0)
		return NULL;

	/* note: it looks like there is no length limit on the srna id since its
	 * just a char pointer, but take care here, also be careful that python
	 * owns the string pointer which it could potentially free while blender
	 * is running. */
	if (BLI_strnlen(identifier, MAX_IDPROP_NAME) == MAX_IDPROP_NAME) {
		BKE_reportf(reports, RPT_ERROR, "Registering id property class: '%s' is too long, maximum length is %d",
		            identifier, MAX_IDPROP_NAME);
		return NULL;
	}

	return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup);  /* XXX */
}
Esempio n. 2
0
static StructRNA *rna_UIList_register(
        Main *bmain, ReportList *reports, void *data, const char *identifier,
        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	uiListType *ult, dummyult = {NULL};
	uiList dummyuilist = {NULL};
	PointerRNA dummyul_ptr;
	int have_function[3];
	size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */

	/* setup dummy menu & menu type to store static properties in */
	dummyuilist.type = &dummyult;
	RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);

	/* validate the python class */
	if (validate(&dummyul_ptr, data, have_function) != 0)
		return NULL;

	if (strlen(identifier) >= sizeof(dummyult.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummyult.idname));
		return NULL;
	}

	/* check if we have registered this uilist type before, and remove it */
	ult = WM_uilisttype_find(dummyult.idname, true);
	if (ult && ult->ext.srna) {
		rna_UIList_unregister(bmain, ult->ext.srna);
	}
	if (!RNA_struct_available_or_report(reports, dummyult.idname)) {
		return NULL;
	}
	if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) {
		return NULL;
	}

	/* create a new menu type */
	ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
	memcpy(ult, &dummyult, sizeof(dummyult));

	ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
	ult->ext.data = data;
	ult->ext.call = call;
	ult->ext.free = free;
	RNA_struct_blender_type_set(ult->ext.srna, ult);

	ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
	ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL;
	ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL;

	WM_uilisttype_add(ult);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);

	return ult->ext.srna;
}
Esempio n. 3
0
static StructRNA *rna_RenderEngine_register(
        Main *bmain, ReportList *reports, void *data, const char *identifier,
        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	RenderEngineType *et, dummyet = {NULL};
	RenderEngine dummyengine = {NULL};
	PointerRNA dummyptr;
	int have_function[7];

	/* setup dummy engine & engine type to store static properties in */
	dummyengine.type = &dummyet;
	dummyet.flag |= RE_USE_SHADING_NODES_CUSTOM;
	RNA_pointer_create(NULL, &RNA_RenderEngine, &dummyengine, &dummyptr);

	/* validate the python class */
	if (validate(&dummyptr, data, have_function) != 0)
		return NULL;

	if (strlen(identifier) >= sizeof(dummyet.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummyet.idname));
		return NULL;
	}

	/* check if we have registered this engine type before, and remove it */
	for (et = R_engines.first; et; et = et->next) {
		if (STREQ(et->idname, dummyet.idname)) {
			if (et->ext.srna)
				rna_RenderEngine_unregister(bmain, et->ext.srna);
			break;
		}
	}
	
	/* create a new engine type */
	et = MEM_callocN(sizeof(RenderEngineType), "python render engine");
	memcpy(et, &dummyet, sizeof(dummyet));

	et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine);
	et->ext.data = data;
	et->ext.call = call;
	et->ext.free = free;
	RNA_struct_blender_type_set(et->ext.srna, et);

	et->update = (have_function[0]) ? engine_update : NULL;
	et->render = (have_function[1]) ? engine_render : NULL;
	et->bake = (have_function[2]) ? engine_bake : NULL;
	et->view_update = (have_function[3]) ? engine_view_update : NULL;
	et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
	et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
	et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL;

	BLI_addtail(&R_engines, et);

	return et->ext.srna;
}
Esempio n. 4
0
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                      StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	ARegionType *art;
	HeaderType *ht, dummyht = {NULL};
	Header dummyheader = {NULL};
	PointerRNA dummyhtr;
	int have_function[1];

	/* setup dummy header & header type to store static properties in */
	dummyheader.type = &dummyht;
	RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);

	/* validate the python class */
	if (validate(&dummyhtr, data, have_function) != 0)
		return NULL;

	if (strlen(identifier) >= sizeof(dummyht.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering header class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummyht.idname));
		return NULL;
	}

	if (!(art = region_type_find(reports, dummyht.space_type, RGN_TYPE_HEADER)))
		return NULL;

	/* check if we have registered this header type before, and remove it */
	for (ht = art->headertypes.first; ht; ht = ht->next) {
		if (strcmp(ht->idname, dummyht.idname) == 0) {
			if (ht->ext.srna)
				rna_Header_unregister(bmain, ht->ext.srna);
			break;
		}
	}
	
	/* create a new header type */
	ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
	memcpy(ht, &dummyht, sizeof(dummyht));

	ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
	ht->ext.data = data;
	ht->ext.call = call;
	ht->ext.free = free;
	RNA_struct_blender_type_set(ht->ext.srna, ht);

	ht->draw = (have_function[0]) ? header_draw : NULL;

	BLI_addtail(&art->headertypes, ht);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);
	
	return ht->ext.srna;
}
Esempio n. 5
0
static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                             StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	KeyingSetInfo dummyksi = {NULL};
	KeyingSetInfo *ksi;
	PointerRNA dummyptr = {{NULL}};
	int have_function[3];

	/* setup dummy type info to store static properties in */
	/* TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? */
	RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr);
	
	/* validate the python class */
	if (validate(&dummyptr, data, have_function) != 0)
		return NULL;
	
	if (strlen(identifier) >= sizeof(dummyksi.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering keying set info class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummyksi.idname));
		return NULL;
	}
	
	/* check if we have registered this info before, and remove it */
	ksi = ANIM_keyingset_info_find_name(dummyksi.idname);
	if (ksi && ksi->ext.srna)
		rna_KeyingSetInfo_unregister(bmain, ksi->ext.srna);
	
	/* create a new KeyingSetInfo type */
	ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info");
	memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
	
	/* set RNA-extensions info */
	ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
	ksi->ext.data = data;
	ksi->ext.call = call;
	ksi->ext.free = free;
	RNA_struct_blender_type_set(ksi->ext.srna, ksi);
	
	/* set callbacks */
	/* NOTE: we really should have all of these...  */
	ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : NULL;
	ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : NULL;
	ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : NULL;
	
	/* add and register with other info as needed */
	ANIM_keyingset_info_register(ksi);
	
	WM_main_add_notifier(NC_WINDOW, NULL);

	/* return the struct-rna added */
	return ksi->ext.srna;
}
Esempio n. 6
0
static StructRNA *rna_Menu_register(
        Main *bmain, ReportList *reports, void *data, const char *identifier,
        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	MenuType *mt, dummymt = {NULL};
	Menu dummymenu = {NULL};
	PointerRNA dummymtr;
	int have_function[2];
	size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
	size_t description_size = 0;
	char _menu_descr[RNA_DYN_DESCR_MAX];

	/* setup dummy menu & menu type to store static properties in */
	dummymenu.type = &dummymt;
	_menu_descr[0] = '\0';
	dummymenu.type->description = _menu_descr;
	RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);

	/* We have to set default context! Else we get a void string... */
	strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);

	/* validate the python class */
	if (validate(&dummymtr, data, have_function) != 0)
		return NULL;

	if (strlen(identifier) >= sizeof(dummymt.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummymt.idname));
		return NULL;
	}

	/* check if we have registered this menu type before, and remove it */
	mt = WM_menutype_find(dummymt.idname, true);
	if (mt && mt->ext.srna) {
		rna_Menu_unregister(bmain, mt->ext.srna);
	}
	if (!RNA_struct_available_or_report(reports, dummymt.idname)) {
		return NULL;
	}
	if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) {
		return NULL;
	}

	/* create a new menu type */
	if (_menu_descr[0]) {
		description_size = strlen(_menu_descr) + 1;
		over_alloc += description_size;
	}

	mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu");
	memcpy(mt, &dummymt, sizeof(dummymt));

	if (_menu_descr[0]) {
		char *buf = (char *)(mt + 1);
		memcpy(buf, _menu_descr, description_size);
		mt->description = buf;
	}
	else
		mt->description = "";

	mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
	RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
	mt->ext.data = data;
	mt->ext.call = call;
	mt->ext.free = free;
	RNA_struct_blender_type_set(mt->ext.srna, mt);
	RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);

	mt->poll = (have_function[0]) ? menu_poll : NULL;
	mt->draw = (have_function[1]) ? menu_draw : NULL;

	WM_menutype_add(mt);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);

	return mt->ext.srna;
}
Esempio n. 7
0
static StructRNA *rna_Panel_register(
        Main *bmain, ReportList *reports, void *data, const char *identifier,
        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	ARegionType *art;
	PanelType *pt, dummypt = {NULL};
	Panel dummypanel = {NULL};
	PointerRNA dummyptr;
	int have_function[3];

	/* setup dummy panel & panel type to store static properties in */
	dummypanel.type = &dummypt;
	RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);

	/* We have to set default context! Else we get a void string... */
	strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);

	/* validate the python class */
	if (validate(&dummyptr, data, have_function) != 0)
		return NULL;

	if (strlen(identifier) >= sizeof(dummypt.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummypt.idname));
		return NULL;
	}

	if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) {
		/* Use a fallback, otherwise an empty value will draw the panel in every category. */
		strcpy(dummypt.category, PNL_CATEGORY_FALLBACK);
	}

	if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type)))
		return NULL;

	/* check if we have registered this panel type before, and remove it */
	for (pt = art->paneltypes.first; pt; pt = pt->next) {
		if (STREQ(pt->idname, dummypt.idname)) {
			if (pt->ext.srna)
				rna_Panel_unregister(bmain, pt->ext.srna);
			else
				BLI_freelinkN(&art->paneltypes, pt);
			break;
		}
	}
	if (!RNA_struct_available_or_report(reports, dummypt.idname)) {
		return NULL;
	}
	if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) {
		return NULL;
	}

	/* create a new panel type */
	pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
	memcpy(pt, &dummypt, sizeof(dummypt));

	pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
	RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
	pt->ext.data = data;
	pt->ext.call = call;
	pt->ext.free = free;
	RNA_struct_blender_type_set(pt->ext.srna, pt);
	RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);

	pt->poll = (have_function[0]) ? panel_poll : NULL;
	pt->draw = (have_function[1]) ? panel_draw : NULL;
	pt->draw_header = (have_function[2]) ? panel_draw_header : NULL;

	/* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
	if (pt->flag & PNL_NO_HEADER) {
		PanelType *pth = art->paneltypes.first;
		while (pth && pth->flag & PNL_NO_HEADER)
			pth = pth->next;

		if (pth)
			BLI_insertlinkbefore(&art->paneltypes, pth, pt);
		else
			BLI_addtail(&art->paneltypes, pt);
	}
	else
		BLI_addtail(&art->paneltypes, pt);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);

	return pt->ext.srna;
}