Merged changes in the trunk up to revision 34193.
[blender.git] / source / blender / editors / animation / anim_channels_defines.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * Contributor(s): Joshua Leung
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <stdio.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_blenlib.h"
33 #include "BLI_math.h"
34 #include "BLI_utildefines.h"
35
36 #include "DNA_anim_types.h"
37 #include "DNA_armature_types.h"
38 #include "DNA_camera_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_particle_types.h"
41 #include "DNA_screen_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_space_types.h"
44 #include "DNA_key_types.h"
45 #include "DNA_lamp_types.h"
46 #include "DNA_lattice_types.h"
47 #include "DNA_linestyle_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_material_types.h"
50 #include "DNA_meta_types.h"
51 #include "DNA_node_types.h"
52 #include "DNA_world_types.h"
53
54 #include "RNA_access.h"
55
56 #include "BKE_curve.h"
57 #include "BKE_key.h"
58 #include "BKE_context.h"
59 #include "BKE_utildefines.h" /* FILE_MAX */
60
61 #include "UI_interface.h"
62 #include "UI_interface_icons.h"
63 #include "UI_resources.h"
64
65 #include "ED_anim_api.h"
66 #include "ED_keyframing.h"
67
68 #include "BIF_gl.h"
69 #include "BIF_glutil.h"
70
71 #include "WM_api.h"
72 #include "WM_types.h"
73
74 /* *********************************************** */
75 // XXX constant defines to be moved elsewhere?
76
77 /* extra padding for lengths (to go under scrollers) */
78 #define EXTRA_SCROLL_PAD        100.0f
79
80 /* size of indent steps */
81 #define INDENT_STEP_SIZE        7
82
83 /* macros used for type defines */
84         /* get the pointer used for some flag */
85 #define GET_ACF_FLAG_PTR(ptr) \
86         { \
87                 *type= sizeof((ptr)); \
88                 return &(ptr); \
89         } 
90
91
92 /* *********************************************** */
93 /* Generic Functions (Type independent) */
94
95 /* Draw Backdrop ---------------------------------- */
96
97 /* get backdrop color for top-level widgets (Scene and Object only) */
98 static void acf_generic_root_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
99 {
100         /* darker blue for top-level widgets */
101         UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, color);
102 }
103
104 /* backdrop for top-level widgets (Scene and Object only) */
105 static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
106 {
107         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
108         View2D *v2d= &ac->ar->v2d;
109         short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
110         short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
111         float color[3];
112         
113         /* set backdrop drawing color */
114         acf->get_backdrop_color(ac, ale, color);
115         glColor3fv(color);
116         
117         /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
118         uiSetRoundBox((expanded)? (1):(1|8));
119         uiDrawBox(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
120 }
121
122
123 /* get backdrop color for data expanders under top-level Scene/Object */
124 static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
125 {
126         /* lighter color than top-level widget */
127         UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, color);
128 }
129
130 /* backdrop for data expanders under top-level Scene/Object */
131 static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
132 {
133         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
134         View2D *v2d= &ac->ar->v2d;
135         short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
136         float color[3];
137         
138         /* set backdrop drawing color */
139         acf->get_backdrop_color(ac, ale, color);
140         glColor3fv(color);
141         
142         /* no rounded corner - just rectangular box */
143         glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
144 }
145
146 /* get backdrop color for generic channels */
147 static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float *color)
148 {
149         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
150         SpaceAction *saction = NULL;
151         bActionGroup *grp = NULL;
152         short indent= (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
153         
154         /* get context info needed... */
155         if ((ac->sa) && (ac->sa->spacetype == SPACE_ACTION))
156                 saction= (SpaceAction *)ac->sa->spacedata.first;
157                 
158         if (ale->type == ANIMTYPE_FCURVE) {
159                 FCurve *fcu= (FCurve *)ale->data;
160                 grp= fcu->grp;
161         }
162         
163         /* set color for normal channels 
164          *      - use 3 shades of color group/standard color for 3 indention level
165          *      - only use group colors if allowed to, and if actually feasible
166          */
167         if ( (saction && !(saction->flag & SACTION_NODRAWGCOLORS)) && 
168                  ((grp) && (grp->customCol)) ) 
169         {
170                 unsigned char cp[3];
171                 
172                 if (indent == 2) {
173                         VECCOPY(cp, grp->cs.solid);
174                 }
175                 else if (indent == 1) {
176                         VECCOPY(cp, grp->cs.select);
177                 }
178                 else {
179                         VECCOPY(cp, grp->cs.active);
180                 }
181                 
182                 /* copy the colors over, transforming from bytes to floats */
183                 rgb_byte_to_float(cp, color);
184         }
185         else {
186                 // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
187                 int colOfs= 20 - 20*indent;
188                 UI_GetThemeColorShade3fv(TH_HEADER, colOfs, color);
189         }
190 }
191
192 /* backdrop for generic channels */
193 static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
194 {
195         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
196         View2D *v2d= &ac->ar->v2d;
197         short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
198         float color[3];
199         
200         /* set backdrop drawing color */
201         acf->get_backdrop_color(ac, ale, color);
202         glColor3fv(color);
203         
204         /* no rounded corners - just rectangular box */
205         glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
206 }
207
208 /* Indention + Offset ------------------------------------------- */
209
210 /* indention level is always the value in the name */
211 static short acf_generic_indention_0(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
212 {
213         return 0;
214 }
215 static short acf_generic_indention_1(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
216 {
217         return 1;
218 }
219 #if 0 // XXX not used
220 static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
221 {
222         return 2;
223 }
224 #endif
225
226 /* indention which varies with the grouping status */
227 static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
228 {
229         short indent= 0;
230         
231         if (ale->id) {
232                 /* special exception for materials, textures, and particles */
233                 // xxx should tex use indention 2?
234                 if (ELEM3(GS(ale->id->name),ID_MA,ID_PA,ID_TE))
235                         indent++;
236         }
237         
238         /* grouped F-Curves need extra level of indention */
239         if (ale->type == ANIMTYPE_FCURVE) {
240                 FCurve *fcu= (FCurve *)ale->data;
241                 
242                 // TODO: we need some way of specifying that the indention color should be one less...
243                 if (fcu->grp)
244                         indent++;
245         }
246         
247         /* no indention */
248         return indent;
249 }
250
251 /* basic offset for channels derived from indention */
252 static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
253 {
254         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
255         
256         if (acf && acf->get_indent_level)
257                 return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
258         else
259                 return 0;
260 }
261
262 /* offset for groups + grouped entities */
263 static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
264 {
265         short offset= acf_generic_basic_offset(ac, ale);
266         
267         if (ale->id) {
268                 /* special exception for textures */
269                 if (GS(ale->id->name) == ID_TE) {
270                         /* minimum offset */
271                         offset += 21;
272                         
273                         /* special offset from owner type */
274                         switch (ale->ownertype) {
275                                 case ANIMTYPE_DSMAT:
276                                         offset += 21;
277                                         break;
278                                         
279                                 case ANIMTYPE_DSLAM:
280                                 case ANIMTYPE_DSWOR:
281                                         offset += 14;
282                                         break;
283                         }
284                 }
285                 /* special exception for materials and particles */
286                 else if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) 
287                         offset += 21;
288                         
289                 /* if not in Action Editor mode, groupings must carry some offset too... */
290                 else if (ac->datatype != ANIMCONT_ACTION)
291                         offset += 14;
292         }
293         
294         /* offset is just the normal type - i.e. based on indention */
295         return offset;
296 }
297
298 /* Name ------------------------------------------- */
299
300 /* name for ID block entries */
301 static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
302 {
303         ID *id= (ID *)ale->data;        /* data pointed to should be an ID block */
304         
305         /* just copy the name... */
306         if (id && name)
307                 strcpy(name, id->name+2);
308 }
309
310 /* Settings ------------------------------------------- */
311
312 #if 0
313 /* channel type has no settings */
314 static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
315 {
316         return 0;
317 }
318 #endif
319
320 /* check if some setting exists for this object-based data-expander (category only) */
321 static short acf_generic_dsexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
322 {
323         switch (setting) {
324                 /* only expand supported everywhere */
325                 case ACHANNEL_SETTING_EXPAND:
326                         return 1;
327                         
328                 /* visible 
329                  *      - only available in Graph Editor 
330                  *      - NOT available for 'filler' channels
331                  */
332                 case ACHANNEL_SETTING_VISIBLE: 
333                         if (ELEM3(ale->type, ANIMTYPE_FILLMATD, ANIMTYPE_FILLPARTD, ANIMTYPE_FILLTEXD))
334                                 return 0;
335                         else
336                                 return ((ac) && (ac->spacetype == SPACE_IPO));
337                         
338                 default:
339                         return 0;
340         }
341 }
342
343 /* get pointer to the setting (category only) */
344 static void *acf_generic_dsexpand_setting_ptr(bAnimListElem *ale, int setting, short *type)
345 {
346         Object *ob= (Object *)ale->data;
347         
348         /* clear extra return data first */
349         *type= 0;
350         
351         switch (setting) {
352                 case ACHANNEL_SETTING_EXPAND: /* expanded */
353                         GET_ACF_FLAG_PTR(ob->nlaflag); // XXX
354                 
355                 default: /* unsupported */
356                         return NULL;
357         }
358 }
359
360 /* check if some setting exists for this object-based data-expander (datablock only) */
361 static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
362 {
363         switch (setting) {
364                 /* expand is always supported */
365                 case ACHANNEL_SETTING_EXPAND:
366                         return 1;
367                         
368                 /* mute is only supported for NLA */
369                 case ACHANNEL_SETTING_MUTE:
370                         return ((ac) && (ac->spacetype == SPACE_NLA));
371                         
372                 /* other flags are never supported */
373                 default:
374                         return 0;
375         }
376 }
377
378 /* *********************************************** */
379 /* Type Specific Functions + Defines */
380
381 /* Animation Summary ----------------------------------- */
382
383 /* get backdrop color for summary widget */
384 static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
385 {
386         // FIXME: hardcoded color - same as the 'action' line in NLA
387                 // reddish color 
388         color[0] = 0.8f;
389         color[1] = 0.2f;
390         color[2] = 0.0f;
391 }
392
393 /* backdrop for summary widget */
394 static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
395 {
396         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
397         View2D *v2d= &ac->ar->v2d;
398         float color[3];
399         
400         /* set backdrop drawing color */
401         acf->get_backdrop_color(ac, ale, color);
402         glColor3fv(color);
403         
404         /* rounded corners on LHS only 
405          *      - top and bottom 
406          *      - special hack: make the top a bit higher, since we are first... 
407          */
408         uiSetRoundBox((1|8));
409         uiDrawBox(GL_POLYGON, 0,  yminc-2, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
410 }
411
412 /* name for summary entries */
413 static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
414 {
415         if (name)
416                 strcpy(name, "DopeSheet Summary");
417 }
418
419 // TODO: this is really a temp icon I think
420 static int acf_summary_icon(bAnimListElem *UNUSED(ale))
421 {
422         return ICON_BORDERMOVE;
423 }
424
425 /* check if some setting exists for this channel */
426 static short acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
427 {
428         /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
429         return (setting == ACHANNEL_SETTING_EXPAND);
430 }
431
432 /* get the appropriate flag(s) for the setting when it is valid  */
433 static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
434 {
435         if (setting == ACHANNEL_SETTING_EXPAND) {
436                 /* expanded */
437                 *neg= 1;
438                 return ADS_FLAG_SUMMARY_COLLAPSED;
439         }
440         else {
441                 /* unsupported */
442                 *neg= 0;
443                 return 0;
444         }
445 }
446
447 /* get pointer to the setting */
448 static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *type)
449 {
450         bAnimContext *ac= (bAnimContext *)ale->data;
451         
452         /* if data is valid, return pointer to active dopesheet's relevant flag 
453          *      - this is restricted to DopeSheet/Action Editor only
454          */
455         if ((ac->sa) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
456                 SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
457                 bDopeSheet *ads= &saction->ads;
458                 
459                 /* return pointer to DopeSheet's flag */
460                 GET_ACF_FLAG_PTR(ads->flag);
461         }
462         else {
463                 /* can't return anything useful - unsupported */
464                 *type= 0;
465                 return 0;
466         }
467 }
468
469 /* all animation summary (DopeSheet only) type define */
470 static bAnimChannelType ACF_SUMMARY = 
471 {
472         "Summary",                                                      /* type name */
473
474         acf_summary_color,                                      /* backdrop color */
475         acf_summary_backdrop,                           /* backdrop */
476         acf_generic_indention_0,                        /* indent level */
477         NULL,                                                           /* offset */
478         
479         acf_summary_name,                                       /* name */
480         acf_summary_icon,                                       /* icon */
481         
482         acf_summary_setting_valid,                      /* has setting */
483         acf_summary_setting_flag,                       /* flag for setting */
484         acf_summary_setting_ptr                         /* pointer for setting */
485 };
486
487 /* Scene ------------------------------------------- */
488
489 // TODO: just get this from RNA?
490 static int acf_scene_icon(bAnimListElem *UNUSED(ale))
491 {
492         return ICON_SCENE_DATA;
493 }
494
495 /* check if some setting exists for this channel */
496 static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
497 {
498         switch (setting) {
499                 /* muted only in NLA */
500                 case ACHANNEL_SETTING_MUTE: 
501                         return ((ac) && (ac->spacetype == SPACE_NLA));
502                         
503                 /* visible only in Graph Editor */
504                 case ACHANNEL_SETTING_VISIBLE: 
505                         return ((ac) && (ac->spacetype == SPACE_IPO));
506                 
507                 /* only select and expand supported otherwise */
508                 case ACHANNEL_SETTING_SELECT:
509                 case ACHANNEL_SETTING_EXPAND:
510                         return 1;
511                         
512                 default:
513                         return 0;
514         }
515 }
516
517 /* get the appropriate flag(s) for the setting when it is valid  */
518 static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
519 {
520         /* clear extra return data first */
521         *neg= 0;
522         
523         switch (setting) {
524                 case ACHANNEL_SETTING_SELECT: /* selected */
525                         return SCE_DS_SELECTED;
526                         
527                 case ACHANNEL_SETTING_EXPAND: /* expanded */
528                         *neg= 1;
529                         return SCE_DS_COLLAPSED;
530                         
531                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
532                         return ADT_NLA_EVAL_OFF;
533                         
534                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
535                         *neg= 1;
536                         return ADT_CURVES_NOT_VISIBLE;
537                         
538                 default: /* unsupported */
539                         return 0;
540         }
541 }
542
543 /* get pointer to the setting */
544 static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
545 {
546         Scene *scene= (Scene *)ale->data;
547         
548         /* clear extra return data first */
549         *type= 0;
550         
551         switch (setting) {
552                 case ACHANNEL_SETTING_SELECT: /* selected */
553                         GET_ACF_FLAG_PTR(scene->flag);
554                         
555                 case ACHANNEL_SETTING_EXPAND: /* expanded */
556                         GET_ACF_FLAG_PTR(scene->flag);
557                         
558                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
559                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
560                         if (scene->adt)
561                                 GET_ACF_FLAG_PTR(scene->adt->flag)
562                         else
563                                 return NULL;
564                         
565                 default: /* unsupported */
566                         return 0;
567         }
568 }
569
570 /* scene type define */
571 static bAnimChannelType ACF_SCENE = 
572 {
573         "Scene",                                                /* type name */
574
575         acf_generic_root_color,                 /* backdrop color */
576         acf_generic_root_backdrop,              /* backdrop */
577         acf_generic_indention_0,                /* indent level */
578         NULL,                                                   /* offset */
579         
580         acf_generic_idblock_name,               /* name */
581         acf_scene_icon,                                 /* icon */
582         
583         acf_scene_setting_valid,                /* has setting */
584         acf_scene_setting_flag,                 /* flag for setting */
585         acf_scene_setting_ptr                   /* pointer for setting */
586 };
587
588 /* Object ------------------------------------------- */
589
590 static int acf_object_icon(bAnimListElem *ale)
591 {
592         Base *base= (Base *)ale->data;
593         Object *ob= base->object;
594         
595         /* icon depends on object-type */
596
597         switch (ob->type) {
598                 case OB_LAMP:
599                         return ICON_OUTLINER_OB_LAMP;
600                 case OB_MESH: 
601                         return ICON_OUTLINER_OB_MESH;
602                 case OB_CAMERA: 
603                         return ICON_OUTLINER_OB_CAMERA;
604                 case OB_CURVE: 
605                         return ICON_OUTLINER_OB_CURVE;
606                 case OB_MBALL: 
607                         return ICON_OUTLINER_OB_META;
608                 case OB_LATTICE: 
609                         return ICON_OUTLINER_OB_LATTICE;
610                 case OB_ARMATURE: 
611                         return ICON_OUTLINER_OB_ARMATURE;
612                 case OB_FONT: 
613                         return ICON_OUTLINER_OB_FONT;
614                 case OB_SURF: 
615                         return ICON_OUTLINER_OB_SURFACE;
616                 case OB_EMPTY: 
617                         return ICON_OUTLINER_OB_EMPTY;
618                 default:
619                         return ICON_OBJECT_DATA;
620         }
621         
622 }
623
624 /* name for object */
625 static void acf_object_name(bAnimListElem *ale, char *name)
626 {
627         Base *base= (Base *)ale->data;
628         Object *ob= base->object;
629         
630         /* just copy the name... */
631         if (ob && name)
632                 strcpy(name, ob->id.name+2);
633 }
634
635 /* check if some setting exists for this channel */
636 static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
637 {
638         Base *base= (Base *)ale->data;
639         Object *ob= base->object;
640         
641         switch (setting) {
642                 /* muted only in NLA */
643                 case ACHANNEL_SETTING_MUTE: 
644                         return ((ac) && (ac->spacetype == SPACE_NLA));
645                         
646                 /* visible only in Graph Editor */
647                 case ACHANNEL_SETTING_VISIBLE: 
648                         return ((ac) && (ac->spacetype == SPACE_IPO) && (ob->adt));
649                 
650                 /* only select and expand supported otherwise */
651                 case ACHANNEL_SETTING_SELECT:
652                 case ACHANNEL_SETTING_EXPAND:
653                         return 1;
654                         
655                 default:
656                         return 0;
657         }
658 }
659
660 /* get the appropriate flag(s) for the setting when it is valid  */
661 static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
662 {
663         /* clear extra return data first */
664         *neg= 0;
665         
666         switch (setting) {
667                 case ACHANNEL_SETTING_SELECT: /* selected */
668                         return SELECT;
669                         
670                 case ACHANNEL_SETTING_EXPAND: /* expanded */
671                         *neg= 1;
672                         return OB_ADS_COLLAPSED;
673                         
674                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
675                         return ADT_NLA_EVAL_OFF;
676                         
677                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
678                         *neg= 1;
679                         return ADT_CURVES_NOT_VISIBLE;
680                         
681                 default: /* unsupported */
682                         return 0;
683         }
684 }
685
686 /* get pointer to the setting */
687 static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type)
688 {
689         Base *base= (Base *)ale->data;
690         Object *ob= base->object;
691         
692         /* clear extra return data first */
693         *type= 0;
694         
695         switch (setting) {
696                 case ACHANNEL_SETTING_SELECT: /* selected */
697                         GET_ACF_FLAG_PTR(ob->flag);
698                         
699                 case ACHANNEL_SETTING_EXPAND: /* expanded */
700                         GET_ACF_FLAG_PTR(ob->nlaflag); // xxx
701                         
702                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
703                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
704                         if (ob->adt)
705                                 GET_ACF_FLAG_PTR(ob->adt->flag)
706                         else
707                                 return NULL;
708                         
709                 default: /* unsupported */
710                         return 0;
711         }
712 }
713
714 /* object type define */
715 static bAnimChannelType ACF_OBJECT = 
716 {
717         "Object",                                               /* type name */
718         
719         acf_generic_root_color,                 /* backdrop color */
720         acf_generic_root_backdrop,              /* backdrop */
721         acf_generic_indention_0,                /* indent level */
722         NULL,                                                   /* offset */
723         
724         acf_object_name,                                /* name */
725         acf_object_icon,                                /* icon */
726         
727         acf_object_setting_valid,               /* has setting */
728         acf_object_setting_flag,                /* flag for setting */
729         acf_object_setting_ptr                  /* pointer for setting */
730 };
731
732 /* Group ------------------------------------------- */
733
734 /* get backdrop color for group widget */
735 static void acf_group_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float *color)
736 {
737         /* highlight only for action group channels */
738         if (ale->flag & AGRP_ACTIVE)
739                 UI_GetThemeColorShade3fv(TH_GROUP_ACTIVE, 10, color);
740         else
741                 UI_GetThemeColorShade3fv(TH_GROUP, 20, color);
742 }
743
744 /* backdrop for group widget */
745 static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
746 {
747         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
748         View2D *v2d= &ac->ar->v2d;
749         short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
750         short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
751         float color[3];
752         
753         /* set backdrop drawing color */
754         acf->get_backdrop_color(ac, ale, color);
755         glColor3fv(color);
756         
757         /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
758         uiSetRoundBox((expanded)? (1):(1|8));
759         uiDrawBox(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
760 }
761
762 /* name for group entries */
763 static void acf_group_name(bAnimListElem *ale, char *name)
764 {
765         bActionGroup *agrp= (bActionGroup *)ale->data;
766         
767         /* just copy the name... */
768         if (agrp && name)
769                 strcpy(name, agrp->name);
770 }
771
772 /* check if some setting exists for this channel */
773 static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
774 {
775         /* for now, all settings are supported, though some are only conditionally */
776         switch (setting) {
777                 case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
778                         return ((ac->sa) && (ac->sa->spacetype==SPACE_IPO));
779                         
780                 default: /* always supported */
781                         return 1;
782         }
783 }
784
785 /* get the appropriate flag(s) for the setting when it is valid  */
786 static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg)
787 {
788         /* clear extra return data first */
789         *neg= 0;
790         
791         switch (setting) {
792                 case ACHANNEL_SETTING_SELECT: /* selected */
793                         return AGRP_SELECTED;
794                         
795                 case ACHANNEL_SETTING_EXPAND: /* expanded */
796                 {
797                         /* NOTE: Graph Editor uses a different flag to everywhere else for this,
798                          * allowing different collapsing of groups there, since sharing the flag
799                          * proved to be a hazard for workflows...
800                          */
801                         return (ac->spacetype == SPACE_IPO) ? 
802                                                 AGRP_EXPANDED_G :       /* Graph Editor case */
803                                                 AGRP_EXPANDED;          /* DopeSheet and elsewhere */
804                 }
805                         
806                 case ACHANNEL_SETTING_MUTE: /* muted */
807                         return AGRP_MUTED;
808                         
809                 case ACHANNEL_SETTING_PROTECT: /* protected */
810                         //*neg= 1; - if we change this to edtiability
811                         return AGRP_PROTECTED;
812                         
813                 case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
814                         *neg= 1;
815                         return AGRP_NOTVISIBLE;
816         }
817         
818         /* this shouldn't happen */
819         return 0;
820 }
821
822 /* get pointer to the setting */
823 static void *acf_group_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
824 {
825         bActionGroup *agrp= (bActionGroup *)ale->data;
826         
827         /* all flags are just in agrp->flag for now... */
828         GET_ACF_FLAG_PTR(agrp->flag);
829 }
830
831 /* group type define */
832 static bAnimChannelType ACF_GROUP = 
833 {
834         "Group",                                                /* type name */
835         
836         acf_group_color,                                /* backdrop color */
837         acf_group_backdrop,                             /* backdrop */
838         acf_generic_indention_0,                /* indent level */
839         acf_generic_group_offset,               /* offset */
840         
841         acf_group_name,                                 /* name */
842         NULL,                                                   /* icon */
843         
844         acf_group_setting_valid,                /* has setting */
845         acf_group_setting_flag,                 /* flag for setting */
846         acf_group_setting_ptr                   /* pointer for setting */
847 };
848
849 /* F-Curve ------------------------------------------- */
850
851 /* name for fcurve entries */
852 static void acf_fcurve_name(bAnimListElem *ale, char *name)
853 {
854         getname_anim_fcurve(name, ale->id, ale->data);
855 }
856
857 /* check if some setting exists for this channel */
858 static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
859 {
860         FCurve *fcu= (FCurve *)ale->data;
861         
862         switch (setting) {
863                 /* unsupported */
864                 case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
865                         return 0;
866                 
867                 /* conditionally available */
868                 case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
869                         if (fcu->bezt)
870                                 return 1;
871                         else
872                                 return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
873                                 
874                 case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
875                         return ((ac->sa) && (ac->sa->spacetype==SPACE_IPO));
876                         
877                 /* always available */
878                 default:
879                         return 1;
880         }
881 }
882
883 /* get the appropriate flag(s) for the setting when it is valid  */
884 static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
885 {
886         /* clear extra return data first */
887         *neg= 0;
888         
889         switch (setting) {
890                 case ACHANNEL_SETTING_SELECT: /* selected */
891                         return FCURVE_SELECTED;
892                         
893                 case ACHANNEL_SETTING_MUTE: /* muted */
894                         return FCURVE_MUTED;
895                         
896                 case ACHANNEL_SETTING_PROTECT: /* protected */
897                         //*neg= 1; - if we change this to edtiability
898                         return FCURVE_PROTECTED;
899                         
900                 case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
901                         return FCURVE_VISIBLE;
902                         
903                 default: /* unsupported */
904                         return 0;
905         }
906 }
907
908 /* get pointer to the setting */
909 static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
910 {
911         FCurve *fcu= (FCurve *)ale->data;
912         
913         /* all flags are just in agrp->flag for now... */
914         GET_ACF_FLAG_PTR(fcu->flag);
915 }
916
917 /* fcurve type define */
918 static bAnimChannelType ACF_FCURVE = 
919 {
920         "F-Curve",                                              /* type name */
921         
922         acf_generic_channel_color,              /* backdrop color */
923         acf_generic_channel_backdrop,   /* backdrop */
924         acf_generic_indention_flexible, /* indent level */              // xxx rename this to f-curves only?
925         acf_generic_group_offset,               /* offset */
926         
927         acf_fcurve_name,                                /* name */
928         NULL,                                                   /* icon */
929         
930         acf_fcurve_setting_valid,               /* has setting */
931         acf_fcurve_setting_flag,                /* flag for setting */
932         acf_fcurve_setting_ptr                  /* pointer for setting */
933 };
934
935 /* Object Action Expander  ------------------------------------------- */
936
937 // TODO: just get this from RNA?
938 static int acf_fillactd_icon(bAnimListElem *UNUSED(ale))
939 {
940         return ICON_ACTION;
941 }
942
943 /* check if some setting exists for this channel */
944 static short acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
945 {
946         switch (setting) {
947                 /* only select and expand supported */
948                 case ACHANNEL_SETTING_SELECT:
949                 case ACHANNEL_SETTING_EXPAND:
950                         return 1;
951                         
952                 default:
953                         return 0;
954         }
955 }
956
957 /* get the appropriate flag(s) for the setting when it is valid  */
958 static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
959 {
960         /* clear extra return data first */
961         *neg= 0;
962         
963         switch (setting) {
964                 case ACHANNEL_SETTING_SELECT: /* selected */
965                         return ADT_UI_SELECTED;
966                         
967                 case ACHANNEL_SETTING_EXPAND: /* expanded */
968                         *neg= 1;
969                         return ACT_COLLAPSED;
970                 
971                 default: /* unsupported */
972                         return 0;
973         }
974 }
975
976 /* get pointer to the setting */
977 static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
978 {
979         bAction *act= (bAction *)ale->data;
980         AnimData *adt= ale->adt;
981         
982         /* clear extra return data first */
983         *type= 0;
984         
985         switch (setting) {
986                 case ACHANNEL_SETTING_SELECT: /* selected */
987                         if (adt) {
988                                 GET_ACF_FLAG_PTR(adt->flag);
989                         }
990                         else
991                                 return 0;
992                         
993                 case ACHANNEL_SETTING_EXPAND: /* expanded */
994                         GET_ACF_FLAG_PTR(act->flag);
995                 
996                 default: /* unsupported */
997                         return 0;
998         }
999 }
1000
1001 /* object action expander type define */
1002 static bAnimChannelType ACF_FILLACTD = 
1003 {
1004         "Ob-Action Filler",                             /* type name */
1005         
1006         acf_generic_dataexpand_color,   /* backdrop color */
1007         acf_generic_dataexpand_backdrop,/* backdrop */
1008         acf_generic_indention_1,                /* indent level */
1009         acf_generic_basic_offset,               /* offset */
1010         
1011         acf_generic_idblock_name,               /* name */
1012         acf_fillactd_icon,                              /* icon */
1013         
1014         acf_fillactd_setting_valid,             /* has setting */
1015         acf_fillactd_setting_flag,              /* flag for setting */
1016         acf_fillactd_setting_ptr                /* pointer for setting */
1017 };
1018
1019 /* Drivers Expander  ------------------------------------------- */
1020
1021 // TODO: just get this from RNA?
1022 static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
1023 {
1024         return ICON_ANIM_DATA;
1025 }
1026
1027 static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
1028 {
1029         strcpy(name, "Drivers");
1030 }
1031
1032 /* check if some setting exists for this channel */
1033 // TODO: this could be made more generic
1034 static short acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
1035 {
1036         switch (setting) {
1037                 /* only expand supported */
1038                 case ACHANNEL_SETTING_EXPAND:
1039                         return 1;
1040                         
1041                 default:
1042                         return 0;
1043         }
1044 }
1045
1046 /* get the appropriate flag(s) for the setting when it is valid  */
1047 static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1048 {
1049         /* clear extra return data first */
1050         *neg= 0;
1051         
1052         switch (setting) {
1053                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1054                         *neg= 1;
1055                         return ADT_DRIVERS_COLLAPSED;
1056                 
1057                 default: /* unsupported */
1058                         return 0;
1059         }
1060 }
1061
1062 /* get pointer to the setting */
1063 static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short *type)
1064 {
1065         AnimData *adt= (AnimData *)ale->data;
1066         
1067         /* clear extra return data first */
1068         *type= 0;
1069         
1070         switch (setting) {
1071                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1072                         GET_ACF_FLAG_PTR(adt->flag);
1073                 
1074                 default: /* unsupported */
1075                         return 0;
1076         }
1077 }
1078
1079 /* drivers expander type define */
1080 static bAnimChannelType ACF_FILLDRIVERS = 
1081 {
1082         "Drivers Filler",                               /* type name */
1083         
1084         acf_generic_dataexpand_color,   /* backdrop color */
1085         acf_generic_dataexpand_backdrop,/* backdrop */
1086         acf_generic_indention_1,                /* indent level */
1087         acf_generic_basic_offset,               /* offset */
1088         
1089         acf_filldrivers_name,                   /* name */
1090         acf_filldrivers_icon,                   /* icon */
1091         
1092         acf_filldrivers_setting_valid,  /* has setting */
1093         acf_filldrivers_setting_flag,   /* flag for setting */
1094         acf_filldrivers_setting_ptr             /* pointer for setting */
1095 };
1096
1097 /* Materials Expander  ------------------------------------------- */
1098
1099 // TODO: just get this from RNA?
1100 static int acf_fillmatd_icon(bAnimListElem *UNUSED(ale))
1101 {
1102         return ICON_MATERIAL_DATA;
1103 }
1104
1105 static void acf_fillmatd_name(bAnimListElem *UNUSED(ale), char *name)
1106 {
1107         strcpy(name, "Materials");
1108 }
1109
1110 /* get the appropriate flag(s) for the setting when it is valid  */
1111 static int acf_fillmatd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1112 {
1113         /* clear extra return data first */
1114         *neg= 0;
1115         
1116         switch (setting) {
1117                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1118                         return OB_ADS_SHOWMATS;
1119                 
1120                 default: /* unsupported */
1121                         return 0;
1122         }
1123 }
1124
1125 /* materials expander type define */
1126 static bAnimChannelType ACF_FILLMATD= 
1127 {
1128         "Materials Filler",                             /* type name */
1129         
1130         acf_generic_dataexpand_color,   /* backdrop color */
1131         acf_generic_dataexpand_backdrop,/* backdrop */
1132         acf_generic_indention_1,                /* indent level */
1133         acf_generic_basic_offset,               /* offset */
1134         
1135         acf_fillmatd_name,                              /* name */
1136         acf_fillmatd_icon,                              /* icon */
1137         
1138         acf_generic_dsexpand_setting_valid,     /* has setting */
1139         acf_fillmatd_setting_flag,                              /* flag for setting */
1140         acf_generic_dsexpand_setting_ptr                /* pointer for setting */
1141 };
1142
1143 /* Particles Expander  ------------------------------------------- */
1144
1145 // TODO: just get this from RNA?
1146 static int acf_fillpartd_icon(bAnimListElem *UNUSED(ale))
1147 {
1148         return ICON_PARTICLE_DATA;
1149 }
1150
1151 static void acf_fillpartd_name(bAnimListElem *UNUSED(ale), char *name)
1152 {
1153         strcpy(name, "Particles");
1154 }
1155
1156 /* get the appropriate flag(s) for the setting when it is valid  */
1157 static int acf_fillpartd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1158 {
1159         /* clear extra return data first */
1160         *neg= 0;
1161         
1162         switch (setting) {
1163                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1164                         return OB_ADS_SHOWPARTS;
1165                 
1166                 default: /* unsupported */
1167                         return 0;
1168         }
1169 }
1170
1171 /* particles expander type define */
1172 static bAnimChannelType ACF_FILLPARTD= 
1173 {
1174         "Particles Filler",                             /* type name */
1175         
1176         acf_generic_dataexpand_color,   /* backdrop color */
1177         acf_generic_dataexpand_backdrop,/* backdrop */
1178         acf_generic_indention_1,                /* indent level */
1179         acf_generic_basic_offset,               /* offset */
1180         
1181         acf_fillpartd_name,                             /* name */
1182         acf_fillpartd_icon,                             /* icon */
1183         
1184         acf_generic_dsexpand_setting_valid,     /* has setting */
1185         acf_fillpartd_setting_flag,                             /* flag for setting */
1186         acf_generic_dsexpand_setting_ptr                /* pointer for setting */
1187 };
1188
1189 /* Textures Expander  ------------------------------------------- */
1190
1191 /* offset for groups + grouped entities */
1192 static short acf_filltexd_offset(bAnimContext *ac, bAnimListElem *ale)
1193 {
1194         short offset= acf_generic_basic_offset(ac, ale);
1195         
1196         if (ale->id) {
1197                 /* materials */
1198                 switch (GS(ale->id->name)) {
1199                         case ID_MA:
1200                                 offset += 21;
1201                                 break;
1202                                 
1203                         case ID_LA:
1204                         case ID_WO:
1205                                 offset += 14;
1206                                 break;
1207                 }
1208         }
1209         
1210         return offset;
1211 }
1212
1213 // TODO: just get this from RNA?
1214 static int acf_filltexd_icon(bAnimListElem *UNUSED(ale))
1215 {
1216         return ICON_TEXTURE_DATA;
1217 }
1218
1219 static void acf_filltexd_name(bAnimListElem *UNUSED(ale), char *name)
1220 {
1221         strcpy(name, "Textures");
1222 }
1223
1224 /* get pointer to the setting (category only) */
1225 static void *acf_filltexd_setting_ptr(bAnimListElem *ale, int setting, short *type)
1226 {
1227         ID *id= (ID *)ale->data;
1228         
1229         /* clear extra return data first */
1230         *type= 0;
1231         
1232         switch (setting) {
1233                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1234                 {
1235                         switch (GS(id->name)) {
1236                                 case ID_MA:
1237                                 {
1238                                         Material *ma= (Material *)id;
1239                                         GET_ACF_FLAG_PTR(ma->flag);
1240                                 }
1241                                 
1242                                 case ID_LA:
1243                                 {
1244                                         Lamp *la= (Lamp *)id;
1245                                         GET_ACF_FLAG_PTR(la->flag);
1246                                 }
1247                                         
1248                                 case ID_WO:
1249                                 {
1250                                         World *wo= (World *)id;
1251                                         GET_ACF_FLAG_PTR(wo->flag);
1252                                 }
1253                         }
1254                 }
1255                 
1256                 default: /* unsupported */
1257                         return NULL;
1258         }
1259 }
1260
1261 /* get the appropriate flag(s) for the setting when it is valid  */
1262 static int acf_filltexd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1263 {
1264         /* clear extra return data first */
1265         *neg= 0;
1266         
1267         switch (setting) {
1268                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1269                         /* NOTE: the exact same flag must be used for other texture stack types too! */
1270                         return MA_DS_SHOW_TEXS; 
1271                 
1272                 default: /* unsupported */
1273                         return 0;
1274         }
1275 }
1276
1277 /* particles expander type define */
1278 static bAnimChannelType ACF_FILLTEXD= 
1279 {
1280         "Textures Filler",                              /* type name */
1281         
1282         acf_generic_dataexpand_color,   /* backdrop color */
1283         acf_generic_dataexpand_backdrop,/* backdrop */
1284         acf_generic_indention_flexible, /* indent level */
1285         acf_filltexd_offset,                    /* offset */
1286         
1287         acf_filltexd_name,                              /* name */
1288         acf_filltexd_icon,                              /* icon */
1289         
1290         acf_generic_dsexpand_setting_valid,     /* has setting */       
1291         acf_filltexd_setting_flag,                      /* flag for setting */
1292         acf_filltexd_setting_ptr                        /* pointer for setting */
1293 };
1294
1295 /* Material Expander  ------------------------------------------- */
1296
1297 // TODO: just get this from RNA?
1298 static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
1299 {
1300         return ICON_MATERIAL_DATA;
1301 }
1302
1303 /* offset for material expanders */
1304 static short acf_dsmat_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
1305 {
1306         return 21;
1307 }
1308
1309 /* get the appropriate flag(s) for the setting when it is valid  */
1310 static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1311 {
1312         /* clear extra return data first */
1313         *neg= 0;
1314         
1315         switch (setting) {
1316                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1317                         return MA_DS_EXPAND;
1318                         
1319                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1320                         return ADT_NLA_EVAL_OFF;
1321                         
1322                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1323                         *neg= 1;
1324                         return ADT_CURVES_NOT_VISIBLE;
1325                         
1326                 case ACHANNEL_SETTING_SELECT: /* selected */
1327                         return ADT_UI_SELECTED;
1328                 
1329                 default: /* unsupported */
1330                         return 0;
1331         }
1332 }
1333
1334 /* get pointer to the setting */
1335 static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
1336 {
1337         Material *ma= (Material *)ale->data;
1338         
1339         /* clear extra return data first */
1340         *type= 0;
1341         
1342         switch (setting) {
1343                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1344                         GET_ACF_FLAG_PTR(ma->flag);
1345                         
1346                 case ACHANNEL_SETTING_SELECT: /* selected */
1347                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1348                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1349                         if (ma->adt)
1350                                 GET_ACF_FLAG_PTR(ma->adt->flag)
1351                         else
1352                                 return NULL;    
1353                 
1354                 default: /* unsupported */
1355                         return NULL;
1356         }
1357 }
1358
1359 /* material expander type define */
1360 static bAnimChannelType ACF_DSMAT= 
1361 {
1362         "Material Data Expander",               /* type name */
1363         
1364         acf_generic_channel_color,              /* backdrop color */
1365         acf_generic_channel_backdrop,   /* backdrop */
1366         acf_generic_indention_0,                /* indent level */
1367         acf_dsmat_offset,                               /* offset */
1368         
1369         acf_generic_idblock_name,               /* name */
1370         acf_dsmat_icon,                                 /* icon */
1371         
1372         acf_generic_dataexpand_setting_valid,   /* has setting */
1373         acf_dsmat_setting_flag,                                 /* flag for setting */
1374         acf_dsmat_setting_ptr                                   /* pointer for setting */
1375 };
1376
1377 /* Lamp Expander  ------------------------------------------- */
1378
1379 // TODO: just get this from RNA?
1380 static int acf_dslam_icon(bAnimListElem *UNUSED(ale))
1381 {
1382         return ICON_LAMP_DATA;
1383 }
1384
1385 /* get the appropriate flag(s) for the setting when it is valid  */
1386 static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1387 {
1388         /* clear extra return data first */
1389         *neg= 0;
1390         
1391         switch (setting) {
1392                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1393                         return LA_DS_EXPAND;
1394                         
1395                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1396                         return ADT_NLA_EVAL_OFF;
1397                         
1398                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1399                         *neg= 1;
1400                         return ADT_CURVES_NOT_VISIBLE;
1401                         
1402                 case ACHANNEL_SETTING_SELECT: /* selected */
1403                         return ADT_UI_SELECTED;
1404                 
1405                 default: /* unsupported */
1406                         return 0;
1407         }
1408 }
1409
1410 /* get pointer to the setting */
1411 static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
1412 {
1413         Lamp *la= (Lamp *)ale->data;
1414         
1415         /* clear extra return data first */
1416         *type= 0;
1417         
1418         switch (setting) {
1419                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1420                         GET_ACF_FLAG_PTR(la->flag);
1421                         
1422                 case ACHANNEL_SETTING_SELECT: /* selected */
1423                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1424                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1425                         if (la->adt)
1426                                 GET_ACF_FLAG_PTR(la->adt->flag)
1427                         else
1428                                 return NULL;    
1429                 
1430                 default: /* unsupported */
1431                         return NULL;
1432         }
1433 }
1434
1435 /* lamp expander type define */
1436 static bAnimChannelType ACF_DSLAM= 
1437 {
1438         "Lamp Expander",                                /* type name */
1439         
1440         acf_generic_dataexpand_color,   /* backdrop color */
1441         acf_generic_dataexpand_backdrop,/* backdrop */
1442         acf_generic_indention_1,                /* indent level */
1443         acf_generic_basic_offset,               /* offset */
1444         
1445         acf_generic_idblock_name,               /* name */
1446         acf_dslam_icon,                                 /* icon */
1447         
1448         acf_generic_dataexpand_setting_valid,   /* has setting */
1449         acf_dslam_setting_flag,                                 /* flag for setting */
1450         acf_dslam_setting_ptr                                   /* pointer for setting */
1451 };
1452
1453 /* Texture Expander  ------------------------------------------- */
1454
1455 // TODO: just get this from RNA?
1456 static int acf_dstex_icon(bAnimListElem *UNUSED(ale))
1457 {
1458         return ICON_TEXTURE_DATA;
1459 }
1460
1461 /* offset for texture expanders */
1462 static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *ale)
1463 {
1464         short offset = 21;
1465         
1466         /* special offset from owner type */
1467         // FIXME: too much now!
1468         switch (ale->ownertype) {
1469                 case ANIMTYPE_DSMAT:
1470                         offset += 14;
1471                         
1472                 case ANIMTYPE_DSLAM:
1473                 case ANIMTYPE_DSWOR:
1474                         offset += 7;
1475         }
1476         
1477         return offset;
1478 }
1479
1480 /* get the appropriate flag(s) for the setting when it is valid  */
1481 static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1482 {
1483         /* clear extra return data first */
1484         *neg= 0;
1485         
1486         switch (setting) {
1487                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1488                         return TEX_DS_EXPAND;
1489                         
1490                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1491                         return ADT_NLA_EVAL_OFF;
1492                         
1493                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1494                         *neg= 1;
1495                         return ADT_CURVES_NOT_VISIBLE;
1496                         
1497                 case ACHANNEL_SETTING_SELECT: /* selected */
1498                         return ADT_UI_SELECTED;
1499                 
1500                 default: /* unsupported */
1501                         return 0;
1502         }
1503 }
1504
1505 /* get pointer to the setting */
1506 static void *acf_dstex_setting_ptr(bAnimListElem *ale, int setting, short *type)
1507 {
1508         Tex *tex= (Tex *)ale->data;
1509         
1510         /* clear extra return data first */
1511         *type= 0;
1512         
1513         switch (setting) {
1514                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1515                         GET_ACF_FLAG_PTR(tex->flag);
1516                         
1517                 case ACHANNEL_SETTING_SELECT: /* selected */
1518                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1519                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1520                         if (tex->adt)
1521                                 GET_ACF_FLAG_PTR(tex->adt->flag)
1522                         else
1523                                 return NULL;    
1524                 
1525                 default: /* unsupported */
1526                         return NULL;
1527         }
1528 }
1529
1530 /* material expander type define */
1531 static bAnimChannelType ACF_DSTEX= 
1532 {
1533         "Texture Data Expander",                /* type name */
1534         
1535         acf_generic_channel_color,              /* backdrop color */
1536         acf_generic_channel_backdrop,   /* backdrop */
1537         acf_generic_indention_0,                /* indent level */
1538         acf_dstex_offset,                               /* offset */
1539         
1540         acf_generic_idblock_name,               /* name */
1541         acf_dstex_icon,                                 /* icon */
1542         
1543         acf_generic_dataexpand_setting_valid,   /* has setting */
1544         acf_dstex_setting_flag,                                 /* flag for setting */
1545         acf_dstex_setting_ptr                                   /* pointer for setting */
1546 };
1547
1548 /* Camera Expander  ------------------------------------------- */
1549
1550 // TODO: just get this from RNA?
1551 static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
1552 {
1553         return ICON_CAMERA_DATA;
1554 }
1555
1556 /* get the appropriate flag(s) for the setting when it is valid  */
1557 static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1558 {
1559         /* clear extra return data first */
1560         *neg= 0;
1561         
1562         switch (setting) {
1563                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1564                         return CAM_DS_EXPAND;
1565                         
1566                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1567                         return ADT_NLA_EVAL_OFF;
1568                         
1569                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1570                         *neg= 1;
1571                         return ADT_CURVES_NOT_VISIBLE;
1572                         
1573                 case ACHANNEL_SETTING_SELECT: /* selected */
1574                         return ADT_UI_SELECTED;
1575                 
1576                 default: /* unsupported */
1577                         return 0;
1578         }
1579 }
1580
1581 /* get pointer to the setting */
1582 static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
1583 {
1584         Camera *ca= (Camera *)ale->data;
1585         
1586         /* clear extra return data first */
1587         *type= 0;
1588         
1589         switch (setting) {
1590                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1591                         GET_ACF_FLAG_PTR(ca->flag);
1592                         
1593                 case ACHANNEL_SETTING_SELECT: /* selected */
1594                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1595                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1596                         if (ca->adt)
1597                                 GET_ACF_FLAG_PTR(ca->adt->flag)
1598                         else
1599                                 return NULL;
1600                 
1601                 default: /* unsupported */
1602                         return NULL;
1603         }
1604 }
1605
1606 /* camera expander type define */
1607 static bAnimChannelType ACF_DSCAM= 
1608 {
1609         "Camera Expander",                              /* type name */
1610         
1611         acf_generic_dataexpand_color,   /* backdrop color */
1612         acf_generic_dataexpand_backdrop,/* backdrop */
1613         acf_generic_indention_1,                /* indent level */
1614         acf_generic_basic_offset,               /* offset */
1615         
1616         acf_generic_idblock_name,               /* name */
1617         acf_dscam_icon,                                 /* icon */
1618         
1619         acf_generic_dataexpand_setting_valid,   /* has setting */
1620         acf_dscam_setting_flag,                                 /* flag for setting */
1621         acf_dscam_setting_ptr                                   /* pointer for setting */
1622 };
1623
1624 /* Curve Expander  ------------------------------------------- */
1625
1626 // TODO: just get this from RNA?
1627 static int acf_dscur_icon(bAnimListElem *ale)
1628 {
1629         Curve *cu= (Curve *)ale->data;
1630         short obtype= curve_type(cu);
1631         
1632         switch (obtype) {
1633                 case OB_FONT:
1634                         return ICON_FONT_DATA;
1635                 case OB_SURF:
1636                         return ICON_SURFACE_DATA;
1637                 default:
1638                         return ICON_CURVE_DATA;
1639         }
1640 }
1641
1642 /* get the appropriate flag(s) for the setting when it is valid  */
1643 static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1644 {
1645         /* clear extra return data first */
1646         *neg= 0;
1647         
1648         switch (setting) {
1649                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1650                         return CU_DS_EXPAND;
1651                         
1652                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1653                         return ADT_NLA_EVAL_OFF;
1654                         
1655                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1656                         *neg= 1;
1657                         return ADT_CURVES_NOT_VISIBLE;
1658                         
1659                 case ACHANNEL_SETTING_SELECT: /* selected */
1660                         return ADT_UI_SELECTED;
1661                 
1662                 default: /* unsupported */
1663                         return 0;
1664         }
1665 }
1666
1667 /* get pointer to the setting */
1668 static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
1669 {
1670         Curve *cu= (Curve *)ale->data;
1671         
1672         /* clear extra return data first */
1673         *type= 0;
1674         
1675         switch (setting) {
1676                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1677                         GET_ACF_FLAG_PTR(cu->flag);
1678                         
1679                 case ACHANNEL_SETTING_SELECT: /* selected */
1680                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1681                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1682                         if (cu->adt)
1683                                 GET_ACF_FLAG_PTR(cu->adt->flag)
1684                         else
1685                                 return NULL;
1686                 
1687                 default: /* unsupported */
1688                         return NULL;
1689         }
1690 }
1691
1692 /* curve expander type define */
1693 static bAnimChannelType ACF_DSCUR= 
1694 {
1695         "Curve Expander",                               /* type name */
1696         
1697         acf_generic_dataexpand_color,   /* backdrop color */
1698         acf_generic_dataexpand_backdrop,/* backdrop */
1699         acf_generic_indention_1,                /* indent level */
1700         acf_generic_basic_offset,               /* offset */
1701         
1702         acf_generic_idblock_name,               /* name */
1703         acf_dscur_icon,                                 /* icon */
1704         
1705         acf_generic_dataexpand_setting_valid,   /* has setting */
1706         acf_dscur_setting_flag,                                 /* flag for setting */
1707         acf_dscur_setting_ptr                                   /* pointer for setting */
1708 };
1709
1710 /* Shape Key Expander  ------------------------------------------- */
1711
1712 // TODO: just get this from RNA?
1713 static int acf_dsskey_icon(bAnimListElem *UNUSED(ale))
1714 {
1715         return ICON_SHAPEKEY_DATA;
1716 }
1717
1718 /* get the appropriate flag(s) for the setting when it is valid  */
1719 static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1720 {
1721         /* clear extra return data first */
1722         *neg= 0;
1723         
1724         switch (setting) {
1725                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1726                         return KEY_DS_EXPAND;
1727                         
1728                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1729                         return ADT_NLA_EVAL_OFF;
1730                         
1731                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1732                         *neg= 1;
1733                         return ADT_CURVES_NOT_VISIBLE;
1734                         
1735                 case ACHANNEL_SETTING_SELECT: /* selected */
1736                         return ADT_UI_SELECTED;
1737                 
1738                 default: /* unsupported */
1739                         return 0;
1740         }
1741 }
1742
1743 /* get pointer to the setting */
1744 static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type)
1745 {
1746         Key *key= (Key *)ale->data;
1747         
1748         /* clear extra return data first */
1749         *type= 0;
1750         
1751         switch (setting) {
1752                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1753                         GET_ACF_FLAG_PTR(key->flag);
1754                         
1755                 case ACHANNEL_SETTING_SELECT: /* selected */
1756                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1757                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1758                         if (key->adt)
1759                                 GET_ACF_FLAG_PTR(key->adt->flag)
1760                         else
1761                                 return NULL;
1762                 
1763                 default: /* unsupported */
1764                         return NULL;
1765         }
1766 }
1767
1768 /* shapekey expander type define */
1769 static bAnimChannelType ACF_DSSKEY= 
1770 {
1771         "Shape Key Expander",                   /* type name */
1772         
1773         acf_generic_dataexpand_color,   /* backdrop color */
1774         acf_generic_dataexpand_backdrop,/* backdrop */
1775         acf_generic_indention_1,                /* indent level */
1776         acf_generic_basic_offset,               /* offset */
1777         
1778         acf_generic_idblock_name,               /* name */
1779         acf_dsskey_icon,                                /* icon */
1780         
1781         acf_generic_dataexpand_setting_valid,   /* has setting */
1782         acf_dsskey_setting_flag,                                /* flag for setting */
1783         acf_dsskey_setting_ptr                                  /* pointer for setting */
1784 };
1785
1786 /* World Expander  ------------------------------------------- */
1787
1788 // TODO: just get this from RNA?
1789 static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
1790 {
1791         return ICON_WORLD_DATA;
1792 }
1793
1794 /* get the appropriate flag(s) for the setting when it is valid  */
1795 static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1796 {
1797         /* clear extra return data first */
1798         *neg= 0;
1799         
1800         switch (setting) {
1801                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1802                         return WO_DS_EXPAND;
1803                         
1804                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1805                         return ADT_NLA_EVAL_OFF;
1806                         
1807                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1808                         *neg= 1;
1809                         return ADT_CURVES_NOT_VISIBLE;
1810                         
1811                 case ACHANNEL_SETTING_SELECT: /* selected */
1812                         return ADT_UI_SELECTED;
1813                 
1814                 default: /* unsupported */
1815                         return 0;
1816         }
1817 }
1818
1819 /* get pointer to the setting */
1820 static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
1821 {
1822         World *wo= (World *)ale->data;
1823         
1824         /* clear extra return data first */
1825         *type= 0;
1826         
1827         switch (setting) {
1828                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1829                         GET_ACF_FLAG_PTR(wo->flag);
1830                         
1831                 case ACHANNEL_SETTING_SELECT: /* selected */
1832                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1833                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1834                         if (wo->adt)
1835                                 GET_ACF_FLAG_PTR(wo->adt->flag)
1836                         else
1837                                 return NULL;
1838                 
1839                 default: /* unsupported */
1840                         return NULL;
1841         }
1842 }
1843
1844 /* world expander type define */
1845 static bAnimChannelType ACF_DSWOR= 
1846 {
1847         "World Expander",                               /* type name */
1848         
1849         acf_generic_dataexpand_color,   /* backdrop color */
1850         acf_generic_dataexpand_backdrop,/* backdrop */
1851         acf_generic_indention_1,                /* indent level */
1852         acf_generic_basic_offset,               /* offset */
1853         
1854         acf_generic_idblock_name,               /* name */
1855         acf_dswor_icon,                                 /* icon */
1856         
1857         acf_generic_dataexpand_setting_valid,   /* has setting */
1858         acf_dswor_setting_flag,                                 /* flag for setting */
1859         acf_dswor_setting_ptr                                   /* pointer for setting */
1860 };
1861
1862 /* Particle Expander  ------------------------------------------- */
1863
1864 // TODO: just get this from RNA?
1865 static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
1866 {
1867         return ICON_PARTICLE_DATA;
1868 }
1869
1870 /* get the appropriate flag(s) for the setting when it is valid  */
1871 static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1872 {
1873         /* clear extra return data first */
1874         *neg= 0;
1875         
1876         switch (setting) {
1877                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1878                         return PART_DS_EXPAND;
1879                         
1880                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1881                         return ADT_NLA_EVAL_OFF;
1882                         
1883                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1884                         *neg= 1;
1885                         return ADT_CURVES_NOT_VISIBLE;
1886                         
1887                 case ACHANNEL_SETTING_SELECT: /* selected */
1888                         return ADT_UI_SELECTED;
1889                 
1890                 default: /* unsupported */
1891                         return 0;
1892         }
1893 }
1894
1895 /* get pointer to the setting */
1896 static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type)
1897 {
1898         ParticleSettings *part= (ParticleSettings *)ale->data;
1899         
1900         /* clear extra return data first */
1901         *type= 0;
1902         
1903         switch (setting) {
1904                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1905                         GET_ACF_FLAG_PTR(part->flag);
1906                         
1907                 case ACHANNEL_SETTING_SELECT: /* selected */
1908                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1909                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1910                         if (part->adt)
1911                                 GET_ACF_FLAG_PTR(part->adt->flag)
1912                         else
1913                                 return NULL;
1914                 
1915                 default: /* unsupported */
1916                         return NULL;
1917         }
1918 }
1919
1920 /* particle expander type define */
1921 static bAnimChannelType ACF_DSPART= 
1922 {
1923         "Particle Data Expander",               /* type name */
1924         
1925         acf_generic_dataexpand_color,   /* backdrop color */
1926         acf_generic_dataexpand_backdrop,/* backdrop */
1927         acf_generic_indention_1,                /* indent level */
1928         acf_generic_basic_offset,               /* offset */
1929         
1930         acf_generic_idblock_name,               /* name */
1931         acf_dspart_icon,                                /* icon */
1932         
1933         acf_generic_dataexpand_setting_valid,   /* has setting */
1934         acf_dspart_setting_flag,                                /* flag for setting */
1935         acf_dspart_setting_ptr                                  /* pointer for setting */
1936 };
1937
1938 /* MetaBall Expander  ------------------------------------------- */
1939
1940 // TODO: just get this from RNA?
1941 static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
1942 {
1943         return ICON_META_DATA;
1944 }
1945
1946 /* get the appropriate flag(s) for the setting when it is valid  */
1947 static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
1948 {
1949         /* clear extra return data first */
1950         *neg= 0;
1951         
1952         switch (setting) {
1953                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1954                         return MB_DS_EXPAND;
1955                         
1956                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
1957                         return ADT_NLA_EVAL_OFF;
1958                         
1959                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
1960                         *neg= 1;
1961                         return ADT_CURVES_NOT_VISIBLE;
1962                 
1963                 case ACHANNEL_SETTING_SELECT: /* selected */
1964                         return ADT_UI_SELECTED;
1965                 
1966                 default: /* unsupported */
1967                         return 0;
1968         }
1969 }
1970
1971 /* get pointer to the setting */
1972 static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *type)
1973 {
1974         MetaBall *mb= (MetaBall *)ale->data;
1975         
1976         /* clear extra return data first */
1977         *type= 0;
1978         
1979         switch (setting) {
1980                 case ACHANNEL_SETTING_EXPAND: /* expanded */
1981                         GET_ACF_FLAG_PTR(mb->flag);
1982                         
1983                 case ACHANNEL_SETTING_SELECT: /* selected */
1984                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
1985                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
1986                         if (mb->adt)
1987                                 GET_ACF_FLAG_PTR(mb->adt->flag)
1988                         else
1989                                 return NULL;
1990                 
1991                 default: /* unsupported */
1992                         return NULL;
1993         }
1994 }
1995
1996 /* metaball expander type define */
1997 static bAnimChannelType ACF_DSMBALL= 
1998 {
1999         "Metaball Expander",                    /* type name */
2000         
2001         acf_generic_dataexpand_color,   /* backdrop color */
2002         acf_generic_dataexpand_backdrop,/* backdrop */
2003         acf_generic_indention_1,                /* indent level */
2004         acf_generic_basic_offset,               /* offset */
2005         
2006         acf_generic_idblock_name,               /* name */
2007         acf_dsmball_icon,                               /* icon */
2008         
2009         acf_generic_dataexpand_setting_valid,   /* has setting */
2010         acf_dsmball_setting_flag,                               /* flag for setting */
2011         acf_dsmball_setting_ptr                                 /* pointer for setting */
2012 };
2013
2014 /* Armature Expander  ------------------------------------------- */
2015
2016 // TODO: just get this from RNA?
2017 static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
2018 {
2019         return ICON_ARMATURE_DATA;
2020 }
2021
2022 /* get the appropriate flag(s) for the setting when it is valid  */
2023 static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2024 {
2025         /* clear extra return data first */
2026         *neg= 0;
2027         
2028         switch (setting) {
2029                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2030                         return ARM_DS_EXPAND;
2031                         
2032                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2033                         return ADT_NLA_EVAL_OFF;
2034                         
2035                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2036                         *neg= 1;
2037                         return ADT_CURVES_NOT_VISIBLE;
2038                         
2039                 case ACHANNEL_SETTING_SELECT: /* selected */
2040                         return ADT_UI_SELECTED;
2041                 
2042                 default: /* unsupported */
2043                         return 0;
2044         }
2045 }
2046
2047 /* get pointer to the setting */
2048 static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
2049 {
2050         bArmature *arm= (bArmature *)ale->data;
2051         
2052         /* clear extra return data first */
2053         *type= 0;
2054         
2055         switch (setting) {
2056                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2057                         GET_ACF_FLAG_PTR(arm->flag);
2058                         
2059                 case ACHANNEL_SETTING_SELECT: /* selected */
2060                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2061                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2062                         if (arm->adt)
2063                                 GET_ACF_FLAG_PTR(arm->adt->flag)
2064                         else
2065                                 return NULL;
2066                 
2067                 default: /* unsupported */
2068                         return NULL;
2069         }
2070 }
2071
2072 /* metaball expander type define */
2073 static bAnimChannelType ACF_DSARM= 
2074 {
2075         "Armature Expander",                    /* type name */
2076         
2077         acf_generic_dataexpand_color,   /* backdrop color */
2078         acf_generic_dataexpand_backdrop,/* backdrop */
2079         acf_generic_indention_1,                /* indent level */
2080         acf_generic_basic_offset,               /* offset */
2081         
2082         acf_generic_idblock_name,               /* name */
2083         acf_dsarm_icon,                         /* icon */
2084         
2085         acf_generic_dataexpand_setting_valid,   /* has setting */
2086         acf_dsarm_setting_flag,                                 /* flag for setting */
2087         acf_dsarm_setting_ptr                                   /* pointer for setting */
2088 };
2089
2090 /* NodeTree Expander  ------------------------------------------- */
2091
2092 // TODO: just get this from RNA?
2093 static int acf_dsntree_icon(bAnimListElem *UNUSED(ale))
2094 {
2095         return ICON_NODETREE;
2096 }
2097
2098 /* get the appropriate flag(s) for the setting when it is valid  */
2099 static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2100 {
2101         /* clear extra return data first */
2102         *neg= 0;
2103         
2104         switch (setting) {
2105                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2106                         return NTREE_DS_EXPAND;
2107                         
2108                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2109                         return ADT_NLA_EVAL_OFF;
2110                         
2111                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2112                         *neg= 1;
2113                         return ADT_CURVES_NOT_VISIBLE;
2114                         
2115                 case ACHANNEL_SETTING_SELECT: /* selected */
2116                         return ADT_UI_SELECTED;
2117                         
2118                 default: /* unsupported */
2119                         return 0;
2120         }
2121 }
2122
2123 /* get pointer to the setting */
2124 static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *type)
2125 {
2126         bNodeTree *ntree= (bNodeTree *)ale->data;
2127         
2128         /* clear extra return data first */
2129         *type= 0;
2130         
2131         switch (setting) {
2132                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2133                         GET_ACF_FLAG_PTR(ntree->flag);
2134                         
2135                 case ACHANNEL_SETTING_SELECT: /* selected */
2136                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2137                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2138                         if (ntree->adt)
2139                                 GET_ACF_FLAG_PTR(ntree->adt->flag)
2140                                 else
2141                                         return NULL;
2142                         
2143                 default: /* unsupported */
2144                         return NULL;
2145         }
2146 }
2147
2148 /* node tree expander type define */
2149 static bAnimChannelType ACF_DSNTREE= 
2150 {
2151         "Node Tree Expander",                   /* type name */
2152         
2153         acf_generic_dataexpand_color,   /* backdrop color */
2154         acf_generic_dataexpand_backdrop,/* backdrop */
2155         acf_generic_indention_1,                /* indent level */              // XXX this only works for compositing
2156         acf_generic_basic_offset,               /* offset */
2157         
2158         acf_generic_idblock_name,               /* name */
2159         acf_dsntree_icon,                               /* icon */
2160         
2161         acf_generic_dataexpand_setting_valid,   /* has setting */
2162         acf_dsntree_setting_flag,                               /* flag for setting */
2163         acf_dsntree_setting_ptr                                 /* pointer for setting */
2164 };
2165
2166 /* LineStyle Expander  ------------------------------------------- */
2167
2168 // TODO: just get this from RNA?
2169 static int acf_dslinestyle_icon(bAnimListElem *ale)
2170 {
2171         return ICON_BRUSH_DATA; /* FIXME */
2172 }
2173
2174 /* get the appropriate flag(s) for the setting when it is valid  */
2175 static int acf_dslinestyle_setting_flag(bAnimContext *ac, int setting, short *neg)
2176 {
2177         /* clear extra return data first */
2178         *neg= 0;
2179         
2180         switch (setting) {
2181                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2182                         return LS_DS_EXPAND;
2183                         
2184                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2185                         return ADT_NLA_EVAL_OFF;
2186                         
2187                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2188                         *neg= 1;
2189                         return ADT_CURVES_NOT_VISIBLE;
2190                         
2191                 case ACHANNEL_SETTING_SELECT: /* selected */
2192                         return ADT_UI_SELECTED;
2193                         
2194                 default: /* unsupported */
2195                         return 0;
2196         }
2197 }
2198
2199 /* get pointer to the setting */
2200 static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short *type)
2201 {
2202         FreestyleLineStyle *linestyle= (FreestyleLineStyle *)ale->data;
2203         
2204         /* clear extra return data first */
2205         *type= 0;
2206         
2207         switch (setting) {
2208                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2209                         GET_ACF_FLAG_PTR(linestyle->flag);
2210                         
2211                 case ACHANNEL_SETTING_SELECT: /* selected */
2212                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2213                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2214                         if (linestyle->adt)
2215                                 GET_ACF_FLAG_PTR(linestyle->adt->flag)
2216                         else
2217                                 return NULL;
2218                         
2219                 default: /* unsupported */
2220                         return NULL;
2221         }
2222 }
2223
2224 /* node tree expander type define */
2225 static bAnimChannelType ACF_DSLINESTYLE= 
2226 {
2227         "Line Style Expander",                  /* type name */
2228         
2229         acf_generic_dataexpand_color,   /* backdrop color */
2230         acf_generic_dataexpand_backdrop,/* backdrop */
2231         acf_generic_indention_1,                /* indent level */
2232         acf_generic_basic_offset,               /* offset */
2233         
2234         acf_generic_idblock_name,               /* name */
2235         acf_dslinestyle_icon,                   /* icon */
2236         
2237         acf_generic_dataexpand_setting_valid,   /* has setting */
2238         acf_dslinestyle_setting_flag,                   /* flag for setting */
2239         acf_dslinestyle_setting_ptr                             /* pointer for setting */
2240 };
2241
2242 /* Mesh Expander  ------------------------------------------- */
2243
2244 // TODO: just get this from RNA?
2245 static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
2246 {
2247         return ICON_MESH_DATA;
2248 }
2249
2250 /* get the appropriate flag(s) for the setting when it is valid  */
2251 static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2252 {
2253         /* clear extra return data first */
2254         *neg= 0;
2255         
2256         switch (setting) {
2257                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2258                         return ME_DS_EXPAND;
2259                         
2260                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2261                         return ADT_NLA_EVAL_OFF;
2262                         
2263                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2264                         *neg= 1;
2265                         return ADT_CURVES_NOT_VISIBLE;
2266                         
2267                 case ACHANNEL_SETTING_SELECT: /* selected */
2268                         return ADT_UI_SELECTED;
2269                         
2270                 default: /* unsupported */
2271                         return 0;
2272         }
2273 }
2274
2275 /* get pointer to the setting */
2276 static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type)
2277 {
2278         Mesh *me= (Mesh *)ale->data;
2279         
2280         /* clear extra return data first */
2281         *type= 0;
2282         
2283         switch (setting) {
2284                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2285                         GET_ACF_FLAG_PTR(me->flag);
2286                         
2287                 case ACHANNEL_SETTING_SELECT: /* selected */
2288                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2289                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2290                         if (me->adt)
2291                                 GET_ACF_FLAG_PTR(me->adt->flag)
2292                                 else
2293                                         return NULL;
2294                         
2295                 default: /* unsupported */
2296                         return NULL;
2297         }
2298 }
2299
2300 /* node tree expander type define */
2301 static bAnimChannelType ACF_DSMESH= 
2302 {
2303         "Mesh Expander",                                /* type name */
2304         
2305         acf_generic_dataexpand_color,   /* backdrop color */
2306         acf_generic_dataexpand_backdrop,/* backdrop */
2307         acf_generic_indention_1,                /* indent level */              // XXX this only works for compositing
2308         acf_generic_basic_offset,               /* offset */
2309         
2310         acf_generic_idblock_name,               /* name */
2311         acf_dsmesh_icon,                                /* icon */
2312         
2313         acf_generic_dataexpand_setting_valid,   /* has setting */
2314         acf_dsmesh_setting_flag,                                /* flag for setting */
2315         acf_dsmesh_setting_ptr                                  /* pointer for setting */
2316 };
2317
2318 /* Lattice Expander  ------------------------------------------- */
2319
2320 // TODO: just get this from RNA?
2321 static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
2322 {
2323         return ICON_LATTICE_DATA;
2324 }
2325
2326 /* get the appropriate flag(s) for the setting when it is valid  */
2327 static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2328 {
2329         /* clear extra return data first */
2330         *neg= 0;
2331         
2332         switch (setting) {
2333                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2334                         return LT_DS_EXPAND;
2335                         
2336                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
2337                         return ADT_NLA_EVAL_OFF;
2338                         
2339                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
2340                         *neg= 1;
2341                         return ADT_CURVES_NOT_VISIBLE;
2342                         
2343                 case ACHANNEL_SETTING_SELECT: /* selected */
2344                         return ADT_UI_SELECTED;
2345                         
2346                 default: /* unsupported */
2347                         return 0;
2348         }
2349 }
2350
2351 /* get pointer to the setting */
2352 static void *acf_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type)
2353 {
2354         Lattice *lt= (Lattice *)ale->data;
2355         
2356         /* clear extra return data first */
2357         *type= 0;
2358         
2359         switch (setting) {
2360                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2361                         GET_ACF_FLAG_PTR(lt->flag);
2362                         
2363                 case ACHANNEL_SETTING_SELECT: /* selected */
2364                 case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
2365                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
2366                         if (lt->adt)
2367                                 GET_ACF_FLAG_PTR(lt->adt->flag)
2368                                 else
2369                                         return NULL;
2370                         
2371                 default: /* unsupported */
2372                         return NULL;
2373         }
2374 }
2375
2376 /* node tree expander type define */
2377 static bAnimChannelType ACF_DSLAT= 
2378 {
2379         "Lattice Expander",                             /* type name */
2380         
2381         acf_generic_dataexpand_color,   /* backdrop color */
2382         acf_generic_dataexpand_backdrop,/* backdrop */
2383         acf_generic_indention_1,                /* indent level */              // XXX this only works for compositing
2384         acf_generic_basic_offset,               /* offset */
2385         
2386         acf_generic_idblock_name,               /* name */
2387         acf_dslat_icon,                                 /* icon */
2388         
2389         acf_generic_dataexpand_setting_valid,   /* has setting */
2390         acf_dslat_setting_flag,                                 /* flag for setting */
2391         acf_dslat_setting_ptr                                   /* pointer for setting */
2392 };
2393
2394 /* ShapeKey Entry  ------------------------------------------- */
2395
2396 /* name for ShapeKey */
2397 static void acf_shapekey_name(bAnimListElem *ale, char *name)
2398 {
2399         KeyBlock *kb= (KeyBlock *)ale->data;
2400         
2401         /* just copy the name... */
2402         if (kb && name) {
2403                 /* if the KeyBlock had a name, use it, otherwise use the index */
2404                 if (kb->name[0])
2405                         strcpy(name, kb->name);
2406                 else
2407                         sprintf(name, "Key %d", ale->index);
2408         }
2409 }
2410
2411 /* check if some setting exists for this channel */
2412 static short acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2413 {
2414         switch (setting) {
2415                 case ACHANNEL_SETTING_SELECT: /* selected */
2416                 case ACHANNEL_SETTING_MUTE: /* muted */
2417                 case ACHANNEL_SETTING_PROTECT: /* protected */
2418                         return 1;
2419                         
2420                 /* nothing else is supported */
2421                 default:
2422                         return 0;
2423         }
2424 }
2425
2426 /* get the appropriate flag(s) for the setting when it is valid  */
2427 static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2428 {
2429         /* clear extra return data first */
2430         *neg= 0;
2431         
2432         switch (setting) {
2433                 case ACHANNEL_SETTING_MUTE: /* mute */
2434                         return KEYBLOCK_MUTE;
2435                 
2436                 case ACHANNEL_SETTING_SELECT: /* selected */
2437                         return KEYBLOCK_SEL;
2438                 
2439                 case ACHANNEL_SETTING_PROTECT: /* locked */
2440                         return KEYBLOCK_LOCKED;
2441                 
2442                 default: /* unsupported */
2443                         return 0;
2444         }
2445 }
2446
2447 /* get pointer to the setting */
2448 static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
2449 {
2450         KeyBlock *kb= (KeyBlock *)ale->data;
2451         
2452         /* clear extra return data first */
2453         *type= 0;
2454         
2455         switch (setting) {
2456                 case ACHANNEL_SETTING_SELECT: /* selected */
2457                 case ACHANNEL_SETTING_MUTE: /* muted */
2458                 case ACHANNEL_SETTING_PROTECT: /* protected */
2459                         GET_ACF_FLAG_PTR(kb->flag)
2460                 
2461                 default: /* unsupported */
2462                         return NULL;
2463         }
2464 }
2465
2466 /* shapekey expander type define */
2467 static bAnimChannelType ACF_SHAPEKEY= 
2468 {
2469         "Shape Key",                                    /* type name */
2470         
2471         acf_generic_channel_color,              /* backdrop color */
2472         acf_generic_channel_backdrop,   /* backdrop */
2473         acf_generic_indention_0,                /* indent level */
2474         acf_generic_basic_offset,               /* offset */
2475         
2476         acf_shapekey_name,                              /* name */
2477         NULL,                                                   /* icon */
2478         
2479         acf_shapekey_setting_valid,             /* has setting */
2480         acf_shapekey_setting_flag,              /* flag for setting */
2481         acf_shapekey_setting_ptr                /* pointer for setting */
2482 };
2483
2484 /* Grease Pencil entries  ------------------------------------------- */
2485 // XXX ... this is currently not restored yet
2486
2487 #if 0
2488 static void dummy_olddraw_gpencil ()
2489 {
2490         /* determine what needs to be drawn */
2491         switch (ale->type) {
2492                 case ANIMTYPE_GPDATABLOCK: /* gpencil datablock */
2493                 {
2494                         bGPdata *gpd = (bGPdata *)ale->data;
2495                         ScrArea *sa = (ScrArea *)ale->owner; // XXX depreceated...
2496                         
2497                         indent = 0;
2498                         group= 3;
2499                         
2500                         /* only show expand if there are any channels */
2501                         if (gpd->layers.first) {
2502                                 if (gpd->flag & GP_DATA_EXPAND)
2503                                         expand = ICON_TRIA_DOWN;
2504                                 else
2505                                         expand = ICON_TRIA_RIGHT;
2506                         }
2507                         
2508                         switch (sa->spacetype) {
2509                                 case SPACE_VIEW3D:
2510                                 {
2511                                         /* this shouldn't cause any overflow... */
2512                                         //sprintf(name, "View3D:%s", view3d_get_name(sa->spacedata.first)); // XXX missing func..
2513                                         strcpy(name, "View3D");
2514                                         special= ICON_VIEW3D;
2515                                 }
2516                                         break;
2517                                 case SPACE_NODE:
2518                                 {
2519                                         SpaceNode *snode= sa->spacedata.first;
2520                                         char treetype[12];
2521                                         
2522                                         if (snode->treetype == 1)
2523                                                 strcpy(treetype, "Composite");
2524                                         else
2525                                                 strcpy(treetype, "Material");
2526                                         sprintf(name, "Nodes:%s", treetype);
2527                                         
2528                                         special= ICON_NODETREE;
2529                                 }
2530                                         break;
2531                                 case SPACE_SEQ:
2532                                 {
2533                                         SpaceSeq *sseq= sa->spacedata.first;
2534                                         char imgpreview[10];
2535                                         
2536                                         switch (sseq->mainb) {
2537                                                 case 1:         sprintf(imgpreview, "Image...");        break;
2538                                                 case 2:         sprintf(imgpreview, "Luma...");         break;
2539                                                 case 3:         sprintf(imgpreview, "Chroma...");       break;
2540                                                 case 4:         sprintf(imgpreview, "Histogram");       break;
2541                                                 
2542                                                 default:        sprintf(imgpreview, "Sequence");        break;
2543                                         }
2544                                         sprintf(name, "Sequencer:%s", imgpreview);
2545                                         
2546                                         special= ICON_SEQUENCE;
2547                                 }
2548                                         break;
2549                                 case SPACE_IMAGE:
2550                                 {
2551                                         SpaceImage *sima= sa->spacedata.first;
2552                                         
2553                                         if (sima->image)
2554                                                 sprintf(name, "Image:%s", sima->image->id.name+2);
2555                                         else
2556                                                 strcpy(name, "Image:<None>");
2557                                                 
2558                                         special= ICON_IMAGE_COL;
2559                                 }
2560                                         break;
2561                                 
2562                                 default:
2563                                 {
2564                                         sprintf(name, "<Unknown GP-Data Source>");
2565                                         special= -1;
2566                                 }
2567                                         break;
2568                         }
2569                 }
2570                         break;
2571                 case ANIMTYPE_GPLAYER: /* gpencil layer */
2572                 {
2573                         bGPDlayer *gpl = (bGPDlayer *)ale->data;
2574                         
2575                         indent = 0;
2576                         special = -1;
2577                         expand = -1;
2578                         group = 1;
2579                         
2580                         if (EDITABLE_GPL(gpl))
2581                                 protect = ICON_UNLOCKED;
2582                         else
2583                                 protect = ICON_LOCKED;
2584                                 
2585                         if (gpl->flag & GP_LAYER_HIDE)
2586                                 mute = ICON_MUTE_IPO_ON;
2587                         else
2588                                 mute = ICON_MUTE_IPO_OFF;
2589                         
2590                         sel = SEL_GPL(gpl);
2591                         BLI_snprintf(name, 32, gpl->info);
2592                 }
2593                         break;
2594         }       
2595         
2596         if (group == 3) {
2597                 /* only for gp-data channels */
2598                 UI_ThemeColorShade(TH_GROUP, 20);
2599                 uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
2600                 gl_round_box(GL_POLYGON, x+offset,  yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
2601         }
2602 }
2603 #endif
2604
2605 /* *********************************************** */
2606 /* Type Registration and General Access */
2607
2608 /* These globals only ever get directly accessed in this file */
2609 static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES];
2610 static short ACF_INIT= 1; /* when non-zero, the list needs to be updated */
2611
2612 /* Initialise type info definitions */
2613 void ANIM_init_channel_typeinfo_data (void)
2614 {
2615         int type= 0;
2616         
2617         /* start initialising if necessary... */
2618         if (ACF_INIT) {
2619                 ACF_INIT= 0;
2620                 
2621                 animchannelTypeInfo[type++]= NULL;                              /* None */
2622                 animchannelTypeInfo[type++]= NULL;                              /* AnimData */
2623                 animchannelTypeInfo[type++]= NULL;                              /* Special */
2624                 
2625                 animchannelTypeInfo[type++]= &ACF_SUMMARY;              /* Motion Summary */
2626                 
2627                 animchannelTypeInfo[type++]= &ACF_SCENE;                /* Scene */
2628                 animchannelTypeInfo[type++]= &ACF_OBJECT;               /* Object */
2629                 animchannelTypeInfo[type++]= &ACF_GROUP;                /* Group */
2630                 animchannelTypeInfo[type++]= &ACF_FCURVE;               /* F-Curve */
2631                 
2632                 animchannelTypeInfo[type++]= &ACF_FILLACTD;     /* Object Action Expander */
2633                 animchannelTypeInfo[type++]= &ACF_FILLDRIVERS;  /* Drivers Expander */
2634                 animchannelTypeInfo[type++]= &ACF_FILLMATD;     /* Materials Expander */
2635                 animchannelTypeInfo[type++]= &ACF_FILLPARTD;    /* Particles Expander */
2636                 animchannelTypeInfo[type++]= &ACF_FILLTEXD;             /* Textures Expander */
2637                 
2638                 animchannelTypeInfo[type++]= &ACF_DSMAT;                /* Material Channel */
2639                 animchannelTypeInfo[type++]= &ACF_DSLAM;                /* Lamp Channel */
2640                 animchannelTypeInfo[type++]= &ACF_DSCAM;                /* Camera Channel */
2641                 animchannelTypeInfo[type++]= &ACF_DSCUR;                /* Curve Channel */
2642                 animchannelTypeInfo[type++]= &ACF_DSSKEY;               /* ShapeKey Channel */
2643                 animchannelTypeInfo[type++]= &ACF_DSWOR;                /* World Channel */
2644                 animchannelTypeInfo[type++]= &ACF_DSNTREE;              /* NodeTree Channel */
2645                 animchannelTypeInfo[type++]= &ACF_DSPART;               /* Particle Channel */
2646                 animchannelTypeInfo[type++]= &ACF_DSMBALL;              /* MetaBall Channel */
2647                 animchannelTypeInfo[type++]= &ACF_DSARM;                /* Armature Channel */
2648                 animchannelTypeInfo[type++]= &ACF_DSMESH;               /* Mesh Channel */
2649                 animchannelTypeInfo[type++]= &ACF_DSTEX;                /* Texture Channel */
2650                 animchannelTypeInfo[type++]= &ACF_DSLAT;                /* Lattice Channel */
2651                 animchannelTypeInfo[type++]= &ACF_DSLINESTYLE;  /* LineStyle Channel */
2652                 
2653                 animchannelTypeInfo[type++]= &ACF_SHAPEKEY;             /* ShapeKey */
2654                 
2655                         // XXX not restored yet
2656                 animchannelTypeInfo[type++]= NULL;                              /* Grease Pencil Datablock */ 
2657                 animchannelTypeInfo[type++]= NULL;                              /* Grease Pencil Layer */ 
2658                 
2659                         // TODO: these types still need to be implemented!!!
2660                         // probably need a few extra flags for these special cases...
2661                 animchannelTypeInfo[type++]= NULL;                              /* NLA Track */ 
2662                 animchannelTypeInfo[type++]= NULL;                              /* NLA Action */ 
2663         }
2664
2665
2666 /* Get type info from given channel type */
2667 bAnimChannelType *ANIM_channel_get_typeinfo (bAnimListElem *ale)
2668 {
2669         /* santiy checks */
2670         if (ale == NULL)
2671                 return NULL;
2672                 
2673         /* init the typeinfo if not available yet... */
2674         ANIM_init_channel_typeinfo_data();
2675         
2676         /* check if type is in bounds... */
2677         if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
2678                 return animchannelTypeInfo[ale->type];
2679         else
2680                 return NULL;
2681 }
2682
2683 /* --------------------------- */
2684
2685 /* Print debug info string for the given channel */
2686 void ANIM_channel_debug_print_info (bAnimListElem *ale, short indent_level)
2687 {
2688         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
2689         
2690         /* print indents */
2691         for (; indent_level > 0; indent_level--)
2692                 printf("  ");
2693         
2694         /* print info */
2695         if (acf) {
2696                 char name[256]; /* hopefully this will be enough! */
2697                 
2698                 /* get UI name */
2699                 if (acf->name)
2700                         acf->name(ale, name);
2701                 else
2702                         sprintf(name, "<No name>");
2703                         
2704                 /* print type name + ui name */
2705                 printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
2706         }
2707         else if (ale)
2708                 printf("ChanType: <Unknown - %d>\n", ale->type);
2709         else
2710                 printf("<Invalid channel - NULL>\n");
2711 }
2712
2713 /* --------------------------- */
2714
2715 /* Check if some setting for a channel is enabled 
2716  * Returns: 1 = On, 0 = Off, -1 = Invalid
2717  */
2718 short ANIM_channel_setting_get (bAnimContext *ac, bAnimListElem *ale, int setting)
2719 {
2720         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
2721         
2722         /* 1) check that the setting exists for the current context */
2723         if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
2724         {
2725                 /* 2) get pointer to check for flag in, and the flag to check for */
2726                 short negflag, ptrsize;
2727                 int flag;
2728                 void *ptr;
2729                 
2730                 flag= acf->setting_flag(ac, setting, &negflag);
2731                 ptr= acf->setting_ptr(ale, setting, &ptrsize);
2732                 
2733                 /* check if flag is enabled */
2734                 if (ptr && flag) {
2735                         switch (ptrsize) {
2736                                 case sizeof(int):       /* integer pointer for setting */
2737                                 {
2738                                         int *val= (int *)ptr;
2739                                         
2740                                         if (negflag)
2741                                                 return ((*val) & flag) == 0;
2742                                         else
2743                                                 return ((*val) & flag) != 0;
2744                                 }
2745                                         break;
2746                                         
2747                                 case sizeof(short):     /* short pointer for setting */
2748                                 {
2749                                         short *val= (short *)ptr;
2750                                         
2751                                         if (negflag)
2752                                                 return ((*val) & flag) == 0;
2753                                         else
2754                                                 return ((*val) & flag) != 0;
2755                                 }
2756                                         break;
2757                                         
2758                                 case sizeof(char):      /* char pointer for setting */
2759                                 {
2760                                         char *val= (char *)ptr;
2761                                         
2762                                         if (negflag)
2763                                                 return ((*val) & flag) == 0;
2764                                         else
2765                                                 return ((*val) & flag) != 0;
2766                                 }
2767                                         break;
2768                         }
2769                 }
2770         }
2771         
2772         /* not found... */
2773         return -1;
2774 }       
2775
2776
2777 /* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
2778 #define ACF_SETTING_SET(sval, sflag, smode) \
2779         {\
2780                 if (negflag) {\
2781                         if (smode == ACHANNEL_SETFLAG_INVERT)   (sval) ^= (sflag); \
2782                         else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \
2783                         else                                                                    (sval) |= (sflag); \
2784                 } \
2785                 else {\
2786                         if (smode == ACHANNEL_SETFLAG_INVERT)   (sval) ^= (sflag); \
2787                         else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \
2788                         else                                                                    (sval) &= ~(sflag); \
2789                 }\
2790         }
2791
2792 /* Change value of some setting for a channel 
2793  *      - setting: eAnimChannel_Settings
2794  *      - mode: eAnimChannels_SetFlag
2795  */
2796 void ANIM_channel_setting_set (bAnimContext *ac, bAnimListElem *ale, int setting, short mode)
2797 {
2798         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
2799         
2800         /* 1) check that the setting exists for the current context */
2801         if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
2802         {
2803                 /* 2) get pointer to check for flag in, and the flag to check for */
2804                 short negflag, ptrsize;
2805                 int flag;
2806                 void *ptr;
2807                 
2808                 flag= acf->setting_flag(ac, setting, &negflag);
2809                 ptr= acf->setting_ptr(ale, setting, &ptrsize);
2810                 
2811                 /* check if flag is enabled */
2812                 if (ptr && flag) {
2813                         switch (ptrsize) {
2814                                 case sizeof(int):       /* integer pointer for setting */
2815                                 {
2816                                         int *val= (int *)ptr;
2817                                         ACF_SETTING_SET(*val, flag, mode);
2818                                 }
2819                                         break;
2820                                         
2821                                 case sizeof(short):     /* short pointer for setting */
2822                                 {
2823                                         short *val= (short *)ptr;
2824                                         ACF_SETTING_SET(*val, flag, mode);
2825                                 }
2826                                         break;
2827                                         
2828                                 case sizeof(char):      /* char pointer for setting */
2829                                 {
2830                                         char *val= (char *)ptr;
2831                                         ACF_SETTING_SET(*val, flag, mode);
2832                                 }
2833                                         break;
2834                         }
2835                 }
2836         }
2837 }
2838
2839 /* --------------------------- */
2840
2841 // XXX hardcoded size of icons
2842 #define ICON_WIDTH              17
2843 // XXX hardcoded width of sliders
2844 #define SLIDER_WIDTH    80
2845
2846 /* Draw the given channel */
2847 // TODO: make this use UI controls for the buttons
2848 void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
2849 {
2850         bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
2851         View2D *v2d= &ac->ar->v2d;
2852         short selected, offset;
2853         float y, ymid, ytext;
2854         
2855         /* sanity checks - don't draw anything */
2856         if ELEM(NULL, acf, ale)
2857                 return;
2858         
2859         /* get initial offset */
2860         if (acf->get_offset)
2861                 offset= acf->get_offset(ac, ale);
2862         else
2863                 offset= 0;
2864                 
2865         /* calculate appropriate y-coordinates for icon buttons 
2866          *      7 is hardcoded factor for half-height of icons
2867          */
2868         y= (ymaxc - yminc)/2 + yminc;
2869         ymid= y - 7;
2870         /* y-coordinates for text is only 4 down from middle */
2871         ytext= y - 4;
2872         
2873         /* check if channel is selected */
2874         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
2875                 selected= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
2876         else
2877                 selected= 0;
2878                 
2879         /* set blending again, as may not be set in previous step */
2880         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2881         glEnable(GL_BLEND);
2882         
2883         /* step 1) draw backdrop ...........................................  */
2884         if (acf->draw_backdrop)
2885                 acf->draw_backdrop(ac, ale, yminc, ymaxc);
2886                 
2887         /* step 2) draw expand widget ....................................... */
2888         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
2889                 /* just skip - drawn as widget now */
2890                 offset += ICON_WIDTH; 
2891         }
2892                 
2893         /* step 3) draw icon ............................................... */
2894         if (acf->icon) {
2895                 UI_icon_draw(offset, ymid, acf->icon(ale));
2896                 offset += ICON_WIDTH; 
2897         }
2898         
2899         /* turn off blending, since not needed anymore... */
2900         glDisable(GL_BLEND);
2901                 
2902         /* step 4) draw special toggles  .................................
2903          *      - in Graph Editor, checkboxes for visibility in curves area
2904          *      - in NLA Editor, glowing dots for solo/not solo...
2905          */
2906         if (ac->sa) {
2907                 if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
2908                         /* for F-Curves, draw color-preview of curve behind checkbox */
2909                         if (ale->type == ANIMTYPE_FCURVE) {
2910                                 FCurve *fcu= (FCurve *)ale->data;
2911                                 
2912                                 /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever 
2913                                  * color the curve has stored 
2914                                  */
2915                                 glColor3fv(fcu->color);
2916                                 
2917                                 /* just a solid color rect
2918                                  *      hardcoded 17 pixels width is slightly wider than icon width, so that 
2919                                  *      there's a slight border around it 
2920                                  */
2921                                 glRectf(offset, yminc, offset+17, ymaxc);
2922                         }
2923                         
2924                         /* icon is drawn as widget now... */
2925                         offset += ICON_WIDTH; 
2926                 }
2927                 else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
2928                         /* just skip - drawn as widget now */
2929                         offset += ICON_WIDTH; 
2930                 }
2931         }
2932         
2933         /* step 5) draw name ............................................... */
2934         if (acf->name) {
2935                 char name[256]; /* hopefully this will be enough! */
2936                 
2937                 /* set text color */
2938                 if (selected)
2939                         UI_ThemeColor(TH_TEXT_HI);
2940                 else
2941                         UI_ThemeColor(TH_TEXT);
2942                         
2943                 /* get name */
2944                 acf->name(ale, name);
2945                 
2946                 offset += 3;
2947                 UI_DrawString(offset, ytext, name);
2948                 
2949                 /* draw red underline if channel is disabled */
2950                 if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) 
2951                 {
2952                         // FIXME: replace hardcoded color here, and check on extents!
2953                         glColor3f(1.0f, 0.0f, 0.0f);
2954                         glLineWidth(2.0);
2955                                 fdrawline((float)(offset), yminc, 
2956                                                   (float)(v2d->cur.xmax), yminc);
2957                         glLineWidth(1.0);
2958                 }
2959         }
2960         
2961         /* step 6) draw backdrops behidn mute+protection toggles + (sliders) ....................... */
2962         /* reset offset - now goes from RHS of panel */
2963         offset = 0;
2964         
2965         // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
2966         
2967         if (v2d) {
2968                 short draw_sliders = 0;
2969                 float color[3];
2970                 
2971                 /* get and set backdrop color */
2972                 acf->get_backdrop_color(ac, ale, color);
2973                 glColor3fv(color);
2974                 
2975                 /* check if we need to show the sliders */
2976                 if ((ac->sa) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
2977                         switch (ac->spacetype) {
2978                                 case SPACE_ACTION:
2979                                 {
2980                                         SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
2981                                         draw_sliders= (saction->flag & SACTION_SLIDERS);
2982                                 }
2983                                         break;
2984                                 case SPACE_IPO:
2985                                 {
2986                                         SpaceIpo *sipo= (SpaceIpo *)ac->sa->spacedata.first;
2987                                         draw_sliders= (sipo->flag & SIPO_SLIDERS);
2988                                 }
2989                                         break;
2990                         }
2991                 }
2992                 
2993                 /* check if there's enough space for the toggles if the sliders are drawn too */
2994                 if ( !(draw_sliders) || ((v2d->mask.xmax-v2d->mask.xmin) > ACHANNEL_BUTTON_WIDTH/2) )&n