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