Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-01-05 12:54:39 +0300
committerJoshua Leung <aligorith@gmail.com>2009-01-05 12:54:39 +0300
commitdf20a12728626372de8a5eb127e57cb2cca40649 (patch)
tree1db0a794e8bd2bcdc899857715859ede024ca564
parent7de52578c044f20b166045eaf5e925c6714f6598 (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.c8
-rw-r--r--source/blender/blenkernel/intern/armature.c8
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/ipo.c1
-rw-r--r--source/blender/editors/animation/anim_channels.c412
-rw-r--r--source/blender/editors/animation/anim_deps.c66
-rw-r--r--source/blender/editors/animation/keyframing.c6
-rw-r--r--source/blender/editors/include/ED_anim_api.h14
-rw-r--r--source/blender/editors/space_action/action_edit.c27
-rw-r--r--source/blender/editors/space_action/action_select.c4
-rw-r--r--source/blender/editors/space_action/space_action.c85
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c2
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 *****
*/