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