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]; /* setup dummy menu & menu type to store static properties in */ dummymenu.type= &dummymt; RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr); /* 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); /* create a new menu type */ mt= MEM_callocN(sizeof(MenuType), "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); 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_SCREEN|NA_EDITED, NULL); return mt->ext.srna; }
static void rna_def_header(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; srna = RNA_def_struct(brna, "Header", NULL); RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements"); RNA_def_struct_sdna(srna, "Header"); RNA_def_struct_refine_func(srna, "rna_Header_refine"); RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL); RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* draw */ func = RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout"); RNA_def_function_flag(func, FUNC_REGISTER); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); RNA_define_verify_sdna(0); /* not in sdna */ prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "layout"); RNA_def_property_struct_type(prop, "UILayout"); RNA_def_property_ui_text(prop, "Layout", "Structure of the header in the UI"); /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", "If this is set, the header gets a custom ID, otherwise it takes the " "name of the class used to define the panel; for example, if the " "class name is \"OBJECT_HT_hello\", and bl_idname is not set by the " "script, then bl_idname = \"OBJECT_HT_hello\""); prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type->space_type"); RNA_def_property_enum_items(prop, rna_enum_space_type_items); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Space type", "The space where the header is going to be used in"); RNA_define_verify_sdna(1); }
static void rna_def_ID(BlenderRNA *brna) { StructRNA *srna; FunctionRNA *func; PropertyRNA *prop, *parm; static EnumPropertyItem update_flag_items[] = { {OB_RECALC_OB, "OBJECT", 0, "Object", ""}, {OB_RECALC_DATA, "DATA", 0, "Data", ""}, {OB_RECALC_TIME, "TIME", 0, "Time", ""}, {0, NULL, 0, NULL, NULL} }; srna = RNA_def_struct(brna, "ID", NULL); RNA_def_struct_ui_text(srna, "ID", "Base type for data-blocks, defining a unique name, linking from other libraries " "and garbage collection"); RNA_def_struct_flag(srna, STRUCT_ID | STRUCT_ID_REFCOUNT); RNA_def_struct_refine_func(srna, "rna_ID_refine"); RNA_def_struct_idprops_func(srna, "rna_ID_idprops"); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique data-block ID name"); RNA_def_property_string_funcs(prop, "rna_ID_name_get", "rna_ID_name_length", "rna_ID_name_set"); RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2); RNA_def_property_editable_func(prop, "rna_ID_name_editable"); RNA_def_property_update(prop, NC_ID | NA_RENAME, NULL); RNA_def_struct_name_property(srna, prop); prop = RNA_def_property(srna, "users", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "us"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Users", "Number of times this data-block is referenced"); prop = RNA_def_property(srna, "use_fake_user", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_FAKEUSER); RNA_def_property_ui_text(prop, "Fake User", "Save this data-block even if it has no users"); RNA_def_property_boolean_funcs(prop, NULL, "rna_ID_fake_user_set"); prop = RNA_def_property(srna, "tag", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_DOIT); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_ui_text(prop, "Tag", "Tools can use this to tag data for their own purposes " "(initial state is undefined)"); prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_ID_RECALC); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Is Updated", "Datablock is tagged for recalculation"); prop = RNA_def_property(srna, "is_updated_data", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_ID_RECALC_DATA); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Is Updated Data", "Datablock data is tagged for recalculation"); prop = RNA_def_property(srna, "is_library_indirect", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_INDIRECT); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Is Indirect", "Is this ID block linked indirectly"); prop = RNA_def_property(srna, "library", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "lib"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Library", "Library file the data-block is linked from"); prop = RNA_def_pointer(srna, "preview", "ImagePreview", "Preview", "Preview image and icon of this data-block (None if not supported for this type of data)"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_IDPreview_get", NULL, NULL, NULL); /* functions */ func = RNA_def_function(srna, "copy", "rna_ID_copy"); RNA_def_function_ui_description(func, "Create a copy of this data-block (not supported for all data-blocks)"); parm = RNA_def_pointer(func, "id", "ID", "", "New copy of the ID"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "user_clear", "rna_ID_user_clear"); RNA_def_function_ui_description(func, "Clear the user count of a data-block so its not saved, " "on reload the data will be removed"); func = RNA_def_function(srna, "animation_data_create", "rna_ID_animation_data_create"); RNA_def_function_flag(func, FUNC_USE_MAIN); RNA_def_function_ui_description(func, "Create animation data to this ID, note that not all ID types support this"); parm = RNA_def_pointer(func, "anim_data", "AnimData", "", "New animation data or NULL"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "animation_data_clear", "rna_ID_animation_data_free"); RNA_def_function_flag(func, FUNC_USE_MAIN); RNA_def_function_ui_description(func, "Clear animation on this this ID"); func = RNA_def_function(srna, "update_tag", "rna_ID_update_tag"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Tag the ID to update its display data, " "e.g. when calling :class:`bpy.types.Scene.update`"); RNA_def_enum_flag(func, "refresh", update_flag_items, 0, "", "Type of updates to perform"); }
static void rna_def_panel(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; static const EnumPropertyItem panel_flag_items[] = { {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed", "Defines if the panel has to be open or collapsed at the time of its creation"}, {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header", "If set to False, the panel shows a header, which contains a clickable " "arrow to collapse the panel and the label (see bl_label)"}, {0, NULL, 0, NULL, NULL} }; srna = RNA_def_struct(brna, "Panel", NULL); RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements"); RNA_def_struct_sdna(srna, "Panel"); RNA_def_struct_refine_func(srna, "rna_Panel_refine"); RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL); RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA); RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* poll */ func = RNA_def_function(srna, "poll", NULL); RNA_def_function_ui_description(func, "If this method returns a non-null output, then the panel can be drawn"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", "")); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); /* draw */ func = RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout"); RNA_def_function_flag(func, FUNC_REGISTER); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); func = RNA_def_function(srna, "draw_header", NULL); RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "UILayout"); RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI"); prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "drawname"); RNA_def_property_ui_text(prop, "Text", "XXX todo"); /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", "If this is set, the panel gets a custom ID, otherwise it takes the " "name of the class used to define the panel. For example, if the " "class name is \"OBJECT_PT_hello\", and bl_idname is not set by the " "script, then bl_idname = \"OBJECT_PT_hello\""); prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->label"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The panel label, shows up in the panel header at the right of the " "triangle used to collapse the panel"); prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->translation_context"); RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); RNA_define_verify_sdna(true); prop = RNA_def_property(srna, "bl_category", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->category"); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type->space_type"); RNA_def_property_enum_items(prop, rna_enum_space_type_items); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in"); prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type->region_type"); RNA_def_property_enum_items(prop, rna_enum_region_type_items); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in"); prop = RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->context"); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* Only used in Properties Editor and 3D View - Thomas */ RNA_def_property_ui_text(prop, "Context", "The context in which the panel belongs to. (TODO: explain the " "possible combinations bl_context/bl_region_type/bl_space_type)"); prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type->flag"); RNA_def_property_enum_items(prop, panel_flag_items); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG); RNA_def_property_ui_text(prop, "Options", "Options for this panel type"); prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN); RNA_def_property_ui_text(prop, "Pin", ""); /* XXX, should only tag region for redraw */ RNA_def_property_update(prop, NC_WINDOW, NULL); }
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; }
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; }
static void rna_def_menu(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; srna = RNA_def_struct(brna, "Menu", NULL); RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons"); RNA_def_struct_sdna(srna, "Menu"); RNA_def_struct_refine_func(srna, "rna_Menu_refine"); RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL); RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA); RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* poll */ func = RNA_def_function(srna, "poll", NULL); RNA_def_function_ui_description(func, "If this method returns a non-null output, then the menu can be drawn"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", "")); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); /* draw */ func = RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout"); RNA_def_function_flag(func, FUNC_REGISTER); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); RNA_define_verify_sdna(false); /* not in sdna */ prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "layout"); RNA_def_property_struct_type(prop, "UILayout"); RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the menu in the UI"); /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", "If this is set, the menu gets a custom ID, otherwise it takes the " "name of the class used to define the menu (for example, if the " "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the " "script, then bl_idname = \"OBJECT_MT_hello\")"); prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->label"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The menu label"); prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->translation_context"); RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set"); /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */ RNA_define_verify_sdna(1); }
static void rna_def_uilist(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; srna = RNA_def_struct(brna, "UIList", NULL); RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection"); RNA_def_struct_sdna(srna, "uiList"); RNA_def_struct_refine_func(srna, "rna_UIList_refine"); RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL); RNA_def_struct_idprops_func(srna, "rna_UIList_idprops"); RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_PUBLIC_NAMESPACE_INHERIT); /* Registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", "If this is set, the uilist gets a custom ID, otherwise it takes the " "name of the class used to define the uilist (for example, if the " "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the " "script, then bl_idname = \"OBJECT_UL_vgroups\")"); /* Data */ prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_uilist_layout_type_items); RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* Filter options */ prop = RNA_def_property(srna, "use_filter_show", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_SHOW); RNA_def_property_ui_text(prop, "Show Filter", "Show filtering options"); prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "filter_byname"); RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE); RNA_def_property_ui_text(prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)"); prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_EXCLUDE); RNA_def_property_ui_text(prop, "Invert", "Invert filtering (show hidden items, and vice-versa)"); prop = RNA_def_property(srna, "use_filter_sort_alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_ALPHA); RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0); RNA_def_property_ui_text(prop, "Sort by Name", "Sort items by their name"); prop = RNA_def_property(srna, "use_filter_sort_reverse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_REVERSE); RNA_def_property_ui_text(prop, "Invert", "Invert the order of shown items"); /* draw_item */ func = RNA_def_function(srna, "draw_item", NULL); RNA_def_function_ui_description(func, "Draw an item in the list (NOTE: when you define your own draw_item " "function, you may want to check given 'item' is of the right type...)"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_string(func, "active_property", NULL, 0, "", "Identifier of property in active_data, for the active element"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL); prop = RNA_def_property(func, "flt_flag", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(prop, "", "The filter-flag result for this item"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL); /* draw_filter */ func = RNA_def_function(srna, "draw_filter", NULL); RNA_def_function_ui_description(func, "Draw filtering options"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); /* filter */ func = RNA_def_function(srna, "filter_items", NULL); RNA_def_function_ui_description(func, "Filter and/or re-order items of the collection (output filter results in " "filter_flags, and reorder results in filter_neworder arrays)"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data, for the collection"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); prop = RNA_def_property(func, "filter_flags", PROP_INT, PROP_UNSIGNED); RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC); RNA_def_property_array(prop, 1); /* XXX Dummy value, default 0 does not work */ RNA_def_property_ui_text(prop, "", "An array of filter flags, one for each item in the collection (NOTE: " "FILTER_ITEM bit is reserved, it defines whether the item is shown or not)"); RNA_def_function_output(func, prop); prop = RNA_def_property(func, "filter_neworder", PROP_INT, PROP_UNSIGNED); RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC); RNA_def_property_array(prop, 1); /* XXX Dummy value, default 0 does not work */ RNA_def_property_ui_text(prop, "", "An array of indices, one for each item in the collection, mapping the org " "index to the new one"); RNA_def_function_output(func, prop); /* "Constants"! */ RNA_define_verify_sdna(0); /* not in sdna */ prop = RNA_def_property(srna, "bitflag_filter_item", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(prop, "FILTER_ITEM", "The value of the reserved bitflag 'FILTER_ITEM' (in filter_flags values)"); RNA_def_property_int_funcs(prop, "rna_UIList_filter_const_FILTER_ITEM_get", NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); }
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); /* 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(!(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(strcmp(pt->idname, dummypt.idname) == 0) { if(pt->ext.srna) rna_Panel_unregister(bmain, pt->ext.srna); else BLI_freelinkN(&art->paneltypes, pt); break; } } /* create a new panel type */ pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); 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_SCREEN|NA_EDITED, NULL); return pt->ext.srna; }