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