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