UI: Allow passing named strings via context
Sometimes it is necessary to pass additional data through generic UI entities, to specific implementations. For example to pass additional options to panel polling & drawing when instantiating a panel through its panel type. Or storing additional data in a button, without hardcoding it in the button struct/class. Passing data via context is a simple solution to this, however so far this only works using hardcoded context queries or RNA pointers. For passing arbitrary strings we've used workarounds like creating an RNA type to wrap it already. For example `RNA_AssetCatalogPath`, which is used to dynamically populate menu items based on an asset catalog path, via a generic menu type. type instantiation. This makes it possible to invoke specific asset shelves as popover panels. Idea is simply to let `bContextStore` entries hold copies of the string (as `std::string`), avoiding lifetime issues. Context APIs are extended to support setting/querying strings via a context member name. Pull Request: https://projects.blender.org/blender/blender/pulls/122113
This commit is contained in:
committed by
Julian Eisel
parent
cdf960ecec
commit
2fbf206491
@@ -4438,6 +4438,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
||||
blender::Vector<PointerRNA> newlb;
|
||||
PropertyRNA *newprop;
|
||||
int newindex;
|
||||
blender::StringRef newstr;
|
||||
short newtype;
|
||||
|
||||
/* An empty string is used to implement #CTX_data_dir_get,
|
||||
@@ -4445,7 +4446,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
||||
eContextResult done;
|
||||
if (name[0]) {
|
||||
done = eContextResult(
|
||||
CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newtype));
|
||||
CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newstr, &newtype));
|
||||
}
|
||||
else {
|
||||
/* Fall through to built-in `getattr`. */
|
||||
@@ -4463,6 +4464,16 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
|
||||
ret = pyrna_struct_CreatePyObject(&newptr);
|
||||
}
|
||||
break;
|
||||
case CTX_DATA_TYPE_STRING: {
|
||||
if (newstr.is_empty()) {
|
||||
ret = Py_None;
|
||||
Py_INCREF(ret);
|
||||
}
|
||||
else {
|
||||
ret = PyUnicode_FromStringAndSize(newstr.data(), newstr.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTX_DATA_TYPE_COLLECTION: {
|
||||
ret = PyList_New(0);
|
||||
for (PointerRNA &ptr : newlb) {
|
||||
@@ -4702,10 +4713,11 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
|
||||
blender::Vector<PointerRNA> newlb;
|
||||
PropertyRNA *newprop;
|
||||
int newindex;
|
||||
blender::StringRef newstr;
|
||||
short newtype;
|
||||
|
||||
const eContextResult done = eContextResult(
|
||||
CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newtype));
|
||||
CTX_data_get(C, name, &newptr, &newlb, &newprop, &newindex, &newstr, &newtype));
|
||||
|
||||
if (done == CTX_RESULT_OK) {
|
||||
PyErr_Format(
|
||||
|
||||
Reference in New Issue
Block a user