[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38174] branches/soc-2011-pepper: Patch [ #23682] Add sort+move to bone group list in panel

Joshua Leung aligorith at gmail.com
Thu Jul 7 06:31:55 CEST 2011


Revision: 38174
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38174
Author:   aligorith
Date:     2011-07-07 04:31:53 +0000 (Thu, 07 Jul 2011)
Log Message:
-----------
Patch [#23682] Add sort+move to bone group list in panel

Thanks  Torsten Rupp (rupp)   for the patch!

This patch adds the abilities to sort the bone group list in the
properties panel and to move bone groups up/down in the list (similar
like for vertex groups)

Modified Paths:
--------------
    branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
    branches/soc-2011-pepper/source/blender/editors/armature/armature_intern.h
    branches/soc-2011-pepper/source/blender/editors/armature/armature_ops.c
    branches/soc-2011-pepper/source/blender/editors/armature/poseobject.c

Modified: branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py	2011-07-07 03:53:24 UTC (rev 38173)
+++ branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py	2011-07-07 04:31:53 UTC (rev 38174)
@@ -96,6 +96,16 @@
         col.prop(arm, "use_deform_delay", text="Delay Refresh")
 
 
+class DATA_PT_bone_group_specials(bpy.types.Menu):
+    bl_label = "Bone Group Specials"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("pose.group_sort", icon='SORTALPHA')
+
+
 class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
     bl_label = "Bone Groups"
 
@@ -108,16 +118,25 @@
 
         ob = context.object
         pose = ob.pose
+        group = pose.bone_groups.active
 
         row = layout.row()
-        row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=2)
 
+        rows = 2
+        if group:
+            rows = 5
+        row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
+
         col = row.column(align=True)
         col.active = (ob.proxy is None)
         col.operator("pose.group_add", icon='ZOOMIN', text="")
         col.operator("pose.group_remove", icon='ZOOMOUT', text="")
+        col.menu("DATA_PT_bone_group_specials", icon='DOWNARROW_HLT', text="")
+        if group:
+            col.separator()
+            col.operator("pose.group_move", icon='TRIA_UP', text="").direction = 'UP'
+            col.operator("pose.group_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
 
-        group = pose.bone_groups.active
         if group:
             col = layout.column()
             col.active = (ob.proxy is None)

Modified: branches/soc-2011-pepper/source/blender/editors/armature/armature_intern.h
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/armature/armature_intern.h	2011-07-07 03:53:24 UTC (rev 38173)
+++ branches/soc-2011-pepper/source/blender/editors/armature/armature_intern.h	2011-07-07 04:31:53 UTC (rev 38174)
@@ -110,6 +110,8 @@
 
 void POSE_OT_group_add(struct wmOperatorType *ot);
 void POSE_OT_group_remove(struct wmOperatorType *ot);
+void POSE_OT_group_move(struct wmOperatorType *ot);
+void POSE_OT_group_sort(struct wmOperatorType *ot);
 void POSE_OT_group_assign(struct wmOperatorType *ot);
 void POSE_OT_group_unassign(struct wmOperatorType *ot);
 void POSE_OT_group_select(struct wmOperatorType *ot);

Modified: branches/soc-2011-pepper/source/blender/editors/armature/armature_ops.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/armature/armature_ops.c	2011-07-07 03:53:24 UTC (rev 38173)
+++ branches/soc-2011-pepper/source/blender/editors/armature/armature_ops.c	2011-07-07 04:31:53 UTC (rev 38174)
@@ -126,6 +126,8 @@
 	
 	WM_operatortype_append(POSE_OT_group_add);
 	WM_operatortype_append(POSE_OT_group_remove);
+	WM_operatortype_append(POSE_OT_group_move);
+	WM_operatortype_append(POSE_OT_group_sort);
 	WM_operatortype_append(POSE_OT_group_assign);
 	WM_operatortype_append(POSE_OT_group_unassign);
 	WM_operatortype_append(POSE_OT_group_select);

Modified: branches/soc-2011-pepper/source/blender/editors/armature/poseobject.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/armature/poseobject.c	2011-07-07 03:53:24 UTC (rev 38173)
+++ branches/soc-2011-pepper/source/blender/editors/armature/poseobject.c	2011-07-07 04:31:53 UTC (rev 38174)
@@ -1433,6 +1433,171 @@
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+static int group_move_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	bPose *pose= (ob) ? ob->pose : NULL;
+	bPoseChannel *pchan;
+	bActionGroup *grp;
+	int dir= RNA_enum_get(op->ptr, "direction");
+	int grpIndexA, grpIndexB;
+
+	if (ELEM(NULL, ob, pose))
+		return OPERATOR_CANCELLED;
+	if (pose->active_group <= 0)
+		return OPERATOR_CANCELLED;
+
+	/* get group to move */
+	grp= BLI_findlink(&pose->agroups, pose->active_group-1);
+	if (grp == NULL)
+		return OPERATOR_CANCELLED;
+
+	/* move bone group */
+	grpIndexA = pose->active_group;
+	if (dir == 1) { /* up */
+		void *prev = grp->prev;
+		
+		if (prev == NULL)
+			return OPERATOR_FINISHED;
+			
+		BLI_remlink(&pose->agroups, grp);
+		BLI_insertlinkbefore(&pose->agroups, prev, grp);
+		
+		grpIndexB = grpIndexA - 1;
+		pose->active_group--;
+	}
+	else { /* down */
+		void *next = grp->next;
+		
+		if (next == NULL)
+			return OPERATOR_FINISHED;
+			
+		BLI_remlink(&pose->agroups, grp);
+		BLI_insertlinkafter(&pose->agroups, next, grp);
+		
+		grpIndexB = grpIndexA + 1;
+		pose->active_group++;
+	}
+
+	/* fix changed bone group indices in bones (swap grpIndexA with grpIndexB) */
+	for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+		if (pchan->agrp_index == grpIndexB)
+			pchan->agrp_index= grpIndexA;
+		else if (pchan->agrp_index == grpIndexA)
+			pchan->agrp_index= grpIndexB;
+	}
+
+	/* notifiers for updates */
+	WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void POSE_OT_group_move(wmOperatorType *ot)
+{
+	static EnumPropertyItem group_slot_move[] = {
+		{1, "UP", 0, "Up", ""},
+		{-1, "DOWN", 0, "Down", ""},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	/* identifiers */
+	ot->name= "Move Bone Group";
+	ot->idname= "POSE_OT_group_move";
+	ot->description= "Change position of active Bone Group in list of Bone Groups";
+
+	/* api callbacks */
+	ot->exec= group_move_exec;
+	ot->poll= ED_operator_posemode;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_enum(ot->srna, "direction", group_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
+/* bone group sort element */
+typedef struct tSortActionGroup {
+	bActionGroup *agrp;
+	int          index;
+} tSortActionGroup;
+
+/* compare bone groups by name */
+static int compare_agroup(const void *sgrp_a_ptr, const void *sgrp_b_ptr)
+{
+	tSortActionGroup *sgrp_a= (tSortActionGroup *)sgrp_a_ptr;
+	tSortActionGroup *sgrp_b= (tSortActionGroup *)sgrp_b_ptr;
+
+	return strcmp(sgrp_a->agrp->name, sgrp_b->agrp->name);
+}
+
+static int group_sort_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	bPose *pose= (ob) ? ob->pose : NULL;
+	bPoseChannel *pchan;
+	tSortActionGroup *agrp_array;
+	bActionGroup *agrp;
+	int agrp_count;
+	int i;
+
+	if (ELEM(NULL, ob, pose))
+		return OPERATOR_CANCELLED;
+	if (pose->active_group <= 0)
+		return OPERATOR_CANCELLED;
+
+	/* create temporary array with bone groups and indices */
+	agrp_count = BLI_countlist(&pose->agroups);
+	agrp_array = MEM_mallocN(sizeof(tSortActionGroup) * agrp_count, "sort bone groups");
+	for (agrp= pose->agroups.first, i= 0; agrp; agrp= agrp->next, i++) {
+		BLI_assert(i < agrp_count);
+		agrp_array[i].agrp = agrp;
+		agrp_array[i].index = i+1;
+	}
+
+	/* sort bone groups by name */
+	qsort(agrp_array, agrp_count, sizeof(tSortActionGroup), compare_agroup);
+
+	/* create sorted bone group list from sorted array */
+	pose->agroups.first= pose->agroups.last= NULL;
+	for (i= 0; i < agrp_count; i++) {
+		BLI_addtail(&pose->agroups, agrp_array[i].agrp);
+	}
+
+	/* fix changed bone group indizes in bones */
+	for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+		for (i= 0; i < agrp_count; i++) {
+			if (pchan->agrp_index == agrp_array[i].index) {
+				pchan->agrp_index= i+1;
+				break;
+			}
+		}
+	}
+
+	/* free temp resources */
+	MEM_freeN(agrp_array);
+
+	/* notifiers for updates */
+	WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void POSE_OT_group_sort(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Sort Bone Groups";
+	ot->idname= "POSE_OT_group_sort";
+	ot->description= "Sort Bone Groups by their names in ascending order";
+
+	/* api callbacks */
+	ot->exec= group_sort_exec;
+	ot->poll= ED_operator_posemode;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 static void pose_group_select(bContext *C, Object *ob, int select)
 {
 	bPose *pose= ob->pose;




More information about the Bf-blender-cvs mailing list