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