static int datadropper_init(bContext *C, wmOperator *op) { DataDropper *ddr; int index_dummy; StructRNA *type; SpaceType *st; ARegionType *art; st = BKE_spacetype_from_id(SPACE_VIEW3D); art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW); op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper"); UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy); if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) || (RNA_property_editable(&ddr->ptr, ddr->prop) == false) || (RNA_property_type(ddr->prop) != PROP_POINTER)) { return false; } ddr->art = art; ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL); type = RNA_property_pointer_type(&ddr->ptr, ddr->prop); ddr->idcode = RNA_type_to_ID_code(type); BLI_assert(ddr->idcode != 0); /* Note we can translate here (instead of on draw time), because this struct has very short lifetime. */ ddr->idcode_name = TIP_(BKE_idcode_to_name(ddr->idcode)); PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop); ddr->init_id = ptr.id.data; return true; }
static int depthdropper_poll(bContext *C) { PointerRNA ptr; PropertyRNA *prop; int index_dummy; uiBut *but; /* check if there's an active button taking depth value */ if ((CTX_wm_window(C) != NULL) && (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) && (but->type == UI_BTYPE_NUM) && (prop != NULL)) { if ((RNA_property_type(prop) == PROP_FLOAT) && (RNA_property_subtype(prop) & PROP_UNIT_LENGTH) && (RNA_property_array_check(prop) == false)) { return 1; } } return 0; }
static int copy_data_path_button_exec(bContext *C, wmOperator *op) { PointerRNA ptr; PropertyRNA *prop; char *path; int index; const bool full_path = RNA_boolean_get(op->ptr, "full_path"); /* try to create driver using property retrieved from UI */ UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data != NULL) { if (full_path) { if (prop) { path = RNA_path_full_property_py_ex(&ptr, prop, index, true); } else { path = RNA_path_full_struct_py(&ptr); } } else { path = RNA_path_from_ID_to_property(&ptr, prop); } if (path) { WM_clipboard_text_set(path, false); MEM_freeN(path); return OPERATOR_FINISHED; } } return OPERATOR_CANCELLED; }
/* Filtering callback for driver mapping types enum */ static EnumPropertyItem *driver_mapping_type_itemsf(bContext *C, PointerRNA *UNUSED(owner_ptr), PropertyRNA *UNUSED(owner_prop), bool *r_free) { EnumPropertyItem *input = prop_driver_create_mapping_types; EnumPropertyItem *item = NULL; PointerRNA ptr = {{NULL}}; PropertyRNA *prop = NULL; int index; int totitem = 0; if (!C) /* needed for docs */ return prop_driver_create_mapping_types; UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { const bool is_array = RNA_property_array_check(prop); while (input->identifier) { if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) { RNA_enum_item_add(&item, &totitem, input); } input++; } } else { /* We need at least this one! */ RNA_enum_items_add_value(&item, &totitem, input, CREATEDRIVER_MAPPING_NONE); } RNA_enum_item_end(&item, &totitem); *r_free = true; return item; }
static int datadropper_poll(bContext *C) { PointerRNA ptr; PropertyRNA *prop; int index_dummy; uiBut *but; /* data dropper only supports object data */ if ((CTX_wm_window(C) != NULL) && (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) && (but->type == UI_BTYPE_SEARCH_MENU) && (but->flag & UI_BUT_SEARCH_UNLINK)) { if (prop && RNA_property_type(prop) == PROP_POINTER) { StructRNA *type = RNA_property_pointer_type(&ptr, prop); const short idcode = RNA_type_to_ID_code(type); if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) { return 1; } } } return 0; }
/** * called from both exec & poll * * \note: normally we wouldn't call a loop from within a poll function, * However this is a special case, and for regular poll calls, getting * the context from the button will fail early. */ static bool copy_to_selected_button(bContext *C, bool all, bool poll) { Main *bmain = CTX_data_main(C); PointerRNA ptr, lptr, idptr; PropertyRNA *prop, *lprop; bool success = false; int index; /* try to reset the nominated setting to its default value */ UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* if there is a valid property that is editable... */ if (ptr.data && prop) { char *path = NULL; bool use_path_from_id; CollectionPointerLink *link; ListBase lb = {NULL}; if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) && !BLI_listbase_is_empty(&lb)) { for (link = lb.first; link; link = link->next) { if (link->ptr.data != ptr.data) { if (use_path_from_id) { /* Path relative to ID. */ lprop = NULL; RNA_id_pointer_create(link->ptr.id.data, &idptr); RNA_path_resolve_property(&idptr, path, &lptr, &lprop); } else if (path) { /* Path relative to elements from list. */ lprop = NULL; RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop); } else { lptr = link->ptr; lprop = prop; } if (lptr.data == ptr.data) { /* lptr might not be the same as link->ptr! */ continue; } if (lprop == prop) { if (RNA_property_editable(&lptr, lprop)) { if (poll) { success = true; break; } else { if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) { RNA_property_update(C, &lptr, prop); success = true; } } } } } } } MEM_SAFE_FREE(path); BLI_freelistN(&lb); } return success; }
static int override_remove_button_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); PointerRNA ptr, id_refptr, src; PropertyRNA *prop; int index; const bool all = RNA_boolean_get(op->ptr, "all"); /* try to reset the nominated setting to its default value */ UI_context_active_but_prop_get(C, &ptr, &prop, &index); ID *id = ptr.id.data; IDOverrideStaticProperty *oprop = RNA_property_override_property_find(&ptr, prop); BLI_assert(oprop != NULL); BLI_assert(id != NULL && id->override_static != NULL); const bool is_template = (id->override_static->reference == NULL); /* We need source (i.e. linked data) to restore values of deleted overrides... * If this is an override template, we obviously do not need to restore anything. */ if (!is_template) { RNA_id_pointer_create(id->override_static->reference, &id_refptr); if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) { BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer"); } } if (!all && index != -1) { bool is_strict_find; /* Remove override operation for given item, * add singular operations for the other items as needed. */ IDOverrideStaticPropertyOperation *opop = BKE_override_static_property_operation_find( oprop, NULL, NULL, index, index, false, &is_strict_find); BLI_assert(opop != NULL); if (!is_strict_find) { /* No specific override operation, we have to get generic one, * and create item-specific override operations for all but given index, * before removing generic one. */ for (int idx = RNA_property_array_length(&ptr, prop); idx--;) { if (idx != index) { BKE_override_static_property_operation_get( oprop, opop->operation, NULL, NULL, idx, idx, true, NULL, NULL); } } } BKE_override_static_property_operation_delete(oprop, opop); if (!is_template) { RNA_property_copy(bmain, &ptr, &src, prop, index); } if (BLI_listbase_is_empty(&oprop->operations)) { BKE_override_static_property_delete(id->override_static, oprop); } } else { /* Just remove whole generic override operation of this property. */ BKE_override_static_property_delete(id->override_static, oprop); if (!is_template) { RNA_property_copy(bmain, &ptr, &src, prop, -1); } } return operator_button_property_finish(C, &ptr, prop); }