static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix) { int dimsize[MAX_ARRAY_DIMENSION]; int totdim = RNA_property_array_dimension(ptr, prop, dimsize); /* validate type first because length validation may modify property array length */ #ifdef USE_MATHUTILS if (lvalue_dim == 0) { /* only valid for first level array */ if (MatrixObject_Check(rvalue)) { MatrixObject *pymat = (MatrixObject *)rvalue; if (BaseMath_ReadCallback(pymat) == -1) return -1; if (RNA_property_type(prop) != PROP_FLOAT) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign to non float array", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); return -1; } else if (totdim != 2) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign array with %d dimensions", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), totdim); return -1; } else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, matrix assign dimension size mismatch, " "is %dx%d, expected be %dx%d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), pymat->num_col, pymat->num_row, dimsize[0], dimsize[1]); return -1; } else { *totitem = dimsize[0] * dimsize[1]; return 0; } } } #endif /* USE_MATHUTILS */ { if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) return -1; return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); } }
void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, int compact) { PropertyRNA *prop; PointerRNA clipptr; MovieClip *clip; uiLayout *row, *split; uiBlock *block; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } clipptr = RNA_property_pointer_get(ptr, prop); clip = clipptr.data; uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr); if (!compact) uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL); if (clip) { uiLayout *col; row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); uiDefBut(block, LABEL, 0, "File Path:", 0, 19, 145, 19, NULL, 0, 0, 0, 0, ""); row = uiLayoutRow(layout, FALSE); split = uiLayoutSplit(row, 0.0f, FALSE); row = uiLayoutRow(split, TRUE); uiItemR(row, &clipptr, "filepath", 0, "", ICON_NONE); uiItemO(row, "", ICON_FILE_REFRESH, "clip.reload"); col = uiLayoutColumn(layout, FALSE); uiTemplateColorspaceSettings(col, &clipptr, "colorspace_settings"); } }
static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propname, const char *identifier) { PropertyRNA *prop = NULL; EnumPropertyItem *items = NULL, *item; bool free; int icon = ICON_NONE; prop = RNA_struct_find_property(ptr, propname); if (!prop || (RNA_property_type(prop) != PROP_ENUM)) { RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname); return icon; } RNA_property_enum_items(C, ptr, prop, &items, NULL, &free); if (items) { for (item = items; item->identifier; item++) { if (item->identifier[0] && STREQ(item->identifier, identifier)) { icon = item->icon; break; } } if (free) { MEM_freeN(items); } } return icon; }
static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt, int translate, int icon, int expand, int slider, int toggle, int icon_only, int event, int full_event, int emboss, int index, int icon_value) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); int flag = 0; if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } if (icon_value && !icon) { icon = icon_value; } /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); flag |= (slider) ? UI_ITEM_R_SLIDER : 0; flag |= (expand) ? UI_ITEM_R_EXPAND : 0; flag |= (toggle) ? UI_ITEM_R_TOGGLE : 0; flag |= (icon_only) ? UI_ITEM_R_ICON_ONLY : 0; flag |= (event) ? UI_ITEM_R_EVENT : 0; flag |= (full_event) ? UI_ITEM_R_FULL_EVENT : 0; flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG; uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon); }
static const char *rna_ui_get_enum_description( bContext *C, PointerRNA *ptr, const char *propname, const char *identifier) { PropertyRNA *prop = NULL; const EnumPropertyItem *items = NULL, *item; bool free; const char *desc = ""; prop = RNA_struct_find_property(ptr, propname); if (!prop || (RNA_property_type(prop) != PROP_ENUM)) { RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname); return desc; } RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free); if (items) { for (item = items; item->identifier; item++) { if (item->identifier[0] && STREQ(item->identifier, identifier)) { desc = item->description; break; } } if (free) { MEM_freeN((void *)items); } } return desc; }
/** * Invokes a new pie menu for a new level. */ static void ui_pie_menu_level_invoke(bContext *C, void *argN, void *arg2) { EnumPropertyItem *item_array = (EnumPropertyItem *)argN; PieMenuLevelData *lvl = (PieMenuLevelData *)arg2; wmWindow *win = CTX_wm_window(C); uiPieMenu *pie = UI_pie_menu_begin(C, IFACE_(lvl->title), lvl->icon, win->eventstate); uiLayout *layout = UI_pie_menu_layout(pie); layout = uiLayoutRadial(layout); PointerRNA ptr; WM_operator_properties_create_ptr(&ptr, lvl->ot); /* so the context is passed to itemf functions (some need it) */ WM_operator_properties_sanitize(&ptr, false); PropertyRNA *prop = RNA_struct_find_property(&ptr, lvl->propname); if (prop) { uiItemsFullEnumO_items( layout, lvl->ot, ptr, prop, lvl->properties, lvl->context, lvl->flag, item_array, lvl->totitem); } else { RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), lvl->propname); } UI_pie_menu_end(C, pie); }
static void rna_uiItemPointerR( uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, const char *text_ctxt, bool translate, int icon) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } PropertyRNA *searchprop = RNA_struct_find_property(searchptr, searchpropname); if (!searchprop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(searchptr->type), searchpropname); return; } /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); uiItemPointerR_prop(layout, ptr, prop, searchptr, searchprop, name, icon); }
void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) { PropertyRNA *prop; PointerRNA scopesptr; uiBlock *block; rctf rect; MovieClipScopes *scopes; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } scopesptr = RNA_property_pointer_get(ptr, prop); scopes = (MovieClipScopes *)scopesptr.data; rect.xmin = 0; rect.xmax = 200; rect.ymin = 0; rect.ymax = 120; block = uiLayoutAbsoluteBlock(layout); scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); }
static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix) { int totdim, dimsize[MAX_ARRAY_DIMENSION]; int totitem, i; totdim = RNA_property_array_dimension(ptr, prop, dimsize); /* convert index */ /* arr[3][4][5] * * arr[2] = x * lvalue_dim = 0, index = 0 + 2 * 4 * 5 * * arr[2][3] = x * lvalue_dim = 1, index = 40 + 3 * 5 */ lvalue_dim++; for (i = lvalue_dim; i < totdim; i++) index *= dimsize[i]; index += arrayoffset; if (lvalue_dim == totdim) { /* single item, assign directly */ if (!check_item_type(py)) { PyErr_Format(PyExc_TypeError, "%s %.200s.%.200s, expected a %s type, not %s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), item_type_str, Py_TYPE(py)->tp_name); return -1; } copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index); } else { if (validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix) == -1) { return -1; } if (totitem) { copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index); } } return 0; }
static void rna_uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *root_ptr, const char *name, const char *text_ctxt, int translate) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); /* XXX This will search property again :( */ uiTemplatePathBuilder(layout, ptr, propname, root_ptr, name); }
static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value, const char *name, const char *text_ctxt, int translate, int icon) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); return; } /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); /* XXX This will search property again :( */ uiItemEnumR_string(layout, ptr, propname, value, name, icon); }
static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, int icon, int expand, int slider, int toggle, int icon_only, int event, int full_event, int emboss, int index) { PropertyRNA *prop= RNA_struct_find_property(ptr, propname); int flag= 0; if(!prop) { RNA_warning("rna_uiItemR: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); return; } flag |= (slider)? UI_ITEM_R_SLIDER: 0; flag |= (expand)? UI_ITEM_R_EXPAND: 0; flag |= (toggle)? UI_ITEM_R_TOGGLE: 0; flag |= (icon_only)? UI_ITEM_R_ICON_ONLY: 0; flag |= (event)? UI_ITEM_R_EVENT: 0; flag |= (full_event)? UI_ITEM_R_FULL_EVENT: 0; flag |= (emboss)? 0: UI_ITEM_R_NO_BG; uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon); }
PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) { wmOperatorType *ot; wmOperatorTypeMacro *otmacro; PyObject *macro; PointerRNA ptr_otmacro; StructRNA *srna; char *opname; const char *macroname; if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) return NULL; if (WM_operatortype_find(opname, TRUE) == NULL) { PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname); return NULL; } /* identifiers */ srna = srna_from_self(macro, "Macro Define:"); macroname = RNA_struct_identifier(srna); ot = WM_operatortype_find(macroname, TRUE); if (!ot) { PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro or hasn't been registered yet", macroname); return NULL; } otmacro = WM_operatortype_macro_define(ot, opname); RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro); return pyrna_struct_CreatePyObject(&ptr_otmacro); }
PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) { void *handle; PyObject *cls; PyObject *cb_func, *cb_args; char *cb_regiontype_str; char *cb_event_str; int cb_event; int cb_regiontype; StructRNA *srna; if (PyTuple_GET_SIZE(args) < 2) { PyErr_SetString(PyExc_ValueError, "handler_add(handle): expected at least 2 args"); return NULL; } cls = PyTuple_GET_ITEM(args, 0); if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) { return NULL; } cb_func = PyTuple_GET_ITEM(args, 1); if (!PyCallable_Check(cb_func)) { PyErr_SetString(PyExc_TypeError, "first argument isn't callable"); return NULL; } /* class specific callbacks */ if (RNA_struct_is_a(srna, &RNA_Space)) { if (!PyArg_ParseTuple(args, "OOO!ss:Space.draw_handler_add", &cls, &cb_func, /* already assigned, no matter */ &PyTuple_Type, &cb_args, &cb_regiontype_str, &cb_event_str)) { return NULL; } if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) { return NULL; } else { const eSpace_Type spaceid = rna_Space_refine_reverse(srna); if (spaceid == -1) { PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); return NULL; } else { SpaceType *st = BKE_spacetype_from_id(spaceid); ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype); handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, cb_event); Py_INCREF(args); } } } else { PyErr_SetString(PyExc_TypeError, "callback_add(): type does not support callbacks"); return NULL; } return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL); }
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact) { PropertyRNA *prop; PointerRNA imaptr; RNAUpdateCb *cb; Image *ima; ImageUser *iuser; ImBuf *ibuf; Scene *scene = CTX_data_scene(C); uiLayout *row, *split, *col; uiBlock *block; uiBut *but; char str[128]; void *lock; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } block = uiLayoutGetBlock(layout); imaptr = RNA_property_pointer_get(ptr, prop); ima = imaptr.data; iuser = userptr->data; cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); cb->ptr = *ptr; cb->prop = prop; cb->iuser = iuser; uiLayoutSetContextPointer(layout, "edit_image", &imaptr); if (!compact) uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); if (ima) { uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); if (ima->source == IMA_SRC_VIEWER) { ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str); BKE_image_release_ibuf(ima, lock); uiItemL(layout, ima->id.name + 2, ICON_NONE); uiItemL(layout, str, ICON_NONE); if (ima->type == IMA_TYPE_COMPOSITE) { // XXX not working yet #if 0 iuser = ntree_get_active_iuser(scene->nodetree); if (iuser) { uiBlockBeginAlign(block); uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, ""); uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, ""); but = uiDefBut(block, BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, ""); uiButSetFunc(but, image_freecache_cb, ima, NULL); if (iuser->frames) BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr); else strcpy(str, "Frames:"); uiBlockBeginAlign(block); uiDefButI(block, NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); uiDefButI(block, NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie"); } #endif } else if (ima->type == IMA_TYPE_R_RESULT) { /* browse layer/passes */ Render *re = RE_GetRender(scene->id.name); RenderResult *rr = RE_AcquireResultRead(re); uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot); RE_ReleaseResult(re); } } else { uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE); if (ima->source != IMA_SRC_GENERATED) { row = uiLayoutRow(layout, 1); if (ima->packedfile) uiItemO(row, "", ICON_PACKAGE, "image.unpack"); else uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); row = uiLayoutRow(row, 0); uiLayoutSetEnabled(row, ima->packedfile == NULL); uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } // XXX what was this for? #if 0 /* check for re-render, only buttons */ if (imagechanged == B_IMAGECHANGED) { if (iuser->flag & IMA_ANIM_REFRESHED) { iuser->flag &= ~IMA_ANIM_REFRESHED; WM_event_add_notifier(C, NC_IMAGE, ima); } } #endif /* multilayer? */ if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) { uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL); } else if (ima->source != IMA_SRC_GENERATED) { if (compact == 0) { ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str); BKE_image_release_ibuf(ima, lock); uiItemL(layout, str, ICON_NONE); } } if (ima->source != IMA_SRC_GENERATED) { if (compact == 0) { /* background image view doesnt need these */ uiItemS(layout); split = uiLayoutSplit(layout, 0, 0); col = uiLayoutColumn(split, 0); uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE); row = uiLayoutRow(col, 0); uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE); row = uiLayoutRow(layout, 0); uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE); uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE); } } if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { uiItemS(layout); split = uiLayoutSplit(layout, 0, 0); col = uiLayoutColumn(split, 0); BLI_snprintf(str, sizeof(str), "(%d) Frames", iuser->framenr); uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE); if (ima->anim) { block = uiLayoutGetBlock(col); but = uiDefBut(block, BUT, 0, "Match Movie Length", 0, 0, UI_UNIT_X * 2, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Set the number of frames to match the movie or sequence"); uiButSetFunc(but, set_frames_cb, ima, iuser); } uiItemR(col, userptr, "frame_start", 0, "Start", ICON_NONE); uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE); col = uiLayoutColumn(split, 0); row = uiLayoutRow(col, 0); uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); uiItemR(row, userptr, "fields_per_frame", 0, "Fields", ICON_NONE); uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE); uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE); } else if (ima->source == IMA_SRC_GENERATED) { split = uiLayoutSplit(layout, 0, 0); col = uiLayoutColumn(split, 1); uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE); uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE); uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE); uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); } } uiBlockSetNFunc(block, NULL, NULL, NULL); } MEM_freeN(cb); }
/* Modifies property array length if needed and PROP_DYNAMIC flag is set. */ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix) { int dimsize[MAX_ARRAY_DIMENSION]; int tot, totdim, len; totdim = RNA_property_array_dimension(ptr, prop, dimsize); tot = count_items(rvalue, totdim - lvalue_dim); if (tot == -1) { PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, error validating the sequence length", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); return -1; } else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { if (RNA_property_array_length(ptr, prop) != tot) { #if 0 /* length is flexible */ if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { /* BLI_snprintf(error_str, error_str_size, * "%s.%s: array length cannot be changed to %d", * RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); return -1; } #else *totitem = tot; return 0; #endif } len = tot; } else { /* length is a constraint */ if (!lvalue_dim) { len = RNA_property_array_length(ptr, prop); } /* array item assignment */ else { int i; len = 1; /* arr[3][4][5] * * arr[2] = x * dimsize = {4, 5} * dimsize[1] = 4 * dimsize[2] = 5 * lvalue_dim = 0, totdim = 3 * * arr[2][3] = x * lvalue_dim = 1 * * arr[2][3][4] = x * lvalue_dim = 2 */ for (i = lvalue_dim; i < totdim; i++) len *= dimsize[i]; } if (tot != len) { /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */ PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, sequence must have %d items total, not %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), len, tot); return -1; } } *totitem = len; return 0; }
PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *args) { PyObject *cls; PyObject *py_handle; void *handle; void *customdata; StructRNA *srna; char *cb_regiontype_str; int cb_regiontype; if (PyTuple_GET_SIZE(args) < 2) { PyErr_SetString(PyExc_ValueError, "callback_remove(handle): expected at least 2 args"); return NULL; } cls = PyTuple_GET_ITEM(args, 0); if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) { return NULL; } py_handle = PyTuple_GET_ITEM(args, 1); handle = PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID); if (handle == NULL) { PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed"); return NULL; } if (RNA_struct_is_a(srna, &RNA_Space)) { if (!PyArg_ParseTuple(args, "OO!s:Space.draw_handler_remove", &cls, &PyCapsule_Type, &py_handle, /* already assigned, no matter */ &cb_regiontype_str)) { return NULL; } customdata = ED_region_draw_cb_customdata(handle); Py_DECREF((PyObject *)customdata); if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) { return NULL; } else { const eSpace_Type spaceid = rna_Space_refine_reverse(srna); if (spaceid == -1) { PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna)); return NULL; } else { SpaceType *st = BKE_spacetype_from_id(spaceid); ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype); ED_region_draw_cb_exit(art, handle); } } } else { PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks"); return NULL; } /* don't allow reuse */ PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID); Py_RETURN_NONE; }
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact) { #define MAX_INFO_LEN 128 PropertyRNA *prop; PointerRNA imaptr; RNAUpdateCb *cb; Image *ima; ImageUser *iuser; Scene *scene = CTX_data_scene(C); uiLayout *row, *split, *col; uiBlock *block; char str[MAX_INFO_LEN]; void *lock; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } block = uiLayoutGetBlock(layout); imaptr = RNA_property_pointer_get(ptr, prop); ima = imaptr.data; iuser = userptr->data; BKE_image_user_check_frame_calc(iuser, (int)scene->r.cfra, 0); cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); cb->ptr = *ptr; cb->prop = prop; cb->iuser = iuser; uiLayoutSetContextPointer(layout, "edit_image", &imaptr); uiLayoutSetContextPointer(layout, "edit_image_user", userptr); if (!compact) uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); if (ima) { uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); if (ima->source == IMA_SRC_VIEWER) { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN); BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, ima->id.name + 2, ICON_NONE); uiItemL(layout, str, ICON_NONE); if (ima->type == IMA_TYPE_COMPOSITE) { // XXX not working yet #if 0 iuser = ntree_get_active_iuser(scene->nodetree); if (iuser) { uiBlockBeginAlign(block); uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, ""); uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, ""); but = uiDefBut(block, BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, ""); uiButSetFunc(but, image_freecache_cb, ima, NULL); if (iuser->frames) BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr); else strcpy(str, "Frames:"); uiBlockBeginAlign(block); uiDefButI(block, NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use"); uiDefButI(block, NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie"); } #endif } else if (ima->type == IMA_TYPE_R_RESULT) { /* browse layer/passes */ RenderResult *rr; /* use BKE_image_acquire_renderresult so we get the correct slot in the menu */ rr = BKE_image_acquire_renderresult(scene, ima); uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot); BKE_image_release_renderresult(scene, ima); } } else { uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE); if (ima->source != IMA_SRC_GENERATED) { row = uiLayoutRow(layout, TRUE); if (ima->packedfile) uiItemO(row, "", ICON_PACKAGE, "image.unpack"); else uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); row = uiLayoutRow(row, TRUE); uiLayoutSetEnabled(row, ima->packedfile == NULL); uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } // XXX what was this for? #if 0 /* check for re-render, only buttons */ if (imagechanged == B_IMAGECHANGED) { if (iuser->flag & IMA_ANIM_REFRESHED) { iuser->flag &= ~IMA_ANIM_REFRESHED; WM_event_add_notifier(C, NC_IMAGE, ima); } } #endif /* multilayer? */ if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) { uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL); } else if (ima->source != IMA_SRC_GENERATED) { if (compact == 0) { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN); BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, str, ICON_NONE); } } col = uiLayoutColumn(layout, FALSE); uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings"); uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE); if (ima->source != IMA_SRC_GENERATED) { if (compact == 0) { /* background image view doesnt need these */ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); int has_alpha = TRUE; if (ibuf) { int imtype = BKE_ftype_to_imtype(ibuf->ftype); char valid_channels = BKE_imtype_valid_channels(imtype); has_alpha = valid_channels & IMA_CHAN_FLAG_ALPHA; BKE_image_release_ibuf(ima, ibuf, NULL); } if (has_alpha) { col = uiLayoutColumn(layout, FALSE); uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE); uiItemR(col, &imaptr, "alpha_mode", 0, "Alpha", ICON_NONE); } uiItemS(layout); split = uiLayoutSplit(layout, 0.0f, FALSE); col = uiLayoutColumn(split, FALSE); /* XXX Why only display fields_per_frame only for video image types? * And why allow fields for non-video image types at all??? */ if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { uiLayout *subsplit = uiLayoutSplit(col, 0.0f, FALSE); uiLayout *subcol = uiLayoutColumn(subsplit, FALSE); uiItemR(subcol, &imaptr, "use_fields", 0, NULL, ICON_NONE); subcol = uiLayoutColumn(subsplit, FALSE); uiLayoutSetActive(subcol, RNA_boolean_get(&imaptr, "use_fields")); uiItemR(subcol, userptr, "fields_per_frame", 0, IFACE_("Fields"), ICON_NONE); } else uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE); row = uiLayoutRow(col, FALSE); uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE); } } if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { uiItemS(layout); split = uiLayoutSplit(layout, 0.0f, FALSE); col = uiLayoutColumn(split, FALSE); BLI_snprintf(str, sizeof(str), IFACE_("(%d) Frames"), iuser->framenr); uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE); uiItemR(col, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE); uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE); col = uiLayoutColumn(split, FALSE); uiItemO(col, NULL, ICON_NONE, "IMAGE_OT_match_movie_length"); uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE); uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE); } else if (ima->source == IMA_SRC_GENERATED) { split = uiLayoutSplit(layout, 0.0f, FALSE); col = uiLayoutColumn(split, TRUE); uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE); uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE); uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE); uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); } } uiBlockSetNFunc(block, NULL, NULL, NULL); } MEM_freeN(cb); #undef MAX_INFO_LEN }
void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact) { PropertyRNA *prop; uiBlock *block; uiBut *bt; PointerRNA clipptr; MovieClip *clip; MovieClipUser *user; MovieTrackingTrack *track; MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; float pat_min[2], pat_max[2]; if (!ptr->data) return; prop = RNA_struct_find_property(ptr, propname); if (!prop) { printf("%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } if (RNA_property_type(prop) != PROP_POINTER) { printf("%s: expected pointer property for %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); return; } clipptr = RNA_property_pointer_get(ptr, prop); clip = (MovieClip *)clipptr.data; user = userptr->data; track = trackptr->data; marker = BKE_tracking_marker_get(track, user->framenr); cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb"); cb->compact = compact; cb->clip = clip; cb->user = user; cb->track = track; cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; if (compact) { block = uiLayoutGetBlock(layout); if (cb->marker_flag & MARKER_DISABLED) tip = "Marker is disabled at current frame"; else tip = "Marker is enabled at current frame"; bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, tip); uiButSetNFunc(bt, marker_update_cb, cb, NULL); } else { int width, height, step, digits; float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); if (track->flag & TRACK_LOCKED) { uiLayoutSetActive(layout, FALSE); block = uiLayoutAbsoluteBlock(layout); uiDefBut(block, LABEL, 0, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, ""); return; } step = 100; digits = 2; BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); sub_v2_v2v2(pat_dim, pat_max, pat_min); sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); add_v2_v2v2(search_pos, marker->search_max, marker->search_min); mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); to_pixel_space(cb->marker_pat, pat_dim, width, height); to_pixel_space(cb->marker_search, search_dim, width, height); to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; block = uiLayoutAbsoluteBlock(layout); uiBlockSetHandleFunc(block, marker_block_handler, cb); uiBlockSetNFunc(block, marker_update_cb, cb, NULL); if (cb->marker_flag & MARKER_DISABLED) tip = "Marker is disabled at current frame"; else tip = "Marker is enabled at current frame"; uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag, 0, 0, 0, 0, tip); col = uiLayoutColumn(layout, TRUE); uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0); block = uiLayoutAbsoluteBlock(col); uiBlockBeginAlign(block); uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0], -10 * width, 10.0 * width, step, digits, "X-position of marker at frame in screen coordinates"); uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1], -10 * height, 10.0 * height, step, digits, "Y-position of marker at frame in screen coordinates"); uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0], -10 * width, 10.0 * width, step, digits, "X-offset to parenting point"); uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1], -10 * height, 10.0 * height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0 * width, step, digits, "Width of marker's pattern in screen coordinates"); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0 * height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0 * width, step, digits, "Width of marker's search in screen soordinates"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0 * height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); } }