4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation (2008).
25 * ***** END GPL LICENSE BLOCK *****
28 #include "MEM_guardedalloc.h"
30 #include "DNA_scene_types.h"
31 #include "DNA_screen_types.h"
32 #include "DNA_space_types.h"
33 #include "DNA_view3d_types.h"
34 #include "DNA_windowmanager_types.h"
35 #include "DNA_object_types.h"
37 #include "RNA_access.h"
39 #include "BLI_listbase.h"
40 #include "BLI_string.h"
42 #include "BKE_context.h"
44 #include "BKE_screen.h"
46 #ifndef DISABLE_PYTHON
47 #include "BPY_extern.h"
57 /* windowmanager context */
59 struct wmWindowManager *manager;
60 struct wmWindow *window;
61 struct bScreen *screen;
63 struct ARegion *region;
65 struct bContextStore *store;
74 int py_init; /* true if python is initialized */
86 bContext *CTX_create()
90 C= MEM_callocN(sizeof(bContext), "bContext");
95 bContext *CTX_copy(const bContext *C)
97 bContext *newC= MEM_dupallocN((void*)C);
102 void CTX_free(bContext *C)
109 bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr)
111 bContextStoreEntry *entry;
112 bContextStore *ctx, *lastctx;
114 /* ensure we have a context to put the entry in, if it was already used
115 * we have to copy the context to ensure */
118 if(!ctx || ctx->used) {
121 ctx= MEM_dupallocN(lastctx);
122 BLI_duplicatelist(&ctx->entries, &lastctx->entries);
125 ctx= MEM_callocN(sizeof(bContextStore), "bContextStore");
127 BLI_addtail(contexts, ctx);
130 entry= MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
131 BLI_strncpy(entry->name, name, sizeof(entry->name));
134 BLI_addtail(&ctx->entries, entry);
139 void CTX_store_set(bContext *C, bContextStore *store)
144 bContextStore *CTX_store_copy(bContextStore *store)
148 ctx= MEM_dupallocN(store);
149 BLI_duplicatelist(&ctx->entries, &store->entries);
154 void CTX_store_free(bContextStore *store)
156 BLI_freelistN(&store->entries);
160 void CTX_store_free_list(ListBase *contexts)
164 while((ctx= contexts->first)) {
165 BLI_remlink(contexts, ctx);
170 /* is python initialied? */
171 int CTX_py_init_get(bContext *C)
173 return C->data.py_init;
175 void CTX_py_init_set(bContext *C, int value)
177 C->data.py_init= value;
180 void *CTX_py_dict_get(bContext *C)
182 return C->data.py_context;
184 void CTX_py_dict_set(bContext *C, void *value)
186 C->data.py_context= value;
189 /* window manager context */
191 wmWindowManager *CTX_wm_manager(const bContext *C)
193 return C->wm.manager;
196 wmWindow *CTX_wm_window(const bContext *C)
201 bScreen *CTX_wm_screen(const bContext *C)
206 ScrArea *CTX_wm_area(const bContext *C)
211 SpaceLink *CTX_wm_space_data(const bContext *C)
213 return (C->wm.area)? C->wm.area->spacedata.first: NULL;
216 ARegion *CTX_wm_region(const bContext *C)
221 void *CTX_wm_region_data(const bContext *C)
223 return (C->wm.region)? C->wm.region->regiondata: NULL;
226 struct ARegion *CTX_wm_menu(const bContext *C)
231 struct ReportList *CTX_wm_reports(const bContext *C)
234 return &(C->wm.manager->reports);
239 View3D *CTX_wm_view3d(const bContext *C)
241 if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
242 return C->wm.area->spacedata.first;
246 RegionView3D *CTX_wm_region_view3d(const bContext *C)
248 if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
250 return C->wm.region->regiondata;
254 struct SpaceText *CTX_wm_space_text(const bContext *C)
256 if(C->wm.area && C->wm.area->spacetype==SPACE_TEXT)
257 return C->wm.area->spacedata.first;
261 struct SpaceConsole *CTX_wm_space_console(const bContext *C)
263 if(C->wm.area && C->wm.area->spacetype==SPACE_CONSOLE)
264 return C->wm.area->spacedata.first;
268 struct SpaceImage *CTX_wm_space_image(const bContext *C)
270 if(C->wm.area && C->wm.area->spacetype==SPACE_IMAGE)
271 return C->wm.area->spacedata.first;
275 struct SpaceButs *CTX_wm_space_buts(const bContext *C)
277 if(C->wm.area && C->wm.area->spacetype==SPACE_BUTS)
278 return C->wm.area->spacedata.first;
282 struct SpaceFile *CTX_wm_space_file(const bContext *C)
284 if(C->wm.area && C->wm.area->spacetype==SPACE_FILE)
285 return C->wm.area->spacedata.first;
289 struct SpaceSeq *CTX_wm_space_seq(const bContext *C)
291 if(C->wm.area && C->wm.area->spacetype==SPACE_SEQ)
292 return C->wm.area->spacedata.first;
296 struct SpaceOops *CTX_wm_space_outliner(const bContext *C)
298 if(C->wm.area && C->wm.area->spacetype==SPACE_OUTLINER)
299 return C->wm.area->spacedata.first;
303 struct SpaceNla *CTX_wm_space_nla(const bContext *C)
305 if(C->wm.area && C->wm.area->spacetype==SPACE_NLA)
306 return C->wm.area->spacedata.first;
310 struct SpaceTime *CTX_wm_space_time(const bContext *C)
312 if(C->wm.area && C->wm.area->spacetype==SPACE_TIME)
313 return C->wm.area->spacedata.first;
317 struct SpaceNode *CTX_wm_space_node(const bContext *C)
319 if(C->wm.area && C->wm.area->spacetype==SPACE_NODE)
320 return C->wm.area->spacedata.first;
324 struct SpaceLogic *CTX_wm_space_logic(const bContext *C)
326 if(C->wm.area && C->wm.area->spacetype==SPACE_LOGIC)
327 return C->wm.area->spacedata.first;
331 struct SpaceIpo *CTX_wm_space_graph(const bContext *C)
333 if(C->wm.area && C->wm.area->spacetype==SPACE_IPO)
334 return C->wm.area->spacedata.first;
338 struct SpaceAction *CTX_wm_space_action(const bContext *C)
340 if(C->wm.area && C->wm.area->spacetype==SPACE_ACTION)
341 return C->wm.area->spacedata.first;
345 struct SpaceInfo *CTX_wm_space_info(const bContext *C)
347 if(C->wm.area && C->wm.area->spacetype==SPACE_INFO)
348 return C->wm.area->spacedata.first;
352 struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
354 if(C->wm.area && C->wm.area->spacetype==SPACE_USERPREF)
355 return C->wm.area->spacedata.first;
359 void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
368 void CTX_wm_window_set(bContext *C, wmWindow *win)
371 C->wm.screen= (win)? win->screen: NULL;
372 C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
377 void CTX_wm_screen_set(bContext *C, bScreen *screen)
379 C->wm.screen= screen;
380 C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
385 void CTX_wm_area_set(bContext *C, ScrArea *area)
391 void CTX_wm_region_set(bContext *C, ARegion *region)
393 C->wm.region= region;
396 void CTX_wm_menu_set(bContext *C, ARegion *menu)
401 /* data context utility functions */
403 struct bContextDataResult {
409 static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
411 int done= 0, recursion= C->data.recursion;
414 memset(result, 0, sizeof(bContextDataResult));
415 #ifndef DISABLE_PYTHON
416 if(CTX_py_dict_get(C)) {
417 return BPY_context_get(C, member, result);
418 // if (BPY_context_get(C, member, result))
422 /* we check recursion to ensure that we do not get infinite
423 * loops requesting data from ourselfs in a context callback */
425 /* Ok, this looks evil...
426 * if(ret) done= -(-ret | -done);
428 * Values in order of importance
429 * (0, -1, 1) - Where 1 is highest priority
431 if(done!=1 && recursion < 1 && C->wm.store) {
432 bContextStoreEntry *entry;
434 C->data.recursion= 1;
436 for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
437 if(strcmp(entry->name, member) == 0) {
438 result->ptr= entry->ptr;
443 if(done!=1 && recursion < 2 && C->wm.region) {
444 C->data.recursion= 2;
445 if(C->wm.region->type && C->wm.region->type->context) {
446 ret = C->wm.region->type->context(C, member, result);
447 if(ret) done= -(-ret | -done);
451 if(done!=1 && recursion < 3 && C->wm.area) {
452 C->data.recursion= 3;
453 if(C->wm.area->type && C->wm.area->type->context) {
454 ret = C->wm.area->type->context(C, member, result);
455 if(ret) done= -(-ret | -done);
458 if(done!=1 && recursion < 4 && C->wm.screen) {
459 bContextDataCallback cb= C->wm.screen->context;
460 C->data.recursion= 4;
462 ret = cb(C, member, result);
463 if(ret) done= -(-ret | -done);
467 C->data.recursion= recursion;
472 static void *ctx_data_pointer_get(const bContext *C, const char *member)
474 bContextDataResult result;
476 if(C && ctx_data_get((bContext*)C, member, &result)==1)
477 return result.ptr.data;
482 static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
484 bContextDataResult result;
486 /* if context is NULL, pointer must be NULL too and that is a valid return */
491 else if(ctx_data_get((bContext*)C, member, &result)==1) {
492 *pointer= result.ptr.data;
501 static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
503 bContextDataResult result;
505 if(ctx_data_get((bContext*)C, member, &result)==1) {
516 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
518 bContextDataResult result;
520 if(ctx_data_get((bContext*)C, member, &result)==1)
523 return PointerRNA_NULL;
526 PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
528 PointerRNA ptr = CTX_data_pointer_get(C, member);
530 if(ptr.data && RNA_struct_is_a(ptr.type, type))
533 return PointerRNA_NULL;
536 ListBase CTX_data_collection_get(const bContext *C, const char *member)
538 bContextDataResult result;
540 if(ctx_data_get((bContext*)C, member, &result)==1) {
545 memset(&list, 0, sizeof(list));
550 /* 1:found, -1:found but not set, 0:not found */
551 int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
553 bContextDataResult result;
554 int ret= ctx_data_get((bContext*)C, member, &result);
561 memset(r_ptr, 0, sizeof(*r_ptr));
562 memset(r_lb, 0, sizeof(*r_lb));
568 static void data_dir_add(ListBase *lb, const char *member)
572 if(strcmp(member, "scene") == 0) /* exception */
575 for(link=lb->first; link; link=link->next)
576 if(strcmp(link->data, member) == 0)
579 link= MEM_callocN(sizeof(LinkData), "LinkData");
580 link->data= (void*)member;
581 BLI_addtail(lb, link);
584 ListBase CTX_data_dir_get(const bContext *C)
586 bContextDataResult result;
590 memset(&lb, 0, sizeof(lb));
593 bContextStoreEntry *entry;
595 for(entry=C->wm.store->entries.first; entry; entry=entry->next)
596 data_dir_add(&lb, entry->name);
598 if(C->wm.region && C->wm.region->type && C->wm.region->type->context) {
599 memset(&result, 0, sizeof(result));
600 C->wm.region->type->context(C, "", &result);
603 for(a=0; result.dir[a]; a++)
604 data_dir_add(&lb, result.dir[a]);
606 if(C->wm.area && C->wm.area->type && C->wm.area->type->context) {
607 memset(&result, 0, sizeof(result));
608 C->wm.area->type->context(C, "", &result);
611 for(a=0; result.dir[a]; a++)
612 data_dir_add(&lb, result.dir[a]);
614 if(C->wm.screen && C->wm.screen->context) {
615 bContextDataCallback cb= C->wm.screen->context;
616 memset(&result, 0, sizeof(result));
620 for(a=0; result.dir[a]; a++)
621 data_dir_add(&lb, result.dir[a]);
627 int CTX_data_equals(const char *member, const char *str)
629 return (strcmp(member, str) == 0);
632 int CTX_data_dir(const char *member)
634 return (strcmp(member, "") == 0);
637 void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
639 RNA_id_pointer_create(id, &result->ptr);
642 void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
644 RNA_pointer_create(id, type, data, &result->ptr);
647 void CTX_data_id_list_add(bContextDataResult *result, ID *id)
649 CollectionPointerLink *link;
651 link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
652 RNA_id_pointer_create(id, &link->ptr);
654 BLI_addtail(&result->list, link);
657 void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
659 CollectionPointerLink *link;
661 link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
662 RNA_pointer_create(id, type, data, &link->ptr);
664 BLI_addtail(&result->list, link);
667 int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase*))
672 int tot= BLI_countlist(&list);
673 BLI_freelistN(&list);
680 void CTX_data_dir_set(bContextDataResult *result, const char **dir)
687 Main *CTX_data_main(const bContext *C)
691 if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
697 void CTX_data_main_set(bContext *C, Main *bmain)
702 Scene *CTX_data_scene(const bContext *C)
706 if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
709 return C->data.scene;
712 int CTX_data_mode_enum(const bContext *C)
714 Object *obedit= CTX_data_edit_object(C);
717 switch(obedit->type) {
719 return CTX_MODE_EDIT_MESH;
721 return CTX_MODE_EDIT_CURVE;
723 return CTX_MODE_EDIT_SURFACE;
725 return CTX_MODE_EDIT_TEXT;
727 return CTX_MODE_EDIT_ARMATURE;
729 return CTX_MODE_EDIT_METABALL;
731 return CTX_MODE_EDIT_LATTICE;
735 Object *ob = CTX_data_active_object(C);
738 if(ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
739 else if(ob->mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT;
740 else if(ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
741 else if(ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
742 else if(ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
743 else if(ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
747 return CTX_MODE_OBJECT;
751 /* would prefer if we can use the enum version below over this one - Campbell */
752 /* must be aligned with above enum */
753 static char *data_mode_strings[] = {
770 char *CTX_data_mode_string(const bContext *C)
772 return data_mode_strings[CTX_data_mode_enum(C)];
775 void CTX_data_scene_set(bContext *C, Scene *scene)
777 C->data.scene= scene;
780 ToolSettings *CTX_data_tool_settings(const bContext *C)
782 Scene *scene = CTX_data_scene(C);
785 return scene->toolsettings;
790 int CTX_data_selected_nodes(const bContext *C, ListBase *list)
792 return ctx_data_collection_get(C, "selected_nodes", list);
795 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
797 return ctx_data_collection_get(C, "selected_editable_objects", list);
800 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
802 return ctx_data_collection_get(C, "selected_editable_bases", list);
805 int CTX_data_selected_objects(const bContext *C, ListBase *list)
807 return ctx_data_collection_get(C, "selected_objects", list);
810 int CTX_data_selected_bases(const bContext *C, ListBase *list)
812 return ctx_data_collection_get(C, "selected_bases", list);
815 int CTX_data_visible_objects(const bContext *C, ListBase *list)
817 return ctx_data_collection_get(C, "visible_objects", list);
820 int CTX_data_visible_bases(const bContext *C, ListBase *list)
822 return ctx_data_collection_get(C, "visible_bases", list);
825 int CTX_data_selectable_objects(const bContext *C, ListBase *list)
827 return ctx_data_collection_get(C, "selectable_objects", list);
830 int CTX_data_selectable_bases(const bContext *C, ListBase *list)
832 return ctx_data_collection_get(C, "selectable_bases", list);
835 struct Object *CTX_data_active_object(const bContext *C)
837 return ctx_data_pointer_get(C, "active_object");
840 struct Base *CTX_data_active_base(const bContext *C)
842 return ctx_data_pointer_get(C, "active_base");
845 struct Object *CTX_data_edit_object(const bContext *C)
847 return ctx_data_pointer_get(C, "edit_object");
850 struct Image *CTX_data_edit_image(const bContext *C)
852 return ctx_data_pointer_get(C, "edit_image");
855 struct Text *CTX_data_edit_text(const bContext *C)
857 return ctx_data_pointer_get(C, "edit_text");
860 struct EditBone *CTX_data_active_bone(const bContext *C)
862 return ctx_data_pointer_get(C, "active_bone");
865 int CTX_data_selected_bones(const bContext *C, ListBase *list)
867 return ctx_data_collection_get(C, "selected_bones", list);
870 int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
872 return ctx_data_collection_get(C, "selected_editable_bones", list);
875 int CTX_data_visible_bones(const bContext *C, ListBase *list)
877 return ctx_data_collection_get(C, "visible_bones", list);
880 int CTX_data_editable_bones(const bContext *C, ListBase *list)
882 return ctx_data_collection_get(C, "editable_bones", list);
885 struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C)
887 return ctx_data_pointer_get(C, "active_pose_bone");
890 int CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
892 return ctx_data_collection_get(C, "selected_pose_bones", list);
895 int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
897 return ctx_data_collection_get(C, "visible_pose_bones", list);