diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-01-05 12:54:39 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-01-05 12:54:39 +0300 |
commit | df20a12728626372de8a5eb127e57cb2cca40649 (patch) | |
tree | 1db0a794e8bd2bcdc899857715859ede024ca564 | |
parent | 7de52578c044f20b166045eaf5e925c6714f6598 (diff) |
2.5 - Animation Fixes + More Porting work in Action Editor
* Added crash fixes for loading old files with Actions/Armatures in them. Was caused by usage of some old globals still and the functions in question not performing NULL checks on the validity of the data they're given.
* Added back reorganise action channels tools (shift/ctrl-shif pageup/down) for Action Editor. These are only available in 'Action Mode' only.
* Tidied up Action Editor/Dopesheet tools code - removed various unused things, and also, added an API call in anim_deps.c to send the correct notifiers, since I anticipate that they're likely to require a few context checks which would be better to centralise than copy+paste everywhere.
Note to Ton: could you have a look at this notifier stuff here? I'm not sure which ones I should be sending...
* Also added a few assorted comments in various places
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 1 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels.c | 412 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_deps.c | 66 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 6 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 14 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_edit.c | 27 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_select.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_action/space_action.c | 85 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 2 |
12 files changed, 569 insertions, 66 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 31669cc212a..06597c983ca 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1493,19 +1493,19 @@ static void do_nla(Scene *scene, Object *ob, int blocktype) void do_all_pose_actions(Scene *scene, Object *ob) { /* only to have safe calls from editor */ - if(ob==NULL) return; - if(ob->type!=OB_ARMATURE || ob->pose==NULL) return; + if(ELEM(NULL, scene, ob)) return; + if((ob->type!=OB_ARMATURE) || (ob->pose==NULL)) return; if(ob->pose->flag & POSE_LOCKED) { /* no actions to execute while transform */ if(ob->pose->flag & POSE_DO_UNLOCK) ob->pose->flag &= ~(POSE_LOCKED|POSE_DO_UNLOCK); } - else if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) { + else if( (ob->action) && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || (ob->nlastrips.first==NULL)) ) { float cframe= (float) scene->r.cfra; cframe= get_action_frame(ob, cframe); - extract_pose_from_action (ob->pose, ob->action, bsystem_time(scene, ob, cframe, 0.0)); + extract_pose_from_action(ob->pose, ob->action, bsystem_time(scene, ob, cframe, 0.0)); } else if(ob->nlastrips.first) { do_nla(scene, ob, ID_AR); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index ce5921a701d..fe1d334f7f9 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2273,13 +2273,15 @@ void where_is_pose (Scene *scene, Object *ob) Bone *bone; bPoseChannel *pchan; float imat[4][4]; - float ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0); /* not accurate... */ + float ctime; arm = get_armature(ob); - if(arm==NULL) return; - if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) + if(ELEM(NULL, arm, scene)) return; + if((ob->pose==NULL) || (ob->pose->flag & POSE_RECALC)) armature_rebuild_pose(ob, arm); + + ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0); /* not accurate... */ /* In editmode or restposition we read the data from the bones */ if(arm->edbo || (arm->flag & ARM_RESTPOS)) { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e6fd3cc8612..262a2b35713 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -352,7 +352,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) /* this can happen when active scene was lib-linked, and doesnt exist anymore */ if(CTX_data_scene(C)==NULL) { - CTX_data_scene_set(C, G.main->scene.first); + CTX_data_scene_set(C, bfd->main->scene.first); CTX_wm_screen(C)->scene= CTX_data_scene(C); curscene= CTX_data_scene(C); } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index de374587f4e..78b1423e6bc 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -233,6 +233,7 @@ void free_ipo (Ipo *ipo) /* ---------------------- Init --------------------------- */ /* on adding new ipos, or for empty views */ +// XXX users usually find these zoom settings problematic... void ipo_default_v2d_cur (Scene *scene, int blocktype, rctf *cur) { switch (blocktype) { diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c index 15dffe24ff2..af12ccd0b18 100644 --- a/source/blender/editors/animation/anim_channels.c +++ b/source/blender/editors/animation/anim_channels.c @@ -276,7 +276,395 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short /* OPERATORS */ /* ****************** Rearrange Channels Operator ******************* */ +/* This operator only works for Action Editor mode for now, as having it elsewhere makes things difficult */ +/* constants for channel rearranging */ +/* WARNING: don't change exising ones without modifying rearrange func accordingly */ +enum { + REARRANGE_ACTCHAN_TOP= -2, + REARRANGE_ACTCHAN_UP= -1, + REARRANGE_ACTCHAN_DOWN= 1, + REARRANGE_ACTCHAN_BOTTOM= 2 +}; + +/* make sure all action-channels belong to a group (and clear action's list) */ +static void split_groups_action_temp (bAction *act, bActionGroup *tgrp) +{ + bActionChannel *achan; + bActionGroup *agrp; + + /* Separate action-channels into lists per group */ + for (agrp= act->groups.first; agrp; agrp= agrp->next) { + if (agrp->channels.first) { + achan= agrp->channels.last; + act->chanbase.first= achan->next; + + achan= agrp->channels.first; + achan->prev= NULL; + + achan= agrp->channels.last; + achan->next= NULL; + } + } + + /* Initialise memory for temp-group */ + memset(tgrp, 0, sizeof(bActionGroup)); + tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP); + strcpy(tgrp->name, "#TempGroup"); + + /* Move any action-channels not already moved, to the temp group */ + if (act->chanbase.first) { + /* start of list */ + achan= act->chanbase.first; + achan->prev= NULL; + tgrp->channels.first= achan; + act->chanbase.first= NULL; + + /* end of list */ + achan= act->chanbase.last; + achan->next= NULL; + tgrp->channels.last= achan; + act->chanbase.last= NULL; + } + + /* Add temp-group to list */ + BLI_addtail(&act->groups, tgrp); +} + +/* link lists of channels that groups have */ +static void join_groups_action_temp (bAction *act) +{ + bActionGroup *agrp; + bActionChannel *achan; + + for (agrp= act->groups.first; agrp; agrp= agrp->next) { + ListBase tempGroup; + + /* add list of channels to action's channels */ + tempGroup= agrp->channels; + addlisttolist(&act->chanbase, &agrp->channels); + agrp->channels= tempGroup; + + /* clear moved flag */ + agrp->flag &= ~AGRP_MOVED; + + /* if temp-group... remove from list (but don't free as it's on the stack!) */ + if (agrp->flag & AGRP_TEMP) { + BLI_remlink(&act->groups, agrp); + break; + } + } + + /* clear "moved" flag from all achans */ + for (achan= act->chanbase.first; achan; achan= achan->next) + achan->flag &= ~ACHAN_MOVED; +} + + +static short rearrange_actchannel_is_ok (Link *channel, short type) +{ + if (type == ANIMTYPE_GROUP) { + bActionGroup *agrp= (bActionGroup *)channel; + + if (SEL_AGRP(agrp) && !(agrp->flag & AGRP_MOVED)) + return 1; + } + else if (type == ANIMTYPE_ACHAN) { + bActionChannel *achan= (bActionChannel *)channel; + + if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) + return 1; + } + + return 0; +} + +static short rearrange_actchannel_after_ok (Link *channel, short type) +{ + if (type == ANIMTYPE_GROUP) { + bActionGroup *agrp= (bActionGroup *)channel; + + if (agrp->flag & AGRP_TEMP) + return 0; + } + + return 1; +} + + +static short rearrange_actchannel_top (ListBase *list, Link *channel, short type) +{ + if (rearrange_actchannel_is_ok(channel, type)) { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* make it first element */ + BLI_insertlinkbefore(list, list->first, channel); + + return 1; + } + + return 0; +} + +static short rearrange_actchannel_up (ListBase *list, Link *channel, short type) +{ + if (rearrange_actchannel_is_ok(channel, type)) { + Link *prev= channel->prev; + + if (prev) { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* push it up */ + BLI_insertlinkbefore(list, prev, channel); + + return 1; + } + } + + return 0; +} + +static short rearrange_actchannel_down (ListBase *list, Link *channel, short type) +{ + if (rearrange_actchannel_is_ok(channel, type)) { + Link *next = (channel->next) ? channel->next->next : NULL; + + if (next) { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* move it down */ + BLI_insertlinkbefore(list, next, channel); + + return 1; + } + else if (rearrange_actchannel_after_ok(list->last, type)) { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* add at end */ + BLI_addtail(list, channel); + + return 1; + } + else { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* add just before end */ + BLI_insertlinkbefore(list, list->last, channel); + + return 1; + } + } + + return 0; +} + +static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short type) +{ + if (rearrange_actchannel_is_ok(channel, type)) { + if (rearrange_actchannel_after_ok(list->last, type)) { + /* take it out off the chain keep data */ + BLI_remlink(list, channel); + + /* add at end */ + BLI_addtail(list, channel); + + return 1; + } + } + + return 0; +} + + +/* Change the order of action-channels + * mode: REARRANGE_ACTCHAN_* + */ +static void rearrange_action_channels (bAnimContext *ac, short mode) +{ + bAction *act; + bActionChannel *achan, *chan; + bActionGroup *agrp, *grp; + bActionGroup tgrp; + + short (*rearrange_func)(ListBase *, Link *, short); + short do_channels = 1; + + /* Get the active action, exit if none are selected */ + act= (bAction *)ac->data; + + /* exit if invalid mode */ + switch (mode) { + case REARRANGE_ACTCHAN_TOP: + rearrange_func= rearrange_actchannel_top; + break; + case REARRANGE_ACTCHAN_UP: + rearrange_func= rearrange_actchannel_up; + break; + case REARRANGE_ACTCHAN_DOWN: + rearrange_func= rearrange_actchannel_down; + break; + case REARRANGE_ACTCHAN_BOTTOM: + rearrange_func= rearrange_actchannel_bottom; + break; + default: + return; + } + + /* make sure we're only operating with groups */ + split_groups_action_temp(act, &tgrp); + + /* rearrange groups first (and then, only consider channels if the groups weren't moved) */ + #define GET_FIRST(list) ((mode > 0) ? (list.first) : (list.last)) + #define GET_NEXT(item) ((mode > 0) ? (item->next) : (item->prev)) + + for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) { + /* Get next group to consider */ + grp= GET_NEXT(agrp); + + /* try to do group first */ + if (rearrange_func(&act->groups, (Link *)agrp, ANIMTYPE_GROUP)) { + do_channels= 0; + agrp->flag |= AGRP_MOVED; + } + } + + if (do_channels) { + for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) { + /* Get next group to consider */ + grp= GET_NEXT(agrp); + + /* only consider action-channels if they're visible (group expanded) */ + if (EXPANDED_AGRP(agrp)) { + for (achan= GET_FIRST(agrp->channels); achan; achan= chan) { + /* Get next channel to consider */ + chan= GET_NEXT(achan); + + /* Try to do channel */ + if (rearrange_func(&agrp->channels, (Link *)achan, ANIMTYPE_ACHAN)) + achan->flag |= ACHAN_MOVED; + } + } + } + } + #undef GET_FIRST + #undef GET_NEXT + + /* assemble lists into one list (and clear moved tags) */ + join_groups_action_temp(act); +} + +/* ------------------- */ + +static int animchannels_rearrange_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + short mode; + + /* get editor data - only for Action Editor (for now) */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + if (ac.datatype != ANIMCONT_ACTION) + return OPERATOR_PASS_THROUGH; + + /* get mode, then rearrange channels */ + mode= RNA_enum_get(op->ptr, "dir"); + rearrange_action_channels(&ac, mode); + + /* set notifier tha things have changed */ + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS); + + return OPERATOR_FINISHED; +} + + +void ANIM_OT_channels_move_up (wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Move Channel(s) Up"; + ot->idname= "ANIM_OT_channels_move_up"; + + /* api callbacks */ + ot->exec= animchannels_rearrange_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + + /* props */ + prop= RNA_def_property(ot->srna, "dir", PROP_ENUM, PROP_NONE); + // xxx add enum for this... + RNA_def_property_enum_default(prop, REARRANGE_ACTCHAN_UP); +} + +void ANIM_OT_channels_move_down (wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Move Channel(s) Down"; + ot->idname= "ANIM_OT_channels_move_down"; + + /* api callbacks */ + ot->exec= animchannels_rearrange_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + + /* props */ + prop= RNA_def_property(ot->srna, "dir", PROP_ENUM, PROP_NONE); + // xxx add enum for this... + RNA_def_property_enum_default(prop, REARRANGE_ACTCHAN_DOWN); +} + +void ANIM_OT_channels_move_top (wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Move Channel(s) to Top"; + ot->idname= "ANIM_OT_channels_move_to_top"; + + /* api callbacks */ + ot->exec= animchannels_rearrange_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + + /* props */ + prop= RNA_def_property(ot->srna, "dir", PROP_ENUM, PROP_NONE); + // xxx add enum for this... + RNA_def_property_enum_default(prop, REARRANGE_ACTCHAN_TOP); +} + +void ANIM_OT_channels_move_bottom (wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Move Channel(s) to Bottom"; + ot->idname= "ANIM_OT_channels_move_to_bottom"; + + /* api callbacks */ + ot->exec= animchannels_rearrange_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + + /* props */ + prop= RNA_def_property(ot->srna, "dir", PROP_ENUM, PROP_NONE); + // xxx add enum for this... + RNA_def_property_enum_default(prop, REARRANGE_ACTCHAN_BOTTOM); +} /* ********************** Set Flags Operator *********************** */ @@ -429,7 +817,7 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op) setflag_anim_channels(&ac, setting, mode); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS); return OPERATOR_FINISHED; } @@ -530,7 +918,7 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op) ANIM_deselect_anim_channels(ac.data, ac.datatype, 1, ACHANNEL_SETFLAG_ADD); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS); return OPERATOR_FINISHED; } @@ -1082,8 +1470,7 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent * mouse_anim_channels(&ac, x, channel_index, selectmode); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! - // FIXME: add tags which will cause 3d-view to do a flush of data... + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS); return OPERATOR_FINISHED; } @@ -1115,6 +1502,11 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_enable_setting); WM_operatortype_append(ANIM_OT_channels_disable_setting); WM_operatortype_append(ANIM_OT_channels_toggle_setting); + + WM_operatortype_append(ANIM_OT_channels_move_up); + WM_operatortype_append(ANIM_OT_channels_move_down); + WM_operatortype_append(ANIM_OT_channels_move_top); + WM_operatortype_append(ANIM_OT_channels_move_bottom); } void ED_keymap_animchannels(wmWindowManager *wm) @@ -1136,9 +1528,15 @@ void ED_keymap_animchannels(wmWindowManager *wm) WM_keymap_add_item(keymap, "ANIM_OT_channels_borderselect", BKEY, KM_PRESS, 0, 0); /* settings */ - RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_toggle_setting", WKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACHANNEL_SETFLAG_TOGGLE); - RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_enable_setting", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "mode", ACHANNEL_SETFLAG_ADD); - RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_disable_setting", WKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACHANNEL_SETFLAG_CLEAR); + WM_keymap_add_item(keymap, "ANIM_OT_channels_toggle_setting", WKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_enable_setting", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_disable_setting", WKEY, KM_PRESS, KM_ALT, 0); + + /* rearranging - actions only */ + WM_keymap_add_item(keymap, "ANIM_OT_channels_move_up", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_move_down", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_top", PAGEUPKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_bottom", PAGEDOWNKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); } /* ************************************************************************** */ diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 336bc6f48ed..eaf4ef7ae12 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -56,6 +56,10 @@ #include "RNA_define.h" #include "ED_anim_api.h" +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" /* ***************** depsgraph calls and anim updates ************* */ @@ -122,6 +126,53 @@ void ED_update_for_newframe(const bContext *C, int mute) } } +/* **************************** animation tool notifiers ******************************** */ + +/* Send notifiers on behalf of animation editing tools, based on various context info + * - data_changed: eAnimData_Changed + */ +void ANIM_animdata_send_notifiers (bContext *C, bAnimContext *ac, short data_changed) +{ + /* types of notifiers to send, depends on the editor context */ + switch (ac->datatype) { + case ANIMCONT_DOPESHEET: /* dopesheet */ + { + /* what action was taken */ + switch (data_changed) { + case ANIM_CHANGED_KEYFRAMES_VALUES: + /* keyframe values changed, so transform may have changed */ + // XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION? + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + break; + //case ANIM_CHANGED_KEYFRAMES_SELECT: // XXX what to do here? + // break; + case ANIM_CHANGED_CHANNELS: + // XXX err... check available datatypes in dopesheet first? + // FIXME: this currently doesn't work (to update own view) + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE|ND_OB_SELECT, ac->scene); + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE|ND_BONE_SELECT, NULL); + break; + } + + // XXX for now, at least update own editor! + ED_area_tag_redraw(CTX_wm_area(C)); + } + break; + + case ANIMCONT_ACTION: /* action editor */ + { + Object *obact= CTX_data_active_object(C); + + // only update active object for now... more detail to come! + WM_event_add_notifier(C, NC_OBJECT, obact); + } + break; + + default: /* some other data... just update area for now */ + ED_area_tag_redraw(CTX_wm_area(C)); + } +} + /* **************************** pose <-> action syncing ******************************** */ /* Summary of what needs to be synced between poses and actions: * 1) Flags @@ -177,8 +228,9 @@ void ANIM_action_to_pose_sync (Object *ob) * An object (usually 'active' Object) needs to be supplied, so that its Pose-Channels can be synced with * the channels in its active Action. */ -void ANIM_pose_to_action_sync (Object *ob) +void ANIM_pose_to_action_sync (Object *ob, ScrArea *sa) { + SpaceAction *saction= (SpaceAction *)sa->spacedata.first; bArmature *arm= (bArmature *)ob->data; bAction *act= (bAction *)ob->action; bActionChannel *achan; @@ -197,12 +249,12 @@ void ANIM_pose_to_action_sync (Object *ob) /* sync selection and visibility settings */ if (pchan && pchan->bone) { /* visibility - if layer is hidden, or if bone itself is hidden */ - // XXX we may not want this happening though! (maybe we need some extra flags from context or so) - // only if SACTION_NOHIDE==0, and saction->pin == 0, when in Action Editor mode - if (!(pchan->bone->layer & arm->layer) || (pchan->bone->flag & BONE_HIDDEN_P)) - achan->flag |= ACHAN_HIDDEN; - else - achan->flag &= ~ACHAN_HIDDEN; + if (!(saction->flag & SACTION_NOHIDE) && !(saction->pin)) { + if (!(pchan->bone->layer & arm->layer) || (pchan->bone->flag & BONE_HIDDEN_P)) + achan->flag |= ACHAN_HIDDEN; + else + achan->flag &= ~ACHAN_HIDDEN; + } /* selection */ if (pchan->bone->flag & BONE_SELECTED) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index dce5fd90eb2..2cd2db3237a 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -67,6 +67,7 @@ #include "DNA_vec_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" +#include "DNA_windowmanager_types.h" #include "BKE_context.h" #include "BKE_utildefines.h" @@ -87,6 +88,9 @@ #include "ED_keyframing.h" #include "ED_keyframes_edit.h" +#include "WM_api.h" +#include "WM_types.h" + #if 0 // XXX resolve these old dependencies! #include "BIF_butspace.h" #include "BIF_editaction.h" @@ -1792,7 +1796,7 @@ static void commonkey_context_getv3d (const bContext *C, ListBase *sources, bKey *ksc= &ks_contexts[KSC_V3D_OBJECT]; /* loop through bases */ - // XXX but we're only supposed to do this on editable ones! + // XXX but we're only supposed to do this on editable ones, not just selected ones! CTX_DATA_BEGIN(C, Base*, base, selected_bases) { bCommonKeySrc *cks; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 410bd77e483..863446fe59f 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -327,7 +327,19 @@ void ED_update_for_newframe(const struct bContext *C, int mute); /* pose <-> action syncing */ void ANIM_action_to_pose_sync(struct Object *ob); -void ANIM_pose_to_action_sync(struct Object *ob); +void ANIM_pose_to_action_sync(struct Object *ob, struct ScrArea *sa); + + +/* what types of animation data was changed (for sending notifiers from animation tools) */ +enum { + ANIM_CHANGED_BOTH= 0, + ANIM_CHANGED_KEYFRAMES_VALUES, + ANIM_CHANGED_KEYFRAMES_SELECT, + ANIM_CHANGED_CHANNELS +} eAnimData_Changed; + +/* Send notifiers on behalf of animation editing tools, based on various context info */ +void ANIM_animdata_send_notifiers(struct bContext *C, bAnimContext *ac, short data_changed); /* ************************************************* */ /* OPERATORS */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 9fc1deab9f2..c17e926559f 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -163,8 +163,9 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *op) scene->r.psfra= (int)floor(min + 0.5f); scene->r.pefra= (int)floor(max + 0.5f); - /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + /* set notifier that things have changed */ + // XXX err... there's nothing for frame ranges yet, but this should do fine too + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, ac.scene); return OPERATOR_FINISHED; } @@ -211,7 +212,7 @@ static int actkeys_viewall_exec(bContext *C, wmOperator *op) UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; } @@ -516,7 +517,7 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) } /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -560,7 +561,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -623,7 +624,7 @@ static int actkeys_delete_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -685,7 +686,7 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -812,7 +813,7 @@ static int actkeys_sample_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -889,7 +890,7 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -970,7 +971,7 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -1071,7 +1072,7 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -1241,7 +1242,7 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } @@ -1359,7 +1360,7 @@ static int actkeys_mirror_exec(bContext *C, wmOperator *op) ANIM_editkeyframes_refresh(&ac); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 832246897e0..0247b656923 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -721,7 +721,7 @@ static int actkeys_columnselect_exec(bContext *C, wmOperator *op) columnselect_action_keys(&ac, mode); /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_SELECT); return OPERATOR_FINISHED; } @@ -1108,7 +1108,7 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even } /* set notifier tha things have changed */ - ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead! + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 172e5d1d839..5c7519774bf 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -254,28 +254,6 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar) UI_view2d_scrollers_free(scrollers); } -static void action_channel_area_listener(ARegion *ar, wmNotifier *wmn) -{ - /* context changes */ - switch(wmn->category) { - case NC_SCENE: - switch(wmn->data) { - case ND_OB_ACTIVE: - ED_region_tag_redraw(ar); - break; - } - break; - case NC_OBJECT: - switch(wmn->data) { - case ND_BONE_ACTIVE: - case ND_BONE_SELECT: - ED_region_tag_redraw(ar); - break; - } - break; - } -} - /* add handlers, stuff you only do once or on area/region changes */ static void action_header_area_init(wmWindowManager *wm, ARegion *ar) @@ -305,6 +283,28 @@ static void action_header_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); } +static void action_channel_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch(wmn->category) { + case NC_SCENE: + switch(wmn->data) { + case ND_OB_ACTIVE: + ED_region_tag_redraw(ar); + break; + } + break; + case NC_OBJECT: + switch(wmn->data) { + case ND_BONE_ACTIVE: + case ND_BONE_SELECT: + ED_region_tag_redraw(ar); + break; + } + break; + } +} + static void action_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ @@ -333,19 +333,52 @@ static void action_main_area_listener(ARegion *ar, wmNotifier *wmn) static void action_listener(ScrArea *sa, wmNotifier *wmn) { /* context changes */ - switch(wmn->category) { + switch (wmn->category) { case NC_SCENE: - switch(wmn->data) { + /*switch (wmn->data) { case ND_OB_ACTIVE: + case ND_OB_SELECT: ED_area_tag_refresh(sa); break; - } + }*/ + ED_area_tag_refresh(sa); + break; + case NC_OBJECT: + /*switch (wmn->data) { + case ND_BONE_SELECT: + case ND_BONE_ACTIVE: + ED_area_tag_refresh(sa); + break; + }*/ + ED_area_tag_refresh(sa); + break; } } static void action_refresh(const bContext *C, ScrArea *sa) { - printf("Heya, Action refresh needed!\n"); + SpaceAction *saction = (SpaceAction *)sa->spacedata.first; + + /* updates to data needed depends on Action Editor mode... */ + switch (saction->mode) { + case SACTCONT_DOPESHEET: /* DopeSheet - for now, just all armatures... */ + { + + } + break; + + case SACTCONT_ACTION: /* Action Editor - just active object will do */ + { + Object *ob= CTX_data_active_object(C); + + /* sync changes to bones to the corresponding action channels */ + ANIM_pose_to_action_sync(ob, sa); + } + break; + } + + /* region updates? */ + // XXX resizing y-extents of tot should go here? } /* only called once, from space/spacetypes.c */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index d5865bab424..761e2b89a62 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.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), Juho Vepsäläinen + * Contributor(s): Blender Foundation (2008), Joshua Leung * * ***** END GPL LICENSE BLOCK ***** */ |