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