4c244899205f9c52a0dbef43eea30b94aad6dee0
[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_mesh_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_meta_types.h"
53 #include "DNA_node_types.h"
54 #include "DNA_world_types.h"
55 #include "DNA_gpencil_types.h"
56 #include "DNA_speaker_types.h"
57 #include "DNA_mask_types.h"
58
59 #include "RNA_access.h"
60
61 #include "BKE_curve.h"
62 #include "BKE_key.h"
63 #include "BKE_context.h"
64
65 #include "UI_interface.h"
66 #include "UI_interface_icons.h"
67 #include "UI_resources.h"
68
69 #include "ED_anim_api.h"
70 #include "ED_keyframing.h"
71
72 #include "BIF_gl.h"
73 #include "BIF_glutil.h"
74
75 #include "WM_api.h"
76 #include "WM_types.h"
77
78 /* *********************************************** */
79 // XXX constant defines to be moved elsewhere?
80
81 /* extra padding for lengths (to go under scrollers) */
82 #define EXTRA_SCROLL_PAD    100.0f
83
84 /* size of indent steps */
85 #define INDENT_STEP_SIZE    7
86
87 #define ANIM_CHAN_NAME_SIZE 256
88
89 /* get the pointer used for some flag */
90 #define GET_ACF_FLAG_PTR(ptr, type) ((*(type) = sizeof((ptr))), &(ptr))
91
92 /* *********************************************** */
93 /* Generic Functions (Type independent) */
94
95 /* Draw Backdrop ---------------------------------- */
96
97 /* get backdrop color for top-level widgets (Scene and Object only) */
98 static void acf_generic_root_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
99 {
100         /* darker blue for top-level widgets */
101         UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, r_color);
102 }
103
104 /* backdrop for top-level widgets (Scene and Object only) */
105 static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
106 {
107         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
108         View2D *v2d = &ac->ar->v2d;
109         short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
110         short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
111         float color[3];
112         
113         /* set backdrop drawing color */
114         acf->get_backdrop_color(ac, ale, color);
115         glColor3fv(color);
116         
117         /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
118         uiSetRoundBox((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
119         uiDrawBox(GL_POLYGON, offset,  yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
120 }
121
122
123 /* get backdrop color for data expanders under top-level Scene/Object */
124 static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
125 {
126         /* lighter color than top-level widget */
127         UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, r_color);
128 }
129
130 /* backdrop for data expanders under top-level Scene/Object */
131 static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
132 {
133         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
134         View2D *v2d = &ac->ar->v2d;
135         short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
136         float color[3];
137         
138         /* set backdrop drawing color */
139         acf->get_backdrop_color(ac, ale, color);
140         glColor3fv(color);
141         
142         /* no rounded corner - just rectangular box */
143         glRectf(offset, yminc,  v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
144 }
145
146 /* helper method to test if group colors should be drawn */
147 static short acf_show_channel_colors(bAnimContext *ac)
148 {
149         short showGroupColors = 0;
150         
151         if (ac->sl) {
152                 switch (ac->spacetype) {
153                         case SPACE_ACTION:
154                         {
155                                 SpaceAction *saction = (SpaceAction *)ac->sl;
156                                 showGroupColors = !(saction->flag & SACTION_NODRAWGCOLORS);
157                         }
158                                 break;
159                         case SPACE_IPO:
160                         {
161                                 SpaceIpo *sipo = (SpaceIpo *)ac->sl;
162                                 showGroupColors = !(sipo->flag & SIPO_NODRAWGCOLORS);
163                         }
164                                 break;
165                 }
166         }
167         
168         return showGroupColors;
169 }
170
171 /* get backdrop color for generic channels */
172 static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
173 {
174         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
175         bActionGroup *grp = NULL;
176         short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
177         short showGroupColors = acf_show_channel_colors(ac);
178         
179         if (ale->type == ANIMTYPE_FCURVE) {
180                 FCurve *fcu = (FCurve *)ale->data;
181                 grp = fcu->grp;
182         }
183         
184         /* set color for normal channels 
185          *      - use 3 shades of color group/standard color for 3 indention level
186          *      - only use group colors if allowed to, and if actually feasible
187          */
188         if (showGroupColors && (grp) && (grp->customCol)) {
189                 unsigned char cp[3];
190                 
191                 if (indent == 2) {
192                         copy_v3_v3_char((char *)cp, grp->cs.solid);
193                 }
194                 else if (indent == 1) {
195                         copy_v3_v3_char((char *)cp, grp->cs.select);
196                 }
197                 else {
198                         copy_v3_v3_char((char *)cp, grp->cs.active);
199                 }
200                 
201                 /* copy the colors over, transforming from bytes to floats */
202                 rgb_uchar_to_float(r_color, cp);
203         }
204         else {
205                 // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
206                 int colOfs = 20 - 20 * indent;
207                 UI_GetThemeColorShade3fv(TH_HEADER, colOfs, r_color);
208         }
209 }
210
211 /* backdrop for generic channels */
212 static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
213 {
214         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
215         View2D *v2d = &ac->ar->v2d;
216         short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
217         float color[3];
218         
219         /* set backdrop drawing color */
220         acf->get_backdrop_color(ac, ale, color);
221         glColor3fv(color);
222         
223         /* no rounded corners - just rectangular box */
224         glRectf(offset, yminc,  v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
225 }
226
227 /* Indention + Offset ------------------------------------------- */
228
229 /* indention level is always the value in the name */
230 static short acf_generic_indention_0(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
231 {
232         return 0;
233 }
234 static short acf_generic_indention_1(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
235 {
236         return 1;
237 }
238 #if 0 // XXX not used
239 static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
240 {
241         return 2;
242 }
243 #endif
244
245 /* indention which varies with the grouping status */
246 static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
247 {
248         short indent = 0;
249         
250         /* grouped F-Curves need extra level of indention */
251         if (ale->type == ANIMTYPE_FCURVE) {
252                 FCurve *fcu = (FCurve *)ale->data;
253                 
254                 // TODO: we need some way of specifying that the indention color should be one less...
255                 if (fcu->grp)
256                         indent++;
257         }
258         
259         /* no indention */
260         return indent;
261 }
262
263 /* basic offset for channels derived from indention */
264 static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
265 {
266         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
267         
268         if (acf && acf->get_indent_level)
269                 return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
270         else
271                 return 0;
272 }
273
274 /* offset based on nodetree type */
275 static short acf_nodetree_rootType_offset(bNodeTree *ntree)
276 {
277         if (ntree) {
278                 switch (ntree->type) {
279                         case NTREE_SHADER:
280                                 /* 1 additional level (i.e. is indented one level in from material, 
281                                  * so shift all right by one step) 
282                                  */
283                                 return INDENT_STEP_SIZE; 
284                                 
285                         case NTREE_COMPOSIT:
286                                 /* no additional levels needed */
287                                 return 0; 
288                                 
289                         case NTREE_TEXTURE:
290                                 /* 2 additional levels */
291                                 return INDENT_STEP_SIZE * 2;
292                 }
293         }
294         
295         // unknown
296         return 0;
297 }
298
299 /* offset for groups + grouped entities */
300 static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
301 {
302         short offset = acf_generic_basic_offset(ac, ale);
303         
304         if (ale->id) {
305                 /* texture animdata */
306                 if (GS(ale->id->name) == ID_TE) {
307                         offset += 21;
308                 }
309                 /* materials and particles animdata */
310                 else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
311                         offset += 14;
312                         
313                 /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
314                 else if (ac->datatype != ANIMCONT_ACTION)
315                         offset += 14;
316                         
317                 /* nodetree animdata */
318                 if (GS(ale->id->name) == ID_NT) {
319                         offset += acf_nodetree_rootType_offset((bNodeTree *)ale->id);
320                 }
321         }
322         
323         /* offset is just the normal type - i.e. based on indention */
324         return offset;
325 }
326
327 /* Name ------------------------------------------- */
328
329 /* name for ID block entries */
330 static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
331 {
332         ID *id = (ID *)ale->data;    /* data pointed to should be an ID block */
333         
334         /* just copy the name... */
335         if (id && name)
336                 BLI_strncpy(name, id->name + 2, ANIM_CHAN_NAME_SIZE);
337 }
338
339 /* name property for ID block entries */
340 static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
341 {
342         RNA_id_pointer_create(ale->id, ptr);
343         *prop = RNA_struct_name_property(ptr->type);
344         
345         return (*prop != NULL);
346 }
347
348
349 /* name property for ID block entries which are just subheading "fillers" */
350 static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
351 {
352         /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
353         RNA_id_pointer_create(ale->data, ptr);
354         *prop = RNA_struct_name_property(ptr->type);
355         
356         return (*prop != NULL);
357 }
358
359 /* Settings ------------------------------------------- */
360
361 #if 0
362 /* channel type has no settings */
363 static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
364 {
365         return 0;
366 }
367 #endif
368
369 /* check if some setting exists for this object-based data-expander (datablock only) */
370 static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
371 {
372         switch (setting) {
373                 /* expand is always supported */
374                 case ACHANNEL_SETTING_EXPAND:
375                         return 1;
376                         
377                 /* mute is only supported for NLA */
378                 case ACHANNEL_SETTING_MUTE:
379                         return ((ac) && (ac->spacetype == SPACE_NLA));
380                         
381                 /* other flags are never supported */
382                 default:
383                         return 0;
384         }
385 }
386
387 /* *********************************************** */
388 /* Type Specific Functions + Defines */
389
390 /* Animation Summary ----------------------------------- */
391
392 /* get backdrop color for summary widget */
393 static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
394 {
395         /* reddish color - same as the 'action' line in NLA */
396         UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color);
397 }
398
399 /* backdrop for summary widget */
400 static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
401 {
402         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
403         View2D *v2d = &ac->ar->v2d;
404         float color[3];
405         
406         /* set backdrop drawing color */
407         acf->get_backdrop_color(ac, ale, color);
408         glColor3fv(color);
409         
410         /* rounded corners on LHS only 
411          *      - top and bottom 
412          *      - special hack: make the top a bit higher, since we are first... 
413          */
414         uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
415         uiDrawBox(GL_POLYGON, 0,  yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
416 }
417
418 /* name for summary entries */
419 static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
420 {
421         if (name)
422                 BLI_strncpy(name, "DopeSheet Summary", ANIM_CHAN_NAME_SIZE);
423 }
424
425 // TODO: this is really a temp icon I think
426 static int acf_summary_icon(bAnimListElem *UNUSED(ale))
427 {
428         return ICON_BORDERMOVE;
429 }
430
431 /* check if some setting exists for this channel */
432 static short acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
433 {
434         /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
435         return (setting == ACHANNEL_SETTING_EXPAND);
436 }
437
438 /* get the appropriate flag(s) for the setting when it is valid  */
439 static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
440 {
441         if (setting == ACHANNEL_SETTING_EXPAND) {
442                 /* expanded */
443                 *neg = 1;
444                 return ADS_FLAG_SUMMARY_COLLAPSED;
445         }
446         else {
447                 /* unsupported */
448                 *neg = 0;
449                 return 0;
450         }
451 }
452
453 /* get pointer to the setting */
454 static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *type)
455 {
456         bAnimContext *ac = (bAnimContext *)ale->data;
457         
458         /* if data is valid, return pointer to active dopesheet's relevant flag 
459          *      - this is restricted to DopeSheet/Action Editor only
460          */
461         if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
462                 SpaceAction *saction = (SpaceAction *)ac->sl;
463                 bDopeSheet *ads = &saction->ads;
464                 
465                 /* return pointer to DopeSheet's flag */
466                 return GET_ACF_FLAG_PTR(ads->flag, type);
467         }
468         else {
469                 /* can't return anything useful - unsupported */
470                 *type = 0;
471                 return NULL;
472         }
473 }
474
475 /* all animation summary (DopeSheet only) type define */
476 static bAnimChannelType ACF_SUMMARY = 
477 {
478         "Summary",                          /* type name */
479
480         acf_summary_color,                  /* backdrop color */
481         acf_summary_backdrop,               /* backdrop */
482         acf_generic_indention_0,            /* indent level */
483         NULL,                               /* offset */
484
485         acf_summary_name,                   /* name */
486         NULL,                               /* name prop */
487         acf_summary_icon,                   /* icon */
488
489         acf_summary_setting_valid,          /* has setting */
490         acf_summary_setting_flag,           /* flag for setting */
491         acf_summary_setting_ptr             /* pointer for setting */
492 };
493
494 /* Scene ------------------------------------------- */
495
496 // TODO: just get this from RNA?
497 static int acf_scene_icon(bAnimListElem *UNUSED(ale))
498 {
499         return ICON_SCENE_DATA;
500 }
501
502 /* check if some setting exists for this channel */
503 static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
504 {
505         switch (setting) {
506                 /* muted only in NLA */
507                 case ACHANNEL_SETTING_MUTE: 
508                         return ((ac) && (ac->spacetype == SPACE_NLA));
509                         
510                 /* visible only in Graph Editor */
511                 case ACHANNEL_SETTING_VISIBLE: 
512                         return ((ac) && (ac->spacetype == SPACE_IPO));
513                 
514                 /* only select and expand supported otherwise */
515                 case ACHANNEL_SETTING_SELECT:
516                 case ACHANNEL_SETTING_EXPAND:
517                         return 1;
518                         
519                 default:
520                         return 0;
521         }
522 }
523
524 /* get the appropriate flag(s) for the setting when it is valid  */
525 static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
526 {
527         /* clear extra return data first */
528         *neg = 0;
529         
530         switch (setting) {
531                 case ACHANNEL_SETTING_SELECT: /* selected */
532                         return SCE_DS_SELECTED;
533                         
534                 case ACHANNEL_SETTING_EXPAND: /* expanded */
535                         *neg = 1;
536                         return SCE_DS_COLLAPSED;
537                         
538                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
539                         return ADT_NLA_EVAL_OFF;
540                         
541                 case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
542                         *neg = 1;
543                         return ADT_CURVES_NOT_VISIBLE;
544                         
545                 default: /* unsupported */
546                         return 0;
547         }
548 }
549
550 /* get pointer to the setting */
551 static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
552 {
553         Scene *scene = (Scene *)ale->data;
554         
555         /* clear extra return data first */
556         *type = 0;
557         
558         switch (setting) {
559                 case ACHANNEL_SETTING_SELECT: /* selected */
560                         return GET_ACF_FLAG_PTR(scene->flag, type);
561                         
562                 case ACHANNEL_SETTING_EXPAND: /* expanded */
563                         return GET_ACF_FLAG_PTR(scene->flag, type);
564                         
565                 case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
566                 case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
567                         if (scene->adt)
568                                 return GET_ACF_FLAG_PTR(scene->adt->flag, type);
569                         else
570                                 return NULL;
571                         
572                 default: /* unsupported */
573                         return NULL;
574         }
575 }
576
577 /* scene type define */
578 static bAnimChannelType ACF_SCENE = 
579 {
580         "Scene",                        /* type name */
581
582         acf_generic_root_color,         /* backdrop color */
583         acf_generic_root_backdrop,      /* backdrop */
584         acf_generic_indention_0,        /* indent level */
585         NULL,                           /* offset */
586
587         acf_generic_idblock_name,       /* name */
588         acf_generic_idblock_nameprop,   /* name prop */
589         acf_scene_icon,                 /* icon */
590
591         acf_scene_setting_valid,        /* has setting */
592         acf_scene_setting_flag,         /* flag for setting */
593         acf_scene_setting_ptr           /* pointer for setting */
594 };
595
596 /* Object ------------------------------------------- */
597
598 static int acf_object_icon(bAnimListElem *ale)
599 {
600         Base *base = (Base *)ale->data;
601         Object *ob = base->object;
602         
603         /* icon depends on object-type */
604
605         switch (ob->type) {
606                 case OB_LAMP:
607                         return ICON_OUTLINER_OB_LAMP;
608                 case OB_MESH: 
609                         return ICON_OUTLINER_OB_MESH;
610                 case OB_CAMERA: 
611                         return ICON_OUTLINER_OB_CAMERA;
612                 case OB_CURVE: 
613                         return ICON_OUTLINER_OB_CURVE;
614                 case OB_MBALL: 
615                         return ICON_OUTLINER_OB_META;
616                 case OB_LATTICE: 
617                         return ICON_OUTLINER_OB_LATTICE;
618                 case OB_SPEAKER:
619                         return ICON_OUTLINER_OB_SPEAKER;
620                 case OB_ARMATURE:
621                         return ICON_OUTLINER_OB_ARMATURE;
622                 case OB_FONT: 
623                         return ICON_OUTLINER_OB_FONT;
624                 case OB_SURF: 
625                         return ICON_OUTLINER_OB_SURFACE;
626                 case OB_EMPTY: 
627                         return ICON_OUTLINER_OB_EMPTY;
628                 default:
629                         return ICON_OBJECT_DATA;
630         }
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 /* Mesh Expander  ------------------------------------------- */
2015
2016 // TODO: just get this from RNA?
2017 static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
2018 {
2019         return ICON_MESH_DATA;
2020 }
2021
2022 /* get the appropriate flag(s) for the setting when it is valid  */
2023 static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2024 {
2025         /* clear extra return data first */
2026         *neg = 0;
2027         
2028         switch (setting) {
2029                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2030                         return ME_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_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type)
2049 {
2050         Mesh *me = (Mesh *)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(me->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 (me->adt)
2063                                 return GET_ACF_FLAG_PTR(me->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_DSMESH =
2074 {
2075         "Mesh Expander",                /* type name */
2076         
2077         acf_generic_dataexpand_color,   /* backdrop color */
2078         acf_generic_dataexpand_backdrop, /* backdrop */
2079         acf_generic_indention_1,        /* indent level */      // XXX this only works for compositing
2080         acf_generic_basic_offset,       /* offset */
2081
2082         acf_generic_idblock_name,       /* name */
2083         acf_generic_idblock_nameprop,   /* name prop */
2084         acf_dsmesh_icon,                /* icon */
2085
2086         acf_generic_dataexpand_setting_valid,   /* has setting */
2087         acf_dsmesh_setting_flag,                /* flag for setting */
2088         acf_dsmesh_setting_ptr                  /* pointer for setting */
2089 };
2090
2091 /* Lattice Expander  ------------------------------------------- */
2092
2093 // TODO: just get this from RNA?
2094 static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
2095 {
2096         return ICON_LATTICE_DATA;
2097 }
2098
2099 /* get the appropriate flag(s) for the setting when it is valid  */
2100 static int acf_dslat_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 LT_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_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type)
2126 {
2127         Lattice *lt = (Lattice *)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(lt->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 (lt->adt)
2140                                 return GET_ACF_FLAG_PTR(lt->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_DSLAT =
2151 {
2152         "Lattice 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_dslat_icon,                 /* icon */
2162
2163         acf_generic_dataexpand_setting_valid,   /* has setting */
2164         acf_dslat_setting_flag,                 /* flag for setting */
2165         acf_dslat_setting_ptr                   /* pointer for setting */
2166 };
2167
2168 /* Speaker Expander  ------------------------------------------- */
2169
2170 // TODO: just get this from RNA?
2171 static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
2172 {
2173         return ICON_SPEAKER;
2174 }
2175
2176 /* get the appropriate flag(s) for the setting when it is valid  */
2177 static int acf_dsspk_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 SPK_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_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type)
2203 {
2204         Speaker *spk = (Speaker *)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(spk->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 (spk->adt)
2217                                 return GET_ACF_FLAG_PTR(spk->adt->flag, type);
2218                         else
2219                                 return NULL;
2220                 
2221                 default: /* unsupported */
2222                         return NULL;
2223         }
2224 }
2225
2226 /* speaker expander type define */
2227 static bAnimChannelType ACF_DSSPK =
2228 {
2229         "Speaker Expander",             /* type name */
2230         
2231         acf_generic_dataexpand_color,   /* backdrop color */
2232         acf_generic_dataexpand_backdrop, /* backdrop */
2233         acf_generic_indention_1,        /* indent level */
2234         acf_generic_basic_offset,       /* offset */
2235
2236         acf_generic_idblock_name,       /* name */
2237         acf_generic_idblock_nameprop,   /* name prop */
2238         acf_dsspk_icon,                 /* icon */
2239
2240         acf_generic_dataexpand_setting_valid,   /* has setting */
2241         acf_dsspk_setting_flag,                 /* flag for setting */
2242         acf_dsspk_setting_ptr                   /* pointer for setting */
2243 };
2244
2245 /* ShapeKey Entry  ------------------------------------------- */
2246
2247 /* name for ShapeKey */
2248 static void acf_shapekey_name(bAnimListElem *ale, char *name)
2249 {
2250         KeyBlock *kb = (KeyBlock *)ale->data;
2251         
2252         /* just copy the name... */
2253         if (kb && name) {
2254                 /* if the KeyBlock had a name, use it, otherwise use the index */
2255                 if (kb->name[0])
2256                         BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
2257                 else
2258                         BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, "Key %d", ale->index);
2259         }
2260 }
2261
2262 /* name property for ShapeKey entries */
2263 static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
2264 {
2265         KeyBlock *kb = (KeyBlock *)ale->data;
2266         
2267         /* if the KeyBlock had a name, use it, otherwise use the index */
2268         if (kb && kb->name[0]) {
2269                 RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
2270                 *prop = RNA_struct_name_property(ptr->type);
2271                 
2272                 return (*prop != NULL);
2273         }
2274         
2275         return 0;
2276 }
2277
2278 /* check if some setting exists for this channel */
2279 static short acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2280 {
2281         switch (setting) {
2282                 case ACHANNEL_SETTING_SELECT: /* selected */
2283                 case ACHANNEL_SETTING_MUTE: /* muted */
2284                 case ACHANNEL_SETTING_PROTECT: /* protected */
2285                         return 1;
2286                         
2287                 /* nothing else is supported */
2288                 default:
2289                         return 0;
2290         }
2291 }
2292
2293 /* get the appropriate flag(s) for the setting when it is valid  */
2294 static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2295 {
2296         /* clear extra return data first */
2297         *neg = 0;
2298         
2299         switch (setting) {
2300                 case ACHANNEL_SETTING_MUTE: /* mute */
2301                         return KEYBLOCK_MUTE;
2302                 
2303                 case ACHANNEL_SETTING_SELECT: /* selected */
2304                         return KEYBLOCK_SEL;
2305                 
2306                 case ACHANNEL_SETTING_PROTECT: /* locked */
2307                         return KEYBLOCK_LOCKED;
2308                 
2309                 default: /* unsupported */
2310                         return 0;
2311         }
2312 }
2313
2314 /* get pointer to the setting */
2315 static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
2316 {
2317         KeyBlock *kb = (KeyBlock *)ale->data;
2318         
2319         /* clear extra return data first */
2320         *type = 0;
2321         
2322         switch (setting) {
2323                 case ACHANNEL_SETTING_SELECT: /* selected */
2324                 case ACHANNEL_SETTING_MUTE: /* muted */
2325                 case ACHANNEL_SETTING_PROTECT: /* protected */
2326                         return GET_ACF_FLAG_PTR(kb->flag, type);
2327                 
2328                 default: /* unsupported */
2329                         return NULL;
2330         }
2331 }
2332
2333 /* shapekey expander type define */
2334 static bAnimChannelType ACF_SHAPEKEY =
2335 {
2336         "Shape Key",                    /* type name */
2337         
2338         acf_generic_channel_color,      /* backdrop color */
2339         acf_generic_channel_backdrop,   /* backdrop */
2340         acf_generic_indention_0,        /* indent level */
2341         acf_generic_basic_offset,       /* offset */
2342
2343         acf_shapekey_name,              /* name */
2344         acf_shapekey_nameprop,          /* name prop */
2345         NULL,                           /* icon */
2346
2347         acf_shapekey_setting_valid,     /* has setting */
2348         acf_shapekey_setting_flag,      /* flag for setting */
2349         acf_shapekey_setting_ptr        /* pointer for setting */
2350 };
2351
2352 /* GPencil Datablock ------------------------------------------- */
2353
2354 /* get backdrop color for gpencil datablock widget */
2355 static void acf_gpd_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
2356 {
2357         /* these are ID-blocks, but not exactly standalone... */
2358         UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
2359 }
2360
2361 // TODO: just get this from RNA?
2362 static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
2363 {
2364         return ICON_GREASEPENCIL;
2365 }
2366
2367 /* check if some setting exists for this channel */
2368 static short acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2369 {
2370         switch (setting) {
2371                 /* only select and expand supported */
2372                 case ACHANNEL_SETTING_SELECT:
2373                 case ACHANNEL_SETTING_EXPAND:
2374                         return 1;
2375                         
2376                 default:
2377                         return 0;
2378         }
2379 }
2380
2381 /* get the appropriate flag(s) for the setting when it is valid  */
2382 static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2383 {
2384         /* clear extra return data first */
2385         *neg = 0;
2386         
2387         switch (setting) {
2388                 case ACHANNEL_SETTING_SELECT: /* selected */
2389                         return AGRP_SELECTED;
2390                         
2391                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2392                         return GP_DATA_EXPAND;
2393         }
2394         
2395         /* this shouldn't happen */
2396         return 0;
2397 }
2398
2399 /* get pointer to the setting */
2400 static void *acf_gpd_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
2401 {
2402         bGPdata *gpd = (bGPdata *)ale->data;
2403         
2404         /* all flags are just in gpd->flag for now... */
2405         return GET_ACF_FLAG_PTR(gpd->flag, type);
2406 }
2407
2408 /* gpencil datablock type define */
2409 static bAnimChannelType ACF_GPD = 
2410 {
2411         "GPencil Datablock",            /* type name */
2412         
2413         acf_gpd_color,                  /* backdrop color */
2414         acf_group_backdrop,             /* backdrop */
2415         acf_generic_indention_0,        /* indent level */
2416         acf_generic_group_offset,       /* offset */
2417
2418         acf_generic_idblock_name,       /* name */
2419         acf_generic_idfill_nameprop,    /* name prop */
2420         acf_gpd_icon,                   /* icon */
2421
2422         acf_gpd_setting_valid,          /* has setting */
2423         acf_gpd_setting_flag,           /* flag for setting */
2424         acf_gpd_setting_ptr             /* pointer for setting */
2425 };
2426
2427 /* GPencil Layer ------------------------------------------- */
2428
2429 /* name for grease pencil layer entries */
2430 static void acf_gpl_name(bAnimListElem *ale, char *name)
2431 {
2432         bGPDlayer *gpl = (bGPDlayer *)ale->data;
2433         
2434         if (gpl && name)
2435                 BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
2436 }
2437
2438 /* name property for grease pencil layer entries */
2439 static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
2440 {
2441         if (ale->data) {
2442                 RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
2443                 *prop = RNA_struct_name_property(ptr->type);
2444                 
2445                 return (*prop != NULL);
2446         }
2447         
2448         return 0;
2449 }
2450
2451 /* check if some setting exists for this channel */
2452 static short acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2453 {
2454         switch (setting) {
2455                 /* unsupported */
2456                 case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
2457                 case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
2458                         return 0;
2459                 
2460                 /* always available */
2461                 default:
2462                         return 1;
2463         }
2464 }
2465
2466 /* get the appropriate flag(s) for the setting when it is valid  */
2467 static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2468 {
2469         /* clear extra return data first */
2470         *neg = 0;
2471         
2472         switch (setting) {
2473                 case ACHANNEL_SETTING_SELECT: /* selected */
2474                         return GP_LAYER_SELECT;
2475                         
2476                 case ACHANNEL_SETTING_MUTE: /* muted */
2477                         return GP_LAYER_HIDE;
2478                         
2479                 case ACHANNEL_SETTING_PROTECT: /* protected */
2480                         // *neg = 1; - if we change this to edtiability
2481                         return GP_LAYER_LOCKED;
2482                         
2483                 default: /* unsupported */
2484                         return 0;
2485         }
2486 }
2487
2488 /* get pointer to the setting */
2489 static void *acf_gpl_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
2490 {
2491         bGPDlayer *gpl = (bGPDlayer *)ale->data;
2492         
2493         /* all flags are just in agrp->flag for now... */
2494         return GET_ACF_FLAG_PTR(gpl->flag, type);
2495 }
2496
2497 /* grease pencil layer type define */
2498 static bAnimChannelType ACF_GPL = 
2499 {
2500         "GPencil Layer",                /* type name */
2501         
2502         acf_generic_channel_color,      /* backdrop color */
2503         acf_generic_channel_backdrop,   /* backdrop */
2504         acf_generic_indention_flexible, /* indent level */
2505         acf_generic_group_offset,       /* offset */
2506         
2507         acf_gpl_name,                   /* name */
2508         acf_gpl_name_prop,              /* name prop */
2509         NULL,                           /* icon */
2510         
2511         acf_gpl_setting_valid,          /* has setting */
2512         acf_gpl_setting_flag,           /* flag for setting */
2513         acf_gpl_setting_ptr             /* pointer for setting */
2514 };
2515
2516
2517 /* Mask Datablock ------------------------------------------- */
2518
2519 /* get backdrop color for mask datablock widget */
2520 static void acf_mask_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
2521 {
2522         /* these are ID-blocks, but not exactly standalone... */
2523         UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
2524 }
2525
2526 // TODO: just get this from RNA?
2527 static int acf_mask_icon(bAnimListElem *UNUSED(ale))
2528 {
2529         return ICON_GREASEPENCIL; // MASK_TODO - need real icon
2530 }
2531
2532 /* check if some setting exists for this channel */
2533 static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2534 {
2535         switch (setting) {
2536                 /* only select and expand supported */
2537                 case ACHANNEL_SETTING_SELECT:
2538                 case ACHANNEL_SETTING_EXPAND:
2539                         return 1;
2540                 
2541                 default:
2542                         return 0;
2543         }
2544 }
2545
2546 /* get the appropriate flag(s) for the setting when it is valid  */
2547 static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2548 {
2549         /* clear extra return data first */
2550         *neg = 0;
2551         
2552         switch (setting) {
2553                 case ACHANNEL_SETTING_SELECT: /* selected */
2554                         return AGRP_SELECTED;
2555                 
2556                 case ACHANNEL_SETTING_EXPAND: /* expanded */
2557                         return MASK_ANIMF_EXPAND;
2558         }
2559         
2560         /* this shouldn't happen */
2561         return 0;
2562 }
2563
2564 /* get pointer to the setting */
2565 static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
2566 {
2567         Mask *mask = (Mask *)ale->data;
2568         
2569         /* all flags are just in mask->flag for now... */
2570         return GET_ACF_FLAG_PTR(mask->flag, type);
2571 }
2572
2573 /* mask datablock type define */
2574 static bAnimChannelType ACF_MASKDATA =
2575 {
2576         "Mask Datablock",            /* type name */
2577         
2578         acf_mask_color,                  /* backdrop color */
2579         acf_group_backdrop,             /* backdrop */
2580         acf_generic_indention_0,        /* indent level */
2581         acf_generic_group_offset,       /* offset */
2582         
2583         acf_generic_idblock_name,       /* name */
2584         acf_generic_idfill_nameprop,    /* name prop */
2585         acf_mask_icon,                   /* icon */
2586         
2587         acf_mask_setting_valid,          /* has setting */
2588         acf_mask_setting_flag,           /* flag for setting */
2589         acf_mask_setting_ptr             /* pointer for setting */
2590 };
2591
2592 /* Mask Layer ------------------------------------------- */
2593
2594 /* name for grease pencil layer entries */
2595 static void acf_masklay_name(bAnimListElem *ale, char *name)
2596 {
2597         MaskLayer *masklay = (MaskLayer *)ale->data;
2598         
2599         if (masklay && name)
2600                 BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
2601 }
2602
2603 /* name property for grease pencil layer entries */
2604 static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
2605 {
2606         if (ale->data) {
2607                 RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
2608                 *prop = RNA_struct_name_property(ptr->type);
2609                 
2610                 return (*prop != NULL);
2611         }
2612
2613         return 0;
2614 }
2615
2616 /* check if some setting exists for this channel */
2617 static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
2618 {
2619         switch (setting) {
2620                 /* unsupported */
2621                 case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */
2622                 case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
2623                         return 0;
2624                 
2625                 /* always available */
2626                 default:
2627                         return 1;
2628         }
2629 }
2630
2631 /* get the appropriate flag(s) for the setting when it is valid  */
2632 static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
2633 {
2634         /* clear extra return data first */
2635         *neg = 0;
2636         
2637         switch (setting) {
2638                 case ACHANNEL_SETTING_SELECT: /* selected */
2639                         return MASK_LAYERFLAG_SELECT;
2640                 
2641 //              case ACHANNEL_SETTING_MUTE: /* muted */
2642 //                      return GP_LAYER_HIDE;
2643                 
2644                 case ACHANNEL_SETTING_PROTECT: /* protected */
2645                         // *neg = 1; - if we change this to edtiability
2646                         return MASK_LAYERFLAG_LOCKED;
2647                 
2648                 default: /* unsupported */
2649                         return 0;
2650         }
2651 }
2652
2653 /* get pointer to the setting */
2654 static void *acf_masklay_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
2655 {
2656         MaskLayer *masklay = (MaskLayer *)ale->data;
2657
2658         /* all flags are just in agrp->flag for now... */
2659         return GET_ACF_FLAG_PTR(masklay->flag, type);
2660 }
2661
2662 /* grease pencil layer type define */
2663 static bAnimChannelType ACF_MASKLAYER =
2664 {
2665         "Mask Layer",                /* type name */
2666
2667         acf_generic_channel_color,      /* backdrop color */
2668         acf_generic_channel_backdrop,   /* backdrop */
2669         acf_generic_indention_flexible, /* indent level */
2670         acf_generic_group_offset,       /* offset */
2671
2672         acf_masklay_name,                   /* name */
2673         acf_masklay_name_prop,              /* name prop */
2674         NULL,                           /* icon */
2675
2676         acf_masklay_setting_valid,          /* has setting */
2677         acf_masklay_setting_flag,           /* flag for setting */
2678         acf_masklay_setting_ptr             /* pointer for setting */
2679 };
2680
2681
2682 /* *********************************************** */
2683 /* Type Registration and General Access */
2684
2685 /* These globals only ever get directly accessed in this file */
2686 static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES];
2687 static short ACF_INIT = 1; /* when non-zero, the list needs to be updated */
2688
2689 /* Initialize type info definitions */
2690 static void ANIM_init_channel_typeinfo_data(void)
2691 {
2692         int type = 0;
2693         
2694         /* start initializing if necessary... */
2695         if (ACF_INIT) {
2696                 ACF_INIT = 0;
2697                 
2698                 animchannelTypeInfo[type++] = NULL;              /* None */
2699                 animchannelTypeInfo[type++] = NULL;              /* AnimData */
2700                 animchannelTypeInfo[type++] = NULL;              /* Special */
2701                 
2702                 animchannelTypeInfo[type++] = &ACF_SUMMARY;      /* Motion Summary */
2703                 
2704                 animchannelTypeInfo[type++] = &ACF_SCENE;        /* Scene */
2705                 animchannelTypeInfo[type++] = &ACF_OBJECT;       /* Object */
2706                 animchannelTypeInfo[type++] = &ACF_GROUP;        /* Group */
2707                 animchannelTypeInfo[type++] = &ACF_FCURVE;       /* F-Curve */
2708                 
2709                 animchannelTypeInfo[type++] = &ACF_FILLACTD;     /* Object Action Expander */
2710                 animchannelTypeInfo[type++] = &ACF_FILLDRIVERS;  /* Drivers Expander */
2711                 
2712                 animchannelTypeInfo[type++] = &ACF_DSMAT;        /* Material Channel */
2713                 animchannelTypeInfo[type++] = &ACF_DSLAM;        /* Lamp Channel */
2714                 animchannelTypeInfo[type++] = &ACF_DSCAM;        /* Camera Channel */
2715                 animchannelTypeInfo[type++] = &ACF_DSCUR;        /* Curve Channel */
2716                 animchannelTypeInfo[type++] = &ACF_DSSKEY;       /* ShapeKey Channel */
2717                 animchannelTypeInfo[type++] = &ACF_DSWOR;        /* World Channel */
2718                 animchannelTypeInfo[type++] = &ACF_DSNTREE;      /* NodeTree Channel */
2719                 animchannelTypeInfo[type++] = &ACF_DSPART;       /* Particle Channel */
2720                 animchannelTypeInfo[type++] = &ACF_DSMBALL;      /* MetaBall Channel */
2721                 animchannelTypeInfo[type++] = &ACF_DSARM;        /* Armature Channel */
2722                 animchannelTypeInfo[type++] = &ACF_DSMESH;       /* Mesh Channel */
2723                 animchannelTypeInfo[type++] = &ACF_DSTEX;        /* Texture Channel */
2724                 animchannelTypeInfo[type++] = &ACF_DSLAT;        /* Lattice Channel */
2725                 animchannelTypeInfo[type++] = &ACF_DSSPK;        /* Speaker Channel */
2726                 
2727                 animchannelTypeInfo[type++] = &ACF_SHAPEKEY;     /* ShapeKey */
2728                 
2729                 animchannelTypeInfo[type++] = &ACF_GPD;          /* Grease Pencil Datablock */
2730                 animchannelTypeInfo[type++] = &ACF_GPL;          /* Grease Pencil Layer */
2731                 
2732                 animchannelTypeInfo[type++] = &ACF_MASKDATA;     /* Mask Datablock */
2733                 animchannelTypeInfo[type++] = &ACF_MASKLAYER;    /* Mask Layer */
2734                 
2735                 // TODO: these types still need to be implemented!!!
2736                 // probably need a few extra flags for these special cases...
2737                 animchannelTypeInfo[type++] = NULL;              /* NLA Track */
2738                 animchannelTypeInfo[type++] = NULL;              /* NLA Action */
2739         }
2740
2741
2742 /* Get type info from given channel type */
2743 bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
2744 {
2745         /* santiy checks */
2746         if (ale == NULL)
2747                 return NULL;
2748                 
2749         /* init the typeinfo if not available yet... */
2750         ANIM_init_channel_typeinfo_data();
2751         
2752         /* check if type is in bounds... */
2753         if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
2754                 return animchannelTypeInfo[ale->type];
2755         else
2756                 return NULL;
2757 }
2758
2759 /* --------------------------- */
2760
2761 /* Print debug info string for the given channel */
2762 void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
2763 {
2764         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
2765         
2766         /* print indents */
2767         for (; indent_level > 0; indent_level--)
2768                 printf("  ");
2769         
2770         /* print info */
2771         if (acf) {
2772                 char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
2773                 
2774                 /* get UI name */
2775                 if (acf->name)
2776                         acf->name(ale, name);
2777                 else
2778                         BLI_strncpy(name, "<No name>", sizeof(name));
2779
2780                 /* print type name + ui name */
2781                 printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
2782         }
2783         else if (ale)
2784                 printf("ChanType: <Unknown - %d>\n", ale->type);
2785         else
2786                 printf("<Invalid channel - NULL>\n");
2787 }
2788
2789 /* --------------------------- */
2790
2791 /* Check if some setting for a channel is enabled 
2792  * Returns: 1 = On, 0 = Off, -1 = Invalid
2793  */
2794 short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting)
2795 {
2796         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
2797         
2798         /* 1) check that the setting exists for the current context */
2799         if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
2800                 /* 2) get pointer to check for flag in, and the flag to check for */
2801                 short negflag, ptrsize;
2802                 int flag;
2803                 void *ptr;
2804                 
2805                 flag = acf->setting_flag(ac, setting, &negflag);
2806                 ptr = acf->setting_ptr(ale, setting, &ptrsize);
2807                 
2808                 /* check if flag is enabled */
2809                 if (ptr && flag) {
2810                         switch (ptrsize) {
2811                                 case sizeof(int):   /* integer pointer for setting */
2812                                 {
2813                                         int *val = (int *)ptr;
2814                                         
2815                                         if (negflag)
2816                                                 return ((*val) & flag) == 0;
2817                                         else
2818                                                 return ((*val) & flag) != 0;
2819                                 }
2820                                 break;
2821                                         
2822                                 case sizeof(short): /* short pointer for setting */
2823                                 {
2824                                         short *val = (short *)ptr;
2825                                         
2826                                         if (negflag)
2827                                                 return ((*val) & flag) == 0;
2828                                         else
2829                                                 return ((*val) & flag) != 0;
2830                                 }
2831                                 break;
2832                                         
2833                                 case sizeof(char):  /* char pointer for setting */
2834                                 {
2835                                         char *val = (char *)ptr;
2836                                         
2837                                         if (negflag)
2838                                                 return ((*val) & flag) == 0;
2839                                         else
2840                                                 return ((*val) & flag) != 0;
2841                                 }
2842                                 break;
2843                         }
2844                 }
2845         }
2846         
2847         /* not found... */
2848         return -1;
2849 }       
2850
2851
2852 /* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
2853 #define ACF_SETTING_SET(sval, sflag, smode) \
2854         { \
2855                 if (negflag) { \
2856                         if (smode == ACHANNEL_SETFLAG_INVERT) (sval) ^= (sflag); \
2857                         else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \
2858                         else (sval) |= (sflag); \
2859                 } \
2860                 else { \
2861                         if (smode == ACHANNEL_SETFLAG_INVERT) (sval) ^= (sflag); \
2862                         else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \
2863                         else (sval) &= ~(sflag); \
2864                 } \
2865         } (void)0
2866
2867 /* Change value of some setting for a channel 
2868  *      - setting: eAnimChannel_Settings
2869  *      - mode: eAnimChannels_SetFlag
2870  */
2871 void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, short mode)
2872 {
2873         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
2874         
2875         /* 1) check that the setting exists for the current context */
2876         if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
2877                 /* 2) get pointer to check for flag in, and the flag to check for */
2878                 short negflag, ptrsize;
2879                 int flag;
2880                 void *ptr;
2881                 
2882                 flag = acf->setting_flag(ac, setting, &negflag);
2883                 ptr = acf->setting_ptr(ale, setting, &ptrsize);
2884                 
2885                 /* check if flag is enabled */
2886                 if (ptr && flag) {
2887                         switch (ptrsize) {
2888                                 case sizeof(int):   /* integer pointer for setting */
2889                                 {
2890                                         int *val = (int *)ptr;
2891                                         ACF_SETTING_SET(*val, flag, mode);
2892                                 }
2893                                 break;
2894                                         
2895                                 case sizeof(short): /* short pointer for setting */
2896                                 {
2897                                         short *val = (short *)ptr;
2898                                         ACF_SETTING_SET(*val, flag, mode);
2899                                 }
2900                                 break;
2901                                         
2902                                 case sizeof(char):  /* char pointer for setting */
2903                                 {
2904                                         char *val = (char *)ptr;
2905                                         ACF_SETTING_SET(*val, flag, mode);
2906                                 }
2907                                 break;
2908                         }
2909                 }
2910         }
2911 }
2912
2913 /* --------------------------- */
2914
2915 // XXX hardcoded size of icons
2916 #define ICON_WIDTH      17
2917 // XXX hardcoded width of sliders
2918 #define SLIDER_WIDTH    80
2919 // XXX hardcoded width of rename textboxes
2920 #define RENAME_TEXT_WIDTH 100
2921
2922 /* Draw the given channel */
2923 // TODO: make this use UI controls for the buttons
2924 void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
2925 {
2926         bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
2927         View2D *v2d = &ac->ar->v2d;
2928         short selected, offset;
2929         float y, ymid, ytext;
2930         
2931         /* sanity checks - don't draw anything */
2932         if (ELEM(NULL, acf, ale))
2933                 return;
2934         
2935         /* get initial offset */
2936         if (acf->get_offset)
2937                 offset = acf->get_offset(ac, ale);
2938         else
2939                 offset = 0;
2940                 
2941         /* calculate appropriate y-coordinates for icon buttons 
2942          *      7 is hardcoded factor for half-height of icons
2943          */
2944         y = (ymaxc - yminc) / 2 + yminc;
2945         ymid = y - 7;
2946         /* y-coordinates for text is only 4 down from middle */
2947         ytext = y - 4;
2948         
2949         /* check if channel is selected */
2950         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
2951                 selected = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
2952         else
2953                 selected = 0;
2954                 
2955         /* set blending again, as may not be set in previous step */
2956         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2957         glEnable(GL_BLEND);
2958         
2959         /* step 1) draw backdrop ...........................................  */
2960         if (acf->draw_backdrop)
2961                 acf->draw_backdrop(ac, ale, yminc, ymaxc);
2962                 
2963         /* step 2) draw expand widget ....................................... */
2964         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
2965                 /* just skip - drawn as widget now */
2966                 offset += ICON_WIDTH; 
2967         }
2968                 
2969         /* step 3) draw icon ............................................... */
2970         if (acf->icon) {
2971                 UI_icon_draw(offset, ymid, acf->icon(ale));
2972                 offset += ICON_WIDTH; 
2973         }
2974         
2975         /* turn off blending, since not needed anymore... */
2976         glDisable(GL_BLEND);
2977                 
2978         /* step 4) draw special toggles  .................................
2979          *      - in Graph Editor, checkboxes for visibility in curves area
2980          *      - in NLA Editor, glowing dots for solo/not solo...
2981          */
2982         if (ac->sl) {
2983                 if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
2984                         /* for F-Curves, draw color-preview of curve behind checkbox */
2985                         if (ale->type == ANIMTYPE_FCURVE) {
2986                                 FCurve *fcu = (FCurve *)ale->data;
2987                                 
2988                                 /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever 
2989                                  * color the curve has stored 
2990                                  */
2991                                 glColor3fv(fcu->color);
2992                                 
2993                                 /* just a solid color rect
2994                                  *  hardcoded 17 pixels width is slightly wider than icon width, so that
2995                                  *      there's a slight border around it 
2996                                  */
2997                                 glRectf(offset, yminc, offset + 17, ymaxc);
2998                         }
2999                         
3000                         /* icon is drawn as widget now... */
3001                         offset += ICON_WIDTH; 
3002                 }
3003                 else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
3004                         /* just skip - drawn as widget now */
3005                         offset += ICON_WIDTH; 
3006                 }
3007         }
3008
3009         /* step 5) draw name ............................................... */
3010         /* TODO: when renaming, we might not want to draw this, especially if name happens to be longer than channel */
3011         if (acf->name) {
3012                 char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
3013
3014                 /* set text color */
3015                 /* XXX: if active, highlight differently? */
3016                 if (selected)
3017                         UI_ThemeColor(TH_TEXT_HI);
3018                 else
3019                         UI_ThemeColor(TH_TEXT);
3020
3021                 /* get name */
3022                 acf->name(ale, name);
3023
3024                 offset += 3;
3025                 UI_DrawString(offset, ytext, name);
3026
3027                 /* draw red underline if channel is disabled */
3028                 if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) {
3029                         /* FIXME: replace hardcoded color here, and check on extents! */
3030                         glColor3f(1.0f, 0.0f, 0.0f);
3031                         glLineWidth(2.0);
3032                         fdrawline((float)(offset), yminc,
3033                                   (float)(v2d->cur.xmax), yminc);
3034                         glLineWidth(1.0);
3035                 }
3036         }
3037
3038         /* step 6) draw backdrops behidn mute+protection toggles + (sliders) ....................... */
3039         /* reset offset - now goes from RHS of panel */
3040         offset = 0;
3041
3042         /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space */
3043
3044         if (v2d) {
3045                 short draw_sliders = 0;
3046                 float color[3];
3047                 
3048                 /* get and set backdrop color */
3049                 acf->get_backdrop_color(ac, ale, color);
3050                 glColor3fv(color);
3051                 
3052                 /* check if we need to show the sliders */
3053                 if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
3054                         switch (ac->spacetype) {
3055                                 case SPACE_ACTION:
3056                                 {
3057                                         SpaceAction *saction = (SpaceAction *)ac->sl;
3058                                         draw_sliders = (saction->flag & SACTION_SLIDERS);
3059                                 }
3060                                 break;
3061                                 case SPACE_IPO:
3062                                 {
3063                                         SpaceIpo *sipo = (SpaceIpo *)ac->sl;
3064                                         draw_sliders = (sipo->flag & SIPO_SLIDERS);
3065                                 }
3066                                 break;
3067                         }
3068                 }
3069
3070                 /* check if there's enough space for the toggles if the sliders are drawn too */
3071                 if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2) ) {
3072                         /* protect... */
3073                         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
3074                                 offset += ICON_WIDTH;
3075                         /* mute... */
3076                         if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
3077                                 offset += ICON_WIDTH;
3078                 }
3079                 
3080                 /* draw slider
3081                  *      - even if we can draw sliders for this view, we must also check that the channel-type supports them
3082                  *        (only only F-Curves really can support them for now)
3083                  *      - slider should start before the toggles (if they're visible) to keep a clean line down the side
3084                  */
3085                 if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
3086                         /* adjust offset */
3087                         offset += SLIDER_WIDTH;
3088                 }
3089                 
3090                &