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>2013-03-16 09:09:32 +0400
committerJoshua Leung <aligorith@gmail.com>2013-03-16 09:09:32 +0400
commit150891605f3f098070b2bb0cd6ef37ae930698d7 (patch)
tree2e2b96e670d84f60b97161b3eb5599e6127444a3
parent7fc79615e0c88aff445178f17e9c267f11a0d791 (diff)
NLA "Add Track" can now be used to add tracks to previously empty AnimData
blocks, provided the blocks in question are in fact selected.
-rw-r--r--source/blender/editors/animation/anim_filter.c8
-rw-r--r--source/blender/editors/include/ED_anim_api.h5
-rw-r--r--source/blender/editors/space_nla/nla_channels.c93
3 files changed, 86 insertions, 20 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index b3b0b09bac0..7416c559522 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1296,7 +1296,9 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
ANIMDATA_FILTER_CASES(iat,
{ /* AnimData */
/* specifically filter animdata block */
- ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ }
},
{ /* NLA */
items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
@@ -1346,7 +1348,9 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
// TODO: somehow manage to pass dopesheet info down here too?
if (key->adt) {
if (filter_mode & ANIMFILTER_ANIMDATA) {
- ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ }
}
else if (key->adt->action) {
items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 20f568a3642..954ea18e0ab 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -292,11 +292,14 @@ typedef enum eAnimFilter_Flags {
#define SEL_MASKLAY(masklay) (masklay->flag & SELECT)
-
/* NLA only */
#define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED)
#define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0)
+
+/* AnimData - NLA mostly... */
+#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED)
+
/* -------------- Channel Defines -------------- */
/* channel heights */
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index f9732a79a11..a4b036bf00f 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -48,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
+#include "BKE_report.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
@@ -393,24 +394,18 @@ void NLA_OT_channels_click(wmOperatorType *ot)
/* ******************** Add Tracks Operator ***************************** */
/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
-static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+/* helper - add NLA Tracks alongside existing ones */
+static bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
{
- bAnimContext ac;
-
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
AnimData *lastAdt = NULL;
- short above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool added = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get a list of the AnimData blocks being shown in the NLA */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get a list of the (selected) NLA Tracks being shown in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* add tracks... */
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -424,11 +419,13 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
if (above_sel) {
/* just add a new one above this one */
add_nlatrack(adt, nlt);
+ added = true;
}
else if ((lastAdt == NULL) || (adt != lastAdt)) {
/* add one track to the top of the owning AnimData's stack, then don't add anymore to this stack */
add_nlatrack(adt, NULL);
lastAdt = adt;
+ added = true;
}
}
}
@@ -436,17 +433,79 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* free temp data */
BLI_freelistN(&anim_data);
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+ return added;
+}
+
+/* helper - add NLA Tracks to empty (and selected) AnimData blocks */
+static bool nlaedit_add_tracks_empty(bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool added = false;
- /* done */
- return OPERATOR_FINISHED;
+ /* get a list of the selected AnimData blocks in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* check if selected AnimData blocks are empty, and add tracks if so... */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ale->adt;
+
+ /* sanity check */
+ BLI_assert(adt->flag & ADT_UI_SELECTED);
+
+ /* ensure it is empty */
+ if (adt->nla_tracks.first == NULL) {
+ /* add new track to this AnimData block then */
+ add_nlatrack(adt, NULL);
+ added = true;
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+
+ return added;
+}
+
+/* Add Tracks exec() */
+static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool op_done = false;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* perform adding in two passes - existing first so that we don't double up for empty */
+ op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
+ op_done |= nlaedit_add_tracks_empty(&ac);
+
+ /* done? */
+ if (op_done) {
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* failed to add any tracks */
+ BKE_report(op->reports, RPT_WARNING,
+ "Select an existing NLA Track or an empty action line first");
+
+ /* not done */
+ return OPERATOR_CANCELLED;
+ }
}
void NLA_OT_tracks_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Track(s)";
+ ot->name = "Add Tracks";
ot->idname = "NLA_OT_tracks_add";
ot->description = "Add NLA-Tracks above/after the selected tracks";