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-06-19 08:45:56 +0400
committerJoshua Leung <aligorith@gmail.com>2009-06-19 08:45:56 +0400
commita87bc73d321f5bddc17fb5c6332637738bfb7fa6 (patch)
treef65a863896bd6402a217ebb679e2872adedd1578 /source/blender/editors
parent74884754d221a97c487d4c3630ceb4412b726863 (diff)
NLA SoC: Transition Strips + Strip Adding Operators + Bugfixes
== Transitions == Transition strips are now able to be created + evaluated. Transitions allow for interpolation between the endpoints of two adjacent strips in the same track (i.e. two strips which occur in the same track one after the other, but with a gap between them). - The current behaviour when only one endpoint affects some setting is non-optimal, since it appears somewhat inconsistently extend/replace values... - Transform code needs a few fixes still to deal with these == Strip Adding Operators == * New strips referencing Actions can be added using the Shift-A hotkey while in the strips-area. You must have a track selected first though. The new strip will get added, starting from the current frame, in the selected track(s) only if there is enough space to do so. Otherwise, the new strip gets added at the top of the stack in a new track. * New transition strips can be added with the Shift-T hotkey while in the strips area. You must have two adjacent strips selected for this to work. == New Backend Methods == * Recoded the strip/track adding API to be more flexible * Added a new method for testing whether F-Curve has any modifiers of with certain attributes. Will be used in a later bugfix... == Bugfixes == - Fixed bug with strip-blending which caused the blending modes to be useless. - NLA buttons now use proper poll callbacks instead of defining checks - Commented out missing operator in menus, silencing warnings in console - Removed obsolete/incorrect comments
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c65
-rw-r--r--source/blender/editors/space_nla/nla_draw.c23
-rw-r--r--source/blender/editors/space_nla/nla_edit.c229
-rw-r--r--source/blender/editors/space_nla/nla_header.c5
-rw-r--r--source/blender/editors/space_nla/nla_intern.h3
-rw-r--r--source/blender/editors/space_nla/nla_ops.c7
6 files changed, 309 insertions, 23 deletions
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index cb21dd66934..cb76f7fc735 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -144,11 +144,38 @@ static int nla_panel_context(const bContext *C, PointerRNA *nlt_ptr, PointerRNA
return found;
}
+#if 0
static int nla_panel_poll(const bContext *C, PanelType *pt)
{
return nla_panel_context(C, NULL, NULL);
}
+#endif
+static int nla_track_panel_poll(const bContext *C, PanelType *pt)
+{
+ PointerRNA ptr;
+ return (nla_panel_context(C, &ptr, NULL) && (ptr.data != NULL));
+}
+
+static int nla_strip_panel_poll(const bContext *C, PanelType *pt)
+{
+ PointerRNA ptr;
+ return (nla_panel_context(C, NULL, &ptr) && (ptr.data != NULL));
+}
+
+static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *pt)
+{
+ PointerRNA ptr;
+ NlaStrip *strip;
+
+ if (!nla_panel_context(C, NULL, &ptr))
+ return 0;
+ if (ptr.data == NULL)
+ return 0;
+
+ strip= ptr.data;
+ return (strip->type == NLASTRIP_TYPE_CLIP);
+}
/* -------------- */
@@ -163,8 +190,6 @@ static void nla_panel_track (const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, &nlt_ptr, NULL))
return;
- if (nlt_ptr.data == NULL)
- return;
block= uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
@@ -185,8 +210,6 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, &strip_ptr))
return;
- if (strip_ptr.data == NULL)
- return;
block= uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
@@ -239,8 +262,6 @@ static void nla_panel_actclip(const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, &strip_ptr))
return;
- if (strip_ptr.data == NULL)
- return;
// XXX FIXME: move this check into a poll callback
if (RNA_enum_get(&strip_ptr, "type") != NLASTRIP_TYPE_CLIP)
@@ -279,8 +300,6 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, &strip_ptr))
return;
- if (strip_ptr.data == NULL)
- return;
block= uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
@@ -291,6 +310,24 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa)
// animated_time
}
+/* F-Modifiers for active NLA-Strip */
+static void nla_panel_modifiers(const bContext *C, Panel *pa)
+{
+ PointerRNA strip_ptr;
+ uiLayout *layout= pa->layout;
+ //uiLayout *column, *row, *subcol;
+ uiBlock *block;
+
+ /* check context and also validity of pointer */
+ if (!nla_panel_context(C, NULL, &strip_ptr))
+ return;
+
+ block= uiLayoutGetBlock(layout);
+ uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+
+ // TODO...
+}
+
/* ******************* general ******************************** */
@@ -302,35 +339,35 @@ void nla_buttons_register(ARegionType *art)
strcpy(pt->idname, "NLA_PT_track");
strcpy(pt->label, "Active Track");
pt->draw= nla_panel_track;
- pt->poll= nla_panel_poll;
+ pt->poll= nla_track_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel properties");
strcpy(pt->idname, "NLA_PT_properties");
strcpy(pt->label, "Active Strip");
pt->draw= nla_panel_properties;
- pt->poll= nla_panel_poll;
+ pt->poll= nla_strip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel properties");
strcpy(pt->idname, "NLA_PT_actionclip");
strcpy(pt->label, "Action Clip");
pt->draw= nla_panel_actclip;
- pt->poll= nla_panel_poll; // XXX need a special one to check for 'action clip' types only
+ pt->poll= nla_strip_actclip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel evaluation");
strcpy(pt->idname, "NLA_PT_evaluation");
strcpy(pt->label, "Evaluation");
pt->draw= nla_panel_evaluation;
- pt->poll= nla_panel_poll;
+ pt->poll= nla_strip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel modifiers");
strcpy(pt->idname, "NLA_PT_modifiers");
strcpy(pt->label, "Modifiers");
- //pt->draw= nla_panel_modifiers;
- pt->poll= nla_panel_poll;
+ pt->draw= nla_panel_modifiers;
+ pt->poll= nla_strip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 8d417a150aa..3a3f86bb5a3 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -202,11 +202,20 @@ static void nla_draw_strip_text (NlaTrack *nlt, NlaStrip *strip, int index, View
char str[256];
rctf rect;
- /* for now, just init the string with a fixed-format */
- if (strip->act)
- sprintf(str, "%d | Act: %s | %.2f <-> %.2f", index, strip->act->id.name+2, strip->start, strip->end);
- else
- sprintf(str, "%d | Act: <NONE>", index);
+ /* for now, just init the string with fixed-formats */
+ switch (strip->type) {
+ case NLASTRIP_TYPE_TRANSITION: /* Transition */
+ sprintf(str, "%d | Transition | %.2f <-> %.2f", index, strip->start, strip->end);
+ break;
+
+ case NLASTRIP_TYPE_CLIP: /* Action-Clip (default) */
+ default:
+ if (strip->act)
+ sprintf(str, "%d | Act: %s | %.2f <-> %.2f", index, strip->act->id.name+2, strip->start, strip->end);
+ else
+ sprintf(str, "%d | Act: <NONE>", index); // xxx... need a better format?
+ break;
+ }
/* set text colour - if colours (see above) are light, draw black text, otherwise draw white */
if (strip->flag & (NLASTRIP_FLAG_ACTIVE|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_TWEAKUSER))
@@ -295,7 +304,9 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
AnimData *adt= BKE_animdata_from_id(ale->id);
- /* just draw a semi-shaded rect spanning the width of the viewable area if there's data */
+ /* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
+ * and a second darker rect within which we draw keyframe indicator dots if there's data
+ */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index e8af67aebd1..2996a005177 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -48,6 +48,8 @@
#include "BKE_animsys.h"
#include "BKE_nla.h"
#include "BKE_context.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -215,6 +217,229 @@ void NLAEDIT_OT_tweakmode_exit (wmOperatorType *ot)
/* *********************************************** */
/* NLA Editing Operations */
+/* ******************** Add Action-Clip Operator ***************************** */
+/* Add a new Action-Clip strip to the active track (or the active block if no space in the track) */
+
+/* pop up menu allowing user to choose the action to use */
+static int nlaedit_add_actionclip_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ Main *m= CTX_data_main(C);
+ bAction *act;
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ pup= uiPupMenuBegin(C, "Add Action Clip", 0);
+ layout= uiPupMenuLayout(pup);
+
+ /* loop through Actions in Main database, adding as items in the menu */
+ for (act= m->action.first; act; act= act->id.next)
+ uiItemStringO(layout, act->id.name+2, 0, "NLAEDIT_OT_add_actionclip", "action", act->id.name);
+ uiItemS(layout);
+
+ uiPupMenuEnd(C, pup);
+
+ return OPERATOR_CANCELLED;
+}
+
+/* add the specified action as new strip */
+static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ Scene *scene;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter, items;
+
+ bAction *act = NULL;
+ char actname[22];
+ float cfra;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ scene= ac.scene;
+ cfra= (float)CFRA;
+
+ /* get action to use */
+ RNA_string_get(op->ptr, "action", actname);
+ act= (bAction *)find_id("AC", actname+2);
+
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No valid Action to add.");
+ //printf("Add strip - actname = '%s' \n", actname);
+ return OPERATOR_CANCELLED;
+ }
+
+ /* get a list of the editable tracks being shown in the NLA
+ * - this is limited to active ones for now, but could be expanded to
+ */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT);
+ items= ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ if (items == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No active track(s) to add strip to.");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* for every active track, try to add strip to free space in track or to the top of the stack if no space */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ NlaTrack *nlt= (NlaTrack *)ale->data;
+ AnimData *adt= BKE_animdata_from_id(ale->id);
+ NlaStrip *strip= NULL;
+
+ /* create a new strip, and offset it to start on the current frame */
+ strip= add_nlastrip(act);
+
+ strip->end += (cfra - strip->start);
+ strip->start = cfra;
+
+ /* firstly try adding strip to our current track, but if that fails, add to a new track */
+ if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
+ /* trying to add to the current failed (no space),
+ * so add a new track to the stack, and add to that...
+ */
+ nlt= add_nlatrack(adt, NULL);
+ BKE_nlatrack_add_strip(nlt, strip);
+ }
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* set notifier that things have changed */
+ ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ WM_event_add_notifier(C, NC_SCENE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLAEDIT_OT_add_actionclip (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Action Strip";
+ ot->idname= "NLAEDIT_OT_add_actionclip";
+ ot->description= "Add an Action-Clip strip (i.e. an NLA Strip referencing an Action) to the active track.";
+
+ /* api callbacks */
+ ot->invoke= nlaedit_add_actionclip_invoke;
+ ot->exec= nlaedit_add_actionclip_exec;
+ ot->poll= nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* props */
+ // TODO: this would be nicer as an ID-pointer...
+ RNA_def_string(ot->srna, "action", "", 21, "Action", "Name of Action to add as a new Action-Clip Strip.");
+}
+
+/* ******************** Add Transition Operator ***************************** */
+/* Add a new transition strip between selected strips */
+
+/* add the specified action as new strip */
+static int nlaedit_add_transition_exec (bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ int done = 0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get a list of the editable tracks being shown in the NLA */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* for each track, find pairs of strips to add transitions to */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ NlaTrack *nlt= (NlaTrack *)ale->data;
+ NlaStrip *s1, *s2;
+
+ /* get initial pair of strips */
+ if ELEM(nlt->strips.first, NULL, nlt->strips.last)
+ continue;
+ s1= nlt->strips.first;
+ s2= s1->next;
+
+ /* loop over strips */
+ for (; s1 && s2; s1=s2, s2=s2->next) {
+ NlaStrip *strip;
+
+ /* check if both are selected */
+ if ELEM(0, (s1->flag & NLASTRIP_FLAG_SELECT), (s2->flag & NLASTRIP_FLAG_SELECT))
+ continue;
+ /* check if there's space between the two */
+ if (IS_EQ(s1->end, s2->start))
+ continue;
+
+ /* allocate new strip */
+ strip= MEM_callocN(sizeof(NlaStrip), "NlaStrip");
+ BLI_insertlinkafter(&nlt->strips, s1, strip);
+
+ /* set the type */
+ strip->type= NLASTRIP_TYPE_TRANSITION;
+
+ /* generic settings
+ * - selected flag to highlight this to the user
+ * - auto-blends to ensure that blend in/out values are automatically
+ * determined by overlaps of strips
+ */
+ strip->flag = NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_AUTO_BLENDS;
+
+ /* range is simply defined as the endpoints of the adjacent strips */
+ strip->start = s1->end;
+ strip->end = s2->start;
+
+ /* scale and repeat aren't of any use, but shouldn't ever be 0 */
+ strip->scale= 1.0f;
+ strip->repeat = 1.0f;
+
+ /* make note of this */
+ done++;
+ }
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* was anything added? */
+ if (done) {
+ /* set notifier that things have changed */
+ ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ WM_event_add_notifier(C, NC_SCENE, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Needs at least a pair of adjacent selected strips.");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void NLAEDIT_OT_add_transition (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Transition";
+ ot->idname= "NLAEDIT_OT_add_transition";
+ ot->description= "Add a transition strip between two adjacent selected strips.";
+
+ /* api callbacks */
+ ot->exec= nlaedit_add_transition_exec;
+ ot->poll= nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
/* ******************** Delete Strips Operator ***************************** */
/* Deletes the selected NLA-Strips */
@@ -230,7 +455,7 @@ static int nlaedit_delete_exec (bContext *C, wmOperator *op)
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- /* get a list of the AnimData blocks being shown in the NLA */
+ /* get a list of the editable tracks being shown in the NLA */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
@@ -292,7 +517,7 @@ static int nlaedit_split_exec (bContext *C, wmOperator *op)
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- /* get a list of the AnimData blocks being shown in the NLA */
+ /* get a list of editable tracks being shown in the NLA */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c
index 0d42c544a3f..970d602c0af 100644
--- a/source/blender/editors/space_nla/nla_header.c
+++ b/source/blender/editors/space_nla/nla_header.c
@@ -110,7 +110,7 @@ static void nla_viewmenu(bContext *C, uiLayout *layout, void *arg_unused)
uiItemS(layout);
- uiItemO(layout, NULL, 0, "NLA_OT_view_all");
+ //uiItemO(layout, NULL, 0, "NLA_OT_view_all");
if (sa->full)
uiItemO(layout, NULL, 0, "SCREEN_OT_screen_full_area"); // "Tile Window", Ctrl UpArrow
@@ -146,6 +146,9 @@ static void nla_editmenu(bContext *C, uiLayout *layout, void *arg_unused)
uiItemO(layout, NULL, 0, "NLA_OT_add_tracks");
uiItemBooleanO(layout, "Add Tracks Above Selected", 0, "NLA_OT_add_tracks", "above_selected", 1);
+ uiItemO(layout, NULL, 0, "NLA_OT_add_actionclip");
+ uiItemO(layout, NULL, 0, "NLA_OT_add_transition");
+
uiItemO(layout, NULL, 0, "NLAEDIT_OT_split");
uiItemS(layout);
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 5c6670cfd6f..f1bde40f4ab 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -92,6 +92,9 @@ void NLAEDIT_OT_tweakmode_exit(wmOperatorType *ot);
/* --- */
+void NLAEDIT_OT_add_actionclip(wmOperatorType *ot);
+void NLAEDIT_OT_add_transition(wmOperatorType *ot);
+
void NLAEDIT_OT_delete(wmOperatorType *ot);
void NLAEDIT_OT_split(wmOperatorType *ot);
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 981ef9a4f87..a9b7022157e 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -134,6 +134,9 @@ void nla_operatortypes(void)
WM_operatortype_append(NLAEDIT_OT_tweakmode_enter);
WM_operatortype_append(NLAEDIT_OT_tweakmode_exit);
+ WM_operatortype_append(NLAEDIT_OT_add_actionclip);
+ WM_operatortype_append(NLAEDIT_OT_add_transition);
+
WM_operatortype_append(NLAEDIT_OT_delete);
WM_operatortype_append(NLAEDIT_OT_split);
}
@@ -208,6 +211,10 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "NLAEDIT_OT_tweakmode_enter", TABKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLAEDIT_OT_tweakmode_exit", TABKEY, KM_PRESS, 0, 0);
+ /* add strips */
+ WM_keymap_add_item(keymap, "NLAEDIT_OT_add_actionclip", AKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "NLAEDIT_OT_add_transition", TKEY, KM_PRESS, KM_SHIFT, 0);
+
/* delete */
WM_keymap_add_item(keymap, "NLAEDIT_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLAEDIT_OT_delete", DELKEY, KM_PRESS, 0, 0);