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