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