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>2007-11-06 14:41:09 +0300
committerJoshua Leung <aligorith@gmail.com>2007-11-06 14:41:09 +0300
commit9cd76a66096491e8994090e1992bb54d19c61950 (patch)
tree9c15073744788663d85e43f74dbfe47a57f80bea /source/blender/src
parentf66aeb7a742a1668ebe9cdd7b06cc83606bb55f4 (diff)
== "Extend" Transform Mode for Action + NLA Editors ==
Peach Request: Now the Action and NLA editors have the "Extend" transform mode first seen in the Sequence Editor. Just use the EKEY to start transforming. It works like Grab, except it only moves the keyframes/side of NLA-strip that was on the same side of the current-frame marker as the mouse was when transform started.
Diffstat (limited to 'source/blender/src')
-rw-r--r--source/blender/src/editaction.c13
-rw-r--r--source/blender/src/editnla.c13
-rw-r--r--source/blender/src/header_action.c10
-rw-r--r--source/blender/src/header_nla.c16
-rw-r--r--source/blender/src/transform.c5
-rw-r--r--source/blender/src/transform_conversions.c155
6 files changed, 174 insertions, 38 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 3957b107814..48a39875cc2 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -739,6 +739,12 @@ void transform_action_keys (int mode, int dummy)
Transform();
}
break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, CTX_NONE);
+ Transform();
+ }
+ break;
}
}
@@ -2645,7 +2651,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
duplicate_action_keys();
}
break;
-
+
+ case EKEY:
+ if (mval[0] >= ACTWIDTH)
+ transform_action_keys('e', 0);
+ break;
+
case GKEY:
if (G.qual & LR_CTRLKEY) {
transform_markers('g', 0);
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 13423424f90..ec3b1c834e5 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -995,6 +995,12 @@ void transform_nlachannel_keys(int mode, int dummy)
Transform();
}
break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, CTX_NONE);
+ Transform();
+ }
+ break;
}
}
@@ -1791,6 +1797,13 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
+ case EKEY:
+ if (mval[0] >= NLAWIDTH) {
+ transform_nlachannel_keys ('e', 0);
+ update_for_newframe_muted();
+ }
+ break;
+
case GKEY:
if (mval[0]>=NLAWIDTH) {
if (G.qual & LR_CTRLKEY) {
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index c6d1b88c95c..4a803926a94 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -114,7 +114,6 @@ enum {
enum {
ACTMENU_KEY_DUPLICATE = 0,
ACTMENU_KEY_DELETE,
- ACTMENU_KEY_BAKE,
ACTMENU_KEY_CLEAN
};
@@ -128,7 +127,8 @@ enum {
enum {
ACTMENU_KEY_TRANSFORM_MOVE = 0,
ACTMENU_KEY_TRANSFORM_SCALE,
- ACTMENU_KEY_TRANSFORM_SLIDE
+ ACTMENU_KEY_TRANSFORM_SLIDE,
+ ACTMENU_KEY_TRANSFORM_EXTEND
};
enum {
@@ -594,6 +594,9 @@ static void do_action_keymenu_transformmenu(void *arg, int event)
case ACTMENU_KEY_TRANSFORM_SLIDE:
transform_action_keys('t', 0);
break;
+ case ACTMENU_KEY_TRANSFORM_EXTEND:
+ transform_action_keys('e', 0);
+ break;
}
scrarea_queue_winredraw(curarea);
@@ -612,6 +615,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused)
"Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_MOVE, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_TRANSFORM_EXTEND, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_SCALE, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c
index 3a3d3dfdb49..96ea6c3d792 100644
--- a/source/blender/src/header_nla.c
+++ b/source/blender/src/header_nla.c
@@ -269,12 +269,16 @@ static void do_nla_strip_transformmenu(void *arg, int event)
{
switch(event) {
case 0: /* grab/move */
- transform_nlachannel_keys ('g', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('g', 0);
+ update_for_newframe_muted();
break;
case 1: /* scale */
- transform_nlachannel_keys ('s', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('s', 0);
+ update_for_newframe_muted();
+ break;
+ case 2: /* extend */
+ transform_nlachannel_keys('e', 0);
+ update_for_newframe_muted();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -289,8 +293,10 @@ static uiBlock *nla_strip_transformmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_nla_strip_transformmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-
+
+
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 321a56c5ebd..2a7f744f219 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -938,6 +938,7 @@ void initTransform(int mode, int context) {
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
+ /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
mode = Trans.mode;
calculatePropRatio(&Trans);
@@ -1004,6 +1005,10 @@ void initTransform(int mode, int context) {
case TFM_TIME_SCALE:
initTimeScale(&Trans);
break;
+ case TFM_TIME_EXTEND:
+ /* now that transdata has been made, do like for TFM_TIME_TRANSLATE */
+ initTimeTranslate(&Trans);
+ break;
}
}
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index b0e2d8144e8..820d79eb809 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -113,6 +113,7 @@
#include "BIF_toolbox.h"
#include "BSE_view.h"
+#include "BSE_drawipo.h"
#include "BSE_edit.h"
#include "BSE_editipo.h"
#include "BSE_editipo_types.h"
@@ -2049,7 +2050,48 @@ void flushTransIpoData(TransInfo *t)
/* ********************* ACTION/NLA EDITOR ****************** */
+/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
+static short FrameOnMouseSide(char side, float frame, float cframe)
+{
+ /* both sides, so it doesn't matter */
+ if (side == 'B') return 1;
+
+ /* only on the named side */
+ if (side == 'R')
+ return (frame >= cframe) ? 1 : 0;
+ else
+ return (frame <= cframe) ? 1 : 0;
+}
+/* fully select selected beztriples, but only include if it's on the right side of cfra */
+static int count_ipo_keys(Ipo *ipo, char side, float cfra)
+{
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int i, count = 0;
+
+ if (ipo == NULL)
+ return count;
+
+ /* only include points that occur on the right side of cfra */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (bezt->f2) {
+ /* fully select the other two keys */
+ bezt->f1 |= 1;
+ bezt->f3 |= 1;
+
+ /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
+ count += 3;
+ }
+ }
+ }
+
+ return count;
+}
+
+/* This function assigns the information to transdata */
static void TimeToTransData(TransData *td, float *time, Object *ob)
{
/* memory is calloc'ed, so that should zero everything nicely for us */
@@ -2065,9 +2107,12 @@ static void TimeToTransData(TransData *td, float *time, Object *ob)
/* This function advances the address to which td points to, so it must return
* the new address so that the next time new transform data is added, it doesn't
- * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob);
+ * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob, side, cfra);
+ *
+ * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
+ * on the named side are used.
*/
-static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob)
+static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
{
IpoCurve *icu;
BezTriple *bezt;
@@ -2077,18 +2122,21 @@ static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob)
return td;
for (icu= ipo->curve.first; icu; icu= icu->next) {
- /* only add selected keyframes (for now, proportional edit is not enabled) */
for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* only add selected keyframes (for now, proportional edit is not enabled) */
if (BEZSELECTED(bezt)) {
- /* each control point needs to be added separetely */
- TimeToTransData(td, bezt->vec[0], ob);
- td++;
-
- TimeToTransData(td, bezt->vec[1], ob);
- td++;
-
- TimeToTransData(td, bezt->vec[2], ob);
- td++;
+ /* only add if on the right 'side' of the current frame */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
+ /* each control point needs to be added separetely */
+ TimeToTransData(td, bezt->vec[0], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[1], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[2], ob);
+ td++;
+ }
}
}
}
@@ -2108,6 +2156,8 @@ static void createTransActionData(TransInfo *t)
int filter;
int count=0;
+ float cfra;
+ char side;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
@@ -2120,10 +2170,31 @@ static void createTransActionData(TransInfo *t)
/* is the action scaled? if so, the it should belong to the active object */
if (NLA_ACTION_SCALED)
ob= OBACT;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
+
+ /* convert current-frame to action-time (slightly less accurate, espcially under
+ * higher scaling ratios, but is faster than converting all points)
+ */
+ if (ob)
+ cfra = get_action_frame(ob, CFRA);
+ else
+ cfra = CFRA;
/* loop 1: fully select ipo-keys and count how many BezTriples are selected */
for (ale= act_data.first; ale; ale= ale->next)
- count += fullselect_ipo_keys(ale->key_data);
+ count += count_ipo_keys(ale->key_data, side, cfra);
/* stop if trying to build list if nothing selected */
if (count == 0) {
@@ -2143,7 +2214,7 @@ static void createTransActionData(TransInfo *t)
for (ale= act_data.first; ale; ale= ale->next) {
Ipo *ipo= (Ipo *)ale->key_data;
- td= IpoToTransData(td, ipo, ob);
+ td= IpoToTransData(td, ipo, ob, side, cfra);
}
/* check if we're supposed to be setting minx/maxx for TimeSlide */
@@ -2178,17 +2249,32 @@ static void createTransNlaData(TransInfo *t)
TransData *td = NULL;
int count=0, i;
+ float cfra;
+ char side;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
/* Ensure that partial selections result in beztriple selections */
for (base=G.scene->base.first; base; base=base->next) {
/* Check object ipos */
- i= fullselect_ipo_keys(base->object->ipo);
+ i= count_ipo_keys(base->object->ipo, side, CFRA);
if (i) base->flag |= BA_HAS_RECALC_OB;
count += i;
/* Check object constraint ipos */
for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- count += fullselect_ipo_keys(conchan->ipo);
+ count += count_ipo_keys(conchan->ipo, side, CFRA);
/* skip actions and nlastrips if object is collapsed */
if (base->object->nlaflag & OB_NLA_COLLAPSED)
@@ -2203,9 +2289,11 @@ static void createTransNlaData(TransInfo *t)
break;
}
if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
if (EDITABLE_ACHAN(achan)) {
- i= fullselect_ipo_keys(achan->ipo);
+ i= count_ipo_keys(achan->ipo, side, cfra);
if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
count += i;
@@ -2213,7 +2301,7 @@ static void createTransNlaData(TransInfo *t)
if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (EDITABLE_CONCHAN(conchan))
- count += fullselect_ipo_keys(conchan->ipo);
+ count += count_ipo_keys(conchan->ipo, side, cfra);
}
}
}
@@ -2225,7 +2313,9 @@ static void createTransNlaData(TransInfo *t)
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
- count += 2;
+
+ if (FrameOnMouseSide(side, strip->start, CFRA)) count++;
+ if (FrameOnMouseSide(side, strip->end, CFRA)) count++;
}
}
}
@@ -2243,12 +2333,12 @@ static void createTransNlaData(TransInfo *t)
for (base=G.scene->base.first; base; base=base->next) {
/* Manipulate object ipos */
/* - no scaling of keyframe times is allowed here */
- td= IpoToTransData(td, base->object->ipo, NULL);
+ td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA);
/* Manipulate object constraint ipos */
/* - no scaling of keyframe times is allowed here */
for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- td= IpoToTransData(td, conchan->ipo, NULL);
+ td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA);
/* skip actions and nlastrips if object collapsed */
if (base->object->nlaflag & OB_NLA_COLLAPSED)
@@ -2265,15 +2355,17 @@ static void createTransNlaData(TransInfo *t)
/* can include if no strip found */
if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
if (EDITABLE_ACHAN(achan)) {
- td= IpoToTransData(td, achan->ipo, base->object);
+ td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
/* Manipulate action constraint ipos */
if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (EDITABLE_CONCHAN(conchan))
- td= IpoToTransData(td, conchan->ipo, base->object);
+ td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
}
}
}
@@ -2285,13 +2377,16 @@ static void createTransNlaData(TransInfo *t)
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
/* first TransData is the start, second is the end */
- td->val = &strip->start;
- td->ival = strip->start;
- td++;
-
- td->val = &strip->end;
- td->ival = strip->end;
- td++;
+ if (FrameOnMouseSide(side, strip->start, CFRA)) {
+ td->val = &strip->start;
+ td->ival = strip->start;
+ td++;
+ }
+ if (FrameOnMouseSide(side, strip->end, CFRA)) {
+ td->val = &strip->end;
+ td->ival = strip->end;
+ td++;
+ }
}
}
}