Blender  V3.3
idprop_py_ui_api.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <Python.h>
8 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_string.h"
12 #include "BLI_utildefines.h"
13 
14 #include "idprop_py_ui_api.h"
15 
16 #include "BKE_idprop.h"
17 
18 #include "DNA_ID.h"
19 
20 #include "RNA_access.h"
21 #include "RNA_enum_types.h"
22 
23 #define USE_STRING_COERCE
24 
25 #ifdef USE_STRING_COERCE
26 # include "py_capi_utils.h"
27 #endif
28 #include "py_capi_rna.h"
29 
30 #include "python_utildefines.h"
31 
32 /* -------------------------------------------------------------------- */
36 static bool args_contain_key(PyObject *kwargs, const char *name)
37 {
38  if (kwargs == NULL) {
39  /* When a function gets called without any kwargs, Python just passes NULL instead.
40  * PyDict_Contains() is not NULL-safe, though. */
41  return false;
42  }
43 
44  PyObject *py_key = PyUnicode_FromString(name);
45  const bool result = PyDict_Contains(kwargs, py_key) == 1;
46  Py_DECREF(py_key);
47  return result;
48 }
49 
54  const char *rna_subtype,
55  const char *description)
56 {
57  if (rna_subtype != NULL) {
59  rna_subtype,
60  &ui_data->rna_subtype,
61  "IDPropertyUIManager.update") == -1) {
62  return false;
63  }
64  }
65 
66  if (description != NULL) {
67  ui_data->description = BLI_strdup(description);
68  }
69 
70  return true;
71 }
72 
78  IDPropertyUIDataInt *ui_data,
79  PyObject *default_value)
80 {
81  if (PySequence_Check(default_value)) {
82  if (idprop->type != IDP_ARRAY) {
83  PyErr_SetString(PyExc_TypeError, "Only array properties can have array default values");
84  return false;
85  }
86 
87  Py_ssize_t len = PySequence_Size(default_value);
88  int *new_default_array = (int *)MEM_malloc_arrayN(len, sizeof(int), __func__);
89  if (PyC_AsArray(
90  new_default_array, sizeof(int), default_value, len, &PyLong_Type, "ui_data_update") ==
91  -1) {
92  MEM_freeN(new_default_array);
93  return false;
94  }
95 
96  ui_data->default_array_len = len;
97  ui_data->default_array = new_default_array;
98  }
99  else {
100  const int value = PyC_Long_AsI32(default_value);
101  if ((value == -1) && PyErr_Occurred()) {
102  PyErr_SetString(PyExc_ValueError, "Error converting \"default\" argument to integer");
103  return false;
104  }
105  ui_data->default_value = value;
106  }
107 
108  return true;
109 }
110 
114 static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObject *kwargs)
115 {
116  const char *rna_subtype = NULL;
117  const char *description = NULL;
118  int min, max, soft_min, soft_max, step;
119  PyObject *default_value = NULL;
120  const char *kwlist[] = {
121  "min", "max", "soft_min", "soft_max", "step", "default", "subtype", "description", NULL};
122  if (!PyArg_ParseTupleAndKeywords(args,
123  kwargs,
124  "|$iiiiiOzz:update",
125  (char **)kwlist,
126  &min,
127  &max,
128  &soft_min,
129  &soft_max,
130  &step,
131  &default_value,
132  &rna_subtype,
133  &description)) {
134  return false;
135  }
136 
137  /* Write to a temporary copy of the UI data in case some part of the parsing fails. */
138  IDPropertyUIDataInt *ui_data_orig = (IDPropertyUIDataInt *)idprop->ui_data;
139  IDPropertyUIDataInt ui_data = *ui_data_orig;
140 
141  if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) {
142  IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
143  return false;
144  }
145 
146  if (args_contain_key(kwargs, "min")) {
147  ui_data.min = min;
148  ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min);
149  ui_data.max = MAX2(ui_data.min, ui_data.max);
150  }
151  if (args_contain_key(kwargs, "max")) {
152  ui_data.max = max;
153  ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max);
154  ui_data.min = MIN2(ui_data.min, ui_data.max);
155  }
156  if (args_contain_key(kwargs, "soft_min")) {
157  ui_data.soft_min = soft_min;
158  ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min);
159  ui_data.soft_max = MAX2(ui_data.soft_min, ui_data.soft_max);
160  }
161  if (args_contain_key(kwargs, "soft_max")) {
162  ui_data.soft_max = soft_max;
163  ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max);
164  ui_data.soft_min = MIN2(ui_data.soft_min, ui_data.soft_max);
165  }
166  if (args_contain_key(kwargs, "step")) {
167  ui_data.step = step;
168  }
169 
170  if (!ELEM(default_value, NULL, Py_None)) {
171  if (!idprop_ui_data_update_int_default(idprop, &ui_data, default_value)) {
173  &ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
174  return false;
175  }
176  }
177 
178  /* Write back to the property's UI data. */
179  IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base);
180  *ui_data_orig = ui_data;
181  return true;
182 }
183 
189  IDPropertyUIDataFloat *ui_data,
190  PyObject *default_value)
191 {
192  if (PySequence_Check(default_value)) {
193  if (idprop->type != IDP_ARRAY) {
194  PyErr_SetString(PyExc_TypeError, "Only array properties can have array default values");
195  return false;
196  }
197 
198  Py_ssize_t len = PySequence_Size(default_value);
199  double *new_default_array = (double *)MEM_malloc_arrayN(len, sizeof(double), __func__);
200  if (PyC_AsArray(new_default_array,
201  sizeof(double),
202  default_value,
203  len,
204  &PyFloat_Type,
205  "ui_data_update") == -1) {
206  MEM_freeN(new_default_array);
207  return false;
208  }
209 
210  ui_data->default_array_len = len;
211  ui_data->default_array = new_default_array;
212  }
213  else {
214  const double value = PyFloat_AsDouble(default_value);
215  if ((value == -1.0) && PyErr_Occurred()) {
216  PyErr_SetString(PyExc_ValueError, "Error converting \"default\" argument to double");
217  return false;
218  }
219  ui_data->default_value = value;
220  }
221 
222  return true;
223 }
224 
228 static bool idprop_ui_data_update_float(IDProperty *idprop, PyObject *args, PyObject *kwargs)
229 {
230  const char *rna_subtype = NULL;
231  const char *description = NULL;
232  int precision;
233  double min, max, soft_min, soft_max, step;
234  PyObject *default_value = NULL;
235  const char *kwlist[] = {"min",
236  "max",
237  "soft_min",
238  "soft_max",
239  "step",
240  "precision",
241  "default",
242  "subtype",
243  "description",
244  NULL};
245  if (!PyArg_ParseTupleAndKeywords(args,
246  kwargs,
247  "|$dddddiOzz:update",
248  (char **)kwlist,
249  &min,
250  &max,
251  &soft_min,
252  &soft_max,
253  &step,
254  &precision,
255  &default_value,
256  &rna_subtype,
257  &description)) {
258  return false;
259  }
260 
261  /* Write to a temporary copy of the UI data in case some part of the parsing fails. */
262  IDPropertyUIDataFloat *ui_data_orig = (IDPropertyUIDataFloat *)idprop->ui_data;
263  IDPropertyUIDataFloat ui_data = *ui_data_orig;
264 
265  if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) {
266  IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
267  return false;
268  }
269 
270  if (args_contain_key(kwargs, "min")) {
271  ui_data.min = min;
272  ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min);
273  ui_data.max = MAX2(ui_data.min, ui_data.max);
274  }
275  if (args_contain_key(kwargs, "max")) {
276  ui_data.max = max;
277  ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max);
278  ui_data.min = MIN2(ui_data.min, ui_data.max);
279  }
280  if (args_contain_key(kwargs, "soft_min")) {
281  ui_data.soft_min = soft_min;
282  ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min);
283  ui_data.soft_max = MAX2(ui_data.soft_min, ui_data.soft_max);
284  }
285  if (args_contain_key(kwargs, "soft_max")) {
286  ui_data.soft_max = soft_max;
287  ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max);
288  ui_data.soft_min = MIN2(ui_data.soft_min, ui_data.soft_max);
289  }
290  if (args_contain_key(kwargs, "step")) {
291  ui_data.step = (float)step;
292  }
293  if (args_contain_key(kwargs, "precision")) {
294  ui_data.precision = precision;
295  }
296 
297  if (!ELEM(default_value, NULL, Py_None)) {
298  if (!idprop_ui_data_update_float_default(idprop, &ui_data, default_value)) {
300  &ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
301  return false;
302  }
303  }
304 
305  /* Write back to the property's UI data. */
306  IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base);
307  *ui_data_orig = ui_data;
308  return true;
309 }
310 
314 static bool idprop_ui_data_update_string(IDProperty *idprop, PyObject *args, PyObject *kwargs)
315 {
316  const char *rna_subtype = NULL;
317  const char *description = NULL;
318  const char *default_value;
319  const char *kwlist[] = {"default", "subtype", "description", NULL};
320  if (!PyArg_ParseTupleAndKeywords(args,
321  kwargs,
322  "|$zzz:update",
323  (char **)kwlist,
324  &default_value,
325  &rna_subtype,
326  &description)) {
327  return false;
328  }
329 
330  /* Write to a temporary copy of the UI data in case some part of the parsing fails. */
331  IDPropertyUIDataString *ui_data_orig = (IDPropertyUIDataString *)idprop->ui_data;
332  IDPropertyUIDataString ui_data = *ui_data_orig;
333 
334  if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) {
335  IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
336  return false;
337  }
338 
339  if (default_value != NULL) {
340  ui_data.default_value = BLI_strdup(default_value);
341  }
342 
343  /* Write back to the property's UI data. */
344  IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base);
345  *ui_data_orig = ui_data;
346  return true;
347 }
348 
352 static bool idprop_ui_data_update_id(IDProperty *idprop, PyObject *args, PyObject *kwargs)
353 {
354  const char *rna_subtype = NULL;
355  const char *description = NULL;
356  const char *kwlist[] = {"subtype", "description", NULL};
357  if (!PyArg_ParseTupleAndKeywords(
358  args, kwargs, "|$zz:update", (char **)kwlist, &rna_subtype, &description)) {
359  return false;
360  }
361 
362  /* Write to a temporary copy of the UI data in case some part of the parsing fails. */
363  IDPropertyUIDataID *ui_data_orig = (IDPropertyUIDataID *)idprop->ui_data;
364  IDPropertyUIDataID ui_data = *ui_data_orig;
365 
366  if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) {
367  IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
368  return false;
369  }
370 
371  /* Write back to the property's UI data. */
372  IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base);
373  *ui_data_orig = ui_data;
374  return true;
375 }
376 
377 PyDoc_STRVAR(BPy_IDPropertyUIManager_update_doc,
378  ".. method:: update( "
379  "subtype=None, "
380  "min=None, "
381  "max=None, "
382  "soft_min=None, "
383  "soft_max=None, "
384  "precision=None, "
385  "step=None, "
386  "default=None, "
387  "description=None)\n"
388  "\n"
389  " Update the RNA information of the IDProperty used for interaction and\n"
390  " display in the user interface. The required types for many of the keyword\n"
391  " arguments depend on the type of the property.\n ");
393  PyObject *args,
394  PyObject *kwargs)
395 {
396  IDProperty *property = self->property;
398 
399  switch (IDP_ui_data_type(property)) {
401  IDP_ui_data_ensure(property);
402  if (!idprop_ui_data_update_int(property, args, kwargs)) {
403  return NULL;
404  }
405  Py_RETURN_NONE;
407  IDP_ui_data_ensure(property);
408  if (!idprop_ui_data_update_float(property, args, kwargs)) {
409  return NULL;
410  }
411  Py_RETURN_NONE;
413  IDP_ui_data_ensure(property);
414  if (!idprop_ui_data_update_string(property, args, kwargs)) {
415  return NULL;
416  }
417  Py_RETURN_NONE;
418  case IDP_UI_DATA_TYPE_ID:
419  IDP_ui_data_ensure(property);
420  if (!idprop_ui_data_update_id(property, args, kwargs)) {
421  return NULL;
422  }
423  Py_RETURN_NONE;
425  PyErr_Format(PyExc_TypeError, "IDProperty \"%s\" does not support RNA data", property->name);
426  return NULL;
427  }
428 
430  Py_RETURN_NONE;
431 }
432 
435 /* -------------------------------------------------------------------- */
439 static void idprop_ui_data_to_dict_int(IDProperty *property, PyObject *dict)
440 {
441  IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)property->ui_data;
442  PyObject *item;
443 
444  PyDict_SetItemString(dict, "min", item = PyLong_FromLong(ui_data->min));
445  Py_DECREF(item);
446  PyDict_SetItemString(dict, "max", item = PyLong_FromLong(ui_data->max));
447  Py_DECREF(item);
448  PyDict_SetItemString(dict, "soft_min", item = PyLong_FromLong(ui_data->soft_min));
449  Py_DECREF(item);
450  PyDict_SetItemString(dict, "soft_max", item = PyLong_FromLong(ui_data->soft_max));
451  Py_DECREF(item);
452  PyDict_SetItemString(dict, "step", item = PyLong_FromLong(ui_data->step));
453  Py_DECREF(item);
454  if (property->type == IDP_ARRAY) {
455  PyObject *list = PyList_New(ui_data->default_array_len);
456  for (int i = 0; i < ui_data->default_array_len; i++) {
457  PyList_SET_ITEM(list, i, PyLong_FromLong(ui_data->default_array[i]));
458  }
459  PyDict_SetItemString(dict, "default", list);
460  Py_DECREF(list);
461  }
462  else {
463  PyDict_SetItemString(dict, "default", item = PyLong_FromLong(ui_data->default_value));
464  Py_DECREF(item);
465  }
466 }
467 
468 static void idprop_ui_data_to_dict_float(IDProperty *property, PyObject *dict)
469 {
470  IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)property->ui_data;
471  PyObject *item;
472 
473  PyDict_SetItemString(dict, "min", item = PyFloat_FromDouble(ui_data->min));
474  Py_DECREF(item);
475  PyDict_SetItemString(dict, "max", item = PyFloat_FromDouble(ui_data->max));
476  Py_DECREF(item);
477  PyDict_SetItemString(dict, "soft_min", item = PyFloat_FromDouble(ui_data->soft_min));
478  Py_DECREF(item);
479  PyDict_SetItemString(dict, "soft_max", item = PyFloat_FromDouble(ui_data->soft_max));
480  Py_DECREF(item);
481  PyDict_SetItemString(dict, "step", item = PyFloat_FromDouble((double)ui_data->step));
482  Py_DECREF(item);
483  PyDict_SetItemString(dict, "precision", item = PyLong_FromDouble((double)ui_data->precision));
484  Py_DECREF(item);
485  if (property->type == IDP_ARRAY) {
486  PyObject *list = PyList_New(ui_data->default_array_len);
487  for (int i = 0; i < ui_data->default_array_len; i++) {
488  PyList_SET_ITEM(list, i, PyFloat_FromDouble(ui_data->default_array[i]));
489  }
490  PyDict_SetItemString(dict, "default", list);
491  Py_DECREF(list);
492  }
493  else {
494  PyDict_SetItemString(dict, "default", item = PyFloat_FromDouble(ui_data->default_value));
495  Py_DECREF(item);
496  }
497 }
498 
499 static void idprop_ui_data_to_dict_string(IDProperty *property, PyObject *dict)
500 {
501  IDPropertyUIDataString *ui_data = (IDPropertyUIDataString *)property->ui_data;
502  PyObject *item;
503 
504  const char *default_value = (ui_data->default_value == NULL) ? "" : ui_data->default_value;
505 
506  PyDict_SetItemString(dict, "default", item = PyUnicode_FromString(default_value));
507  Py_DECREF(item);
508 }
509 
510 PyDoc_STRVAR(BPy_IDPropertyUIManager_as_dict_doc,
511  ".. method:: as_dict()\n"
512  "\n"
513  " Return a dictionary of the property's RNA UI data. The fields in the\n"
514  " returned dictionary and their types will depend on the property's type.\n");
516 {
517  IDProperty *property = self->property;
519 
520  IDPropertyUIData *ui_data = IDP_ui_data_ensure(property);
521 
522  PyObject *dict = PyDict_New();
523 
524  /* RNA subtype. */
525  {
526  const char *subtype_id = NULL;
528  PyObject *item = PyUnicode_FromString(subtype_id);
529  PyDict_SetItemString(dict, "subtype", item);
530  Py_DECREF(item);
531  }
532 
533  /* Description. */
534  if (ui_data->description != NULL) {
535  PyObject *item = PyUnicode_FromString(ui_data->description);
536  PyDict_SetItemString(dict, "description", item);
537  Py_DECREF(item);
538  }
539 
540  /* Type specific data. */
541  switch (IDP_ui_data_type(property)) {
543  idprop_ui_data_to_dict_string(property, dict);
544  break;
545  case IDP_UI_DATA_TYPE_ID:
546  break;
548  idprop_ui_data_to_dict_int(property, dict);
549  break;
551  idprop_ui_data_to_dict_float(property, dict);
552  break;
555  break;
556  }
557 
558  return dict;
559 }
560 
563 /* -------------------------------------------------------------------- */
567 PyDoc_STRVAR(BPy_IDPropertyUIManager_clear_doc,
568  ".. method:: clear()\n"
569  "\n"
570  " Remove the RNA UI data from this IDProperty.\n");
572 {
573  IDProperty *property = self->property;
575 
576  if (property == NULL) {
577  PyErr_SetString(PyExc_RuntimeError, "IDPropertyUIManager missing property");
579  return NULL;
580  }
581 
582  if (property->ui_data != NULL) {
583  IDP_ui_data_free(property);
584  }
585 
586  Py_RETURN_NONE;
587 }
588 
591 /* -------------------------------------------------------------------- */
596  BPy_IDPropertyUIManager_update_from_doc,
597  ".. method:: update_from(ui_manager_source)\n"
598  "\n"
599  " Copy UI data from an IDProperty in the source group to a property in this group.\n "
600  " If the source property has no UI data, the target UI data will be reset if it exists.\n"
601  "\n"
602  " :raises TypeError: If the types of the two properties don't match.\n");
603 static PyObject *BPy_IDPropertyUIManager_update_from(BPy_IDPropertyUIManager *self, PyObject *args)
604 {
605  IDProperty *property = self->property;
607 
608  BPy_IDPropertyUIManager *ui_manager_src;
609  if (!PyArg_ParseTuple(args, "O!:update_from", &BPy_IDPropertyUIManager_Type, &ui_manager_src)) {
610  return NULL;
611  }
612 
613  if (property->ui_data != NULL) {
614  IDP_ui_data_free(property);
615  }
616 
617  if (ui_manager_src->property && ui_manager_src->property->ui_data) {
618  property->ui_data = IDP_ui_data_copy(ui_manager_src->property);
619  }
620 
621  Py_RETURN_NONE;
622 }
623 
626 /* -------------------------------------------------------------------- */
630 static struct PyMethodDef BPy_IDPropertyUIManager_methods[] = {
631  {"update",
632  (PyCFunction)BPy_IDPropertyUIManager_update,
633  METH_VARARGS | METH_KEYWORDS,
634  BPy_IDPropertyUIManager_update_doc},
635  {"as_dict",
637  METH_NOARGS,
638  BPy_IDPropertyUIManager_as_dict_doc},
639  {"clear",
640  (PyCFunction)BPy_IDPropertyUIManager_clear,
641  METH_NOARGS,
642  BPy_IDPropertyUIManager_clear_doc},
643  {"update_from",
645  METH_VARARGS,
646  BPy_IDPropertyUIManager_update_from_doc},
647  {NULL, NULL, 0, NULL},
648 };
649 
651 {
652  return PyUnicode_FromFormat(
653  "<bpy id prop ui manager: name=\"%s\", address=%p>", self->property->name, self->property);
654 }
655 
657 {
658  return _Py_HashPointer(self->property);
659 }
660 
662  PyVarObject_HEAD_INIT(NULL, 0)
663  /* For printing, in format "<module>.<name>" */
664  "IDPropertyUIManager", /* char *tp_name; */
665  sizeof(BPy_IDPropertyUIManager), /* int tp_basicsize; */
666  0, /* tp_itemsize; For allocation */
667 
668  /* Methods to implement standard operations */
669 
670  NULL, /* destructor tp_dealloc; */
671  0, /* tp_vectorcall_offset */
672  NULL, /* getattrfunc tp_getattr; */
673  NULL, /* setattrfunc tp_setattr; */
674  NULL, /* cmpfunc tp_compare; */
675  (reprfunc)BPy_IDPropertyUIManager_repr, /* reprfunc tp_repr; */
676 
677  /* Method suites for standard classes */
678 
679  NULL, /* PyNumberMethods *tp_as_number; */
680  NULL, /* PySequenceMethods *tp_as_sequence; */
681  NULL, /* PyMappingMethods *tp_as_mapping; */
682 
683  /* More standard operations (here for binary compatibility) */
684 
685  (hashfunc)BPy_IDPropertyUIManager_hash, /* hashfunc tp_hash; */
686  NULL, /* ternaryfunc tp_call; */
687  NULL, /* reprfunc tp_str; */
688  NULL, /* getattrofunc tp_getattro; */
689  NULL, /* setattrofunc tp_setattro; */
690 
691  /* Functions to access object as input/output buffer */
692  NULL, /* PyBufferProcs *tp_as_buffer; */
693 
694  /*** Flags to define presence of optional/expanded features ***/
695  Py_TPFLAGS_DEFAULT, /* long tp_flags; */
696 
697  NULL, /* char *tp_doc; Documentation string */
698  /*** Assigned meaning in release 2.0 ***/
699  /* call function for all accessible objects */
700  NULL, /* traverseproc tp_traverse; */
701 
702  /* delete references to contained objects */
703  NULL, /* inquiry tp_clear; */
704 
705  /*** Assigned meaning in release 2.1 ***/
706  /*** rich comparisons ***/
707  NULL, /* richcmpfunc tp_richcompare; */
708 
709  /*** weak reference enabler ***/
710  0, /* long tp_weaklistoffset; */
711 
712  /*** Added in release 2.2 ***/
713  /* Iterators */
714  NULL, /* getiterfunc tp_iter; */
715  NULL, /* iternextfunc tp_iternext; */
716  /*** Attribute descriptor and subclassing stuff ***/
717  BPy_IDPropertyUIManager_methods, /* struct PyMethodDef *tp_methods; */
718  NULL, /* struct PyMemberDef *tp_members; */
719  NULL, /* struct PyGetSetDef *tp_getset; */
720 };
721 
723 {
724  PyType_Ready(&BPy_IDPropertyUIManager_Type);
725 }
726 
typedef float(TangentPoint)[2]
eIDPropertyUIDataType IDP_ui_data_type(const struct IDProperty *prop)
struct IDPropertyUIData * IDP_ui_data_ensure(struct IDProperty *prop)
Definition: idprop.c:1519
bool IDP_ui_data_supported(const struct IDProperty *prop)
void IDP_ui_data_free_unique_contents(struct IDPropertyUIData *ui_data, eIDPropertyUIDataType type, const struct IDPropertyUIData *other)
@ IDP_UI_DATA_TYPE_ID
Definition: BKE_idprop.h:335
@ IDP_UI_DATA_TYPE_UNSUPPORTED
Definition: BKE_idprop.h:327
@ IDP_UI_DATA_TYPE_INT
Definition: BKE_idprop.h:329
@ IDP_UI_DATA_TYPE_FLOAT
Definition: BKE_idprop.h:331
@ IDP_UI_DATA_TYPE_STRING
Definition: BKE_idprop.h:333
struct IDPropertyUIData * IDP_ui_data_copy(const struct IDProperty *prop)
void IDP_ui_data_free(struct IDProperty *prop)
Definition: idprop.c:1023
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
#define MAX2(a, b)
#define ELEM(...)
#define MIN2(a, b)
ID and Library types, which are fundamental for sdna.
@ IDP_ARRAY
Definition: DNA_ID.h:140
Read Guarded memory(de)allocation.
PyObject * self
Definition: bpy_driver.c:165
int len
Definition: draw_manager.c:108
PyDoc_STRVAR(BPy_IDPropertyUIManager_update_doc, ".. method:: update( " "subtype=None, " "min=None, " "max=None, " "soft_min=None, " "soft_max=None, " "precision=None, " "step=None, " "default=None, " "description=None)\n" "\n" " Update the RNA information of the IDProperty used for interaction and\n" " display in the user interface. The required types for many of the keyword\n" " arguments depend on the type of the property.\n ")
void IDPropertyUIData_Init_Types()
static bool idprop_ui_data_update_float(IDProperty *idprop, PyObject *args, PyObject *kwargs)
static PyObject * BPy_IDIDPropertyUIManager_as_dict(BPy_IDPropertyUIManager *self)
static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObject *kwargs)
static struct PyMethodDef BPy_IDPropertyUIManager_methods[]
static PyObject * BPy_IDPropertyUIManager_update_from(BPy_IDPropertyUIManager *self, PyObject *args)
static bool idprop_ui_data_update_id(IDProperty *idprop, PyObject *args, PyObject *kwargs)
static void idprop_ui_data_to_dict_string(IDProperty *property, PyObject *dict)
static PyObject * BPy_IDPropertyUIManager_clear(BPy_IDPropertyUIManager *self)
static bool idprop_ui_data_update_base(IDPropertyUIData *ui_data, const char *rna_subtype, const char *description)
static void idprop_ui_data_to_dict_float(IDProperty *property, PyObject *dict)
static bool args_contain_key(PyObject *kwargs, const char *name)
static bool idprop_ui_data_update_float_default(IDProperty *idprop, IDPropertyUIDataFloat *ui_data, PyObject *default_value)
static void idprop_ui_data_to_dict_int(IDProperty *property, PyObject *dict)
static Py_hash_t BPy_IDPropertyUIManager_hash(BPy_IDPropertyUIManager *self)
static bool idprop_ui_data_update_string(IDProperty *idprop, PyObject *args, PyObject *kwargs)
static PyObject * BPy_IDPropertyUIManager_update(BPy_IDPropertyUIManager *self, PyObject *args, PyObject *kwargs)
PyTypeObject BPy_IDPropertyUIManager_Type
static PyObject * BPy_IDPropertyUIManager_repr(BPy_IDPropertyUIManager *self)
static bool idprop_ui_data_update_int_default(IDProperty *idprop, IDPropertyUIDataInt *ui_data, PyObject *default_value)
struct BPy_IDPropertyUIManager BPy_IDPropertyUIManager
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
int pyrna_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value, const char *error_prefix)
Definition: py_capi_rna.c:54
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
header-only utilities
bool RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **r_identifier)
Definition: rna_access.c:1668
const EnumPropertyItem rna_enum_property_subtype_items[]
Definition: rna_rna.c:120
#define min(a, b)
Definition: sort.c:35
PyObject_VAR_HEAD struct IDProperty * property
double * default_array
Definition: DNA_ID.h:74
IDPropertyUIData base
Definition: DNA_ID.h:73
double default_value
Definition: DNA_ID.h:85
IDPropertyUIData base
Definition: DNA_ID.h:96
int default_array_len
Definition: DNA_ID.h:60
IDPropertyUIData base
Definition: DNA_ID.h:58
int * default_array
Definition: DNA_ID.h:59
IDPropertyUIData base
Definition: DNA_ID.h:90
char * default_value
Definition: DNA_ID.h:91
char * description
Definition: DNA_ID.h:49
int rna_subtype
Definition: DNA_ID.h:51
IDPropertyUIData * ui_data
Definition: DNA_ID.h:128
char type
Definition: DNA_ID.h:108
float max