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