1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17 /** \file
18 * \ingroup RNA
19 */
20
21 #include <stdlib.h>
22
23 #include "DNA_screen_types.h"
24 #include "DNA_space_types.h"
25
26 #include "BLT_translation.h"
27
28 #include "BKE_idprop.h"
29
30 #include "BLI_listbase.h"
31
32 #include "RNA_define.h"
33
34 #include "RNA_enum_types.h"
35 #include "rna_internal.h"
36
37 #include "UI_interface.h"
38
39 #include "WM_toolsystem.h"
40 #include "WM_types.h"
41
42 /* see WM_types.h */
43 const EnumPropertyItem rna_enum_operator_context_items[] = {
44 {WM_OP_INVOKE_DEFAULT, "INVOKE_DEFAULT", 0, "Invoke Default", ""},
45 {WM_OP_INVOKE_REGION_WIN, "INVOKE_REGION_WIN", 0, "Invoke Region Window", ""},
46 {WM_OP_INVOKE_REGION_CHANNELS, "INVOKE_REGION_CHANNELS", 0, "Invoke Region Channels", ""},
47 {WM_OP_INVOKE_REGION_PREVIEW, "INVOKE_REGION_PREVIEW", 0, "Invoke Region Preview", ""},
48 {WM_OP_INVOKE_AREA, "INVOKE_AREA", 0, "Invoke Area", ""},
49 {WM_OP_INVOKE_SCREEN, "INVOKE_SCREEN", 0, "Invoke Screen", ""},
50 {WM_OP_EXEC_DEFAULT, "EXEC_DEFAULT", 0, "Exec Default", ""},
51 {WM_OP_EXEC_REGION_WIN, "EXEC_REGION_WIN", 0, "Exec Region Window", ""},
52 {WM_OP_EXEC_REGION_CHANNELS, "EXEC_REGION_CHANNELS", 0, "Exec Region Channels", ""},
53 {WM_OP_EXEC_REGION_PREVIEW, "EXEC_REGION_PREVIEW", 0, "Exec Region Preview", ""},
54 {WM_OP_EXEC_AREA, "EXEC_AREA", 0, "Exec Area", ""},
55 {WM_OP_EXEC_SCREEN, "EXEC_SCREEN", 0, "Exec Screen", ""},
56 {0, NULL, 0, NULL, NULL},
57 };
58
59 const EnumPropertyItem rna_enum_uilist_layout_type_items[] = {
60 {UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout", "Use the default, multi-rows layout"},
61 {UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout", "Use the compact, single-row layout"},
62 {UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout", "Use the grid-based layout"},
63 {0, NULL, 0, NULL, NULL},
64 };
65
66 #ifdef RNA_RUNTIME
67
68 # include "MEM_guardedalloc.h"
69
70 # include "RNA_access.h"
71
72 # include "BLI_dynstr.h"
73
74 # include "BKE_context.h"
75 # include "BKE_report.h"
76 # include "BKE_screen.h"
77
78 # include "WM_api.h"
79
region_type_find(ReportList * reports,int space_type,int region_type)80 static ARegionType *region_type_find(ReportList *reports, int space_type, int region_type)
81 {
82 SpaceType *st;
83 ARegionType *art;
84
85 st = BKE_spacetype_from_id(space_type);
86
87 for (art = (st) ? st->regiontypes.first : NULL; art; art = art->next) {
88 if (art->regionid == region_type) {
89 break;
90 }
91 }
92
93 /* region type not found? abort */
94 if (art == NULL) {
95 BKE_report(reports, RPT_ERROR, "Region not found in space type");
96 return NULL;
97 }
98
99 return art;
100 }
101
102 /* Panel */
103
panel_poll(const bContext * C,PanelType * pt)104 static bool panel_poll(const bContext *C, PanelType *pt)
105 {
106 extern FunctionRNA rna_Panel_poll_func;
107
108 PointerRNA ptr;
109 ParameterList list;
110 FunctionRNA *func;
111 void *ret;
112 bool visible;
113
114 RNA_pointer_create(NULL, pt->rna_ext.srna, NULL, &ptr); /* dummy */
115 func = &rna_Panel_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
116
117 RNA_parameter_list_create(&list, &ptr, func);
118 RNA_parameter_set_lookup(&list, "context", &C);
119 pt->rna_ext.call((bContext *)C, &ptr, func, &list);
120
121 RNA_parameter_get_lookup(&list, "visible", &ret);
122 visible = *(bool *)ret;
123
124 RNA_parameter_list_free(&list);
125
126 return visible;
127 }
128
panel_draw(const bContext * C,Panel * panel)129 static void panel_draw(const bContext *C, Panel *panel)
130 {
131 extern FunctionRNA rna_Panel_draw_func;
132
133 PointerRNA ptr;
134 ParameterList list;
135 FunctionRNA *func;
136
137 RNA_pointer_create(&CTX_wm_screen(C)->id, panel->type->rna_ext.srna, panel, &ptr);
138 func = &rna_Panel_draw_func; /* RNA_struct_find_function(&ptr, "draw"); */
139
140 RNA_parameter_list_create(&list, &ptr, func);
141 RNA_parameter_set_lookup(&list, "context", &C);
142 panel->type->rna_ext.call((bContext *)C, &ptr, func, &list);
143
144 RNA_parameter_list_free(&list);
145 }
146
panel_draw_header(const bContext * C,Panel * panel)147 static void panel_draw_header(const bContext *C, Panel *panel)
148 {
149 extern FunctionRNA rna_Panel_draw_header_func;
150
151 PointerRNA ptr;
152 ParameterList list;
153 FunctionRNA *func;
154
155 RNA_pointer_create(&CTX_wm_screen(C)->id, panel->type->rna_ext.srna, panel, &ptr);
156 func = &rna_Panel_draw_header_func; /* RNA_struct_find_function(&ptr, "draw_header"); */
157
158 RNA_parameter_list_create(&list, &ptr, func);
159 RNA_parameter_set_lookup(&list, "context", &C);
160 panel->type->rna_ext.call((bContext *)C, &ptr, func, &list);
161
162 RNA_parameter_list_free(&list);
163 }
164
panel_draw_header_preset(const bContext * C,Panel * panel)165 static void panel_draw_header_preset(const bContext *C, Panel *panel)
166 {
167 extern FunctionRNA rna_Panel_draw_header_preset_func;
168
169 PointerRNA ptr;
170 ParameterList list;
171 FunctionRNA *func;
172
173 RNA_pointer_create(&CTX_wm_screen(C)->id, panel->type->rna_ext.srna, panel, &ptr);
174 func = &rna_Panel_draw_header_preset_func;
175
176 RNA_parameter_list_create(&list, &ptr, func);
177 RNA_parameter_set_lookup(&list, "context", &C);
178 panel->type->rna_ext.call((bContext *)C, &ptr, func, &list);
179
180 RNA_parameter_list_free(&list);
181 }
182
panel_type_clear_recursive(Panel * panel,const PanelType * type)183 static void panel_type_clear_recursive(Panel *panel, const PanelType *type)
184 {
185 if (panel->type == type) {
186 panel->type = NULL;
187 }
188
189 LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
190 panel_type_clear_recursive(child_panel, type);
191 }
192 }
193
rna_Panel_unregister(Main * bmain,StructRNA * type)194 static void rna_Panel_unregister(Main *bmain, StructRNA *type)
195 {
196 ARegionType *art;
197 PanelType *pt = RNA_struct_blender_type_get(type);
198
199 if (!pt) {
200 return;
201 }
202 if (!(art = region_type_find(NULL, pt->space_type, pt->region_type))) {
203 return;
204 }
205
206 RNA_struct_free_extension(type, &pt->rna_ext);
207 RNA_struct_free(&BLENDER_RNA, type);
208
209 if (pt->parent) {
210 LinkData *link = BLI_findptr(&pt->parent->children, pt, offsetof(LinkData, data));
211 BLI_freelinkN(&pt->parent->children, link);
212 }
213
214 WM_paneltype_remove(pt);
215
216 LISTBASE_FOREACH (LinkData *, link, &pt->children) {
217 PanelType *child_pt = link->data;
218 child_pt->parent = NULL;
219 }
220
221 const char space_type = pt->space_type;
222 BLI_freelistN(&pt->children);
223 BLI_freelinkN(&art->paneltypes, pt);
224
225 for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
226 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
227 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
228 if (sl->spacetype == space_type) {
229 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
230 &sl->regionbase;
231 LISTBASE_FOREACH (ARegion *, region, regionbase) {
232 if (region->type == art) {
233 LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
234 panel_type_clear_recursive(panel, pt);
235 }
236 }
237 /* The unregistered panel might have had a template that added instanced panels,
238 * so remove them just in case. They can be re-added on redraw anyway. */
239 UI_panels_free_instanced(NULL, region);
240 }
241 }
242 }
243 }
244 }
245
246 /* update while blender is running */
247 WM_main_add_notifier(NC_WINDOW, NULL);
248 }
249
rna_Panel_register(Main * bmain,ReportList * reports,void * data,const char * identifier,StructValidateFunc validate,StructCallbackFunc call,StructFreeFunc free)250 static StructRNA *rna_Panel_register(Main *bmain,
251 ReportList *reports,
252 void *data,
253 const char *identifier,
254 StructValidateFunc validate,
255 StructCallbackFunc call,
256 StructFreeFunc free)
257 {
258 ARegionType *art;
259 PanelType *pt, *parent = NULL, dummypt = {NULL};
260 Panel dummypanel = {NULL};
261 PointerRNA dummyptr;
262 int have_function[4];
263
264 /* setup dummy panel & panel type to store static properties in */
265 dummypanel.type = &dummypt;
266 RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
267
268 /* We have to set default context! Else we get a void string... */
269 strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
270
271 /* validate the python class */
272 if (validate(&dummyptr, data, have_function) != 0) {
273 return NULL;
274 }
275
276 if (strlen(identifier) >= sizeof(dummypt.idname)) {
277 BKE_reportf(reports,
278 RPT_ERROR,
279 "Registering panel class: '%s' is too long, maximum length is %d",
280 identifier,
281 (int)sizeof(dummypt.idname));
282 return NULL;
283 }
284
285 if ((1 << dummypt.region_type) & RGN_TYPE_HAS_CATEGORY_MASK) {
286 if (dummypt.category[0] == '\0') {
287 /* Use a fallback, otherwise an empty value will draw the panel in every category. */
288 strcpy(dummypt.category, PNL_CATEGORY_FALLBACK);
289 # ifndef NDEBUG
290 printf("Registering panel class: '%s' misses category, please update the script\n",
291 dummypt.idname);
292 # endif
293 }
294 }
295 else {
296 if (dummypt.category[0] != '\0') {
297 if ((1 << dummypt.space_type) & WM_TOOLSYSTEM_SPACE_MASK) {
298 BKE_reportf(reports,
299 RPT_ERROR,
300 "Registering panel class: '%s' has category '%s' ",
301 dummypt.idname,
302 dummypt.category);
303 return NULL;
304 }
305 }
306 }
307
308 if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type))) {
309 return NULL;
310 }
311
312 /* check if we have registered this panel type before, and remove it */
313 for (pt = art->paneltypes.first; pt; pt = pt->next) {
314 if (STREQ(pt->idname, dummypt.idname)) {
315 PanelType *pt_next = pt->next;
316 if (pt->rna_ext.srna) {
317 rna_Panel_unregister(bmain, pt->rna_ext.srna);
318 }
319 else {
320 BLI_freelinkN(&art->paneltypes, pt);
321 }
322
323 /* The order of panel types will be altered on re-registration. */
324 if (dummypt.parent_id[0] && (parent == NULL)) {
325 for (pt = pt_next; pt; pt = pt->next) {
326 if (STREQ(pt->idname, dummypt.parent_id)) {
327 parent = pt;
328 break;
329 }
330 }
331 }
332
333 break;
334 }
335
336 if (dummypt.parent_id[0] && STREQ(pt->idname, dummypt.parent_id)) {
337 parent = pt;
338 }
339 }
340
341 if (!RNA_struct_available_or_report(reports, dummypt.idname)) {
342 return NULL;
343 }
344 if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) {
345 return NULL;
346 }
347 if (dummypt.parent_id[0] && !parent) {
348 BKE_reportf(reports,
349 RPT_ERROR,
350 "Registering panel class: parent '%s' for '%s' not found",
351 dummypt.parent_id,
352 dummypt.idname);
353 return NULL;
354 }
355
356 /* create a new panel type */
357 pt = MEM_mallocN(sizeof(PanelType), "python buttons panel");
358 memcpy(pt, &dummypt, sizeof(dummypt));
359
360 pt->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
361 RNA_def_struct_translation_context(pt->rna_ext.srna, pt->translation_context);
362 pt->rna_ext.data = data;
363 pt->rna_ext.call = call;
364 pt->rna_ext.free = free;
365 RNA_struct_blender_type_set(pt->rna_ext.srna, pt);
366 RNA_def_struct_flag(pt->rna_ext.srna, STRUCT_NO_IDPROPERTIES);
367
368 pt->poll = (have_function[0]) ? panel_poll : NULL;
369 pt->draw = (have_function[1]) ? panel_draw : NULL;
370 pt->draw_header = (have_function[2]) ? panel_draw_header : NULL;
371 pt->draw_header_preset = (have_function[3]) ? panel_draw_header_preset : NULL;
372
373 /* Find position to insert panel based on order. */
374 PanelType *pt_iter = art->paneltypes.last;
375
376 for (; pt_iter; pt_iter = pt_iter->prev) {
377 /* No header has priority. */
378 if ((pt->flag & PNL_NO_HEADER) && !(pt_iter->flag & PNL_NO_HEADER)) {
379 continue;
380 }
381 if (pt_iter->order <= pt->order) {
382 break;
383 }
384 }
385
386 /* Insert into list. */
387 BLI_insertlinkafter(&art->paneltypes, pt_iter, pt);
388
389 if (parent) {
390 pt->parent = parent;
391 BLI_addtail(&parent->children, BLI_genericNodeN(pt));
392 }
393
394 {
395 const char *owner_id = RNA_struct_state_owner_get();
396 if (owner_id) {
397 BLI_strncpy(pt->owner_id, owner_id, sizeof(pt->owner_id));
398 }
399 }
400
401 WM_paneltype_add(pt);
402
403 /* update while blender is running */
404 WM_main_add_notifier(NC_WINDOW, NULL);
405
406 return pt->rna_ext.srna;
407 }
408
rna_Panel_refine(PointerRNA * ptr)409 static StructRNA *rna_Panel_refine(PointerRNA *ptr)
410 {
411 Panel *menu = (Panel *)ptr->data;
412 return (menu->type && menu->type->rna_ext.srna) ? menu->type->rna_ext.srna : &RNA_Panel;
413 }
414
rna_Panel_custom_data_typef(PointerRNA * ptr)415 static StructRNA *rna_Panel_custom_data_typef(PointerRNA *ptr)
416 {
417 Panel *panel = (Panel *)ptr->data;
418
419 return UI_panel_custom_data_get(panel)->type;
420 }
421
rna_Panel_custom_data_get(PointerRNA * ptr)422 static PointerRNA rna_Panel_custom_data_get(PointerRNA *ptr)
423 {
424 Panel *panel = (Panel *)ptr->data;
425
426 /* Because the panel custom data is general we can't refine the pointer type here. */
427 return *UI_panel_custom_data_get(panel);
428 }
429
430 /* UIList */
rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA * UNUSED (ptr))431 static unsigned int rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA *UNUSED(ptr))
432 {
433 return UILST_FLT_ITEM;
434 }
435
rna_UIList_idprops(PointerRNA * ptr,bool create)436 static IDProperty *rna_UIList_idprops(PointerRNA *ptr, bool create)
437 {
438 uiList *ui_list = (uiList *)ptr->data;
439 if (create && !ui_list->properties) {
440 IDPropertyTemplate val = {0};
441 ui_list->properties = IDP_New(IDP_GROUP, &val, "RNA_UIList IDproperties group");
442 }
443
444 return ui_list->properties;
445 }
446
uilist_draw_item(uiList * ui_list,bContext * C,uiLayout * layout,PointerRNA * dataptr,PointerRNA * itemptr,int icon,PointerRNA * active_dataptr,const char * active_propname,int index,int flt_flag)447 static void uilist_draw_item(uiList *ui_list,
448 bContext *C,
449 uiLayout *layout,
450 PointerRNA *dataptr,
451 PointerRNA *itemptr,
452 int icon,
453 PointerRNA *active_dataptr,
454 const char *active_propname,
455 int index,
456 int flt_flag)
457 {
458 extern FunctionRNA rna_UIList_draw_item_func;
459
460 PointerRNA ul_ptr;
461 ParameterList list;
462 FunctionRNA *func;
463
464 RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->rna_ext.srna, ui_list, &ul_ptr);
465 func = &rna_UIList_draw_item_func; /* RNA_struct_find_function(&ul_ptr, "draw_item"); */
466
467 RNA_parameter_list_create(&list, &ul_ptr, func);
468 RNA_parameter_set_lookup(&list, "context", &C);
469 RNA_parameter_set_lookup(&list, "layout", &layout);
470 RNA_parameter_set_lookup(&list, "data", dataptr);
471 RNA_parameter_set_lookup(&list, "item", itemptr);
472 RNA_parameter_set_lookup(&list, "icon", &icon);
473 RNA_parameter_set_lookup(&list, "active_data", active_dataptr);
474 RNA_parameter_set_lookup(&list, "active_property", &active_propname);
475 RNA_parameter_set_lookup(&list, "index", &index);
476 RNA_parameter_set_lookup(&list, "flt_flag", &flt_flag);
477 ui_list->type->rna_ext.call((bContext *)C, &ul_ptr, func, &list);
478
479 RNA_parameter_list_free(&list);
480 }
481
uilist_draw_filter(uiList * ui_list,bContext * C,uiLayout * layout)482 static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout)
483 {
484 extern FunctionRNA rna_UIList_draw_filter_func;
485
486 PointerRNA ul_ptr;
487 ParameterList list;
488 FunctionRNA *func;
489
490 RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->rna_ext.srna, ui_list, &ul_ptr);
491 func = &rna_UIList_draw_filter_func; /* RNA_struct_find_function(&ul_ptr, "draw_filter"); */
492
493 RNA_parameter_list_create(&list, &ul_ptr, func);
494 RNA_parameter_set_lookup(&list, "context", &C);
495 RNA_parameter_set_lookup(&list, "layout", &layout);
496 ui_list->type->rna_ext.call((bContext *)C, &ul_ptr, func, &list);
497
498 RNA_parameter_list_free(&list);
499 }
500
uilist_filter_items(uiList * ui_list,bContext * C,PointerRNA * dataptr,const char * propname)501 static void uilist_filter_items(uiList *ui_list,
502 bContext *C,
503 PointerRNA *dataptr,
504 const char *propname)
505 {
506 extern FunctionRNA rna_UIList_filter_items_func;
507
508 PointerRNA ul_ptr;
509 ParameterList list;
510 FunctionRNA *func;
511 PropertyRNA *parm;
512
513 uiListDyn *flt_data = ui_list->dyn_data;
514 int *filter_flags, *filter_neworder;
515 void *ret1, *ret2;
516 int ret_len;
517 int len = flt_data->items_len = RNA_collection_length(dataptr, propname);
518
519 RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->rna_ext.srna, ui_list, &ul_ptr);
520 func = &rna_UIList_filter_items_func; /* RNA_struct_find_function(&ul_ptr, "filter_items"); */
521
522 RNA_parameter_list_create(&list, &ul_ptr, func);
523 RNA_parameter_set_lookup(&list, "context", &C);
524 RNA_parameter_set_lookup(&list, "data", dataptr);
525 RNA_parameter_set_lookup(&list, "property", &propname);
526
527 ui_list->type->rna_ext.call((bContext *)C, &ul_ptr, func, &list);
528
529 parm = RNA_function_find_parameter(NULL, func, "filter_flags");
530 ret_len = RNA_parameter_dynamic_length_get(&list, parm);
531 if (ret_len != len && ret_len != 0) {
532 printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n",
533 __func__,
534 RNA_parameter_dynamic_length_get(&list, parm),
535 "filter_flags",
536 len);
537 /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
538 filter_flags = NULL;
539 }
540 else {
541 RNA_parameter_get(&list, parm, &ret1);
542 filter_flags = (int *)ret1;
543 }
544
545 parm = RNA_function_find_parameter(NULL, func, "filter_neworder");
546 ret_len = RNA_parameter_dynamic_length_get(&list, parm);
547 if (ret_len != len && ret_len != 0) {
548 printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n",
549 __func__,
550 RNA_parameter_dynamic_length_get(&list, parm),
551 "filter_neworder",
552 len);
553 /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
554 filter_neworder = NULL;
555 }
556 else {
557 RNA_parameter_get(&list, parm, &ret2);
558 filter_neworder = (int *)ret2;
559 }
560
561 /* We have to do some final checks and transforms... */
562 {
563 int i, filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
564 if (filter_flags) {
565 flt_data->items_filter_flags = MEM_mallocN(sizeof(int) * len, __func__);
566 memcpy(flt_data->items_filter_flags, filter_flags, sizeof(int) * len);
567
568 if (filter_neworder) {
569 /* For sake of simplicity, py filtering is expected to filter all items,
570 * but we actually only want reordering data for shown items!
571 */
572 int items_shown, shown_idx;
573 int t_idx, t_ni, prev_ni;
574 flt_data->items_shown = 0;
575 for (i = 0, shown_idx = 0; i < len; i++) {
576 if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
577 filter_neworder[shown_idx++] = filter_neworder[i];
578 }
579 }
580 items_shown = flt_data->items_shown = shown_idx;
581 flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * items_shown, __func__);
582 /* And now, bring back new indices into the [0, items_shown[ range!
583 * XXX This is O(N²)... :/
584 */
585 for (shown_idx = 0, prev_ni = -1; shown_idx < items_shown; shown_idx++) {
586 for (i = 0, t_ni = len, t_idx = -1; i < items_shown; i++) {
587 int ni = filter_neworder[i];
588 if (ni > prev_ni && ni < t_ni) {
589 t_idx = i;
590 t_ni = ni;
591 }
592 }
593 if (t_idx >= 0) {
594 prev_ni = t_ni;
595 flt_data->items_filter_neworder[t_idx] = shown_idx;
596 }
597 }
598 }
599 else {
600 /* we still have to set flt_data->items_shown... */
601 flt_data->items_shown = 0;
602 for (i = 0; i < len; i++) {
603 if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
604 flt_data->items_shown++;
605 }
606 }
607 }
608 }
609 else {
610 flt_data->items_shown = len;
611
612 if (filter_neworder) {
613 flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * len, __func__);
614 memcpy(flt_data->items_filter_neworder, filter_neworder, sizeof(int) * len);
615 }
616 }
617 }
618
619 RNA_parameter_list_free(&list);
620 }
621
rna_UIList_unregister(Main * UNUSED (bmain),StructRNA * type)622 static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
623 {
624 uiListType *ult = RNA_struct_blender_type_get(type);
625
626 if (!ult) {
627 return;
628 }
629
630 RNA_struct_free_extension(type, &ult->rna_ext);
631 RNA_struct_free(&BLENDER_RNA, type);
632
633 WM_uilisttype_freelink(ult);
634
635 /* update while blender is running */
636 WM_main_add_notifier(NC_WINDOW, NULL);
637 }
638
rna_UIList_register(Main * bmain,ReportList * reports,void * data,const char * identifier,StructValidateFunc validate,StructCallbackFunc call,StructFreeFunc free)639 static StructRNA *rna_UIList_register(Main *bmain,
640 ReportList *reports,
641 void *data,
642 const char *identifier,
643 StructValidateFunc validate,
644 StructCallbackFunc call,
645 StructFreeFunc free)
646 {
647 uiListType *ult, dummyult = {NULL};
648 uiList dummyuilist = {NULL};
649 PointerRNA dummyul_ptr;
650 int have_function[3];
651 size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
652
653 /* setup dummy menu & menu type to store static properties in */
654 dummyuilist.type = &dummyult;
655 RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);
656
657 /* validate the python class */
658 if (validate(&dummyul_ptr, data, have_function) != 0) {
659 return NULL;
660 }
661
662 if (strlen(identifier) >= sizeof(dummyult.idname)) {
663 BKE_reportf(reports,
664 RPT_ERROR,
665 "Registering uilist class: '%s' is too long, maximum length is %d",
666 identifier,
667 (int)sizeof(dummyult.idname));
668 return NULL;
669 }
670
671 /* check if we have registered this uilist type before, and remove it */
672 ult = WM_uilisttype_find(dummyult.idname, true);
673 if (ult && ult->rna_ext.srna) {
674 rna_UIList_unregister(bmain, ult->rna_ext.srna);
675 }
676 if (!RNA_struct_available_or_report(reports, dummyult.idname)) {
677 return NULL;
678 }
679 if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) {
680 return NULL;
681 }
682
683 /* create a new menu type */
684 ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
685 memcpy(ult, &dummyult, sizeof(dummyult));
686
687 ult->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
688 ult->rna_ext.data = data;
689 ult->rna_ext.call = call;
690 ult->rna_ext.free = free;
691 RNA_struct_blender_type_set(ult->rna_ext.srna, ult);
692
693 ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
694 ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL;
695 ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL;
696
697 WM_uilisttype_add(ult);
698
699 /* update while blender is running */
700 WM_main_add_notifier(NC_WINDOW, NULL);
701
702 return ult->rna_ext.srna;
703 }
704
rna_UIList_refine(PointerRNA * ptr)705 static StructRNA *rna_UIList_refine(PointerRNA *ptr)
706 {
707 uiList *ui_list = (uiList *)ptr->data;
708 return (ui_list->type && ui_list->type->rna_ext.srna) ? ui_list->type->rna_ext.srna :
709 &RNA_UIList;
710 }
711
712 /* Header */
713
header_draw(const bContext * C,Header * hdr)714 static void header_draw(const bContext *C, Header *hdr)
715 {
716 extern FunctionRNA rna_Header_draw_func;
717
718 PointerRNA htr;
719 ParameterList list;
720 FunctionRNA *func;
721
722 RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->rna_ext.srna, hdr, &htr);
723 func = &rna_Header_draw_func; /* RNA_struct_find_function(&htr, "draw"); */
724
725 RNA_parameter_list_create(&list, &htr, func);
726 RNA_parameter_set_lookup(&list, "context", &C);
727 hdr->type->rna_ext.call((bContext *)C, &htr, func, &list);
728
729 RNA_parameter_list_free(&list);
730 }
731
rna_Header_unregister(Main * UNUSED (bmain),StructRNA * type)732 static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
733 {
734 ARegionType *art;
735 HeaderType *ht = RNA_struct_blender_type_get(type);
736
737 if (!ht) {
738 return;
739 }
740 if (!(art = region_type_find(NULL, ht->space_type, ht->region_type))) {
741 return;
742 }
743
744 RNA_struct_free_extension(type, &ht->rna_ext);
745 RNA_struct_free(&BLENDER_RNA, type);
746
747 BLI_freelinkN(&art->headertypes, ht);
748
749 /* update while blender is running */
750 WM_main_add_notifier(NC_WINDOW, NULL);
751 }
752
rna_Header_register(Main * bmain,ReportList * reports,void * data,const char * identifier,StructValidateFunc validate,StructCallbackFunc call,StructFreeFunc free)753 static StructRNA *rna_Header_register(Main *bmain,
754 ReportList *reports,
755 void *data,
756 const char *identifier,
757 StructValidateFunc validate,
758 StructCallbackFunc call,
759 StructFreeFunc free)
760 {
761 ARegionType *art;
762 HeaderType *ht, dummyht = {NULL};
763 Header dummyheader = {NULL};
764 PointerRNA dummyhtr;
765 int have_function[1];
766
767 /* setup dummy header & header type to store static properties in */
768 dummyheader.type = &dummyht;
769 dummyht.region_type = RGN_TYPE_HEADER; /* RGN_TYPE_HEADER by default, may be overridden */
770 RNA_pointer_create(NULL, &RNA_Header, &dummyheader, &dummyhtr);
771
772 /* validate the python class */
773 if (validate(&dummyhtr, data, have_function) != 0) {
774 return NULL;
775 }
776
777 if (strlen(identifier) >= sizeof(dummyht.idname)) {
778 BKE_reportf(reports,
779 RPT_ERROR,
780 "Registering header class: '%s' is too long, maximum length is %d",
781 identifier,
782 (int)sizeof(dummyht.idname));
783 return NULL;
784 }
785
786 if (!(art = region_type_find(reports, dummyht.space_type, dummyht.region_type))) {
787 return NULL;
788 }
789
790 /* check if we have registered this header type before, and remove it */
791 for (ht = art->headertypes.first; ht; ht = ht->next) {
792 if (STREQ(ht->idname, dummyht.idname)) {
793 if (ht->rna_ext.srna) {
794 rna_Header_unregister(bmain, ht->rna_ext.srna);
795 }
796 break;
797 }
798 }
799 if (!RNA_struct_available_or_report(reports, dummyht.idname)) {
800 return NULL;
801 }
802 if (!RNA_struct_bl_idname_ok_or_report(reports, dummyht.idname, "_HT_")) {
803 return NULL;
804 }
805
806 /* create a new header type */
807 ht = MEM_mallocN(sizeof(HeaderType), "python buttons header");
808 memcpy(ht, &dummyht, sizeof(dummyht));
809
810 ht->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
811 ht->rna_ext.data = data;
812 ht->rna_ext.call = call;
813 ht->rna_ext.free = free;
814 RNA_struct_blender_type_set(ht->rna_ext.srna, ht);
815
816 ht->draw = (have_function[0]) ? header_draw : NULL;
817
818 BLI_addtail(&art->headertypes, ht);
819
820 /* update while blender is running */
821 WM_main_add_notifier(NC_WINDOW, NULL);
822
823 return ht->rna_ext.srna;
824 }
825
rna_Header_refine(PointerRNA * htr)826 static StructRNA *rna_Header_refine(PointerRNA *htr)
827 {
828 Header *hdr = (Header *)htr->data;
829 return (hdr->type && hdr->type->rna_ext.srna) ? hdr->type->rna_ext.srna : &RNA_Header;
830 }
831
832 /* Menu */
833
menu_poll(const bContext * C,MenuType * pt)834 static bool menu_poll(const bContext *C, MenuType *pt)
835 {
836 extern FunctionRNA rna_Menu_poll_func;
837
838 PointerRNA ptr;
839 ParameterList list;
840 FunctionRNA *func;
841 void *ret;
842 bool visible;
843
844 RNA_pointer_create(NULL, pt->rna_ext.srna, NULL, &ptr); /* dummy */
845 func = &rna_Menu_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
846
847 RNA_parameter_list_create(&list, &ptr, func);
848 RNA_parameter_set_lookup(&list, "context", &C);
849 pt->rna_ext.call((bContext *)C, &ptr, func, &list);
850
851 RNA_parameter_get_lookup(&list, "visible", &ret);
852 visible = *(bool *)ret;
853
854 RNA_parameter_list_free(&list);
855
856 return visible;
857 }
858
menu_draw(const bContext * C,Menu * menu)859 static void menu_draw(const bContext *C, Menu *menu)
860 {
861 extern FunctionRNA rna_Menu_draw_func;
862
863 PointerRNA mtr;
864 ParameterList list;
865 FunctionRNA *func;
866
867 RNA_pointer_create(&CTX_wm_screen(C)->id, menu->type->rna_ext.srna, menu, &mtr);
868 func = &rna_Menu_draw_func; /* RNA_struct_find_function(&mtr, "draw"); */
869
870 RNA_parameter_list_create(&list, &mtr, func);
871 RNA_parameter_set_lookup(&list, "context", &C);
872 menu->type->rna_ext.call((bContext *)C, &mtr, func, &list);
873
874 RNA_parameter_list_free(&list);
875 }
876
rna_Menu_unregister(Main * UNUSED (bmain),StructRNA * type)877 static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
878 {
879 MenuType *mt = RNA_struct_blender_type_get(type);
880
881 if (!mt) {
882 return;
883 }
884
885 RNA_struct_free_extension(type, &mt->rna_ext);
886 RNA_struct_free(&BLENDER_RNA, type);
887
888 WM_menutype_freelink(mt);
889
890 /* update while blender is running */
891 WM_main_add_notifier(NC_WINDOW, NULL);
892 }
893
rna_Menu_register(Main * bmain,ReportList * reports,void * data,const char * identifier,StructValidateFunc validate,StructCallbackFunc call,StructFreeFunc free)894 static StructRNA *rna_Menu_register(Main *bmain,
895 ReportList *reports,
896 void *data,
897 const char *identifier,
898 StructValidateFunc validate,
899 StructCallbackFunc call,
900 StructFreeFunc free)
901 {
902 MenuType *mt, dummymt = {NULL};
903 Menu dummymenu = {NULL};
904 PointerRNA dummymtr;
905 int have_function[2];
906 size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
907 size_t description_size = 0;
908 char _menu_descr[RNA_DYN_DESCR_MAX];
909
910 /* setup dummy menu & menu type to store static properties in */
911 dummymenu.type = &dummymt;
912 _menu_descr[0] = '\0';
913 dummymenu.type->description = _menu_descr;
914 RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);
915
916 /* We have to set default context! Else we get a void string... */
917 strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
918
919 /* validate the python class */
920 if (validate(&dummymtr, data, have_function) != 0) {
921 return NULL;
922 }
923
924 if (strlen(identifier) >= sizeof(dummymt.idname)) {
925 BKE_reportf(reports,
926 RPT_ERROR,
927 "Registering menu class: '%s' is too long, maximum length is %d",
928 identifier,
929 (int)sizeof(dummymt.idname));
930 return NULL;
931 }
932
933 /* check if we have registered this menu type before, and remove it */
934 mt = WM_menutype_find(dummymt.idname, true);
935 if (mt && mt->rna_ext.srna) {
936 rna_Menu_unregister(bmain, mt->rna_ext.srna);
937 }
938 if (!RNA_struct_available_or_report(reports, dummymt.idname)) {
939 return NULL;
940 }
941 if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) {
942 return NULL;
943 }
944
945 /* create a new menu type */
946 if (_menu_descr[0]) {
947 description_size = strlen(_menu_descr) + 1;
948 over_alloc += description_size;
949 }
950
951 mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu");
952 memcpy(mt, &dummymt, sizeof(dummymt));
953
954 if (_menu_descr[0]) {
955 char *buf = (char *)(mt + 1);
956 memcpy(buf, _menu_descr, description_size);
957 mt->description = buf;
958 }
959 else {
960 mt->description = NULL;
961 }
962
963 mt->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
964 RNA_def_struct_translation_context(mt->rna_ext.srna, mt->translation_context);
965 mt->rna_ext.data = data;
966 mt->rna_ext.call = call;
967 mt->rna_ext.free = free;
968 RNA_struct_blender_type_set(mt->rna_ext.srna, mt);
969 RNA_def_struct_flag(mt->rna_ext.srna, STRUCT_NO_IDPROPERTIES);
970
971 mt->poll = (have_function[0]) ? menu_poll : NULL;
972 mt->draw = (have_function[1]) ? menu_draw : NULL;
973
974 {
975 const char *owner_id = RNA_struct_state_owner_get();
976 if (owner_id) {
977 BLI_strncpy(mt->owner_id, owner_id, sizeof(mt->owner_id));
978 }
979 }
980
981 WM_menutype_add(mt);
982
983 /* update while blender is running */
984 WM_main_add_notifier(NC_WINDOW, NULL);
985
986 return mt->rna_ext.srna;
987 }
988
rna_Menu_refine(PointerRNA * mtr)989 static StructRNA *rna_Menu_refine(PointerRNA *mtr)
990 {
991 Menu *menu = (Menu *)mtr->data;
992 return (menu->type && menu->type->rna_ext.srna) ? menu->type->rna_ext.srna : &RNA_Menu;
993 }
994
rna_Menu_bl_description_set(PointerRNA * ptr,const char * value)995 static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
996 {
997 Menu *data = (Menu *)(ptr->data);
998 char *str = (char *)data->type->description;
999 if (!str[0]) {
1000 BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */
1001 }
1002 else {
1003 BLI_assert(!"setting the bl_description on a non-builtin menu");
1004 }
1005 }
1006
1007 /* UILayout */
1008
rna_UILayout_active_get(PointerRNA * ptr)1009 static bool rna_UILayout_active_get(PointerRNA *ptr)
1010 {
1011 return uiLayoutGetActive(ptr->data);
1012 }
1013
rna_UILayout_active_set(PointerRNA * ptr,bool value)1014 static void rna_UILayout_active_set(PointerRNA *ptr, bool value)
1015 {
1016 uiLayoutSetActive(ptr->data, value);
1017 }
1018
rna_UILayout_active_default_get(PointerRNA * ptr)1019 static bool rna_UILayout_active_default_get(PointerRNA *ptr)
1020 {
1021 return uiLayoutGetActiveDefault(ptr->data);
1022 }
1023
rna_UILayout_active_default_set(PointerRNA * ptr,bool value)1024 static void rna_UILayout_active_default_set(PointerRNA *ptr, bool value)
1025 {
1026 uiLayoutSetActiveDefault(ptr->data, value);
1027 }
1028
rna_UILayout_activate_init_get(PointerRNA * ptr)1029 static bool rna_UILayout_activate_init_get(PointerRNA *ptr)
1030 {
1031 return uiLayoutGetActivateInit(ptr->data);
1032 }
1033
rna_UILayout_activate_init_set(PointerRNA * ptr,bool value)1034 static void rna_UILayout_activate_init_set(PointerRNA *ptr, bool value)
1035 {
1036 uiLayoutSetActivateInit(ptr->data, value);
1037 }
1038
rna_UILayout_alert_get(PointerRNA * ptr)1039 static bool rna_UILayout_alert_get(PointerRNA *ptr)
1040 {
1041 return uiLayoutGetRedAlert(ptr->data);
1042 }
1043
rna_UILayout_alert_set(PointerRNA * ptr,bool value)1044 static void rna_UILayout_alert_set(PointerRNA *ptr, bool value)
1045 {
1046 uiLayoutSetRedAlert(ptr->data, value);
1047 }
1048
rna_UILayout_op_context_set(PointerRNA * ptr,int value)1049 static void rna_UILayout_op_context_set(PointerRNA *ptr, int value)
1050 {
1051 uiLayoutSetOperatorContext(ptr->data, value);
1052 }
1053
rna_UILayout_op_context_get(PointerRNA * ptr)1054 static int rna_UILayout_op_context_get(PointerRNA *ptr)
1055 {
1056 return uiLayoutGetOperatorContext(ptr->data);
1057 }
1058
rna_UILayout_enabled_get(PointerRNA * ptr)1059 static bool rna_UILayout_enabled_get(PointerRNA *ptr)
1060 {
1061 return uiLayoutGetEnabled(ptr->data);
1062 }
1063
rna_UILayout_enabled_set(PointerRNA * ptr,bool value)1064 static void rna_UILayout_enabled_set(PointerRNA *ptr, bool value)
1065 {
1066 uiLayoutSetEnabled(ptr->data, value);
1067 }
1068
1069 # if 0
1070 static int rna_UILayout_red_alert_get(PointerRNA *ptr)
1071 {
1072 return uiLayoutGetRedAlert(ptr->data);
1073 }
1074
1075 static void rna_UILayout_red_alert_set(PointerRNA *ptr, bool value)
1076 {
1077 uiLayoutSetRedAlert(ptr->data, value);
1078 }
1079
1080 static bool rna_UILayout_keep_aspect_get(PointerRNA *ptr)
1081 {
1082 return uiLayoutGetKeepAspect(ptr->data);
1083 }
1084
1085 static void rna_UILayout_keep_aspect_set(PointerRNA *ptr, int value)
1086 {
1087 uiLayoutSetKeepAspect(ptr->data, value);
1088 }
1089 # endif
1090
rna_UILayout_alignment_get(PointerRNA * ptr)1091 static int rna_UILayout_alignment_get(PointerRNA *ptr)
1092 {
1093 return uiLayoutGetAlignment(ptr->data);
1094 }
1095
rna_UILayout_alignment_set(PointerRNA * ptr,int value)1096 static void rna_UILayout_alignment_set(PointerRNA *ptr, int value)
1097 {
1098 uiLayoutSetAlignment(ptr->data, value);
1099 }
1100
rna_UILayout_direction_get(PointerRNA * ptr)1101 static int rna_UILayout_direction_get(PointerRNA *ptr)
1102 {
1103 return uiLayoutGetLocalDir(ptr->data);
1104 }
1105
rna_UILayout_scale_x_get(PointerRNA * ptr)1106 static float rna_UILayout_scale_x_get(PointerRNA *ptr)
1107 {
1108 return uiLayoutGetScaleX(ptr->data);
1109 }
1110
rna_UILayout_scale_x_set(PointerRNA * ptr,float value)1111 static void rna_UILayout_scale_x_set(PointerRNA *ptr, float value)
1112 {
1113 uiLayoutSetScaleX(ptr->data, value);
1114 }
1115
rna_UILayout_scale_y_get(PointerRNA * ptr)1116 static float rna_UILayout_scale_y_get(PointerRNA *ptr)
1117 {
1118 return uiLayoutGetScaleY(ptr->data);
1119 }
1120
rna_UILayout_scale_y_set(PointerRNA * ptr,float value)1121 static void rna_UILayout_scale_y_set(PointerRNA *ptr, float value)
1122 {
1123 uiLayoutSetScaleY(ptr->data, value);
1124 }
1125
rna_UILayout_units_x_get(PointerRNA * ptr)1126 static float rna_UILayout_units_x_get(PointerRNA *ptr)
1127 {
1128 return uiLayoutGetUnitsX(ptr->data);
1129 }
1130
rna_UILayout_units_x_set(PointerRNA * ptr,float value)1131 static void rna_UILayout_units_x_set(PointerRNA *ptr, float value)
1132 {
1133 uiLayoutSetUnitsX(ptr->data, value);
1134 }
1135
rna_UILayout_units_y_get(PointerRNA * ptr)1136 static float rna_UILayout_units_y_get(PointerRNA *ptr)
1137 {
1138 return uiLayoutGetUnitsY(ptr->data);
1139 }
1140
rna_UILayout_units_y_set(PointerRNA * ptr,float value)1141 static void rna_UILayout_units_y_set(PointerRNA *ptr, float value)
1142 {
1143 uiLayoutSetUnitsY(ptr->data, value);
1144 }
1145
rna_UILayout_emboss_get(PointerRNA * ptr)1146 static int rna_UILayout_emboss_get(PointerRNA *ptr)
1147 {
1148 return uiLayoutGetEmboss(ptr->data);
1149 }
1150
rna_UILayout_emboss_set(PointerRNA * ptr,int value)1151 static void rna_UILayout_emboss_set(PointerRNA *ptr, int value)
1152 {
1153 uiLayoutSetEmboss(ptr->data, value);
1154 }
1155
rna_UILayout_property_split_get(PointerRNA * ptr)1156 static bool rna_UILayout_property_split_get(PointerRNA *ptr)
1157 {
1158 return uiLayoutGetPropSep(ptr->data);
1159 }
1160
rna_UILayout_property_split_set(PointerRNA * ptr,bool value)1161 static void rna_UILayout_property_split_set(PointerRNA *ptr, bool value)
1162 {
1163 uiLayoutSetPropSep(ptr->data, value);
1164 }
1165
rna_UILayout_property_decorate_get(PointerRNA * ptr)1166 static bool rna_UILayout_property_decorate_get(PointerRNA *ptr)
1167 {
1168 return uiLayoutGetPropDecorate(ptr->data);
1169 }
1170
rna_UILayout_property_decorate_set(PointerRNA * ptr,bool value)1171 static void rna_UILayout_property_decorate_set(PointerRNA *ptr, bool value)
1172 {
1173 uiLayoutSetPropDecorate(ptr->data, value);
1174 }
1175
1176 #else /* RNA_RUNTIME */
1177
rna_def_ui_layout(BlenderRNA * brna)1178 static void rna_def_ui_layout(BlenderRNA *brna)
1179 {
1180 StructRNA *srna;
1181 PropertyRNA *prop;
1182
1183 static const EnumPropertyItem alignment_items[] = {
1184 {UI_LAYOUT_ALIGN_EXPAND, "EXPAND", 0, "Expand", ""},
1185 {UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
1186 {UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
1187 {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
1188 {0, NULL, 0, NULL, NULL},
1189 };
1190
1191 static const EnumPropertyItem direction_items[] = {
1192 {UI_LAYOUT_HORIZONTAL, "HORIZONTAL", 0, "Horizontal", ""},
1193 {UI_LAYOUT_VERTICAL, "VERTICAL", 0, "Vertical", ""},
1194 {0, NULL, 0, NULL, NULL},
1195 };
1196
1197 static const EnumPropertyItem emboss_items[] = {
1198 {UI_EMBOSS, "NORMAL", 0, "Regular", "Draw standard button emboss style"},
1199 {UI_EMBOSS_NONE, "NONE", 0, "None", "Draw only text and icons"},
1200 {UI_EMBOSS_PULLDOWN, "PULLDOWN_MENU", 0, "Pulldown Menu", "Draw pulldown menu style"},
1201 {UI_EMBOSS_RADIAL, "RADIAL_MENU", 0, "Radial Menu", "Draw radial menu style"},
1202 {0, NULL, 0, NULL, NULL},
1203 };
1204
1205 /* layout */
1206
1207 srna = RNA_def_struct(brna, "UILayout", NULL);
1208 RNA_def_struct_sdna(srna, "uiLayout");
1209 RNA_def_struct_ui_text(srna, "UI Layout", "User interface layout in a panel or header");
1210
1211 prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
1212 RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
1213
1214 prop = RNA_def_property(srna, "active_default", PROP_BOOLEAN, PROP_NONE);
1215 RNA_def_property_boolean_funcs(
1216 prop, "rna_UILayout_active_default_get", "rna_UILayout_active_default_set");
1217 RNA_def_property_ui_text(
1218 prop,
1219 "Active Default",
1220 "When true, an operator button defined after this will be activated when pressing return"
1221 "(use with popup dialogs)");
1222
1223 prop = RNA_def_property(srna, "activate_init", PROP_BOOLEAN, PROP_NONE);
1224 RNA_def_property_boolean_funcs(
1225 prop, "rna_UILayout_activate_init_get", "rna_UILayout_activate_init_set");
1226 RNA_def_property_ui_text(
1227 prop,
1228 "Activate on Init",
1229 "When true, buttons defined in popups will be activated on first display "
1230 "(use so you can type into a field without having to click on it first)");
1231
1232 prop = RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
1233 RNA_def_property_enum_items(prop, rna_enum_operator_context_items);
1234 RNA_def_property_enum_funcs(
1235 prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
1236
1237 prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
1238 RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
1239 RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is grayed out");
1240
1241 prop = RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
1242 RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
1243
1244 prop = RNA_def_property(srna, "alignment", PROP_ENUM, PROP_NONE);
1245 RNA_def_property_enum_items(prop, alignment_items);
1246 RNA_def_property_enum_funcs(
1247 prop, "rna_UILayout_alignment_get", "rna_UILayout_alignment_set", NULL);
1248
1249 prop = RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE);
1250 RNA_def_property_enum_items(prop, direction_items);
1251 RNA_def_property_enum_funcs(prop, "rna_UILayout_direction_get", NULL, NULL);
1252 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1253
1254 # if 0
1255 prop = RNA_def_property(srna, "keep_aspect", PROP_BOOLEAN, PROP_NONE);
1256 RNA_def_property_boolean_funcs(
1257 prop, "rna_UILayout_keep_aspect_get", "rna_UILayout_keep_aspect_set");
1258 # endif
1259
1260 prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
1261 RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
1262 RNA_def_property_ui_text(
1263 prop, "Scale X", "Scale factor along the X for items in this (sub)layout");
1264
1265 prop = RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
1266 RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
1267 RNA_def_property_ui_text(
1268 prop, "Scale Y", "Scale factor along the Y for items in this (sub)layout");
1269
1270 prop = RNA_def_property(srna, "ui_units_x", PROP_FLOAT, PROP_UNSIGNED);
1271 RNA_def_property_float_funcs(prop, "rna_UILayout_units_x_get", "rna_UILayout_units_x_set", NULL);
1272 RNA_def_property_ui_text(
1273 prop, "Units X", "Fixed Size along the X for items in this (sub)layout");
1274
1275 prop = RNA_def_property(srna, "ui_units_y", PROP_FLOAT, PROP_UNSIGNED);
1276 RNA_def_property_float_funcs(prop, "rna_UILayout_units_y_get", "rna_UILayout_units_y_set", NULL);
1277 RNA_def_property_ui_text(
1278 prop, "Units Y", "Fixed Size along the Y for items in this (sub)layout");
1279 RNA_api_ui_layout(srna);
1280
1281 prop = RNA_def_property(srna, "emboss", PROP_ENUM, PROP_NONE);
1282 RNA_def_property_enum_items(prop, emboss_items);
1283 RNA_def_property_enum_funcs(prop, "rna_UILayout_emboss_get", "rna_UILayout_emboss_set", NULL);
1284
1285 prop = RNA_def_property(srna, "use_property_split", PROP_BOOLEAN, PROP_NONE);
1286 RNA_def_property_boolean_funcs(
1287 prop, "rna_UILayout_property_split_get", "rna_UILayout_property_split_set");
1288
1289 prop = RNA_def_property(srna, "use_property_decorate", PROP_BOOLEAN, PROP_NONE);
1290 RNA_def_property_boolean_funcs(
1291 prop, "rna_UILayout_property_decorate_get", "rna_UILayout_property_decorate_set");
1292 }
1293
rna_def_panel(BlenderRNA * brna)1294 static void rna_def_panel(BlenderRNA *brna)
1295 {
1296 StructRNA *srna;
1297 PropertyRNA *prop;
1298 PropertyRNA *parm;
1299 FunctionRNA *func;
1300
1301 static const EnumPropertyItem panel_flag_items[] = {
1302 {PNL_DEFAULT_CLOSED,
1303 "DEFAULT_CLOSED",
1304 0,
1305 "Default Closed",
1306 "Defines if the panel has to be open or collapsed at the time of its creation"},
1307 {PNL_NO_HEADER,
1308 "HIDE_HEADER",
1309 0,
1310 "Hide Header",
1311 "If set to False, the panel shows a header, which contains a clickable "
1312 "arrow to collapse the panel and the label (see bl_label)"},
1313 {PNL_INSTANCED,
1314 "INSTANCED",
1315 0,
1316 "Instanced Panel",
1317 "Multiple panels with this type can be used as part of a list depending on data external "
1318 "to the UI. Used to create panels for the modifiers and other stacks"},
1319 {PNL_LAYOUT_HEADER_EXPAND,
1320 "HEADER_LAYOUT_EXPAND",
1321 0,
1322 "Expand Header Layout",
1323 "Allow buttons in the header to stretch and shrink to fill the entire layout width"},
1324 {PNL_DRAW_BOX, "DRAW_BOX", 0, "Box Style", "Draw panel with the box widget theme"},
1325 {0, NULL, 0, NULL, NULL},
1326 };
1327
1328 srna = RNA_def_struct(brna, "Panel", NULL);
1329 RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
1330 RNA_def_struct_sdna(srna, "Panel");
1331 RNA_def_struct_refine_func(srna, "rna_Panel_refine");
1332 RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
1333 RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1334 RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
1335
1336 /* poll */
1337 func = RNA_def_function(srna, "poll", NULL);
1338 RNA_def_function_ui_description(
1339 func, "If this method returns a non-null output, then the panel can be drawn");
1340 RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
1341 RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
1342 parm = RNA_def_pointer(func, "context", "Context", "", "");
1343 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1344
1345 /* draw */
1346 func = RNA_def_function(srna, "draw", NULL);
1347 RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout");
1348 RNA_def_function_flag(func, FUNC_REGISTER);
1349 parm = RNA_def_pointer(func, "context", "Context", "", "");
1350 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1351
1352 func = RNA_def_function(srna, "draw_header", NULL);
1353 RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout");
1354 RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1355 parm = RNA_def_pointer(func, "context", "Context", "", "");
1356 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1357
1358 func = RNA_def_function(srna, "draw_header_preset", NULL);
1359 RNA_def_function_ui_description(func, "Draw UI elements for presets in the panel's header");
1360 RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1361 parm = RNA_def_pointer(func, "context", "Context", "", "");
1362 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1363
1364 prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
1365 RNA_def_property_struct_type(prop, "UILayout");
1366 RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI");
1367
1368 prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
1369 RNA_def_property_string_sdna(prop, NULL, "drawname");
1370 RNA_def_property_ui_text(prop, "Text", "XXX todo");
1371
1372 prop = RNA_def_property(srna, "custom_data", PROP_POINTER, PROP_NONE);
1373 RNA_def_property_struct_type(prop, "Constraint");
1374 RNA_def_property_pointer_sdna(prop, NULL, "runtime.custom_data_ptr");
1375 RNA_def_property_pointer_funcs(
1376 prop, "rna_Panel_custom_data_get", NULL, "rna_Panel_custom_data_typef", NULL);
1377 RNA_def_property_ui_text(prop, "Custom Data", "Panel Data");
1378 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1379
1380 /* registration */
1381 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1382 RNA_def_property_string_sdna(prop, NULL, "type->idname");
1383 RNA_def_property_flag(prop, PROP_REGISTER);
1384 RNA_def_property_ui_text(prop,
1385 "ID Name",
1386 "If this is set, the panel gets a custom ID, otherwise it takes the "
1387 "name of the class used to define the panel. For example, if the "
1388 "class name is \"OBJECT_PT_hello\", and bl_idname is not set by the "
1389 "script, then bl_idname = \"OBJECT_PT_hello\"");
1390
1391 prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1392 RNA_def_property_string_sdna(prop, NULL, "type->label");
1393 RNA_def_property_flag(prop, PROP_REGISTER);
1394 RNA_def_property_ui_text(prop,
1395 "Label",
1396 "The panel label, shows up in the panel header at the right of the "
1397 "triangle used to collapse the panel");
1398
1399 prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
1400 RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
1401 RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1402 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1403 RNA_define_verify_sdna(true);
1404
1405 prop = RNA_def_property(srna, "bl_category", PROP_STRING, PROP_NONE);
1406 RNA_def_property_string_sdna(prop, NULL, "type->category");
1407 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1408
1409 prop = RNA_def_property(srna, "bl_owner_id", PROP_STRING, PROP_NONE);
1410 RNA_def_property_string_sdna(prop, NULL, "type->owner_id");
1411 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1412
1413 prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
1414 RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
1415 RNA_def_property_enum_items(prop, rna_enum_space_type_items);
1416 RNA_def_property_flag(prop, PROP_REGISTER);
1417 RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
1418
1419 prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
1420 RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
1421 RNA_def_property_enum_items(prop, rna_enum_region_type_items);
1422 RNA_def_property_flag(prop, PROP_REGISTER);
1423 RNA_def_property_ui_text(
1424 prop, "Region Type", "The region where the panel is going to be used in");
1425
1426 prop = RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
1427 RNA_def_property_string_sdna(prop, NULL, "type->context");
1428 RNA_def_property_flag(
1429 prop, PROP_REGISTER_OPTIONAL); /* Only used in Properties Editor and 3D View - Thomas */
1430 RNA_def_property_ui_text(prop,
1431 "Context",
1432 "The context in which the panel belongs to. (TODO: explain the "
1433 "possible combinations bl_context/bl_region_type/bl_space_type)");
1434
1435 prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
1436 RNA_def_property_enum_sdna(prop, NULL, "type->flag");
1437 RNA_def_property_enum_items(prop, panel_flag_items);
1438 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
1439 RNA_def_property_ui_text(prop, "Options", "Options for this panel type");
1440
1441 prop = RNA_def_property(srna, "bl_parent_id", PROP_STRING, PROP_NONE);
1442 RNA_def_property_string_sdna(prop, NULL, "type->parent_id");
1443 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1444 RNA_def_property_ui_text(
1445 prop, "Parent ID Name", "If this is set, the panel becomes a sub-panel");
1446
1447 prop = RNA_def_property(srna, "bl_ui_units_x", PROP_INT, PROP_UNSIGNED);
1448 RNA_def_property_int_sdna(prop, NULL, "type->ui_units_x");
1449 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1450 RNA_def_property_ui_text(prop, "Units X", "When set, defines popup panel width");
1451
1452 prop = RNA_def_property(srna, "bl_order", PROP_INT, PROP_UNSIGNED);
1453 RNA_def_property_int_sdna(prop, NULL, "type->order");
1454 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1455 RNA_def_property_ui_text(
1456 prop,
1457 "Order",
1458 "Panels with lower numbers are default ordered before panels with higher numbers");
1459
1460 prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
1461 RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN);
1462 RNA_def_property_ui_text(prop, "Pin", "Show the panel on all tabs");
1463 /* XXX, should only tag region for redraw */
1464 RNA_def_property_update(prop, NC_WINDOW, NULL);
1465
1466 prop = RNA_def_property(srna, "is_popover", PROP_BOOLEAN, PROP_NONE);
1467 RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_POPOVER);
1468 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1469 RNA_def_property_ui_text(prop, "Popover", "");
1470 }
1471
rna_def_uilist(BlenderRNA * brna)1472 static void rna_def_uilist(BlenderRNA *brna)
1473 {
1474 StructRNA *srna;
1475 PropertyRNA *prop;
1476 PropertyRNA *parm;
1477 FunctionRNA *func;
1478
1479 srna = RNA_def_struct(brna, "UIList", NULL);
1480 RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection");
1481 RNA_def_struct_sdna(srna, "uiList");
1482 RNA_def_struct_refine_func(srna, "rna_UIList_refine");
1483 RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
1484 RNA_def_struct_idprops_func(srna, "rna_UIList_idprops");
1485 RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_PUBLIC_NAMESPACE_INHERIT);
1486
1487 /* Registration */
1488 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1489 RNA_def_property_string_sdna(prop, NULL, "type->idname");
1490 RNA_def_property_flag(prop, PROP_REGISTER);
1491 RNA_def_property_ui_text(prop,
1492 "ID Name",
1493 "If this is set, the uilist gets a custom ID, otherwise it takes the "
1494 "name of the class used to define the uilist (for example, if the "
1495 "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the "
1496 "script, then bl_idname = \"OBJECT_UL_vgroups\")");
1497
1498 /* Data */
1499 prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE);
1500 RNA_def_property_enum_items(prop, rna_enum_uilist_layout_type_items);
1501 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1502
1503 /* Filter options */
1504 prop = RNA_def_property(srna, "use_filter_show", PROP_BOOLEAN, PROP_NONE);
1505 RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_SHOW);
1506 RNA_def_property_ui_text(prop, "Show Filter", "Show filtering options");
1507
1508 prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE);
1509 RNA_def_property_string_sdna(prop, NULL, "filter_byname");
1510 RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
1511 RNA_def_property_ui_text(
1512 prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)");
1513
1514 prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE);
1515 RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_EXCLUDE);
1516 RNA_def_property_ui_text(prop, "Invert", "Invert filtering (show hidden items, and vice-versa)");
1517
1518 /* WARNING: This is sort of an abuse, sort-by-alpha is actually a value,
1519 * should even be an enum in full logic (of two values, sort by index and sort by name).
1520 * But for default UIList, it's nicer (better UI-wise) to show this as a boolean bit-flag option,
1521 * avoids having to define custom setters/getters using UILST_FLT_SORT_MASK to mask out
1522 * actual bitflags on same var, etc.
1523 */
1524 prop = RNA_def_property(srna, "use_filter_sort_alpha", PROP_BOOLEAN, PROP_NONE);
1525 RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_ALPHA);
1526 RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
1527 RNA_def_property_ui_text(prop, "Sort by Name", "Sort items by their name");
1528
1529 prop = RNA_def_property(srna, "use_filter_sort_reverse", PROP_BOOLEAN, PROP_NONE);
1530 RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_REVERSE);
1531 RNA_def_property_ui_text(prop, "Reverse", "Reverse the order of shown items");
1532
1533 prop = RNA_def_property(srna, "use_filter_sort_lock", PROP_BOOLEAN, PROP_NONE);
1534 RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_LOCK);
1535 RNA_def_property_ui_text(
1536 prop, "Lock Order", "Lock the order of shown items (user cannot change it)");
1537
1538 /* draw_item */
1539 func = RNA_def_function(srna, "draw_item", NULL);
1540 RNA_def_function_ui_description(
1541 func,
1542 "Draw an item in the list (NOTE: when you define your own draw_item "
1543 "function, you may want to check given 'item' is of the right type...)");
1544 RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1545 parm = RNA_def_pointer(func, "context", "Context", "", "");
1546 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1547 parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
1548 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1549 parm = RNA_def_pointer(
1550 func, "data", "AnyType", "", "Data from which to take Collection property");
1551 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1552 parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property");
1553 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1554 parm = RNA_def_int(
1555 func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX);
1556 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1557 parm = RNA_def_pointer(func,
1558 "active_data",
1559 "AnyType",
1560 "",
1561 "Data from which to take property for the active element");
1562 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1563 parm = RNA_def_string(func,
1564 "active_property",
1565 NULL,
1566 0,
1567 "",
1568 "Identifier of property in active_data, for the active element");
1569 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1570 RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX);
1571 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
1572 prop = RNA_def_property(func, "flt_flag", PROP_INT, PROP_UNSIGNED);
1573 RNA_def_property_ui_text(prop, "", "The filter-flag result for this item");
1574 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
1575
1576 /* draw_filter */
1577 func = RNA_def_function(srna, "draw_filter", NULL);
1578 RNA_def_function_ui_description(func, "Draw filtering options");
1579 RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1580 parm = RNA_def_pointer(func, "context", "Context", "", "");
1581 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1582 parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
1583 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1584
1585 /* filter */
1586 func = RNA_def_function(srna, "filter_items", NULL);
1587 RNA_def_function_ui_description(
1588 func,
1589 "Filter and/or re-order items of the collection (output filter results in "
1590 "filter_flags, and reorder results in filter_neworder arrays)");
1591 RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
1592 parm = RNA_def_pointer(func, "context", "Context", "", "");
1593 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1594 parm = RNA_def_pointer(
1595 func, "data", "AnyType", "", "Data from which to take Collection property");
1596 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
1597 parm = RNA_def_string(
1598 func, "property", NULL, 0, "", "Identifier of property in data, for the collection");
1599 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1600 prop = RNA_def_property(func, "filter_flags", PROP_INT, PROP_UNSIGNED);
1601 RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
1602 RNA_def_property_array(prop, 1); /* XXX Dummy value, default 0 does not work */
1603 RNA_def_property_ui_text(
1604 prop,
1605 "",
1606 "An array of filter flags, one for each item in the collection (NOTE: "
1607 "FILTER_ITEM bit is reserved, it defines whether the item is shown or not)");
1608 RNA_def_function_output(func, prop);
1609 prop = RNA_def_property(func, "filter_neworder", PROP_INT, PROP_UNSIGNED);
1610 RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
1611 RNA_def_property_array(prop, 1); /* XXX Dummy value, default 0 does not work */
1612 RNA_def_property_ui_text(
1613 prop,
1614 "",
1615 "An array of indices, one for each item in the collection, mapping the org "
1616 "index to the new one");
1617 RNA_def_function_output(func, prop);
1618
1619 /* "Constants"! */
1620 RNA_define_verify_sdna(0); /* not in sdna */
1621
1622 prop = RNA_def_property(srna, "bitflag_filter_item", PROP_INT, PROP_UNSIGNED);
1623 RNA_def_property_ui_text(
1624 prop,
1625 "FILTER_ITEM",
1626 "The value of the reserved bitflag 'FILTER_ITEM' (in filter_flags values)");
1627 RNA_def_property_int_funcs(prop, "rna_UIList_filter_const_FILTER_ITEM_get", NULL, NULL);
1628 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1629 }
1630
rna_def_header(BlenderRNA * brna)1631 static void rna_def_header(BlenderRNA *brna)
1632 {
1633 StructRNA *srna;
1634 PropertyRNA *prop;
1635 PropertyRNA *parm;
1636 FunctionRNA *func;
1637
1638 srna = RNA_def_struct(brna, "Header", NULL);
1639 RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements");
1640 RNA_def_struct_sdna(srna, "Header");
1641 RNA_def_struct_refine_func(srna, "rna_Header_refine");
1642 RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL);
1643 RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
1644
1645 /* draw */
1646 func = RNA_def_function(srna, "draw", NULL);
1647 RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout");
1648 RNA_def_function_flag(func, FUNC_REGISTER);
1649 parm = RNA_def_pointer(func, "context", "Context", "", "");
1650 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1651
1652 RNA_define_verify_sdna(0); /* not in sdna */
1653
1654 prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
1655 RNA_def_property_pointer_sdna(prop, NULL, "layout");
1656 RNA_def_property_struct_type(prop, "UILayout");
1657 RNA_def_property_ui_text(prop, "Layout", "Structure of the header in the UI");
1658
1659 /* registration */
1660 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1661 RNA_def_property_string_sdna(prop, NULL, "type->idname");
1662 RNA_def_property_flag(prop, PROP_REGISTER);
1663 RNA_def_property_ui_text(prop,
1664 "ID Name",
1665 "If this is set, the header gets a custom ID, otherwise it takes the "
1666 "name of the class used to define the panel; for example, if the "
1667 "class name is \"OBJECT_HT_hello\", and bl_idname is not set by the "
1668 "script, then bl_idname = \"OBJECT_HT_hello\"");
1669
1670 prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
1671 RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
1672 RNA_def_property_enum_items(prop, rna_enum_space_type_items);
1673 RNA_def_property_flag(prop, PROP_REGISTER);
1674 RNA_def_property_ui_text(
1675 prop, "Space type", "The space where the header is going to be used in");
1676
1677 prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
1678 RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
1679 RNA_def_property_enum_default(prop, RGN_TYPE_HEADER);
1680 RNA_def_property_enum_items(prop, rna_enum_region_type_items);
1681 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1682 RNA_def_property_ui_text(prop,
1683 "Region Type",
1684 "The region where the header is going to be used in "
1685 "(defaults to header region)");
1686
1687 RNA_define_verify_sdna(1);
1688 }
1689
rna_def_menu(BlenderRNA * brna)1690 static void rna_def_menu(BlenderRNA *brna)
1691 {
1692 StructRNA *srna;
1693 PropertyRNA *prop;
1694 PropertyRNA *parm;
1695 FunctionRNA *func;
1696
1697 srna = RNA_def_struct(brna, "Menu", NULL);
1698 RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
1699 RNA_def_struct_sdna(srna, "Menu");
1700 RNA_def_struct_refine_func(srna, "rna_Menu_refine");
1701 RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
1702 RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1703 RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
1704
1705 /* poll */
1706 func = RNA_def_function(srna, "poll", NULL);
1707 RNA_def_function_ui_description(
1708 func, "If this method returns a non-null output, then the menu can be drawn");
1709 RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
1710 RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
1711 parm = RNA_def_pointer(func, "context", "Context", "", "");
1712 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1713
1714 /* draw */
1715 func = RNA_def_function(srna, "draw", NULL);
1716 RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout");
1717 RNA_def_function_flag(func, FUNC_REGISTER);
1718 parm = RNA_def_pointer(func, "context", "Context", "", "");
1719 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1720
1721 RNA_define_verify_sdna(false); /* not in sdna */
1722
1723 prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
1724 RNA_def_property_pointer_sdna(prop, NULL, "layout");
1725 RNA_def_property_struct_type(prop, "UILayout");
1726 RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the menu in the UI");
1727
1728 /* registration */
1729 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1730 RNA_def_property_string_sdna(prop, NULL, "type->idname");
1731 RNA_def_property_flag(prop, PROP_REGISTER);
1732 RNA_def_property_ui_text(prop,
1733 "ID Name",
1734 "If this is set, the menu gets a custom ID, otherwise it takes the "
1735 "name of the class used to define the menu (for example, if the "
1736 "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
1737 "script, then bl_idname = \"OBJECT_MT_hello\")");
1738
1739 prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1740 RNA_def_property_string_sdna(prop, NULL, "type->label");
1741 RNA_def_property_flag(prop, PROP_REGISTER);
1742 RNA_def_property_ui_text(prop, "Label", "The menu label");
1743
1744 prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
1745 RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
1746 RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
1747 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1748
1749 prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
1750 RNA_def_property_string_sdna(prop, NULL, "type->description");
1751 RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
1752 RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
1753 /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
1754 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1755 RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
1756
1757 prop = RNA_def_property(srna, "bl_owner_id", PROP_STRING, PROP_NONE);
1758 RNA_def_property_string_sdna(prop, NULL, "type->owner_id");
1759 RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
1760
1761 RNA_define_verify_sdna(1);
1762 }
1763
RNA_def_ui(BlenderRNA * brna)1764 void RNA_def_ui(BlenderRNA *brna)
1765 {
1766 rna_def_ui_layout(brna);
1767 rna_def_panel(brna);
1768 rna_def_uilist(brna);
1769 rna_def_header(brna);
1770 rna_def_menu(brna);
1771 }
1772
1773 #endif /* RNA_RUNTIME */
1774