2009-04-08 16:40:46 +00:00
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation (2009)
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
#include "RNA_types.h"
|
|
|
|
|
|
|
|
#include "rna_internal.h"
|
2009-04-19 17:12:16 +00:00
|
|
|
#include "RNA_enum_types.h"
|
2009-04-08 16:40:46 +00:00
|
|
|
|
|
|
|
#ifdef RNA_RUNTIME
|
|
|
|
|
2009-04-19 13:37:59 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
|
|
|
#include "BLI_dynstr.h"
|
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BKE_report.h"
|
|
|
|
#include "BKE_screen.h"
|
|
|
|
|
2009-04-08 16:40:46 +00:00
|
|
|
#include "UI_interface.h"
|
|
|
|
|
2009-04-19 13:37:59 +00:00
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type)
|
2009-04-19 13:37:59 +00:00
|
|
|
{
|
2009-04-19 17:12:16 +00:00
|
|
|
SpaceType *st;
|
|
|
|
ARegionType *art;
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
st= BKE_spacetype_from_id(space_type);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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;
|
|
|
|
}
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
return art;
|
2009-04-19 13:37:59 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* Panel */
|
|
|
|
|
2009-04-19 13:37:59 +00:00
|
|
|
static int panel_poll(const bContext *C, PanelType *pt)
|
|
|
|
{
|
|
|
|
PointerRNA ptr;
|
|
|
|
ParameterList *list;
|
|
|
|
FunctionRNA *func;
|
|
|
|
void *ret;
|
|
|
|
int visible;
|
|
|
|
|
|
|
|
RNA_pointer_create(NULL, pt->py_srna, NULL, &ptr); /* dummy */
|
|
|
|
func= RNA_struct_find_function(&ptr, "poll");
|
|
|
|
|
|
|
|
list= RNA_parameter_list_create(&ptr, func);
|
|
|
|
RNA_parameter_set_lookup(list, "context", &C);
|
|
|
|
pt->py_call(&ptr, func, list);
|
|
|
|
|
|
|
|
RNA_parameter_get_lookup(list, "visible", &ret);
|
|
|
|
visible= *(int*)ret;
|
|
|
|
|
|
|
|
RNA_parameter_list_free(list);
|
|
|
|
|
|
|
|
return visible;
|
|
|
|
}
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
static void panel_draw(const bContext *C, Panel *pnl)
|
2009-04-19 13:37:59 +00:00
|
|
|
{
|
2009-04-19 17:12:16 +00:00
|
|
|
PointerRNA ptr;
|
|
|
|
ParameterList *list;
|
|
|
|
FunctionRNA *func;
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr);
|
|
|
|
func= RNA_struct_find_function(&ptr, "draw");
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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);
|
2009-04-19 13:37:59 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
static void rna_Panel_unregister(const bContext *C, StructRNA *type)
|
2009-04-19 13:37:59 +00:00
|
|
|
{
|
|
|
|
ARegionType *art;
|
2009-04-19 17:12:16 +00:00
|
|
|
PanelType *pt= RNA_struct_blender_type_get(type);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
if(!pt)
|
|
|
|
return;
|
|
|
|
if(!(art=region_type_find(NULL, pt->space_type, pt->region_type)))
|
|
|
|
return;
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
BLI_freelinkN(&art->paneltypes, pt);
|
|
|
|
RNA_struct_free(&BLENDER_RNA, type);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* update while blender is running */
|
|
|
|
if(C)
|
|
|
|
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
|
2009-04-19 13:37:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
|
|
|
|
{
|
|
|
|
ARegionType *art;
|
2009-04-19 20:09:31 +00:00
|
|
|
PanelType *pt, dummypt = {0};
|
|
|
|
Panel dummypanel= {0};
|
2009-04-19 13:37:59 +00:00
|
|
|
PointerRNA dummyptr;
|
|
|
|
int have_function[2];
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type)))
|
2009-04-19 13:37:59 +00:00
|
|
|
return NULL;
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* 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);
|
2009-04-19 13:37:59 +00:00
|
|
|
break;
|
2009-04-19 17:12:16 +00:00
|
|
|
}
|
2009-04-19 13:37:59 +00:00
|
|
|
}
|
2009-04-19 17:12:16 +00:00
|
|
|
|
|
|
|
/* create a new panel type */
|
|
|
|
pt= MEM_callocN(sizeof(PanelType), "python buttons panel");
|
|
|
|
memcpy(pt, &dummypt, sizeof(dummypt));
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
|
|
|
pt->poll= (have_function[0])? panel_poll: NULL;
|
|
|
|
pt->draw= (have_function[1])? panel_draw: NULL;
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
BLI_addtail(&art->paneltypes, pt);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
|
|
|
/* update while blender is running */
|
|
|
|
if(C)
|
|
|
|
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
|
|
|
|
|
|
|
|
return pt->py_srna;
|
|
|
|
}
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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)
|
2009-04-19 13:37:59 +00:00
|
|
|
{
|
|
|
|
ARegionType *art;
|
2009-04-19 17:12:16 +00:00
|
|
|
HeaderType *ht= RNA_struct_blender_type_get(type);
|
2009-04-19 13:37:59 +00:00
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
if(!ht)
|
|
|
|
return;
|
|
|
|
if(!(art=region_type_find(NULL, ht->space_type, RGN_TYPE_HEADER)))
|
2009-04-19 13:37:59 +00:00
|
|
|
return;
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
BLI_freelinkN(&art->headertypes, ht);
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_struct_free(&BLENDER_RNA, type);
|
|
|
|
|
|
|
|
/* update while blender is running */
|
|
|
|
if(C)
|
|
|
|
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
|
|
|
|
}
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
static StructRNA *rna_Header_register(const bContext *C, ReportList *reports, void *data, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
|
2009-04-19 13:37:59 +00:00
|
|
|
{
|
2009-04-19 17:12:16 +00:00
|
|
|
ARegionType *art;
|
2009-04-19 20:09:31 +00:00
|
|
|
HeaderType *ht, dummyht = {0};
|
|
|
|
Header dummyheader= {0};
|
2009-04-19 17:12:16 +00:00
|
|
|
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;
|
2009-04-19 13:37:59 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 16:40:46 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
static void rna_def_ui_layout(BlenderRNA *brna)
|
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
|
|
|
srna= RNA_def_struct(brna, "UILayout", NULL);
|
|
|
|
RNA_def_struct_sdna(srna, "uiLayout");
|
|
|
|
RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header.");
|
|
|
|
|
|
|
|
RNA_api_ui_layout(srna);
|
|
|
|
}
|
|
|
|
|
2009-04-19 13:37:59 +00:00
|
|
|
static void rna_def_panel(BlenderRNA *brna)
|
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
PropertyRNA *prop;
|
|
|
|
FunctionRNA *func;
|
|
|
|
|
|
|
|
srna= RNA_def_struct(brna, "Panel", NULL);
|
2009-04-19 17:12:16 +00:00
|
|
|
RNA_def_struct_ui_text(srna, "Panel", "Panel containing buttons.");
|
2009-04-19 13:37:59 +00:00
|
|
|
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");
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* poll */
|
2009-04-19 13:37:59 +00:00
|
|
|
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", "", "");
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* draw */
|
2009-04-19 13:37:59 +00:00
|
|
|
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);
|
|
|
|
RNA_def_pointer(func, "context", "Context", "", "");
|
|
|
|
|
|
|
|
prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
|
|
|
|
RNA_def_property_struct_type(prop, "UILayout");
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
/* registration */
|
2009-04-19 13:37:59 +00:00
|
|
|
prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE);
|
2009-04-19 17:12:16 +00:00
|
|
|
RNA_def_property_string_sdna(prop, NULL, "type->idname");
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_REGISTER);
|
|
|
|
|
|
|
|
prop= RNA_def_property(srna, "label", PROP_STRING, PROP_NONE);
|
2009-04-19 17:12:16 +00:00
|
|
|
RNA_def_property_string_sdna(prop, NULL, "type->label");
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_REGISTER);
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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);
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_REGISTER);
|
|
|
|
|
2009-04-19 17:12:16 +00:00
|
|
|
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);
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_REGISTER);
|
|
|
|
|
|
|
|
prop= RNA_def_property(srna, "context", PROP_STRING, PROP_NONE);
|
2009-04-19 17:12:16 +00:00
|
|
|
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);
|
2009-04-19 13:37:59 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_REGISTER);
|
|
|
|
}
|
|
|
|
|
2009-04-08 16:40:46 +00:00
|
|
|
void RNA_def_ui(BlenderRNA *brna)
|
|
|
|
{
|
|
|
|
rna_def_ui_layout(brna);
|
2009-04-19 13:37:59 +00:00
|
|
|
rna_def_panel(brna);
|
2009-04-19 17:12:16 +00:00
|
|
|
rna_def_header(brna);
|
2009-04-08 16:40:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|