Animation Editors: Code Cleanup Part 1 - Drawing
authorJoshua Leung <aligorith@gmail.com>
Tue, 11 Aug 2009 11:52:23 +0000 (11:52 +0000)
committerJoshua Leung <aligorith@gmail.com>
Tue, 11 Aug 2009 11:52:23 +0000 (11:52 +0000)
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

source/blender/editors/animation/anim_channels_defines.c [new file with mode: 0644]
source/blender/editors/animation/anim_channels_edit.c [moved from source/blender/editors/animation/anim_channels.c with 90% similarity]
source/blender/editors/include/ED_anim_api.h
source/blender/editors/space_action/action_draw.c
source/blender/editors/space_graph/graph_draw.c

diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
new file mode 100644 (file)
index 0000000..8132d83
--- /dev/null
@@ -0,0 +1,1946 @@
+/**
+ * $Id: $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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) 2009 Blender Foundation, Joshua Leung
+ * All rights reserved.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_listBase.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_windowmanager_types.h"
+#include "DNA_world_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
+#include "BKE_key.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
+#include "BKE_context.h"
+#include "BKE_utildefines.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframes_edit.h" // XXX move the select modes out of there!
+#include "ED_screen.h"
+#include "ED_space_api.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* *********************************************** */
+// XXX constant defines to be moved elsewhere?
+
+/* extra padding for lengths (to go under scrollers) */
+#define EXTRA_SCROLL_PAD       100.0f
+
+/* size of indent steps */
+#define INDENT_STEP_SIZE       7
+
+/* macros used for type defines */
+       /* get the pointer used for some flag */
+#define GET_ACF_FLAG_PTR(ptr) \
+       { \
+               *type= sizeof((ptr)); \
+               return &(ptr); \
+       } 
+
+
+/* XXX */
+extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
+extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
+
+
+/* *********************************************** */
+/* Generic Functions (Type independent) */
+
+/* Draw Backdrop ---------------------------------- */
+
+/* backdrop for top-level widgets (Scene and Object only) */
+static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       View2D *v2d= &ac->ar->v2d;
+       short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
+       short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+       
+       /* darker blue for top-level widgets */
+       UI_ThemeColor(TH_DOPESHEET_CHANNELOB);
+       
+       /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+       uiSetRoundBox((expanded)? (1):(1|8));
+       gl_round_box(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
+}
+
+/* backdrop for data expanders under top-level Scene/Object */
+static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       View2D *v2d= &ac->ar->v2d;
+       short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+       
+       /* lighter color than top-level widget */
+       UI_ThemeColor(TH_DOPESHEET_CHANNELSUBOB);
+       
+       /* no rounded corner - just rectangular box */
+       glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
+}
+
+/* backdrop for generic channels */
+static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       View2D *v2d= &ac->ar->v2d;
+       SpaceAction *saction = NULL;
+       bActionGroup *grp = NULL;
+       short indent= (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
+       short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+       
+       /* get context info needed... */
+       if ((ac->sa) && (ac->sa->spacetype == SPACE_ACTION))
+               saction= (SpaceAction *)ac->sa->spacedata.first;
+               
+       if (ale->type == ANIMTYPE_FCURVE) {
+               FCurve *fcu= (FCurve *)ale->data;
+               grp= fcu->grp;
+       }
+       
+       /* set color 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 && !(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 // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
+               UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40));
+       
+       /* no rounded corners - just rectangular box */
+       glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
+}
+
+/* Indention + Offset ------------------------------------------- */
+
+/* indention level is always the value in the name */
+static short acf_generic_indention_0(bAnimContext *ac, bAnimListElem *ale)
+{
+       return 0;
+}
+static short acf_generic_indention_1(bAnimContext *ac, bAnimListElem *ale)
+{
+       return 1;
+}
+#if 0 // XXX not used
+static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
+{
+       return 2;
+}
+#endif
+
+/* indention which varies with the grouping status */
+static short acf_generic_indention_flexible(bAnimContext *ac, bAnimListElem *ale)
+{
+       short indent= 0;
+       
+       if (ale->id) {
+               /* special exception for materials and particles */
+               if (ELEM(GS(ale->id->name),ID_MA,ID_PA))
+                       indent++;
+       }
+       
+       /* grouped F-Curves need extra level of indention */
+       if (ale->type == ANIMTYPE_FCURVE) {
+               FCurve *fcu= (FCurve *)ale->data;
+               
+               // TODO: we need some way of specifying that the indention color should be one less...
+               if (fcu->grp)
+                       indent++;
+       }
+       
+       /* no indention */
+       return indent;
+}
+
+/* basic offset for channels derived from indention */
+static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       
+       if (acf && acf->get_indent_level)
+               return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
+       else
+               return 0;
+}
+
+/* offset for groups + grouped entities */
+static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
+{
+       short offset= acf_generic_basic_offset(ac, ale);
+       
+       if (ale->id) {
+               /* special exception for materials and particles */
+               if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) 
+                       offset += 21;
+                       
+               /* if not in Action Editor mode, groupings must carry some offset too... */
+               else if (ac->datatype != ANIMCONT_ACTION)
+                       offset += 14;
+       }
+       
+       /* offset is just the normal type - i.e. based on indention */
+       return offset;
+}
+
+/* Name ------------------------------------------- */
+
+/* name for ID block entries */
+static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
+{
+       ID *id= (ID *)ale->data;        /* data pointed to should be an ID block */
+       
+       /* just copy the name... */
+       if (id && name)
+               sprintf(name, id->name+2);
+}
+
+/* Settings ------------------------------------------- */
+
+/* check if some setting exists for this object-based data-expander (category only) */
+static short acf_generic_dsexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* only expand supported */
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               default:
+                       return 0;
+       }
+}
+
+/* get pointer to the setting (category only) */
+static void *acf_generic_dsexpand_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Object *ob= (Object *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(ob->nlaflag); // XXX
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* check if some setting exists for this object-based data-expander (datablock only) */
+static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* expand is always supported */
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               /* mute is only supported for NLA */
+               case ACHANNEL_SETTING_MUTE:
+                       return ((ac) && (ac->spacetype == SPACE_NLA));
+                       
+               /* other flags are never supported */
+               default:
+                       return 0;
+       }
+}
+
+/* *********************************************** */
+/* Type Specific Functions + Defines */
+
+/* Scene ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_scene_icon(bAnimListElem *ale)
+{
+       return ICON_SCENE_DATA;
+}
+
+/* check if some setting exists for this channel */
+static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* muted only in NLA */
+               case ACHANNEL_SETTING_MUTE: 
+                       return ((ac) && (ac->spacetype == SPACE_NLA));
+               
+               /* only select and expand supported otherwise */
+               case ACHANNEL_SETTING_SELECT:
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               default:
+                       return 0;
+       }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_scene_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return SCE_DS_SELECTED;
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return SCE_DS_COLLAPSED;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+                       
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Scene *scene= (Scene *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       GET_ACF_FLAG_PTR(scene->flag);
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(scene->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       if (scene->adt)
+                               GET_ACF_FLAG_PTR(scene->adt->flag)
+                       else
+                               return NULL;
+                       
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* scene type define */
+static bAnimChannelType ACF_SCENE = 
+{
+       acf_generic_root_backdrop,              /* backdrop */
+       acf_generic_indention_0,                /* indent level */
+       NULL,                                                   /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_scene_icon,                                 /* icon */
+       
+       acf_scene_setting_valid,                /* has setting */
+       acf_scene_setting_flag,                 /* flag for setting */
+       acf_scene_setting_ptr                   /* pointer for setting */
+};
+
+/* Object ------------------------------------------- */
+
+static int acf_object_icon(bAnimListElem *ale)
+{
+       Base *base= (Base *)ale->data;
+       Object *ob= base->object;
+       
+       /* icon depends on object-type */
+       if (ob->type == OB_ARMATURE)
+               return ICON_ARMATURE_DATA;
+       else    
+               return ICON_OBJECT_DATA;
+}
+
+/* name for object */
+static void acf_object_name(bAnimListElem *ale, char *name)
+{
+       Base *base= (Base *)ale->data;
+       Object *ob= base->object;
+       
+       /* just copy the name... */
+       if (ob && name)
+               sprintf(name, ob->id.name+2);
+}
+
+/* check if some setting exists for this channel */
+static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* muted only in NLA */
+               case ACHANNEL_SETTING_MUTE: 
+                       return ((ac) && (ac->spacetype == SPACE_NLA));
+               
+               /* only select and expand supported otherwise */
+               case ACHANNEL_SETTING_SELECT:
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               default:
+                       return 0;
+       }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_object_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return SELECT;
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return OB_ADS_COLLAPSED;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+                       
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Base *base= (Base *)ale->data;
+       Object *ob= base->object;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       GET_ACF_FLAG_PTR(ob->flag);
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(ob->nlaflag); // xxx
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       if (ob->adt)
+                               GET_ACF_FLAG_PTR(ob->adt->flag)
+                       else
+                               return NULL;
+                       
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* object type define */
+static bAnimChannelType ACF_OBJECT = 
+{
+       acf_generic_root_backdrop,              /* backdrop */
+       acf_generic_indention_0,                /* indent level */
+       NULL,                                                   /* offset */
+       
+       acf_object_name,                                /* name */
+       acf_object_icon,                                /* icon */
+       
+       acf_object_setting_valid,               /* has setting */
+       acf_object_setting_flag,                /* flag for setting */
+       acf_object_setting_ptr                  /* pointer for setting */
+};
+
+/* Group ------------------------------------------- */
+
+/* backdrop for group widget */
+static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       View2D *v2d= &ac->ar->v2d;
+       short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
+       short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+       
+       /* only for action group channels */
+       if (ale->flag & AGRP_ACTIVE)
+               UI_ThemeColorShade(TH_GROUP_ACTIVE, 10);
+       else
+               UI_ThemeColorShade(TH_GROUP, 20);
+       
+       /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+       uiSetRoundBox((expanded)? (1):(1|8));
+       gl_round_box(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
+}
+
+/* name for group entries */
+static void acf_group_name(bAnimListElem *ale, char *name)
+{
+       bActionGroup *agrp= (bActionGroup *)ale->data;
+       
+       /* just copy the name... */
+       if (agrp && name)
+               sprintf(name, agrp->name);
+}
+
+/* check if some setting exists for this channel */
+static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       /* for now, all settings are supported */
+       return 1;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_group_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return AGRP_SELECTED;
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return AGRP_EXPANDED;
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted */
+                       return AGRP_MUTED;
+                       
+               case ACHANNEL_SETTING_PROTECT: /* protected */
+                       //*neg= 1; - if we change this to edtiability
+                       return AGRP_PROTECTED;
+                       
+               case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
+                       *neg= 1;
+                       return AGRP_NOTVISIBLE;
+       }
+       
+       /* this shouldn't happen */
+       return 0;
+}
+
+/* get pointer to the setting */
+static void *acf_group_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       bActionGroup *agrp= (bActionGroup *)ale->data;
+       
+       /* all flags are just in agrp->flag for now... */
+       GET_ACF_FLAG_PTR(agrp->flag);
+}
+
+/* group type define */
+static bAnimChannelType ACF_GROUP = 
+{
+       acf_group_backdrop,                             /* backdrop */
+       acf_generic_indention_0,                /* indent level */
+       acf_generic_group_offset,               /* offset */
+       
+       acf_group_name,                                 /* name */
+       NULL,                                                   /* icon */
+       
+       acf_group_setting_valid,                /* has setting */
+       acf_group_setting_flag,                 /* flag for setting */
+       acf_group_setting_ptr                   /* pointer for setting */
+};
+
+/* F-Curve ------------------------------------------- */
+
+/* name for fcurve entries */
+static void acf_fcurve_name(bAnimListElem *ale, char *name)
+{
+       getname_anim_fcurve(name, ale->id, ale->data);
+}
+
+/* check if some setting exists for this channel */
+static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       FCurve *fcu= (FCurve *)ale->data;
+       
+       switch (setting) {
+               /* unsupported */
+               case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
+                       return 0;
+               
+               /* conditionally available */
+               case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
+                       if (fcu->bezt)
+                               return 1;
+                       else
+                               return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
+                       
+               /* always available */
+               default:
+                       return 1;
+       }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_fcurve_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return FCURVE_SELECTED;
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted */
+                       return FCURVE_MUTED;
+                       
+               case ACHANNEL_SETTING_PROTECT: /* protected */
+                       //*neg= 1; - if we change this to edtiability
+                       return FCURVE_PROTECTED;
+                       
+               case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
+                       return FCURVE_VISIBLE;
+                       
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       FCurve *fcu= (FCurve *)ale->data;
+       
+       /* all flags are just in agrp->flag for now... */
+       GET_ACF_FLAG_PTR(fcu->flag);
+}
+
+/* fcurve type define */
+static bAnimChannelType ACF_FCURVE = 
+{
+       acf_generic_channel_backdrop,   /* backdrop */
+       acf_generic_indention_flexible, /* indent level */              // xxx rename this to f-curves only?
+       acf_generic_group_offset,               /* offset */
+       
+       acf_fcurve_name,                                /* name */
+       NULL,                                                   /* icon */
+       
+       acf_fcurve_setting_valid,               /* has setting */
+       acf_fcurve_setting_flag,                /* flag for setting */
+       acf_fcurve_setting_ptr                  /* pointer for setting */
+};
+
+/* Object Action Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_fillactd_icon(bAnimListElem *ale)
+{
+       return ICON_ACTION;
+}
+
+/* check if some setting exists for this channel */
+static short acf_fillactd_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* only select and expand supported */
+               case ACHANNEL_SETTING_SELECT:
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               default:
+                       return 0;
+       }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_fillactd_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return ACT_SELECTED;
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return ACT_COLLAPSED;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       bAction *act= (bAction *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       GET_ACF_FLAG_PTR(act->flag);
+                       
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(act->flag);
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* object action expander type define */
+static bAnimChannelType ACF_FILLACTD = 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_fillactd_icon,                              /* icon */
+       
+       acf_fillactd_setting_valid,             /* has setting */
+       acf_fillactd_setting_flag,              /* flag for setting */
+       acf_fillactd_setting_ptr                /* pointer for setting */
+};
+
+/* Drivers Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_filldrivers_icon(bAnimListElem *ale)
+{
+       return ICON_ANIM_DATA;
+}
+
+static void acf_filldrivers_name(bAnimListElem *ale, char *name)
+{
+       sprintf(name, "Drivers");
+}
+
+/* check if some setting exists for this channel */
+// TODO: this could be made more generic
+static short acf_filldrivers_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       switch (setting) {
+               /* only expand supported */
+               case ACHANNEL_SETTING_EXPAND:
+                       return 1;
+                       
+               default:
+                       return 0;
+       }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_filldrivers_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return ADT_DRIVERS_COLLAPSED;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       AnimData *adt= (AnimData *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(adt->flag);
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* drivers expander type define */
+static bAnimChannelType ACF_FILLDRIVERS = 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_filldrivers_name,                   /* name */
+       acf_filldrivers_icon,                   /* icon */
+       
+       acf_filldrivers_setting_valid,  /* has setting */
+       acf_filldrivers_setting_flag,   /* flag for setting */
+       acf_filldrivers_setting_ptr             /* pointer for setting */
+};
+
+/* Materials Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_fillmatd_icon(bAnimListElem *ale)
+{
+       return ICON_MATERIAL_DATA;
+}
+
+static void acf_fillmatd_name(bAnimListElem *ale, char *name)
+{
+       sprintf(name, "Materials");
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_fillmatd_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return OB_ADS_SHOWMATS;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* materials expander type define */
+static bAnimChannelType ACF_FILLMATD= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_fillmatd_name,                              /* name */
+       acf_fillmatd_icon,                              /* icon */
+       
+       acf_generic_dsexpand_setting_valid,     /* has setting */
+       acf_fillmatd_setting_flag,                              /* flag for setting */
+       acf_generic_dsexpand_setting_ptr                /* pointer for setting */
+};
+
+/* Particles Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_fillpartd_icon(bAnimListElem *ale)
+{
+       return ICON_PARTICLE_DATA;
+}
+
+static void acf_fillpartd_name(bAnimListElem *ale, char *name)
+{
+       sprintf(name, "Particles");
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_fillpartd_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       *neg= 1;
+                       return OB_ADS_SHOWPARTS;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* particles expander type define */
+static bAnimChannelType ACF_FILLPARTD= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_fillpartd_name,                             /* name */
+       acf_fillpartd_icon,                             /* icon */
+       
+       acf_generic_dsexpand_setting_valid,     /* has setting */
+       acf_fillpartd_setting_flag,                             /* flag for setting */
+       acf_generic_dsexpand_setting_ptr                /* pointer for setting */
+};
+
+/* Material Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsmat_icon(bAnimListElem *ale)
+{
+       return ICON_MATERIAL_DATA;
+}
+
+/* offset for material expanders */
+static short acf_dsmat_offset(bAnimContext *ac, bAnimListElem *ale)
+{
+       return 21;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dsmat_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return MA_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Material *ma= (Material *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(ma->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (ma->adt)
+                               GET_ACF_FLAG_PTR(ma->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* material expander type define */
+static bAnimChannelType ACF_DSMAT= 
+{
+       acf_generic_channel_backdrop,   /* backdrop */
+       acf_generic_indention_0,                /* indent level */
+       acf_dsmat_offset,                               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dsmat_icon,                                 /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dsmat_setting_flag,                                 /* flag for setting */
+       acf_dsmat_setting_ptr                                   /* pointer for setting */
+};
+
+/* Lamp Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dslam_icon(bAnimListElem *ale)
+{
+       return ICON_LAMP_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dslam_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return LA_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Lamp *la= (Lamp *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(la->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (la->adt)
+                               GET_ACF_FLAG_PTR(la->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* lamp expander type define */
+static bAnimChannelType ACF_DSLAM= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dslam_icon,                                 /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dslam_setting_flag,                                 /* flag for setting */
+       acf_dslam_setting_ptr                                   /* pointer for setting */
+};
+
+/* Camera Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dscam_icon(bAnimListElem *ale)
+{
+       return ICON_CAMERA_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dscam_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return CAM_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Camera *ca= (Camera *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(ca->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (ca->adt)
+                               GET_ACF_FLAG_PTR(ca->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* camera expander type define */
+static bAnimChannelType ACF_DSCAM= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dscam_icon,                                 /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dscam_setting_flag,                                 /* flag for setting */
+       acf_dscam_setting_ptr                                   /* pointer for setting */
+};
+
+/* Curve Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dscur_icon(bAnimListElem *ale)
+{
+       return ICON_CURVE_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dscur_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return CU_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Curve *cu= (Curve *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(cu->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (cu->adt)
+                               GET_ACF_FLAG_PTR(cu->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* curve expander type define */
+static bAnimChannelType ACF_DSCUR= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dscur_icon,                                 /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dscur_setting_flag,                                 /* flag for setting */
+       acf_dscur_setting_ptr                                   /* pointer for setting */
+};
+
+/* Shape Key Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsskey_icon(bAnimListElem *ale)
+{
+       return ICON_SHAPEKEY_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dsskey_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return KEYBLOCK_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Key *key= (Key *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(key->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (key->adt)
+                               GET_ACF_FLAG_PTR(key->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* shapekey expander type define */
+static bAnimChannelType ACF_DSSKEY= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dsskey_icon,                                /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dsskey_setting_flag,                                /* flag for setting */
+       acf_dsskey_setting_ptr                                  /* pointer for setting */
+};
+
+/* World Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dswor_icon(bAnimListElem *ale)
+{
+       return ICON_WORLD_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dswor_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return WO_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       World *wo= (World *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(wo->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (wo->adt)
+                               GET_ACF_FLAG_PTR(wo->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* world expander type define */
+static bAnimChannelType ACF_DSWOR= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dswor_icon,                                 /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dswor_setting_flag,                                 /* flag for setting */
+       acf_dswor_setting_ptr                                   /* pointer for setting */
+};
+
+/* Particle Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dspart_icon(bAnimListElem *ale)
+{
+       return ICON_PARTICLE_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dspart_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return PART_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       ParticleSettings *part= (ParticleSettings *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(part->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (part->adt)
+                               GET_ACF_FLAG_PTR(part->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* particle expander type define */
+static bAnimChannelType ACF_DSPART= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dspart_icon,                                /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dspart_setting_flag,                                /* flag for setting */
+       acf_dspart_setting_ptr                                  /* pointer for setting */
+};
+
+/* MetaBall Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsmball_icon(bAnimListElem *ale)
+{
+       return ICON_META_DATA;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dsmball_setting_flag(int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return MB_DS_EXPAND;
+                       
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+               
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       MetaBall *mb= (MetaBall *)ale->data;
+       
+       /* clear extra return data first */
+       *type= 0;
+       
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(mb->flag);
+                       
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+                       if (mb->adt)
+                               GET_ACF_FLAG_PTR(mb->adt->flag)
+                       else
+                               return NULL;
+               
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* metaball expander type define */
+static bAnimChannelType ACF_DSMBALL= 
+{
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+       
+       acf_generic_idblock_name,               /* name */
+       acf_dsmball_icon,                               /* icon */
+       
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dsmball_setting_flag,                               /* flag for setting */
+       acf_dsmball_setting_ptr                                 /* pointer for setting */
+};
+
+/* ShapeKey Entry  ------------------------------------------- */
+// XXX ... this is currently obsolete...
+
+#if 0
+static void dummy_olddraw_shapekeys ()
+{
+       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;
+}
+#endif
+
+/* Grease Pencil entries  ------------------------------------------- */
+// XXX ... this is currently not restored yet
+
+#if 0
+static void dummy_olddraw_gpencil ()
+{
+       /* determine what needs to be drawn */
+       switch (ale->type) {
+               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;
+       }       
+       
+       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);
+       }
+}
+#endif
+
+/* *********************************************** */
+/* Type Registration and General Access */
+
+/* These globals only ever get directly accessed in this file */
+static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES];
+static short ACF_INIT= 1; /* when non-zero, the list needs to be updated */
+
+/* Initialise type info definitions */
+void ANIM_init_channel_typeinfo_data (void)
+{
+       int type= 0;
+       
+       /* start initialising if necessary... */
+       if (ACF_INIT) {
+               ACF_INIT= 0;
+               
+               animchannelTypeInfo[type++]= NULL;                              /* None */
+               animchannelTypeInfo[type++]= NULL;                              /* AnimData */
+               animchannelTypeInfo[type++]= NULL;                              /* Special */
+               
+               animchannelTypeInfo[type++]= &ACF_SCENE;                /* Scene */
+               animchannelTypeInfo[type++]= &ACF_OBJECT;               /* Object */
+               animchannelTypeInfo[type++]= &ACF_GROUP;                /* Group */
+               animchannelTypeInfo[type++]= &ACF_FCURVE;               /* F-Curve */
+               
+               animchannelTypeInfo[type++]= &ACF_FILLACTD;     /* Object Action Expander */
+               animchannelTypeInfo[type++]= &ACF_FILLDRIVERS;  /* Drivers Expander */
+               animchannelTypeInfo[type++]= &ACF_FILLMATD;     /* Materials Expander */
+               animchannelTypeInfo[type++]= &ACF_FILLPARTD;    /* Particles Expander */
+               
+               animchannelTypeInfo[type++]= &ACF_DSMAT;                /* Material Channel */
+               animchannelTypeInfo[type++]= &ACF_DSLAM;                /* Lamp Channel */
+               animchannelTypeInfo[type++]= &ACF_DSCAM;                /* Camera Channel */
+               animchannelTypeInfo[type++]= &ACF_DSCUR;                /* Curve Channel */
+               animchannelTypeInfo[type++]= &ACF_DSSKEY;               /* ShapeKey Channel */
+               animchannelTypeInfo[type++]= &ACF_DSWOR;                /* World Channel */
+               animchannelTypeInfo[type++]= &ACF_DSPART;               /* Particle Channel */
+               animchannelTypeInfo[type++]= &ACF_DSMBALL;              /* MetaBall Channel */
+               
+               animchannelTypeInfo[type++]= NULL;                              /* ShapeKey */ // XXX this is no longer used for now...
+               
+                       // XXX not restored yet
+               animchannelTypeInfo[type++]= NULL;                              /* Grease Pencil Datablock */ 
+               animchannelTypeInfo[type++]= NULL;                              /* Grease Pencil Layer */ 
+               
+                       // TODO: these types still need to be implemented!!!
+                       // probably need a few extra flags for these special cases...
+               animchannelTypeInfo[type++]= NULL;                              /* NLA Track */ 
+               animchannelTypeInfo[type++]= NULL;                              /* NLA Action */ 
+       }
+} 
+
+/* Get type info from given channel type */
+bAnimChannelType *ANIM_channel_get_typeinfo (bAnimListElem *ale)
+{
+       /* santiy checks */
+       if (ale == NULL)
+               return NULL;
+               
+       /* init the typeinfo if not available yet... */
+       ANIM_init_channel_typeinfo_data();
+       
+       /* check if type is in bounds... */
+       if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
+               return animchannelTypeInfo[ale->type];
+       else
+               return NULL;
+}
+
+/* --------------------------- */
+
+/* Check if some setting for a channel is enabled 
+ * Returns: 1 = On, 0 = Off, -1 = Invalid
+ */
+short ANIM_channel_setting_get (bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       
+       /* 1) check that the setting exists for the current context */
+       if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
+       {
+               /* 2) get pointer to check for flag in, and the flag to check for */
+               short negflag, ptrsize;
+               int flag;
+               void *ptr;
+               
+               flag= acf->setting_flag(setting, &negflag);
+               ptr= acf->setting_ptr(ale, setting, &ptrsize);
+               
+               /* check if flag is enabled */
+               if (ptr && flag) {
+                       switch (ptrsize) {
+                               case sizeof(int):       /* integer pointer for setting */
+                               {
+                                       int *val= (int *)ptr;
+                                       
+                                       if (negflag)
+                                               return ((*val) & flag) == 0;
+                                       else
+                                               return ((*val) & flag) != 0;
+                               }
+                                       break;
+                                       
+                               case sizeof(short):     /* short pointer for setting */
+                               {
+                                       short *val= (short *)ptr;
+                                       
+                                       if (negflag)
+                                               return ((*val) & flag) == 0;
+                                       else
+                                               return ((*val) & flag) != 0;
+                               }
+                                       break;
+                                       
+                               case sizeof(char):      /* char pointer for setting */
+                               {
+                                       char *val= (char *)ptr;
+                                       
+                                       if (negflag)
+                                               return ((*val) & flag) == 0;
+                                       else
+                                               return ((*val) & flag) != 0;
+                               }
+                                       break;
+                       }
+               }
+       }
+       
+       /* not found... */
+       return -1;
+}      
+
+
+/* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
+#define ACF_SETTING_SET(sval, sflag, smode) \
+       {\
+               if (negflag) {\
+                       if (smode == ACHANNEL_SETFLAG_TOGGLE)   (sval) ^= (sflag); \
+                       else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \
+                       else                                                                    (sval) |= (sflag); \
+               } \
+               else {\
+                       if (smode == ACHANNEL_SETFLAG_TOGGLE)   (sval) ^= (sflag); \
+                       else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \
+                       else                                                                    (sval) &= ~(sflag); \
+               }\
+       }
+
+/* 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)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       
+       /* 1) check that the setting exists for the current context */
+       if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
+       {
+               /* 2) get pointer to check for flag in, and the flag to check for */
+               short negflag, ptrsize;
+               int flag;
+               void *ptr;
+               
+               flag= acf->setting_flag(setting, &negflag);
+               ptr= acf->setting_ptr(ale, setting, &ptrsize);
+               
+               /* check if flag is enabled */
+               if (ptr && flag) {
+                       switch (ptrsize) {
+                               case sizeof(int):       /* integer pointer for setting */
+                               {
+                                       int *val= (int *)ptr;
+                                       ACF_SETTING_SET(*val, flag, mode);
+                               }
+                                       break;
+                                       
+                               case sizeof(short):     /* short pointer for setting */
+                               {
+                                       short *val= (short *)ptr;
+                                       ACF_SETTING_SET(*val, flag, mode);
+                               }
+                                       break;
+                                       
+                               case sizeof(char):      /* char pointer for setting */
+                               {
+                                       char *val= (char *)ptr;
+                                       ACF_SETTING_SET(*val, flag, mode);
+                               }
+                                       break;
+                       }
+               }
+       }
+}
+
+/* --------------------------- */
+
+// XXX hardcoded size of icons
+#define ICON_WIDTH             17
+
+/* Draw the given channel */
+// TODO: make this use UI controls for the buttons
+void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+{
+       bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+       View2D *v2d= &ac->ar->v2d;
+       short selected, offset, enabled;
+       float y, ymid, ytext;
+       
+       /* sanity checks - don't draw anything */
+       if ELEM(NULL, acf, ale)
+               return;
+       
+       /* get initial offset */
+       if (acf->get_offset)
+               offset= acf->get_offset(ac, ale);
+       else if (acf->get_indent_level)
+               offset= acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
+       else
+               offset= 0;
+               
+       /* calculate appropriate y-coordinates for icon buttons 
+        *      7 is hardcoded factor for half-height of icons
+        */
+       y= (ymaxc - yminc)/2 + yminc;
+       ymid= y - 7;
+       /* y-coordinates for text is only 4 down from middle */
+       ytext= y - 4;
+       
+       /* check if channel is selected */
+       if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
+               selected= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
+       else
+               selected= 0;
+       
+       /* enable correct blending mode for icons to work... */
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+       
+       /* step 1) draw backdrop ...........................................  */
+       if (acf->draw_backdrop)
+               acf->draw_backdrop(ac, ale, yminc, ymaxc);
+               
+       /* step 2) draw expand widget ....................................... */
+       if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
+               enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND);
+               
+               UI_icon_draw(offset, ymid, ((enabled)? ICON_TRIA_DOWN : ICON_TRIA_RIGHT));
+               offset += ICON_WIDTH; 
+       }
+               
+       /* step 3) draw icon ............................................... */
+       if (acf->icon) {
+               UI_icon_draw(offset, ymid, acf->icon(ale));
+               offset += ICON_WIDTH; 
+       }
+               
+       /* step 4) draw special toggles  .................................
+        *      - in Graph Editor, checkboxes for visibility in curves area
+        *      - in NLA Editor, glowing dots for solo/not solo...
+        */
+       if (ac->sa) {
+               if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
+                       enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_VISIBLE);
+                       
+                       /* for F-Curves, draw color-preview of curve behind checkbox */
+                       if (ale->type == ANIMTYPE_FCURVE) {
+                               FCurve *fcu= (FCurve *)ale->data;
+                               
+                               /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever 
+                                * color the curve has stored 
+                                */
+                               glColor3fv(fcu->color);
+                               
+                               /* just a solid color rect
+                                *      hardcoded 18 pixels width is slightly wider than icon width, so that 
+                                *      there's a slight border around it 
+                                */
+                               glRectf(offset, yminc, offset+18, ymaxc);
+                       }
+                       
+                       /* finally the icon itself */
+                       UI_icon_draw(offset, ymid, ((enabled)? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT));
+                       offset += ICON_WIDTH; 
+               }
+               else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
+                       /* simply draw glowing dot in NLA for whether the track is enabled or not... */
+                       // NOTE: assumed to be for NLA track only for now...
+                       enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SOLO);
+                       
+                       UI_icon_draw(offset, ymid, ((enabled)? ICON_LAYER_ACTIVE : ICON_LAYER_USED));
+                       offset += ICON_WIDTH; 
+               }
+       }
+       
+       glDisable(GL_BLEND); /* End of blending with background (text now gets drawn) */
+       
+       /* step 5) draw name ............................................... */
+       if (acf->name) {
+               char name[256]; /* hopefully this will be enough! */
+               
+               /* set text color */
+               if (selected)
+                       UI_ThemeColor(TH_TEXT_HI);
+               else
+                       UI_ThemeColor(TH_TEXT);
+                       
+               /* get name */
+               acf->name(ale, name);
+               
+               offset += 3;
+               UI_DrawString(offset, ytext, name);
+       }
+       
+       /* step 6) draw mute+protection toggles ............................. */
+       /* reset offset - now goes from RHS of panel */
+       offset = 0;
+       
+       // TODO: we need a mechanism of drawing over (and hiding) stuff from here...
+       
+       /* set blending again, as text drawing may clear it */
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+       
+       /* protect... */
+       // XXX v2d might not be valid
+       if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
+               enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_PROTECT);
+               
+               offset += ICON_WIDTH;
+               UI_icon_draw(v2d->cur.xmax-(float)offset, ymid, ((enabled)? ICON_LOCKED : ICON_UNLOCKED));
+       }
+       /* mute... */
+       // XXX v2d might not be valid
+       if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
+               enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_MUTE);
+               
+               offset += ICON_WIDTH; 
+               UI_icon_draw(v2d->cur.xmax-(float)offset, ymid, ((enabled)? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF));
+       }
+       
+       glDisable(GL_BLEND); /* End of blending with background */
+}
+
+/* *********************************************** */
similarity index 90%
rename from source/blender/editors/animation/anim_channels.c
rename to source/blender/editors/animation/anim_channels_edit.c
index 235a3039b2caab772d1e4ff1c5753dc5438f6d08..d74c9fbf48becc81925a16e45b87de64e4316cf3 100644 (file)
  * 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);
index 0786d0f9be0567559916abdc4c2fd6704fe13cdb..d3d42deba21926bddf8708d49c168b4a020cacf8 100644 (file)
@@ -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,25 +281,87 @@ short ANIM_animdata_context_getdata(bAnimContext *ac);
 
 /* ************************************************ */
 /* ANIMATION CHANNELS LIST */
-/* anim_channels.c */
-
-/* ------------------------ API -------------------------- */
-
-/* Deselect all animation channels */
-void ANIM_deselect_anim_channels(void *data, short datatype, short test, short sel);
-
-/* 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);
+/* anim_channels_*.c */
 
-/* --------------- Settings and/or Defines -------------- */
+/* ------------------------ Drawing TypeInfo -------------------------- */
 
 /* flag-setting behaviour */
-enum {
+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);
+
+
+/* Deselect all animation channels */
+void ANIM_deselect_anim_channels(void *data, short datatype, short test, short sel);
+
+/* 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);
+
 /* ************************************************ */
 /* DRAWING API */
 /* anim_draw.c */
index 6e86748adaeff74209c27cd7f3f35498bea2009d..f5fa263eee847dec1b9baff31b47a992927fe9d5 100644 (file)
@@ -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 */
index f6915c4db0150cef8a8453cc9b872095b948a09b..07918646926cade62ea4ee26ecbca89501f6b3fd 100644 (file)
@@ -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 */