From 7284eb6d9119f70766242f490a0dc841e01cc585 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 21 Jul 2009 12:38:01 +0000 Subject: 2.5 - More work on Bone Groups * Added a new UI Template for the 3-colour picker used to visualise + select the custom colours for a bone group. * Finished wrapping the colour properties for Bone Groups in RNA. Although changing the colour-set used will change the displayed/cached colours, changing the colours via the colour wells will not change the colour set to 'custom' (as per 2.4x) yet. This needs a nice solution... * Fixed context-related bugs with the Assign/Remove operators for bone groups. These were using context-iterators for selected posechannels, but that was only defined/valid for the 3d view (but not for the buttons window), hence a failure in that case. --- source/blender/editors/armature/poseobject.c | 99 ++++++++-------------- source/blender/editors/include/UI_interface.h | 1 + .../editors/interface/interface_templates.c | 35 +++++++- source/blender/makesrna/intern/rna_pose.c | 91 ++++++++++++++++++-- source/blender/makesrna/intern/rna_ui_api.c | 3 + 5 files changed, 156 insertions(+), 73 deletions(-) (limited to 'source') diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index d753cf39f69..eface169387 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1035,7 +1035,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) ob= CTX_data_active_object(C); /* only continue if there's an object, and a pose there too */ - if (ELEM(NULL, ob, ob->pose)) + if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; pose= ob->pose; @@ -1065,7 +1065,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) 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; + return op->type->exec(C, op); } } @@ -1074,7 +1074,9 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); Object *ob; + bArmature *arm; bPose *pose; + bPoseChannel *pchan; short done= 0; /* since this call may also be used from the buttons window, we need to check for where to get the object */ @@ -1086,18 +1088,29 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; + arm= ob->data; pose= ob->pose; - /* set the active group number to the one from operator props */ + /* 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) + pose_add_group(ob); /* add selected bones to group then */ - CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) - { - pchan->agrp_index= pose->active_group; - done= 1; + // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined... + // CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { + /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ + // NOTE: sync this view3d_context() in space_view3d.c + if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { + if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) { + pchan->agrp_index= pose->active_group; + done= 1; + } + } } - CTX_DATA_END; /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1133,7 +1146,9 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); Object *ob; + bArmature *arm; bPose *pose; + bPoseChannel *pchan; short done= 0; /* since this call may also be used from the buttons window, we need to check for where to get the object */ @@ -1146,16 +1161,23 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op) if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; pose= ob->pose; + arm= ob->data; /* add selected bones to ungroup then */ - CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) - { - if (pchan->agrp_index) { - pchan->agrp_index= 0; - done= 1; + // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined... + // CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { + /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ + // NOTE: sync this view3d_context() in space_view3d.c + if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { + if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) { + if (pchan->agrp_index) { + pchan->agrp_index= 0; + done= 1; + } + } } } - CTX_DATA_END; /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1228,55 +1250,6 @@ void POSE_OT_groups_menu (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER; } -#if 0 -/* Ctrl-G in 3D-View while in PoseMode */ -void pgroup_operation_with_menu (Scene *scene) -{ - Object *ob= OBACT; - bArmature *arm= (ob) ? ob->data : NULL; - bPose *pose= (ob) ? ob->pose : NULL; - bPoseChannel *pchan= NULL; - int mode; - - /* sanity checks */ - if (ELEM3(NULL, ob, pose, arm)) - return; - - /* check that something is selected */ - for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) - break; - } - if (pchan == NULL) - return; - - /* get mode of action */ - if (pchan) - mode= pupmenu("Bone Groups%t|Add Selected to Active Group%x1|Add Selected to Group%x2|%|Remove Selected From Groups%x3|Remove Active Group%x4"); - else - mode= pupmenu("Bone Groups%t|Add New Group%x5|Remove Active Group%x4"); - - /* handle mode */ - switch (mode) { - case 1: - pose_assign_to_posegroup(scene, 1); - break; - case 2: - pose_assign_to_posegroup(scene, 0); - break; - case 5: - pose_add_posegroup(scene); - break; - case 3: - pose_remove_from_posegroups(scene); - break; - case 4: - pose_remove_posegroup(scene); - break; - } -} -#endif - /* ********************************************** */ static short pose_select_same_group (Object *ob) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b7f75386113..f6774d6ac92 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -622,6 +622,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent); void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand); void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type); +void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname); void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname); void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser); void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e70510753e1..24009819f45 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1173,7 +1173,7 @@ void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent) { uiLayout *row, *col; uiBlock *block; - Material *ma; + Material *ma= NULL; ID *pid, *pparent; if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) { @@ -1265,6 +1265,34 @@ void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type) } } +/********************* TriColor (ThemeWireColorSet) Template ************************/ + +void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname) +{ + uiLayout *row; + PropertyRNA *prop; + PointerRNA csPtr; + + if (!ptr->data) + return; + + prop= RNA_struct_find_property(ptr, propname); + if (!prop) { + printf("uiTemplateTriColorSet: property not found: %s\n", propname); + return; + } + + /* we lay out the data in a row as 3 color swatches */ + row= uiLayoutRow(layout, 1); + + /* nselected, selected, active color swatches */ + csPtr= RNA_property_pointer_get(ptr, prop); + + uiItemR(row, "", 0, &csPtr, "normal", 0, 0, 0); + uiItemR(row, "", 0, &csPtr, "selected", 0, 0, 0); + uiItemR(row, "", 0, &csPtr, "active", 0, 0, 0); +} + /********************* Layer Buttons Template ************************/ // TODO: @@ -1299,7 +1327,10 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname) groups= ((cols / 2) < 5) ? (1) : (cols / 2); /* layers are laid out going across rows, with the columns being divided into groups */ - uSplit= uiLayoutSplit(layout, (1.0f/(float)groups)); + if (groups > 1) + uSplit= uiLayoutSplit(layout, (1.0f/(float)groups)); + else + uSplit= layout; for (group= 0; group < groups; group++) { uCol= uiLayoutColumn(uSplit, 1); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index e15310a02bf..0963f2483f3 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Contributor(s): Blender Foundation (2008), Roland Hess + * Contributor(s): Blender Foundation (2008), Roland Hess, Joshua Leung * * ***** END GPL LICENSE BLOCK ***** */ @@ -39,8 +39,12 @@ #ifdef RNA_RUNTIME +#include + #include "BLI_arithb.h" +#include "DNA_userdef_types.h" + #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_idprop.h" @@ -54,6 +58,41 @@ static void rna_Pose_update(bContext *C, PointerRNA *ptr) DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); } +static void rna_BoneGroup_color_set_set(PointerRNA *ptr, int value) +{ + bActionGroup *grp= ptr->data; + + /* if valid value, set the new enum value, then copy the relevant colours? */ + if ((value >= -1) && (value < 21)) + grp->customCol= value; + else + return; + + /* only do color copying if using a custom color (i.e. not default colour) */ + if (grp->customCol) { + if (grp->customCol > 0) { + /* copy theme colors on-to group's custom color in case user tries to edit color */ + bTheme *btheme= U.themes.first; + ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)]; + + memcpy(&grp->cs, col_set, sizeof(ThemeWireColor)); + } + else { + /* init custom colors with a generic multi-color rgb set, if not initialised already (for custom color set) */ + if (grp->cs.solid[0] == 0) { + /* define for setting colors in theme below */ + #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a; + + SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255); + SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255); + SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255); + + #undef SETCOL + } + } + } +} + IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create) { bPoseChannel *pchan= ptr->data; @@ -189,23 +228,60 @@ void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result, static void rna_def_bone_group(BlenderRNA *brna) { + static EnumPropertyItem prop_colorSets_items[] = { + {0, "DEFAULT", 0, "Default Colors", ""}, + {1, "THEME01", 0, "01 - Theme Color Set", ""}, + {2, "THEME02", 0, "02 - Theme Color Set", ""}, + {3, "THEME03", 0, "03 - Theme Color Set", ""}, + {4, "THEME04", 0, "04 - Theme Color Set", ""}, + {5, "THEME05", 0, "05 - Theme Color Set", ""}, + {6, "THEME06", 0, "06 - Theme Color Set", ""}, + {7, "THEME07", 0, "07 - Theme Color Set", ""}, + {8, "THEME08", 0, "08 - Theme Color Set", ""}, + {9, "THEME09", 0, "09 - Theme Color Set", ""}, + {10, "THEME10", 0, "10 - Theme Color Set", ""}, + {11, "THEME11", 0, "11 - Theme Color Set", ""}, + {12, "THEME12", 0, "12 - Theme Color Set", ""}, + {13, "THEME13", 0, "13 - Theme Color Set", ""}, + {14, "THEME14", 0, "14 - Theme Color Set", ""}, + {15, "THEME15", 0, "15 - Theme Color Set", ""}, + {16, "THEME16", 0, "16 - Theme Color Set", ""}, + {17, "THEME17", 0, "17 - Theme Color Set", ""}, + {18, "THEME18", 0, "18 - Theme Color Set", ""}, + {19, "THEME19", 0, "19 - Theme Color Set", ""}, + {20, "THEME20", 0, "20 - Theme Color Set", ""}, + {-1, "CUSTOM", 0, "Custom Color Set", ""}, + {0, NULL, 0, NULL, NULL}}; + StructRNA *srna; PropertyRNA *prop; - + + /* struct */ srna= RNA_def_struct(brna, "BoneGroup", NULL); RNA_def_struct_sdna(srna, "bActionGroup"); RNA_def_struct_ui_text(srna, "Bone Group", "Groups of Pose Channels (Bones)."); - + + /* name */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); RNA_def_struct_name_property(srna, prop); // TODO: add some runtime-collections stuff to access grouped bones - // FIXME: this needs more work - probably a custom template? - prop= RNA_def_property(srna, "custom_color", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "customCol"); - RNA_def_property_ui_text(prop, "Custom Color", "Index of custom color set."); + /* color set + colors */ + prop= RNA_def_property(srna, "color_set", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "customCol"); + RNA_def_property_enum_items(prop, prop_colorSets_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_BoneGroup_color_set_set", NULL); + RNA_def_property_ui_text(prop, "Color Set", "Custom color set to use."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); + + // TODO: editing the colors for this should result in changes to the color type... + prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ThemeBoneColorSet"); + RNA_def_property_pointer_sdna(prop, NULL, "cs"); /* NOTE: the DNA data is not really a pointer, but this code works :) */ + RNA_def_property_ui_text(prop, "Colors", "Copy of the colors associated with the group's color set."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); } static void rna_def_pose_channel(BlenderRNA *brna) @@ -272,7 +348,6 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "selectflag", BONE_SELECTED); RNA_def_property_ui_text(prop, "Selected", ""); - /* XXX note: bone groups are stored internally as bActionGroups :) - Aligorith */ prop= RNA_def_property(srna, "bone_group_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "agrp_index"); RNA_def_property_ui_text(prop, "Bone Group Index", "Bone Group this pose channel belongs to (0=no group)."); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 05255036992..b88a2d50d7e 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -256,6 +256,9 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_layers", "uiTemplateLayers"); api_ui_item_rna_common(func); + + func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet"); + api_ui_item_rna_common(func); func= RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); -- cgit v1.2.3