diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_ui.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_ui.c | 306 |
1 files changed, 187 insertions, 119 deletions
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 2d624db8ad8..c0b4fd28892 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -28,13 +28,13 @@ #include "RNA_types.h" #include "rna_internal.h" +#include "RNA_enum_types.h" #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" #include "RNA_access.h" -#include "RNA_enum_types.h" #include "DNA_screen_types.h" @@ -49,44 +49,29 @@ #include "WM_api.h" #include "WM_types.h" -#define RNA_STRING_FUNCTIONS(fname, member) \ -static void fname##_get(PointerRNA *ptr, char *value) \ -{ \ - BLI_strncpy(value, member, sizeof(member)); \ -} \ -\ -static int fname##_length(PointerRNA *ptr) \ -{ \ - return strlen(member); \ -} \ -\ -static void fname##_set(PointerRNA *ptr, const char *value) \ -{ \ - BLI_strncpy(member, value, sizeof(member)); \ -} \ - -RNA_STRING_FUNCTIONS(rna_Panel_idname, ((Panel*)ptr->data)->type->idname) -RNA_STRING_FUNCTIONS(rna_Panel_label, ((Panel*)ptr->data)->type->label) -RNA_STRING_FUNCTIONS(rna_Panel_context, ((Panel*)ptr->data)->type->context) -RNA_STRING_FUNCTIONS(rna_Panel_space_type, ((Panel*)ptr->data)->type->space_type) -RNA_STRING_FUNCTIONS(rna_Panel_region_type, ((Panel*)ptr->data)->type->region_type) - -static void panel_draw(const bContext *C, Panel *pnl) +static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type) { - PointerRNA ptr; - ParameterList *list; - FunctionRNA *func; + SpaceType *st; + ARegionType *art; - RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr); - func= RNA_struct_find_function(&ptr, "draw"); + st= BKE_spacetype_from_id(space_type); - list= RNA_parameter_list_create(&ptr, func); - RNA_parameter_set_lookup(list, "context", &C); - pnl->type->py_call(&ptr, func, list); + for(art= (st)? st->regiontypes.first: NULL; art; art= art->next) { + if (art->regionid==region_type) + break; + } + + /* region type not found? abort */ + if (art==NULL) { + BKE_report(reports, RPT_ERROR, "Region not found in spacetype."); + return NULL; + } - RNA_parameter_list_free(list); + return art; } +/* Panel */ + static int panel_poll(const bContext *C, PanelType *pt) { PointerRNA ptr; @@ -110,76 +95,49 @@ static int panel_poll(const bContext *C, PanelType *pt) return visible; } -static char *enum_as_string(EnumPropertyItem *item) +static void panel_draw(const bContext *C, Panel *pnl) { - DynStr *dynstr= BLI_dynstr_new(); - EnumPropertyItem *e; - char *cstring; + PointerRNA ptr; + ParameterList *list; + FunctionRNA *func; - for (e= item; item->identifier; item++) { - BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier); - } + RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr); + func= RNA_struct_find_function(&ptr, "draw"); - cstring = BLI_dynstr_get_cstring(dynstr); - BLI_dynstr_free(dynstr); - return cstring; + list= RNA_parameter_list_create(&ptr, func); + RNA_parameter_set_lookup(list, "context", &C); + pnl->type->py_call(&ptr, func, list); + + RNA_parameter_list_free(list); } -static int space_region_type_from_panel(PanelType *pt, ReportList *reports, SpaceType **r_st, ARegionType **r_art) +static void rna_Panel_unregister(const bContext *C, StructRNA *type) { - SpaceType *st; ARegionType *art; - int space_value; - int region_value; - - /* find the space type */ - if (RNA_enum_value_from_id(space_type_items, pt->space_type, &space_value)==0) { - char *cstring= enum_as_string(space_type_items); - BKE_reportf(reports, RPT_ERROR, "SpaceType \"%s\" is not one of [%s]", pt->space_type, cstring); - MEM_freeN(cstring); - return 0; - } - - /* find the region type */ - if (RNA_enum_value_from_id(region_type_items, pt->region_type, ®ion_value)==0) { - char *cstring= enum_as_string(region_type_items); - BKE_reportf(reports, RPT_ERROR, "RegionType \"%s\" is not one of [%s]", pt->region_type, cstring); - MEM_freeN(cstring); - return 0; - } - - st= BKE_spacetype_from_id(space_value); + PanelType *pt= RNA_struct_blender_type_get(type); - for(art= st->regiontypes.first; art; art= art->next) { - if (art->regionid==region_value) - break; - } + if(!pt) + return; + if(!(art=region_type_find(NULL, pt->space_type, pt->region_type))) + return; - /* region type not found? abort */ - if (art==NULL) { - BKE_reportf(reports, RPT_ERROR, "SpaceType \"%s\" does not have a UI region '%s'", pt->space_type, pt->region_type); - return 0; - } - - *r_st= st; - *r_art= art; + BLI_freelinkN(&art->paneltypes, pt); + RNA_struct_free(&BLENDER_RNA, type); - return 1; + /* update while blender is running */ + if(C) + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { - SpaceType *st; ARegionType *art; - PanelType *pt; - Panel dummypanel; - PanelType dummypt; + PanelType *pt, dummypt = {}; + Panel dummypanel= {}; PointerRNA dummyptr; int have_function[2]; /* setup dummy panel & panel type to store static properties in */ - memset(&dummypanel, 0, sizeof(dummypanel)); - memset(&dummypt, 0, sizeof(dummypt)); dummypanel.type= &dummypt; RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr); @@ -187,34 +145,32 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi if(validate(&dummyptr, data, have_function) != 0) return NULL; - if(!space_region_type_from_panel(&dummypt, reports, &st, &art)) + if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type))) return NULL; - /* check if we have registered this panel type before */ - for(pt=art->paneltypes.first; pt; pt=pt->next) - if(strcmp(pt->idname, dummypt.idname) == 0) + /* 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->py_srna) + rna_Panel_unregister(C, pt->py_srna); break; - - /* create a new panel type if needed, otherwise we overwrite */ - if(!pt) { - pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); - BLI_strncpy(pt->idname, dummypt.idname, sizeof(pt->idname)); - pt->py_srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); - RNA_struct_blender_type_set(pt->py_srna, pt); - BLI_addtail(&art->paneltypes, pt); + } } + + /* create a new panel type */ + pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); + memcpy(pt, &dummypt, sizeof(dummypt)); - BLI_strncpy(pt->label, dummypt.label, sizeof(pt->label)); - BLI_strncpy(pt->space_type, dummypt.space_type, sizeof(pt->space_type)); - BLI_strncpy(pt->region_type, dummypt.region_type, sizeof(pt->region_type)); - BLI_strncpy(pt->context, dummypt.context, sizeof(pt->context)); + pt->py_srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); + pt->py_data= data; + pt->py_call= call; + pt->py_free= free; + RNA_struct_blender_type_set(pt->py_srna, pt); pt->poll= (have_function[0])? panel_poll: NULL; pt->draw= (have_function[1])? panel_draw: NULL; - pt->py_data= data; - pt->py_call= call; - pt->py_free= free; + BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ if(C) @@ -223,16 +179,41 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi return pt->py_srna; } -static void rna_Panel_unregister(const bContext *C, StructRNA *type) +static StructRNA* rna_Panel_refine(struct PointerRNA *ptr) +{ + Panel *hdr= (Panel*)ptr->data; + return (hdr->type)? hdr->type->py_srna: &RNA_Panel; +} + +/* Header */ + +static void header_draw(const bContext *C, Header *hdr) +{ + PointerRNA htr; + ParameterList *list; + FunctionRNA *func; + + RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->py_srna, hdr, &htr); + func= RNA_struct_find_function(&htr, "draw"); + + list= RNA_parameter_list_create(&htr, func); + RNA_parameter_set_lookup(list, "context", &C); + hdr->type->py_call(&htr, func, list); + + RNA_parameter_list_free(list); +} + +static void rna_Header_unregister(const bContext *C, StructRNA *type) { - SpaceType *st; ARegionType *art; - PanelType *pt= RNA_struct_blender_type_get(type); + HeaderType *ht= RNA_struct_blender_type_get(type); - if(!space_region_type_from_panel(pt, NULL, &st, &art)) + if(!ht) + return; + if(!(art=region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER))) return; - BLI_freelinkN(&art->paneltypes, pt); + BLI_freelinkN(&art->headertypes, ht); RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ @@ -240,10 +221,59 @@ static void rna_Panel_unregister(const bContext *C, StructRNA *type) WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } -static StructRNA* rna_Panel_refine(struct PointerRNA *ptr) +static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { - Panel *pnl= (Panel*)ptr->data; - return (pnl->type)? pnl->type->py_srna: &RNA_Panel; + ARegionType *art; + HeaderType *ht, dummyht = {}; + Header dummyheader= {}; + 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(!(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->py_srna) + rna_Header_unregister(C, ht->py_srna); + break; + } + } + + /* create a new header type */ + ht= MEM_callocN(sizeof(HeaderType), "python buttons header"); + memcpy(ht, &dummyht, sizeof(dummyht)); + + ht->py_srna= RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); + ht->py_data= data; + ht->py_call= call; + ht->py_free= free; + RNA_struct_blender_type_set(ht->py_srna, ht); + + ht->draw= (have_function[0])? header_draw: NULL; + + BLI_addtail(&art->headertypes, ht); + + /* update while blender is running */ + if(C) + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + + return ht->py_srna; +} + +static StructRNA* rna_Header_refine(struct PointerRNA *htr) +{ + Header *hdr= (Header*)htr->data; + return (hdr->type)? hdr->type->py_srna: &RNA_Header; } #else @@ -266,17 +296,19 @@ static void rna_def_panel(BlenderRNA *brna) FunctionRNA *func; srna= RNA_def_struct(brna, "Panel", NULL); - RNA_def_struct_ui_text(srna, "Panel", "Buttons panel."); + RNA_def_struct_ui_text(srna, "Panel", "Panel containing buttons."); 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"); + /* poll */ func= RNA_def_function(srna, "poll", NULL); RNA_def_function_ui_description(func, "Test if the panel is visible or not."); RNA_def_function_flag(func, FUNC_REGISTER|FUNC_REGISTER_OPTIONAL); RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", "")); RNA_def_pointer(func, "context", "Context", "", ""); + /* draw */ func= RNA_def_function(srna, "draw", NULL); RNA_def_function_ui_description(func, "Draw buttons into the panel UI layout."); RNA_def_function_flag(func, FUNC_REGISTER); @@ -285,31 +317,67 @@ static void rna_def_panel(BlenderRNA *brna) prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "UILayout"); + /* registration */ prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER); - RNA_def_property_string_funcs(prop, "rna_Panel_idname_get", "rna_Panel_idname_length", "rna_Panel_idname_set"); prop= RNA_def_property(srna, "label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->label"); RNA_def_property_flag(prop, PROP_REGISTER); - RNA_def_property_string_funcs(prop, "rna_Panel_label_get", "rna_Panel_label_length", "rna_Panel_label_set"); - prop= RNA_def_property(srna, "space_type", PROP_STRING, PROP_NONE); + prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type->space_type"); + RNA_def_property_enum_items(prop, space_type_items); RNA_def_property_flag(prop, PROP_REGISTER); - RNA_def_property_string_funcs(prop, "rna_Panel_space_type_get", "rna_Panel_space_type_length", "rna_Panel_space_type_set"); - prop= RNA_def_property(srna, "region_type", PROP_STRING, PROP_NONE); + prop= RNA_def_property(srna, "region_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type->region_type"); + RNA_def_property_enum_items(prop, region_type_items); RNA_def_property_flag(prop, PROP_REGISTER); - RNA_def_property_string_funcs(prop, "rna_Panel_region_type_get", "rna_Panel_region_type_length", "rna_Panel_region_type_set"); prop= RNA_def_property(srna, "context", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->context"); + RNA_def_property_flag(prop, PROP_REGISTER); +} + +static void rna_def_header(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + FunctionRNA *func; + + srna= RNA_def_struct(brna, "Header", NULL); + RNA_def_struct_ui_text(srna, "Header", "Editor header containing buttons."); + 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"); + + /* draw */ + func= RNA_def_function(srna, "draw", NULL); + RNA_def_function_ui_description(func, "Draw buttons into the header UI layout."); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "context", "Context", "", ""); + + prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "UILayout"); + + /* registration */ + prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->idname"); + RNA_def_property_flag(prop, PROP_REGISTER); + + prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type->space_type"); + RNA_def_property_enum_items(prop, space_type_items); RNA_def_property_flag(prop, PROP_REGISTER); - RNA_def_property_string_funcs(prop, "rna_Panel_context_get", "rna_Panel_context_length", "rna_Panel_context_set"); } void RNA_def_ui(BlenderRNA *brna) { rna_def_ui_layout(brna); rna_def_panel(brna); + rna_def_header(brna); } #endif |