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