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