/* Assign selected pchans to the bone group that the user selects */ static int pose_group_assign_exec(bContext *C, wmOperator *op) { Object *ob = ED_pose_object_from_context(C); bPose *pose; bool done = false; /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; pose = ob->pose; /* set the active group number to the one from operator props * - if 0 after this, make a new group... */ pose->active_group = RNA_int_get(op->ptr, "type"); if (pose->active_group == 0) BKE_pose_add_group(ob->pose, NULL); /* add selected bones to group then */ CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) { pchan->agrp_index = pose->active_group; done = true; }
/* invoke callback which presents a list of bone-groups for the user to choose from */ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Object *ob = ED_pose_object_from_context(C); bPose *pose; PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type"); uiPopupMenu *pup; uiLayout *layout; bActionGroup *grp; int i; /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; pose = ob->pose; /* If group index is set, try to use it! */ if (RNA_property_is_set(op->ptr, prop)) { const int num_groups = BLI_listbase_count(&pose->agroups); const int group = RNA_property_int_get(op->ptr, prop); /* just use the active group index, and call the exec callback for the calling operator */ if (group > 0 && group <= num_groups) { return op->type->exec(C, op); } } /* if there's no active group (or active is invalid), create a new menu to find it */ if (pose->active_group <= 0) { /* create a new menu, and start populating it with group names */ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); layout = UI_popup_menu_layout(pup); /* special entry - allow to create new group, then use that * (not to be used for removing though) */ if (strstr(op->idname, "assign")) { uiItemIntO(layout, "New Group", ICON_NONE, op->idname, "type", 0); uiItemS(layout); } /* add entries for each group */ for (grp = pose->agroups.first, i = 1; grp; grp = grp->next, i++) uiItemIntO(layout, grp->name, ICON_NONE, op->idname, "type", i); /* finish building the menu, and process it (should result in calling self again) */ UI_popup_menu_end(C, pup); return OPERATOR_INTERFACE; } else { /* just use the active group index, and call the exec callback for the calling operator */ RNA_int_set(op->ptr, "type", pose->active_group); return op->type->exec(C, op); } }
static int pose_group_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_pose_object_from_context(C); /* only continue if there's an object and pose */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; /* for now, just call the API function for this */ BKE_pose_remove_group_index(ob->pose, ob->pose->active_group); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); return OPERATOR_FINISHED; }
static int pose_group_add_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_pose_object_from_context(C); /* only continue if there's an object */ if (ob == NULL) return OPERATOR_CANCELLED; /* for now, just call the API function for this */ BKE_pose_add_group(ob); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); return OPERATOR_FINISHED; }