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