Dev:2.7/Source/Checklists/ContextEntry
目次
Adding a new Context entry
This checklist documents how to add a new entry in the global "Context" object (i.e. via bContext *C
in C, and bpy.context
in Python). Examples of these properties include bpy.context.active_object
, bpy.context.active_gpencil_layer
, bpy.context.tool_settings
, bpy.context.area
and more.
Checklist - Single Item
This assumes that we are adding a property my_prop
of type PropType
(commonly referred to as pro
in the code). See the next section/checklist for what to do if you want to add a set of thing instead.
Furthermore, we assume that this property refers to some "data" (e.g. a datablock, or an entity like a bone/keyingset/driver/node/etc., or similiar) as opposed to something window-management ("wm") related such as active area/region/etc.
When properly defined, you should be able to do:
#include "BKE_context.h"
...
void some_func(bContext *C, ...)
{
PropType *pro = CTX_data_my_prop(C);
... do something with "prop" ...
}
blenkernel
- BKE_context.h - Add one of the following lines somewhere near another conceptually similar one:
PropType *CTX_data_my_prop(const bContext *C);
- context.c - Add a function corresponding to the one below (and in a similar location in the file, grouping-wise):
PropType *CTX_data_my_prop(const bContext *C)
{
return ctx_data_pointer_get(C, "my_prop");
}
editors/screen/screen_context.c
- screen_context_dir[] - Add a string entry for your property
- ed_screen_context() - Add an
else if
block for setting your prop in Context. For example:
else if (CTX_data_equals(member, "my_prop")) {
PropType *pro = ...
... Do some magic to get the property, and to test that should be made available at this time (as appropriate) ...
CTX_data_id_pointer_set(result, pro);
return 1;
}
doc/python_api/sphinx_doc_gen.py
- context_type_map - Add an entry for
my_prop
, following the examples for other properties. These are arranged in alphabetical order.
---
Checklist - Collection/Set
We still need to add code to the same places as before. This assuming that the context entry is now called my_things
.
This collection can then be used via:
CTX_DATA_BEGIN(C, PropType *, pro, my_things)
{
... do something with pro ...
}
CTX_DATA_END;
blenkernel
- BKE_context.h - Add the following line instead:
int CTX_data_my_things(const bContext *C, ListBase *list);
- context.c - Add the following code instead:
int CTX_data_my_things(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "my_things", list);
}
editors/screen/screen_context.c
- screen_context_dir[] - (Same as before) Add a string entry for your collection
- ed_screen_context() - Add an
else if
block for setting your prop in Context. For example:
else if (CTX_data_equals(member, "my_prop")) {
for (...) {
PropType *pro = ...
if (...)
CTX_data_id_list_add(result, pro);
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
doc/python_api/sphinx_doc_gen.py
- context_type_map - Add an entry for
my_prop
, following the examples for other properties. These are arranged in alphabetical order.
---
Precautions
- When doing the
ed_screen_context()
logic, it is not advised to try and use CTX_* stuff to get hold of pointers to data you need. Instead use the local vars declared at the start of that function instead.- For more details, see the comments in the
gpencil_data
case
- For more details, see the comments in the
- Try to keep any logic needed here simple - especially if the property is likely to be looked up in
Operator.poll()
callbacks. If necessary, consider revising or improving your data structures to make these lookups simpler.