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