Animation Editors: Code Cleanup Part 1 - Drawing

Finally started refactoring the drawing code for animation editors so that all the drawing (of the channels/names list) is done using standardised code for all the editors. 

A little specialised system for this has been made, and is now used for DopeSheet and Graph Editor drawing. This should make it easier to add new channel types with less effort.

Protect/mute toggles are now always clamped to the right-hand edge of the channels list. So you can now make the list wider to view longer names fully. However, since the mouse-handling hasn't been fixed yet, this won't always work.

TODOs:
* make mouse-click handling code use this system too, simplifying things to 1-2 lines of code there. Maybe this could be made to use UI widgets instead at a later date?
* NLA still needs to be ported to this system
This commit is contained in:
Joshua Leung 2009-08-11 11:52:23 +00:00
parent 911078aaad
commit b9584607c5
5 changed files with 2038 additions and 1299 deletions

File diff suppressed because it is too large Load Diff

@ -17,11 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
@ -884,14 +882,6 @@ void ANIM_OT_channels_visibility_toggle (wmOperatorType *ot)
/* ********************** Set Flags Operator *********************** */
enum {
// ACHANNEL_SETTING_SELECT = 0,
ACHANNEL_SETTING_PROTECT = 1,
ACHANNEL_SETTING_MUTE,
ACHANNEL_SETTING_VISIBLE,
ACHANNEL_SETTING_EXPAND,
} eAnimChannel_Settings;
/* defines for setting animation-channel flags */
EnumPropertyItem prop_animchannel_setflag_types[] = {
{ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
@ -901,6 +891,7 @@ EnumPropertyItem prop_animchannel_setflag_types[] = {
};
/* defines for set animation-channel settings */
// TODO: could add some more types, but those are really quite dependent on the mode...
EnumPropertyItem prop_animchannel_settings_types[] = {
{ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
{ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
@ -932,213 +923,8 @@ static void setflag_anim_channels (bAnimContext *ac, short setting, short mode,
/* affect selected channels */
for (ale= anim_data.first; ale; ale= ale->next) {
switch (ale->type) {
case ANIMTYPE_OBJECT:
{
Base *base= (Base *)ale->data;
Object *ob= base->object;
if (setting == ACHANNEL_SETTING_EXPAND) {
// XXX - settings should really be moved out of ob->nlaflag
if (mode == ACHANNEL_SETFLAG_TOGGLE) ob->nlaflag ^= OB_ADS_COLLAPSED;
else if (mode == ACHANNEL_SETFLAG_ADD) ob->nlaflag &= ~OB_ADS_COLLAPSED;
else ob->nlaflag |= OB_ADS_COLLAPSED;
}
}
break;
case ANIMTYPE_FILLACTD:
{
bAction *act= (bAction *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG_NEG(act, mode, ACT_COLLAPSED);
}
}
}
break;
case ANIMTYPE_FILLDRIVERS:
{
AnimData *adt= (AnimData *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG_NEG(adt, mode, ADT_DRIVERS_COLLAPSED);
}
}
}
break;
case ANIMTYPE_FILLMATD:
{
Object *ob= (Object *)ale->data;
// XXX - settings should really be moved out of ob->nlaflag
if ((onlysel == 0) || (ob->flag & SELECT)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
if (mode == ACHANNEL_SETFLAG_TOGGLE) ob->nlaflag ^= OB_ADS_SHOWMATS;
else if (mode == ACHANNEL_SETFLAG_ADD) ob->nlaflag |= OB_ADS_SHOWMATS;
else ob->nlaflag &= ~OB_ADS_SHOWMATS;
}
}
}
break;
case ANIMTYPE_FILLPARTD:
{
Object *ob= (Object *)ale->data;
// XXX - settings should really be moved out of ob->nlaflag
if ((onlysel == 0) || (ob->flag & SELECT)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
if (mode == ACHANNEL_SETFLAG_TOGGLE) ob->nlaflag ^= OB_ADS_SHOWPARTS;
else if (mode == ACHANNEL_SETFLAG_ADD) ob->nlaflag |= OB_ADS_SHOWPARTS;
else ob->nlaflag &= ~OB_ADS_SHOWPARTS;
}
}
}
break;
case ANIMTYPE_DSMAT:
{
Material *ma= (Material *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(ma, mode, MA_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSLAM:
{
Lamp *la= (Lamp *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(la, mode, LA_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSCAM:
{
Camera *ca= (Camera *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(ca, mode, CAM_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSCUR:
{
Curve *cu= (Curve *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(cu, mode, CU_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSSKEY:
{
Key *key= (Key *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(key, mode, KEYBLOCK_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSWOR:
{
World *wo= (World *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(wo, mode, WO_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSPART:
{
ParticleSettings *part= (ParticleSettings*)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(part, mode, PART_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_DSMBALL:
{
MetaBall *mb= (MetaBall *)ale->data;
if (ASUBCHANNEL_SEL_OK(ale)) {
if (setting == ACHANNEL_SETTING_EXPAND) {
ACHANNEL_SET_FLAG(mb, mode, MB_DS_EXPAND);
}
}
}
break;
case ANIMTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)ale->data;
switch (setting) {
case ACHANNEL_SETTING_PROTECT:
ACHANNEL_SET_FLAG(agrp, mode, AGRP_PROTECTED);
break;
case ACHANNEL_SETTING_EXPAND:
ACHANNEL_SET_FLAG(agrp, mode, AGRP_EXPANDED);
break;
case ACHANNEL_SETTING_MUTE:
ACHANNEL_SET_FLAG(agrp, mode, AGRP_MUTED);
break;
case ACHANNEL_SETTING_VISIBLE:
ACHANNEL_SET_FLAG_NEG(agrp, mode, AGRP_NOTVISIBLE);
break;
}
}
break;
case ANIMTYPE_FCURVE:
{
FCurve *fcu= (FCurve *)ale->data;
switch (setting) {
case ACHANNEL_SETTING_MUTE:
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_MUTED);
break;
case ACHANNEL_SETTING_PROTECT:
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_PROTECTED);
break;
case ACHANNEL_SETTING_VISIBLE:
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_VISIBLE);
break;
}
}
break;
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl= (bGPDlayer *)ale->data;
switch (setting) {
case ACHANNEL_SETTING_MUTE:
ACHANNEL_SET_FLAG(gpl, mode, GP_LAYER_HIDE);
break;
case ACHANNEL_SETTING_PROTECT:
ACHANNEL_SET_FLAG(gpl, mode, GP_LAYER_LOCKED);
break;
}
}
break;
}
/* set the setting in the appropriate way (if available) */
ANIM_channel_setting_set(ac, ale, setting, mode);
}
BLI_freelistN(&anim_data);

@ -107,7 +107,10 @@ typedef struct bAnimListElem {
} bAnimListElem;
/* Some types for easier type-testing */
/* Some types for easier type-testing
* NOTE: need to keep the order of these synchronised with the channels define code
* which is used for drawing and handling channel lists for
*/
// XXX was ACTTYPE_*
typedef enum eAnim_ChannelType {
ANIMTYPE_NONE= 0,
@ -140,6 +143,9 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_NLATRACK,
ANIMTYPE_NLAACTION,
/* always as last item, the total number of channel types... */
ANIMTYPE_NUM_TYPES,
} eAnim_ChannelType;
/* types of keyframe data in bAnimListElem */
@ -275,9 +281,80 @@ short ANIM_animdata_context_getdata(bAnimContext *ac);
/* ************************************************ */
/* ANIMATION CHANNELS LIST */
/* anim_channels.c */
/* anim_channels_*.c */
/* ------------------------ Drawing TypeInfo -------------------------- */
/* flag-setting behaviour */
typedef enum eAnimChannels_SetFlag {
ACHANNEL_SETFLAG_CLEAR = 0,
ACHANNEL_SETFLAG_ADD,
ACHANNEL_SETFLAG_TOGGLE
} eAnimChannels_SetFlag;
/* types of settings for AnimChanels */
typedef enum eAnimChannel_Settings {
ACHANNEL_SETTING_SELECT = 0,
ACHANNEL_SETTING_PROTECT, // warning: for drawing UI's, need to check if this is off (maybe inverse this later)
ACHANNEL_SETTING_MUTE,
ACHANNEL_SETTING_EXPAND,
ACHANNEL_SETTING_VISIBLE, /* only for Graph Editor */
ACHANNEL_SETTING_SOLO, /* only for NLA Tracks */
} eAnimChannel_Settings;
/* Drawing, mouse handling, and flag setting behaviour... */
typedef struct bAnimChannelType {
/* drawing */
/* draw backdrop strip for channel */
void (*draw_backdrop)(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc);
/* get depth of indention (relative to the depth channel is nested at) */
short (*get_indent_level)(bAnimContext *ac, bAnimListElem *ale);
/* get offset in pixels for the start of the channel (in addition to the indent depth) */
short (*get_offset)(bAnimContext *ac, bAnimListElem *ale);
/* get name (for channel lists) */
void (*name)(bAnimListElem *ale, char *name);
/* get icon (for channel lists) */
int (*icon)(bAnimListElem *ale);
/* settings */
/* check if the given setting is valid in the current context */
short (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting);
/* get the flag used for this setting */
int (*setting_flag)(int setting, short *neg);
/* get the pointer to int/short where data is stored,
* with type being sizeof(ptr_data) which should be fine for runtime use...
* - assume that setting has been checked to be valid for current context
*/
void *(*setting_ptr)(bAnimListElem *ale, int setting, short *type);
} bAnimChannelType;
/* ------------------------ Drawing API -------------------------- */
/* Get typeinfo for the given channel */
bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale);
/* Draw the given channel */
void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc);
/* ------------------------ Editing API -------------------------- */
/* Check if some setting for a channel is enabled
* Returns: 1 = On, 0 = Off, -1 = Invalid
*
* - setting: eAnimChannel_Settings
*/
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting);
/* Change value of some setting for a channel
* - setting: eAnimChannel_Settings
* - mode: eAnimChannels_SetFlag
*/
void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, short mode);
/* ------------------------ API -------------------------- */
/* Deselect all animation channels */
void ANIM_deselect_anim_channels(void *data, short datatype, short test, short sel);
@ -285,15 +362,6 @@ void ANIM_deselect_anim_channels(void *data, short datatype, short test, short s
/* Set the 'active' channel of type channel_type, in the given action */
void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type);
/* --------------- Settings and/or Defines -------------- */
/* flag-setting behaviour */
enum {
ACHANNEL_SETFLAG_CLEAR = 0,
ACHANNEL_SETFLAG_ADD,
ACHANNEL_SETFLAG_TOGGLE
} eAnimChannels_SetFlag;
/* ************************************************ */
/* DRAWING API */
/* anim_draw.c */

@ -404,7 +404,7 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
int filter;
View2D *v2d= &ar->v2d;
float x= 0.0f, y= 0.0f;
float y= 0.0f;
int items, height;
/* build list of channels to draw */
@ -431,575 +431,15 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
y= (float)ACHANNEL_FIRST;
for (ale= anim_data.first; ale; ale= ale->next) {
const float yminc= (float)(y - ACHANNEL_HEIGHT_HALF);
const float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF);
float yminc= (float)(y - ACHANNEL_HEIGHT_HALF);
float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF);
/* check if visible */
if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
{
bActionGroup *grp = NULL;
short indent= 0, offset= 0, sel= 0, group= 0;
int expand= -1, protect = -1, special= -1, mute = -1;
char name[128];
/* determine what needs to be drawn */
switch (ale->type) {
case ANIMTYPE_SCENE: /* scene */
{
Scene *sce= (Scene *)ale->data;
group= 4;
indent= 0;
special= ICON_SCENE_DATA;
/* only show expand if there are any channels */
if (EXPANDED_SCEC(sce))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_SCEC(sce);
strcpy(name, sce->id.name+2);
}
break;
case ANIMTYPE_OBJECT: /* object */
{
Base *base= (Base *)ale->data;
Object *ob= base->object;
group= 4;
indent= 0;
/* icon depends on object-type */
if (ob->type == OB_ARMATURE)
special= ICON_ARMATURE_DATA;
else
special= ICON_OBJECT_DATA;
/* only show expand if there are any channels */
if (EXPANDED_OBJC(ob))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_OBJC(base);
strcpy(name, ob->id.name+2);
}
break;
case ANIMTYPE_FILLACTD: /* action widget */
{
bAction *act= (bAction *)ale->data;
group = 4;
indent= 1;
special= ICON_ACTION;
if (EXPANDED_ACTC(act))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_ACTC(act);
strcpy(name, act->id.name+2);
}
break;
case ANIMTYPE_FILLMATD: /* object materials (dopesheet) expand widget */
{
Object *ob = (Object *)ale->data;
group = 4;
indent = 1;
special = ICON_MATERIAL_DATA;
if (FILTER_MAT_OBJC(ob))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, "Materials");
}
break;
case ANIMTYPE_FILLPARTD: /* object particles (dopesheet) expand widget */
{
Object *ob = (Object *)ale->data;
group = 4;
indent = 1;
special = ICON_PARTICLE_DATA;
if (FILTER_PART_OBJC(ob))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, "Particles");
}
break;
case ANIMTYPE_DSMAT: /* single material (dopesheet) expand widget */
{
Material *ma = (Material *)ale->data;
group = 0;
indent = 0;
special = ICON_MATERIAL_DATA;
offset = 21;
if (FILTER_MAT_OBJD(ma))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, ma->id.name+2);
}
break;
case ANIMTYPE_DSLAM: /* lamp (dopesheet) expand widget */
{
Lamp *la = (Lamp *)ale->data;
group = 4;
indent = 1;
special = ICON_LAMP_DATA;
if (FILTER_LAM_OBJD(la))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, la->id.name+2);
}
break;
case ANIMTYPE_DSCAM: /* camera (dopesheet) expand widget */
{
Camera *ca = (Camera *)ale->data;
group = 4;
indent = 1;
special = ICON_CAMERA_DATA;
if (FILTER_CAM_OBJD(ca))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, ca->id.name+2);
}
break;
case ANIMTYPE_DSCUR: /* curve (dopesheet) expand widget */
{
Curve *cu = (Curve *)ale->data;
group = 4;
indent = 1;
special = ICON_CURVE_DATA;
if (FILTER_CUR_OBJD(cu))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, cu->id.name+2);
}
break;
case ANIMTYPE_DSSKEY: /* shapekeys (dopesheet) expand widget */
{
Key *key= (Key *)ale->data;
group = 4;
indent = 1;
special = ICON_SHAPEKEY_DATA; // XXX
if (FILTER_SKE_OBJD(key))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
//sel = SEL_OBJC(base);
strcpy(name, "Shape Keys");
}
break;
case ANIMTYPE_DSWOR: /* world (dopesheet) expand widget */
{
World *wo= (World *)ale->data;
group = 4;
indent = 1;
special = ICON_WORLD_DATA;
if (FILTER_WOR_SCED(wo))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, wo->id.name+2);
}
break;
case ANIMTYPE_DSPART: /* particle (dopesheet) expand widget */
{
ParticleSettings *part= (ParticleSettings*)ale->data;
group = 0;
indent = 0;
special = ICON_PARTICLE_DATA;
offset = 21;
if (FILTER_PART_OBJD(part))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, part->id.name+2);
}
break;
case ANIMTYPE_DSMBALL: /* metaball (dopesheet) expand widget */
{
MetaBall *mb = (MetaBall *)ale->data;
group = 4;
indent = 1;
special = ICON_META_DATA;
if (FILTER_MBALL_OBJD(mb))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, mb->id.name+2);
}
break;
case ANIMTYPE_GROUP: /* action group */
{
bActionGroup *agrp= (bActionGroup *)ale->data;
group= 2;
indent= 0;
special= -1;
if (ale->id) {
/* special exception for materials */
if (GS(ale->id->name) == ID_MA)
offset= 25;
else
offset= 14;
}
else
offset= 0;
/* only show expand if there are any channels */
if (agrp->channels.first) {
if (EXPANDED_AGRP(agrp))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
}
if (agrp->flag & AGRP_MUTED)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
if (EDITABLE_AGRP(agrp))
protect = ICON_UNLOCKED;
else
protect = ICON_LOCKED;
sel = SEL_AGRP(agrp);
strcpy(name, agrp->name);
}
break;
case ANIMTYPE_FCURVE: /* F-Curve channel */
{
FCurve *fcu = (FCurve *)ale->data;
indent = 0;
group= (fcu->grp) ? 1 : 0;
grp= fcu->grp;
if (ale->id) {
/* special exception for materials and particles */
if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) {
offset= 21;
indent= 1;
}
else
offset= 14;
}
else
offset= 0;
if (fcu->flag & FCURVE_MUTED)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
if (fcu->bezt) {
if (EDITABLE_FCU(fcu))
protect = ICON_UNLOCKED;
else
protect = ICON_LOCKED;
}
else
protect = ICON_ZOOMOUT; // XXX editability is irrelevant here, but this icon is temp...
sel = SEL_FCU(fcu);
getname_anim_fcurve(name, ale->id, fcu);
}
break;
case ANIMTYPE_SHAPEKEY: /* shapekey channel */
{
KeyBlock *kb = (KeyBlock *)ale->data;
indent = 0;
special = -1;
offset= (ale->id) ? 21 : 0;
if (kb->name[0] == '\0')
sprintf(name, "Key %d", ale->index);
else
strcpy(name, kb->name);
}
break;
case ANIMTYPE_GPDATABLOCK: /* gpencil datablock */
{
bGPdata *gpd = (bGPdata *)ale->data;
ScrArea *sa = (ScrArea *)ale->owner;
indent = 0;
group= 3;
/* only show expand if there are any channels */
if (gpd->layers.first) {
if (gpd->flag & GP_DATA_EXPAND)
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
}
switch (sa->spacetype) {
case SPACE_VIEW3D:
{
/* this shouldn't cause any overflow... */
//sprintf(name, "3DView:%s", view3d_get_name(sa->spacedata.first)); // XXX missing func..
strcpy(name, "3dView");
special= ICON_VIEW3D;
}
break;
case SPACE_NODE:
{
SpaceNode *snode= sa->spacedata.first;
char treetype[12];
if (snode->treetype == 1)
strcpy(treetype, "Composite");
else
strcpy(treetype, "Material");
sprintf(name, "Nodes:%s", treetype);
special= ICON_NODE;
}
break;
case SPACE_SEQ:
{
SpaceSeq *sseq= sa->spacedata.first;
char imgpreview[10];
switch (sseq->mainb) {
case 1: sprintf(imgpreview, "Image..."); break;
case 2: sprintf(imgpreview, "Luma..."); break;
case 3: sprintf(imgpreview, "Chroma..."); break;
case 4: sprintf(imgpreview, "Histogram"); break;
default: sprintf(imgpreview, "Sequence"); break;
}
sprintf(name, "Sequencer:%s", imgpreview);
special= ICON_SEQUENCE;
}
break;
case SPACE_IMAGE:
{
SpaceImage *sima= sa->spacedata.first;
if (sima->image)
sprintf(name, "Image:%s", sima->image->id.name+2);
else
strcpy(name, "Image:<None>");
special= ICON_IMAGE_COL;
}
break;
default:
{
sprintf(name, "<Unknown GP-Data Source>");
special= -1;
}
break;
}
}
break;
case ANIMTYPE_GPLAYER: /* gpencil layer */
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
indent = 0;
special = -1;
expand = -1;
group = 1;
if (EDITABLE_GPL(gpl))
protect = ICON_UNLOCKED;
else
protect = ICON_LOCKED;
if (gpl->flag & GP_LAYER_HIDE)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
sel = SEL_GPL(gpl);
BLI_snprintf(name, 32, gpl->info);
}
break;
}
/* now, start drawing based on this information */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* draw backing strip behind channel name */
if (group == 4) {
/* only used in dopesheet... */
if (ELEM(ale->type, ANIMTYPE_SCENE, ANIMTYPE_OBJECT)) {
/* object channel - darker */
UI_ThemeColor(TH_DOPESHEET_CHANNELOB);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else {
/* sub-object folders - lighter */
UI_ThemeColor(TH_DOPESHEET_CHANNELSUBOB);
offset += 7 * indent;
glBegin(GL_QUADS);
glVertex2f(x+offset, yminc);
glVertex2f(x+offset, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, yminc);
glEnd();
/* clear group value, otherwise we cause errors... */
group = 0;
}
}
else if (group == 3) {
/* only for gp-data channels */
UI_ThemeColorShade(TH_GROUP, 20);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else if (group == 2) {
/* only for action group channels */
if (ale->flag & AGRP_ACTIVE)
UI_ThemeColorShade(TH_GROUP_ACTIVE, 10);
else
UI_ThemeColorShade(TH_GROUP, 20);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else {
/* for normal channels
* - use 3 shades of color group/standard color for 3 indention level
* - only use group colors if allowed to, and if actually feasible
*/
if ( !(saction->flag & SACTION_NODRAWGCOLORS) &&
(grp) && (grp->customCol) )
{
char cp[3];
if (indent == 2) {
VECCOPY(cp, grp->cs.solid);
}
else if (indent == 1) {
VECCOPY(cp, grp->cs.select);
}
else {
VECCOPY(cp, grp->cs.active);
}
glColor3ub(cp[0], cp[1], cp[2]);
}
else
UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40));
indent += group;
offset += 7 * indent;
glBegin(GL_QUADS);
glVertex2f(x+offset, yminc);
glVertex2f(x+offset, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, yminc);
glEnd();
}
/* draw expand/collapse triangle */
if (expand > 0) {
UI_icon_draw(x+offset, yminc, expand);
offset += 17;
}
/* draw special icon indicating certain data-types */
if (special > -1) {
if (ELEM(group, 3, 4)) {
/* for gpdatablock channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
else {
/* for normal channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
}
glDisable(GL_BLEND);
/* draw name */
if (sel)
UI_ThemeColor(TH_TEXT_HI);
else
UI_ThemeColor(TH_TEXT);
offset += 3;
UI_DrawString(x+offset, y-4, name);
/* reset offset - for RHS of panel */
offset = 0;
/* set blending again, as text drawing may clear it */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* draw protect 'lock' */
if (protect > -1) {
offset = 16;
UI_icon_draw((float)ACHANNEL_NAMEWIDTH-offset, yminc, protect);
}
/* draw mute 'eye' */
if (mute > -1) {
offset += 16;
UI_icon_draw((float)(ACHANNEL_NAMEWIDTH-offset), yminc, mute);
}
glDisable(GL_BLEND);
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw(ac, ale, yminc, ymaxc);
}
/* adjust y-position for next one */

@ -889,7 +889,7 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
int filter;
View2D *v2d= &ar->v2d;
float x= 0.0f, y= 0.0f, height;
float y= 0.0f, height;
int items, i=0;
/* build list of channels to draw */
@ -927,509 +927,8 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
{
bActionGroup *grp = NULL;
short indent= 0, offset= 0, sel= 0, group= 0;
int expand= -1, protect = -1, special= -1, mute = -1;
char name[128];
/* determine what needs to be drawn */
switch (ale->type) {
case ANIMTYPE_SCENE: /* scene */
{
Scene *sce= (Scene *)ale->data;
group= 4;
indent= 0;
special= ICON_SCENE_DATA;
/* only show expand if there are any channels */
if (EXPANDED_SCEC(sce))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_SCEC(sce);
strcpy(name, sce->id.name+2);
}
break;
case ANIMTYPE_OBJECT: /* object */
{
Base *base= (Base *)ale->data;
Object *ob= base->object;
group= 4;
indent= 0;
/* icon depends on object-type */
if (ob->type == OB_ARMATURE)
special= ICON_ARMATURE_DATA;
else
special= ICON_OBJECT_DATA;
/* only show expand if there are any channels */
if (EXPANDED_OBJC(ob))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_OBJC(base);
strcpy(name, ob->id.name+2);
}
break;
case ANIMTYPE_FILLACTD: /* action widget */
{
bAction *act= (bAction *)ale->data;
group = 4;
indent= 1;
special= ICON_ACTION;
if (EXPANDED_ACTC(act))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
sel = SEL_ACTC(act);
strcpy(name, act->id.name+2);
}
break;
case ANIMTYPE_FILLDRIVERS: /* drivers widget */
{
AnimData *adt= (AnimData *)ale->data;
group = 4;
indent= 1;
special= ICON_ANIM_DATA;
if (EXPANDED_DRVD(adt))
expand= ICON_TRIA_DOWN;
else
expand= ICON_TRIA_RIGHT;
strcpy(name, "Drivers");
}
break;
case ANIMTYPE_FILLMATD: /* object materials (dopesheet) expand widget */
{
Object *ob = (Object *)ale->data;
group = 4;
indent = 1;
special = ICON_MATERIAL_DATA;
if (FILTER_MAT_OBJC(ob))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, "Materials");
}
break;
case ANIMTYPE_FILLPARTD: /* object particles (dopesheet) expand widget */
{
Object *ob = (Object *)ale->data;
group = 4;
indent = 1;
special = ICON_PARTICLE_DATA;
if (FILTER_PART_OBJC(ob))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, "Particles");
}
break;
case ANIMTYPE_DSMAT: /* single material (dopesheet) expand widget */
{
Material *ma = (Material *)ale->data;
group = 0;
indent = 0;
special = ICON_MATERIAL_DATA;
offset = 21;
if (FILTER_MAT_OBJD(ma))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, ma->id.name+2);
}
break;
case ANIMTYPE_DSLAM: /* lamp (dopesheet) expand widget */
{
Lamp *la = (Lamp *)ale->data;
group = 4;
indent = 1;
special = ICON_LAMP_DATA;
if (FILTER_LAM_OBJD(la))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, la->id.name+2);
}
break;
case ANIMTYPE_DSCAM: /* camera (dopesheet) expand widget */
{
Camera *ca = (Camera *)ale->data;
group = 4;
indent = 1;
special = ICON_CAMERA_DATA;
if (FILTER_CAM_OBJD(ca))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, ca->id.name+2);
}
break;
case ANIMTYPE_DSCUR: /* curve (dopesheet) expand widget */
{
Curve *cu = (Curve *)ale->data;
group = 4;
indent = 1;
special = ICON_CURVE_DATA;
if (FILTER_CUR_OBJD(cu))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, cu->id.name+2);
}
break;
case ANIMTYPE_DSSKEY: /* shapekeys (dopesheet) expand widget */
{
Key *key= (Key *)ale->data;
group = 4;
indent = 1;
special = ICON_SHAPEKEY_DATA;
if (FILTER_SKE_OBJD(key))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
//sel = SEL_OBJC(base);
strcpy(name, "Shape Keys");
}
break;
case ANIMTYPE_DSWOR: /* world (dopesheet) expand widget */
{
World *wo= (World *)ale->data;
group = 4;
indent = 1;
special = ICON_WORLD_DATA;
if (FILTER_WOR_SCED(wo))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, wo->id.name+2);
}
break;
case ANIMTYPE_DSPART: /* particle (dopesheet) expand widget */
{
ParticleSettings *part= (ParticleSettings*)ale->data;
group = 0;
indent = 0;
special = ICON_PARTICLE_DATA;
offset = 21;
if (FILTER_PART_OBJD(part))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, part->id.name+2);
}
break;
case ANIMTYPE_DSMBALL: /* metaball (dopesheet) expand widget */
{
MetaBall *mb = (MetaBall *)ale->data;
group = 4;
indent = 1;
special = ICON_META_DATA;
if (FILTER_MBALL_OBJD(mb))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
strcpy(name, mb->id.name+2);
}
break;
case ANIMTYPE_GROUP: /* action group */
{
bActionGroup *agrp= (bActionGroup *)ale->data;
group= 2;
indent= 0;
special= -1;
if (ale->id) {
/* special exception for materials */
if (GS(ale->id->name) == ID_MA)
offset= 25;
else
offset= 14;
}
else
offset= 0;
/* only show expand if there are any channels */
if (agrp->channels.first) {
if (EXPANDED_AGRP(agrp))
expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
}
/* for now, 'special' (i.e. in front of name) is used to show visibility status */
if (agrp->flag & AGRP_NOTVISIBLE)
special= ICON_CHECKBOX_DEHLT;
else
special= ICON_CHECKBOX_HLT;
if (agrp->flag & AGRP_MUTED)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
if (EDITABLE_AGRP(agrp))
protect = ICON_UNLOCKED;
else
protect = ICON_LOCKED;
sel = SEL_AGRP(agrp);
strcpy(name, agrp->name);
}
break;
case ANIMTYPE_FCURVE: /* F-Curve channel */
{
FCurve *fcu = (FCurve *)ale->data;
indent = 0;
group= (fcu->grp) ? 1 : 0;
grp= fcu->grp;
if (ale->id) {
/* special exception for materials and particles */
if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) {
offset= 21;
indent= 1;
}
else
offset= 14;
}
else
offset= 0;
/* for now, 'special' (i.e. in front of name) is used to show visibility status */
if (fcu->flag & FCURVE_VISIBLE)
special= ICON_CHECKBOX_HLT;
else
special= ICON_CHECKBOX_DEHLT;
if (fcu->flag & FCURVE_MUTED)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
if (fcu->bezt) {
if (EDITABLE_FCU(fcu))
protect = ICON_UNLOCKED;
else
protect = ICON_LOCKED;
}
else
protect = ICON_ZOOMOUT; // XXX editability is irrelevant here, but this icon is temp...
sel = SEL_FCU(fcu);
getname_anim_fcurve(name, ale->id, fcu);
}
break;
case ANIMTYPE_SHAPEKEY: /* shapekey channel */
{
KeyBlock *kb = (KeyBlock *)ale->data;
indent = 0;
special = -1;
offset= (ale->id) ? 21 : 0;
if (kb->name[0] == '\0')
sprintf(name, "Key %d", ale->index);
else
strcpy(name, kb->name);
}
break;
}
/* now, start drawing based on this information */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* draw backing strip behind channel name */
if (group == 4) {
/* only used in dopesheet... */
if (ELEM(ale->type, ANIMTYPE_SCENE, ANIMTYPE_OBJECT)) {
/* object channel - darker */
UI_ThemeColor(TH_DOPESHEET_CHANNELOB);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else {
/* sub-object folders - lighter */
UI_ThemeColor(TH_DOPESHEET_CHANNELSUBOB);
offset += 7 * indent;
glBegin(GL_QUADS);
glVertex2f(x+offset, yminc);
glVertex2f(x+offset, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, yminc);
glEnd();
/* clear group value, otherwise we cause errors... */
group = 0;
}
}
else if (group == 3) {
/* only for gp-data channels */
UI_ThemeColorShade(TH_GROUP, 20);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else if (group == 2) {
/* only for action group channels */
if (ale->flag & AGRP_ACTIVE)
UI_ThemeColorShade(TH_GROUP_ACTIVE, 10);
else
UI_ThemeColorShade(TH_GROUP, 20);
uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
}
else {
short shadefac= ((indent==0)?20: (indent==1)?-20: -40);
indent += group;
offset += 7 * indent;
/* draw channel backdrop */
UI_ThemeColorShade(TH_HEADER, shadefac);
glBegin(GL_QUADS);
glVertex2f(x+offset, yminc);
glVertex2f(x+offset, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, ymaxc);
glVertex2f((float)ACHANNEL_NAMEWIDTH, yminc);
glEnd();
/* most of the time, only F-Curves are going to be drawn here */
if (ale->type == ANIMTYPE_FCURVE) {
/* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
* color the curve has stored
*/
FCurve *fcu= (FCurve *)ale->data;
glColor3fv(fcu->color);
// NOTE: only enable the following line for the fading-out gradient
//glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
/* solid color for the area around the checkbox */
glVertex2f(x+offset, yminc);
glVertex2f(x+offset, ymaxc);
glVertex2f(x+offset+18, ymaxc);
glVertex2f(x+offset+18, yminc);
#if 0 // fading out gradient
/* fading out gradient for the rest of the box */
glVertex2f(x+offset+18, yminc);
glVertex2f(x+offset+18, ymaxc);
UI_ThemeColorShade(TH_HEADER, shadefac); // XXX does this cause any problems on some cards?
glVertex2f(x+offset+20, ymaxc);
glVertex2f(x+offset+20, yminc);
#endif // fading out gradient
glEnd();
// NOTE: only enable the following line for the fading-out gradient
//glShadeModel(GL_FLAT);
}
}
/* draw expand/collapse triangle */
if (expand > 0) {
UI_icon_draw(x+offset, yminc, expand);
offset += 17;
}
/* draw special icon indicating certain data-types */
if (special > -1) {
if (ELEM(group, 3, 4)) {
/* for gpdatablock channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
else {
/* for normal channels */
UI_icon_draw(x+offset, yminc, special);
offset += 17;
}
}
glDisable(GL_BLEND);
/* draw name */
if (sel)
UI_ThemeColor(TH_TEXT_HI);
else
UI_ThemeColor(TH_TEXT);
offset += 3;
UI_DrawString(x+offset, y-4, name);
/* reset offset - for RHS of panel */
offset = 0;
/* set blending again, as text drawing may clear it */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
/* draw protect 'lock' */
if (protect > -1) {
offset = 16;
UI_icon_draw((float)ACHANNEL_NAMEWIDTH-offset, yminc, protect);
}
/* draw mute 'eye' */
if (mute > -1) {
offset += 16;
UI_icon_draw((float)(ACHANNEL_NAMEWIDTH-offset), yminc, mute);
}
glDisable(GL_BLEND);
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw(ac, ale, yminc, ymaxc);
}
/* adjust y-position for next one */