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