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