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