diff options
-rw-r--r-- | release/scripts/ui/properties_data_armature.py | 45 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/armature/poselib.c | 114 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_action.c | 15 |
5 files changed, 174 insertions, 7 deletions
diff --git a/release/scripts/ui/properties_data_armature.py b/release/scripts/ui/properties_data_armature.py index 6550e1bb1ed..566cf1dc3cc 100644 --- a/release/scripts/ui/properties_data_armature.py +++ b/release/scripts/ui/properties_data_armature.py @@ -154,6 +154,51 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel): sub.operator("pose.group_deselect", text="Deselect") +class DATA_PT_pose_library(ArmatureButtonsPanel, bpy.types.Panel): + bl_label = "Pose Library" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return (context.object and context.object.type == 'ARMATURE' and context.object.pose) + + def draw(self, context): + layout = self.layout + + ob = context.object + poselib = ob.pose_library + + row = layout.row() + row.template_ID(ob, "pose_library", new="poselib.new", unlink="poselib.unlink") + + if poselib: + activePoseIndex = poselib.pose_markers.active_index + if len(poselib.pose_markers): + activePose = poselib.pose_markers[activePoseIndex] + activePoseName = activePose.name if activePose else None + else: + activePose = None + activePoseName = None + + row = layout.row() + row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5) + + col = row.column(align=True) + col.active = (poselib.library is None) + + # invoke should still be used for 'add', as it is needed to allow + # add/replace options to be used properly + col.operator("poselib.pose_add", icon='ZOOMIN', text="") + + col.operator_context = 'EXEC_DEFAULT' # exec not invoke, so that menu doesn't need showing + col.operator("poselib.pose_remove", icon='ZOOMOUT', text="").pose = activePoseName + + # TODO: + # - show selected pose in 3d-view using browse op... + # - rename selected pose... + + # TODO: "validate action" operator to be restored + # TODO: this panel will soon be depreceated too class DATA_PT_ghost(ArmatureButtonsPanel, bpy.types.Panel): bl_label = "Ghost" diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index fd54d10fd88..580579990bd 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -171,9 +171,13 @@ LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, cha /* PoseLib */ /* poselib.c */ +void POSELIB_OT_new(struct wmOperatorType *ot); +void POSELIB_OT_unlink(struct wmOperatorType *ot); + void POSELIB_OT_pose_add(struct wmOperatorType *ot); void POSELIB_OT_pose_remove(struct wmOperatorType *ot); void POSELIB_OT_pose_rename(struct wmOperatorType *ot); + void POSELIB_OT_browse_interactive(struct wmOperatorType *ot); /* ******************************************************* */ diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index e28c7e9a6f1..37978244b15 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -147,6 +147,9 @@ void ED_operatortypes_armature(void) WM_operatortype_append(POSELIB_OT_pose_remove); WM_operatortype_append(POSELIB_OT_pose_rename); + WM_operatortype_append(POSELIB_OT_new); + WM_operatortype_append(POSELIB_OT_unlink); + /* POSE SLIDING */ WM_operatortype_append(POSE_OT_push); WM_operatortype_append(POSE_OT_relax); diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 2b30af6bc17..22aca8014cd 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -50,6 +50,7 @@ #include "BKE_armature.h" #include "BKE_depsgraph.h" #include "BKE_idprop.h" +#include "BKE_library.h" #include "BKE_context.h" #include "BKE_report.h" @@ -180,7 +181,7 @@ static bAction *poselib_init_new (Object *ob) /* init object's poselib action (unlink old one if there) */ if (ob->poselib) - ob->poselib->id.us--; + id_us_min(&ob->poselib->id); ob->poselib= add_empty_action("PoseLib"); return ob->poselib; @@ -232,13 +233,10 @@ static void poselib_validate_act (bAction *act) /* add new if none found */ if (marker == NULL) { - char name[64]; - /* add pose to poselib */ marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker"); - strcpy(name, "Pose"); - BLI_strncpy(marker->name, name, sizeof(marker->name)); + BLI_strncpy(marker->name, "Pose", sizeof(marker->name)); marker->frame= (int)ak->cfra; marker->flag= -1; @@ -264,6 +262,107 @@ static void poselib_validate_act (bAction *act) } /* ************************************************************* */ +/* Pose Lib UI Operators */ + +static int poselib_new_exec (bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + Object *ob; + + /* get object to add Pose Lib to */ + if (sa->spacetype == SPACE_BUTS) + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + else + ob= ED_object_pose_armature(CTX_data_active_object(C)); + + /* sanity checks */ + if (ob == NULL) + return OPERATOR_CANCELLED; + + /* new method here deals with the rest... */ + poselib_init_new(ob); + + /* notifier here might evolve? */ + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + + return OPERATOR_FINISHED; +} + +void POSELIB_OT_new (wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Pose Library"; + ot->idname = "POSELIB_OT_new"; + ot->description = "Add New Pose Library to active Object"; + + /* callbacks */ + ot->exec = poselib_new_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ------------------------------------------------ */ + +static int poselib_unlink_poll (bContext *C) +{ + /* object must exist, and so must a poselib */ + ScrArea *sa = CTX_wm_area(C); + Object *ob; + + /* get object to add Pose Lib to */ + if (sa->spacetype == SPACE_BUTS) + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + else + ob= ED_object_pose_armature(CTX_data_active_object(C)); + + /* sanity checks */ + return (ob && ob->poselib); +} + +static int poselib_unlink_exec (bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + Object *ob; + + /* get object to add Pose Lib to */ + if (sa->spacetype == SPACE_BUTS) + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + else + ob= ED_object_pose_armature(CTX_data_active_object(C)); + + /* sanity checks */ + if (ELEM(NULL, ob, ob->poselib)) + return OPERATOR_CANCELLED; + + /* there should be a poselib (we just checked above!), so just lower its user count and remove */ + id_us_min(&ob->poselib->id); + ob->poselib = NULL; + + /* notifier here might evolve? */ + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + + return OPERATOR_FINISHED; +} + +void POSELIB_OT_unlink (wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink Pose Library"; + ot->idname = "POSELIB_OT_unlink"; + ot->description = "Remove Pose Library from active Object"; + + /* callbacks */ + ot->exec = poselib_unlink_exec; + ot->poll= ED_operator_posemode; // TODO: this here should require that a poselib exists! + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ************************************************************* */ +/* Pose Editing Operators */ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout, void *UNUSED(arg)) { @@ -370,7 +469,7 @@ static int poselib_add_exec (bContext *C, wmOperator *op) ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame); /* store new 'active' pose number */ - act->active_marker= BLI_countlist(&act->markers); + act->active_marker= BLI_countlist(&act->markers) - 1; /* done */ return OPERATOR_FINISHED; @@ -444,7 +543,7 @@ static int poselib_remove_exec (bContext *C, wmOperator *op) /* get index (and pointer) of pose to remove */ marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_reportf(op->reports, RPT_ERROR, "Invalid Pose specified %d", RNA_int_get(op->ptr, "pose")); return OPERATOR_CANCELLED; } @@ -583,6 +682,7 @@ void POSELIB_OT_pose_rename (wmOperatorType *ot) } /* ************************************************************* */ +/* Pose-Lib Browsing/Previewing Operator */ /* Simple struct for storing settings/data for use during PoseLib preview */ typedef struct tPoseLib_PreviewData { diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index f9f6478cc3d..6cfd122d08e 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -149,6 +149,15 @@ static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, Ti MEM_freeN(marker); } +static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min, int *max) +{ + bAction *act= (bAction *)ptr->data; + + *min= 0; + *max= BLI_countlist(&act->markers)-1; + *max= MAX2(0, *max); +} + static void rna_Action_frame_range_get(PointerRNA *ptr,float *values) { calc_action_range(ptr->id.data, values, values+1, 1); @@ -422,6 +431,7 @@ static void rna_def_action_fcurves(BlenderRNA *brna, PropertyRNA *cprop) static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; + PropertyRNA *prop; FunctionRNA *func; PropertyRNA *parm; @@ -445,6 +455,11 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); parm= RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove."); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); + + prop= RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "active_marker"); + RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Action_active_pose_marker_index_range"); + RNA_def_property_ui_text(prop, "Active Pose Marker Index", "Index of active pose marker"); } static void rna_def_action(BlenderRNA *brna) |