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