== Action Editor - Individual IPO-Curves Now Shown ==

Continuing on from my previous 'Expandable/Collapsable Action Channel' commit, this commit introduces the ability to show/hide the keyframes in each ipo-curve represented by an Action Channel.

When you expand an Action-Channel by clicking on the triangle beside its name, you will now be presented with options to show/hide the ipo-curves represented by
the Action-Channel, and/or the Constraint Channels belonging to that Action-Channel. Actual ipo-curves will not be drawn in the Action-Editor, but the keyframes
will be shown.

Screenshot:
* http://wiki.blender.org/index.php/Image:244_ActionEditor_SubTracks_01.png

Possibly Coming Soon/Further Work:
* 'Protection' options for ipo-curves (currently disabled in code, as all IPO-related
 tools will need to be made aware of this)
* Sliders for IPO-Curve Channels of the active Action-Channel
This commit is contained in:
2007-04-13 11:15:08 +00:00
parent 54efb4c916
commit 99e4e1fcb7
8 changed files with 737 additions and 252 deletions

View File

@@ -46,34 +46,31 @@
#define CHANNELHEIGHT 16
#define CHANNELSKIP 2
#define NAMEWIDTH 144
#define NAMEWIDTH 164
#define SLIDERWIDTH 125
#define ACTWIDTH (G.saction->actwidth)
/* Some types for easier type-testing */
#define ACTTYPE_NONE 0
#define ACTTYPE_ACHAN 1
#define ACTTYPE_CONCHAN 2
#define ACTTYPE_NONE 0
#define ACTTYPE_ACHAN 1
#define ACTTYPE_CONCHAN 2
#define ACTTYPE_ICU 3
#define ACTTYPE_FILLIPO 4
#define ACTTYPE_FILLCON 5
/* Macros for easier/more consistant state testing */
#define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
#define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0))
#define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED))
#define SEL_ACHAN(achan) ((achan->flag & ACHAN_SELECTED) || (achan->flag & ACHAN_HILIGHTED))
#define FILTER_IPO_ACHAN(achan) ((achan->flag & ACHAN_SHOWIPO))
#define FILTER_CON_ACHAN(achan) ((achan->flag & ACHAN_SHOWCONS))
#define EDITABLE_CONCHAN(conchan) ((conchan->flag & CONSTRAINT_CHANNEL_PROTECTED)==0)
#define SEL_CONCHAN(conchan) (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
#define CHANNEL_FILTER_LOC 0x00000001 /* Show location keys */
#define CHANNEL_FILTER_ROT 0x00000002 /* Show rotation keys */
#define CHANNEL_FILTER_SIZE 0x00000004 /* Show size keys */
#define CHANNEL_FILTER_CON 0x00000008 /* Show constraint keys */
#define CHANNEL_FILTER_RGB 0x00000010 /* Show object color keys */
#define CHANNEL_FILTER_CU 0x00010000 /* Show curve keys */
#define CHANNEL_FILTER_ME 0x00020000 /* Show mesh keys */
#define CHANNEL_FILTER_LA 0x00040000 /* Show lamp keys */
#define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
#define SEL_ICU(icu) (icu->flag & IPO_SELECT)
struct bAction;
struct bActionChannel;

View File

@@ -60,6 +60,9 @@ char *getname_cam_ei(int nr);
char *getname_snd_ei(int nr);
char *getname_fluidsim_ei(int nr);
char *getname_ipocurve(struct IpoCurve *icu);
int geticon_ipo_blocktype(short blocktype);
struct EditIpo *get_active_editipo(void);
void boundbox_ipocurve(struct IpoCurve *icu);

View File

@@ -95,10 +95,10 @@ typedef struct bActionChannel {
struct bActionChannel *next, *prev;
struct Ipo *ipo;
ListBase constraintChannels;
int flag;
char name[32]; /* Channel name */
int reserved1;
} bActionChannel;
typedef struct bAction {
@@ -127,6 +127,8 @@ typedef struct SpaceAction {
#define ACHAN_HIDDEN 0x00000004
#define ACHAN_PROTECTED 0x00000008
#define ACHAN_EXPANDED 0x00000010
#define ACHAN_SHOWIPO 0x00000020
#define ACHAN_SHOWCONS 0x00000040
#define ACHAN_MOVED 0x80000000
/* SpaceAction flag */

View File

@@ -390,6 +390,7 @@ typedef short IPO_Channel;
#define IPO_LOCK 8
#define IPO_AUTO_HORIZ 16
#define IPO_ACTIVE 32
#define IPO_PROTECT 64
#endif

View File

@@ -82,6 +82,7 @@
#include "BSE_drawnla.h"
#include "BSE_drawipo.h"
#include "BSE_editipo.h"
#include "BSE_time.h"
#include "BSE_view.h"
@@ -136,7 +137,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
XIC,YIC-2,
&(G.saction->flag), 0, 0, 0, 0,
"Show action window sliders");
// no hilite, the winmatrix is not correct later on...
/* no hilite, the winmatrix is not correct later on... */
uiButSetFlag(but, UI_NO_HILITE);
}
@@ -147,7 +148,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
XIC,YIC-2,
&(G.saction->flag), 0, 0, 0, 0,
"Hide action window sliders");
// no hilite, the winmatrix is not correct later on...
/* no hilite, the winmatrix is not correct later on... */
uiButSetFlag(but, UI_NO_HILITE);
ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
@@ -205,12 +206,12 @@ void draw_cfra_action(void)
glLineWidth(1.0);
}
/* left hand */
static void draw_action_channel_names(bAction *act)
static void draw_action_channel_names(bAction *act)
{
bActionChannel *achan;
bConstraintChannel *conchan;
IpoCurve *icu;
float x, y;
x = 0.0;
@@ -226,12 +227,10 @@ static void draw_action_channel_names(bAction *act)
glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
/* draw expand/collapse triangle for action-channel */
if (achan->constraintChannels.first) { /* until we get ipo-channels */
if (EXPANDED_ACHAN(achan))
BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
else
BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
}
if (EXPANDED_ACHAN(achan))
BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
else
BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
/* draw name of action channel */
if (SEL_ACHAN(achan))
@@ -249,26 +248,106 @@ static void draw_action_channel_names(bAction *act)
y-=CHANNELHEIGHT+CHANNELSKIP;
if (EXPANDED_ACHAN(achan)) {
/* Draw constraint channels */
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
/* draw backing strip behind constraint channel*/
/* Draw IPO-curves show/hide widget */
if (achan->ipo) {
/* draw backing strip behind */
BIF_ThemeColorShade(TH_HEADER, -20);
glRectf(x+7, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
/* draw name of constraint channel */
if (SEL_CONCHAN(conchan))
/* draw expand/collapse triangle for showing sub-channels */
if (FILTER_IPO_ACHAN(achan))
BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
else
BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
/* draw icon showing type of ipo-block */
BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, geticon_ipo_blocktype(achan->ipo->blocktype));
/* draw name of ipo-block */
if (SEL_ACHAN(achan))
BIF_ThemeColor(TH_TEXT_HI);
else
BIF_ThemeColor(TH_TEXT);
glRasterPos2f(x+18, y-4);
BMF_DrawString(G.font, conchan->name);
/* draw 'lock' to indicate if constraint channel is protected */
if (EDITABLE_CONCHAN(conchan)==0)
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
else
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
glRasterPos2f(x+40, y-4);
BMF_DrawString(G.font, "IPO Curves"); // TODO: make proper naming scheme
y-=CHANNELHEIGHT+CHANNELSKIP;
/* Draw IPO-curve-channels? */
if (FILTER_IPO_ACHAN(achan)) {
for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
/* draw backing strip behind ipo-curve channel*/
BIF_ThemeColorShade(TH_HEADER, -40);
glRectf(x+14, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
/* draw name of ipo-curve channel */
if (SEL_ICU(icu))
BIF_ThemeColor(TH_TEXT_HI);
else
BIF_ThemeColor(TH_TEXT);
glRasterPos2f(x+24, y-4);
BMF_DrawString(G.font, getname_ipocurve(icu));
#if 0 /* tempolarily disabled until all ipo-code can support this option */
/* draw 'lock' to indicate if ipo-curve channel is protected */
if (EDITABLE_ICU(icu)==0)
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
else
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
#endif
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
/* Draw constraints show/hide widget */
if (achan->constraintChannels.first) {
/* draw backing strip behind */
BIF_ThemeColorShade(TH_HEADER, -20);
glRectf(x+7, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
/* draw expand/collapse triangle for showing sub-channels */
if (FILTER_CON_ACHAN(achan))
BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
else
BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
/* draw constraint icon */
BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, ICON_CONSTRAINT);
/* draw name of widget */
if (SEL_ACHAN(achan))
BIF_ThemeColor(TH_TEXT_HI);
else
BIF_ThemeColor(TH_TEXT);
glRasterPos2f(x+40, y-4);
BMF_DrawString(G.font, "Constraints");
y-=CHANNELHEIGHT+CHANNELSKIP;
/* Draw constraint channels? */
if (FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
/* draw backing strip behind constraint channel*/
BIF_ThemeColorShade(TH_HEADER, -40);
glRectf(x+14, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
/* draw name of constraint channel */
if (SEL_CONCHAN(conchan))
BIF_ThemeColor(TH_TEXT_HI);
else
BIF_ThemeColor(TH_TEXT);
glRasterPos2f(x+25, y-4);
BMF_DrawString(G.font, conchan->name);
/* draw 'lock' to indicate if constraint channel is protected */
if (EDITABLE_CONCHAN(conchan)==0)
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
else
BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
}
@@ -369,17 +448,27 @@ static void draw_channel_names(void)
int count_action_levels(bAction *act)
{
bActionChannel *achan;
int y= 0;
int y=0;
if (!act)
if (!act)
return 0;
for (achan=act->chanbase.first; achan; achan=achan->next) {
if(VISIBLE_ACHAN(achan)) {
y+= 1;
y++;
if (EXPANDED_ACHAN(achan))
y+= BLI_countlist(&achan->constraintChannels);
if (EXPANDED_ACHAN(achan)) {
if (achan->constraintChannels.first) {
y++;
if (FILTER_CON_ACHAN(achan))
y += BLI_countlist(&achan->constraintChannels);
}
else if (achan->ipo) {
y++;
if (FILTER_IPO_ACHAN(achan))
y += BLI_countlist(&achan->ipo->curve);
}
}
}
}
@@ -417,6 +506,7 @@ static void draw_channel_strips(SpaceAction *saction)
bAction *act;
bActionChannel *achan;
bConstraintChannel *conchan;
IpoCurve *icu;
float y, sta, end;
int act_start, act_end, dummy;
char col1[3], col2[3];
@@ -466,20 +556,48 @@ static void draw_channel_strips(SpaceAction *saction)
/* Increment the step */
y-=CHANNELHEIGHT+CHANNELSKIP;
/* Draw constraint channels */
/* Draw sub channels */
if (EXPANDED_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4);
/* Draw ipo channels */
if (achan->ipo) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_IPO_ACHAN(achan)) {
for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4);
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
/* Draw constraint channels */
if (achan->constraintChannels.first) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
else glColor4ub(col2[0], col2[1], col2[2], 0x22);
glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4);
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
}
}
@@ -497,11 +615,30 @@ static void draw_channel_strips(SpaceAction *saction)
draw_ipo_channel(di, achan->ipo, y);
y-=CHANNELHEIGHT+CHANNELSKIP;
/* Draw constraint channels */
/* Draw sub channels */
if (EXPANDED_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
draw_ipo_channel(di, conchan->ipo, y);
/* Draw ipo curves */
if (achan->ipo) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_IPO_ACHAN(achan)) {
for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
draw_icu_channel(di, icu, y);
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
/* Draw constraint channels */
if (achan->constraintChannels.first) {
y-=CHANNELHEIGHT+CHANNELSKIP;
if (FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
draw_ipo_channel(di, conchan->ipo, y);
y-=CHANNELHEIGHT+CHANNELSKIP;
}
}
}
}
}
@@ -639,6 +776,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
uiFreeBlocksWin(&sa->uiblocks, sa->win);
if (!G.saction->pin) {
/* allow more than one active action sometime? */
if (OBACT)
G.saction->action = OBACT->action;
else

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,8 @@
#include "BKE_ipo.h"
#include "BKE_utildefines.h"
#include "BIF_resources.h"
#include "BSE_edit.h"
#include "BSE_editipo_types.h"
#include "BSE_editipo.h"
@@ -95,6 +97,51 @@ char *ac_ic_names[AC_TOTNAM] = {"LocX", "LocY", "LocZ", "ScaleX", "ScaleY",
char *ic_name_empty[1] ={ "" };
char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time", "GravX","GravY","GravZ", "VelX","VelY","VelZ", "Active" };
/* gets the appropriate icon for the given blocktype */
int geticon_ipo_blocktype(short blocktype)
{
switch (blocktype) {
case ID_OB:
return ICON_OBJECT;
case ID_PO:
return ICON_POSE_HLT;
case ID_KE:
return ICON_EDIT;
case ID_MA:
return ICON_MATERIAL;
case ID_WO:
return ICON_WORLD;
case ID_CU:
return ICON_CURVE;
case ID_CA:
return ICON_CAMERA;
case ID_LA:
return ICON_LAMP;
case ID_TE:
return ICON_TEXTURE;
case ID_CO:
return ICON_CONSTRAINT;
case ID_FLUIDSIM:
return ICON_WORLD; // uggh
default:
return 0; // what about blank icon?
}
}
/* get name of ipo-curve (icu should be valid pointer) */
char *getname_ipocurve(IpoCurve *icu)
{
switch (icu->blocktype) {
case ID_OB:
return getname_ob_ei(icu->adrcode, 0); /* dummy 2nd arg */
case ID_PO:
return getname_ac_ei(icu->adrcode);
default: /* fixme - add all of the other types! */
return NULL;
}
}
char *getname_ac_ei(int nr)
{
switch(nr) {

View File

@@ -1117,7 +1117,7 @@ int fullselect_ipo_keys(Ipo *ipo)
if (!ipo)
return tvtot;
for (icu=ipo->curve.first; icu; icu=icu->next){
for (icu=ipo->curve.first; icu; icu=icu->next) {
for (i=0; i<icu->totvert; i++){
if (icu->bezt[i].f2 & 1){
tvtot+=3;