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