Blender V2.61 - r43446

anim_channels_defines.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Joshua Leung
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <stdio.h>
00032 
00033 #include "MEM_guardedalloc.h"
00034 
00035 #include "BLI_blenlib.h"
00036 #include "BLI_math.h"
00037 #include "BLI_utildefines.h"
00038 
00039 #include "DNA_anim_types.h"
00040 #include "DNA_armature_types.h"
00041 #include "DNA_camera_types.h"
00042 #include "DNA_object_types.h"
00043 #include "DNA_particle_types.h"
00044 #include "DNA_screen_types.h"
00045 #include "DNA_scene_types.h"
00046 #include "DNA_space_types.h"
00047 #include "DNA_key_types.h"
00048 #include "DNA_lamp_types.h"
00049 #include "DNA_lattice_types.h"
00050 #include "DNA_mesh_types.h"
00051 #include "DNA_material_types.h"
00052 #include "DNA_meta_types.h"
00053 #include "DNA_node_types.h"
00054 #include "DNA_world_types.h"
00055 #include "DNA_gpencil_types.h"
00056 #include "DNA_speaker_types.h"
00057 
00058 #include "RNA_access.h"
00059 
00060 #include "BKE_curve.h"
00061 #include "BKE_key.h"
00062 #include "BKE_context.h"
00063 #include "BKE_utildefines.h" /* FILE_MAX */
00064 
00065 #include "UI_interface.h"
00066 #include "UI_interface_icons.h"
00067 #include "UI_resources.h"
00068 
00069 #include "ED_anim_api.h"
00070 #include "ED_keyframing.h"
00071 
00072 #include "BIF_gl.h"
00073 #include "BIF_glutil.h"
00074 
00075 #include "WM_api.h"
00076 #include "WM_types.h"
00077 
00078 /* *********************************************** */
00079 // XXX constant defines to be moved elsewhere?
00080 
00081 /* extra padding for lengths (to go under scrollers) */
00082 #define EXTRA_SCROLL_PAD    100.0f
00083 
00084 /* size of indent steps */
00085 #define INDENT_STEP_SIZE    7
00086 
00087 #define ANIM_CHAN_NAME_SIZE 256
00088 
00089 /* macros used for type defines */
00090     /* get the pointer used for some flag */
00091 #define GET_ACF_FLAG_PTR(ptr) \
00092     { \
00093         *type= sizeof((ptr)); \
00094         return &(ptr); \
00095     } 
00096 
00097 
00098 /* *********************************************** */
00099 /* Generic Functions (Type independent) */
00100 
00101 /* Draw Backdrop ---------------------------------- */
00102 
00103 /* get backdrop color for top-level widgets (Scene and Object only) */
00104 static void acf_generic_root_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
00105 {
00106     /* darker blue for top-level widgets */
00107     UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, color);
00108 }
00109 
00110 /* backdrop for top-level widgets (Scene and Object only) */
00111 static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
00112 {
00113     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00114     View2D *v2d= &ac->ar->v2d;
00115     short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
00116     short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
00117     float color[3];
00118     
00119     /* set backdrop drawing color */
00120     acf->get_backdrop_color(ac, ale, color);
00121     glColor3fv(color);
00122     
00123     /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
00124     uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
00125     uiDrawBox(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
00126 }
00127 
00128 
00129 /* get backdrop color for data expanders under top-level Scene/Object */
00130 static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
00131 {
00132     /* lighter color than top-level widget */
00133     UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, color);
00134 }
00135 
00136 /* backdrop for data expanders under top-level Scene/Object */
00137 static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
00138 {
00139     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00140     View2D *v2d= &ac->ar->v2d;
00141     short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
00142     float color[3];
00143     
00144     /* set backdrop drawing color */
00145     acf->get_backdrop_color(ac, ale, color);
00146     glColor3fv(color);
00147     
00148     /* no rounded corner - just rectangular box */
00149     glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
00150 }
00151 
00152 /* get backdrop color for generic channels */
00153 static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float *color)
00154 {
00155     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00156     SpaceAction *saction = NULL;
00157     bActionGroup *grp = NULL;
00158     short indent= (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
00159     
00160     /* get context info needed... */
00161     if ((ac->sl) && (ac->spacetype == SPACE_ACTION))
00162         saction= (SpaceAction *)ac->sl;
00163         
00164     if (ale->type == ANIMTYPE_FCURVE) {
00165         FCurve *fcu= (FCurve *)ale->data;
00166         grp= fcu->grp;
00167     }
00168     
00169     /* set color for normal channels 
00170      *  - use 3 shades of color group/standard color for 3 indention level
00171      *  - only use group colors if allowed to, and if actually feasible
00172      */
00173     if ( (saction && !(saction->flag & SACTION_NODRAWGCOLORS)) && 
00174          ((grp) && (grp->customCol)) ) 
00175     {
00176         unsigned char cp[3];
00177         
00178         if (indent == 2) {
00179             copy_v3_v3_char((char *)cp, grp->cs.solid);
00180         }
00181         else if (indent == 1) {
00182             copy_v3_v3_char((char *)cp, grp->cs.select);
00183         }
00184         else {
00185             copy_v3_v3_char((char *)cp, grp->cs.active);
00186         }
00187         
00188         /* copy the colors over, transforming from bytes to floats */
00189         rgb_byte_to_float(cp, color);
00190     }
00191     else {
00192         // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
00193         int colOfs= 20 - 20*indent;
00194         UI_GetThemeColorShade3fv(TH_HEADER, colOfs, color);
00195     }
00196 }
00197 
00198 /* backdrop for generic channels */
00199 static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
00200 {
00201     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00202     View2D *v2d= &ac->ar->v2d;
00203     short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
00204     float color[3];
00205     
00206     /* set backdrop drawing color */
00207     acf->get_backdrop_color(ac, ale, color);
00208     glColor3fv(color);
00209     
00210     /* no rounded corners - just rectangular box */
00211     glRectf(offset, yminc,  v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
00212 }
00213 
00214 /* Indention + Offset ------------------------------------------- */
00215 
00216 /* indention level is always the value in the name */
00217 static short acf_generic_indention_0(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
00218 {
00219     return 0;
00220 }
00221 static short acf_generic_indention_1(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
00222 {
00223     return 1;
00224 }
00225 #if 0 // XXX not used
00226 static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
00227 {
00228     return 2;
00229 }
00230 #endif
00231 
00232 /* indention which varies with the grouping status */
00233 static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
00234 {
00235     short indent= 0;
00236     
00237     /* grouped F-Curves need extra level of indention */
00238     if (ale->type == ANIMTYPE_FCURVE) {
00239         FCurve *fcu= (FCurve *)ale->data;
00240         
00241         // TODO: we need some way of specifying that the indention color should be one less...
00242         if (fcu->grp)
00243             indent++;
00244     }
00245     
00246     /* no indention */
00247     return indent;
00248 }
00249 
00250 /* basic offset for channels derived from indention */
00251 static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
00252 {
00253     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00254     
00255     if (acf && acf->get_indent_level)
00256         return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
00257     else
00258         return 0;
00259 }
00260 
00261 /* offset based on nodetree type */
00262 static short acf_nodetree_rootType_offset(bNodeTree *ntree)
00263 {
00264     if (ntree) {
00265         switch (ntree->type) {
00266             case NTREE_SHADER:
00267                 /* 1 additional level (i.e. is indented one level in from material, 
00268                  * so shift all right by one step) 
00269                  */
00270                 return INDENT_STEP_SIZE; 
00271                 
00272             case NTREE_COMPOSIT:
00273                 /* no additional levels needed */
00274                 return 0; 
00275                 
00276             case NTREE_TEXTURE:
00277                 /* 2 additional levels */
00278                 return INDENT_STEP_SIZE*2; 
00279         }
00280     }
00281     
00282     // unknown
00283     return 0;
00284 }
00285 
00286 /* offset for groups + grouped entities */
00287 static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
00288 {
00289     short offset= acf_generic_basic_offset(ac, ale);
00290     
00291     if (ale->id) {
00292         /* texture animdata */
00293         if (GS(ale->id->name) == ID_TE) {
00294             offset += 21;
00295         }
00296         /* materials and particles animdata */
00297         else if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) 
00298             offset += 14;
00299             
00300         /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
00301         else if (ac->datatype != ANIMCONT_ACTION)
00302             offset += 14;
00303             
00304         /* nodetree animdata */
00305         if (GS(ale->id->name) == ID_NT) {
00306             offset += acf_nodetree_rootType_offset((bNodeTree*)ale->id);
00307         }
00308     }
00309     
00310     /* offset is just the normal type - i.e. based on indention */
00311     return offset;
00312 }
00313 
00314 /* Name ------------------------------------------- */
00315 
00316 /* name for ID block entries */
00317 static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
00318 {
00319     ID *id= (ID *)ale->data;    /* data pointed to should be an ID block */
00320     
00321     /* just copy the name... */
00322     if (id && name)
00323         BLI_strncpy(name, id->name+2, ANIM_CHAN_NAME_SIZE);
00324 }
00325 
00326 /* name property for ID block entries */
00327 static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
00328 {
00329     RNA_id_pointer_create(ale->id, ptr);
00330     *prop = RNA_struct_name_property(ptr->type);
00331     
00332     return (*prop != NULL);
00333 }
00334 
00335 
00336 /* name property for ID block entries which are just subheading "fillers" */
00337 static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
00338 {
00339     /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
00340     RNA_id_pointer_create(ale->data, ptr);
00341     *prop = RNA_struct_name_property(ptr->type);
00342     
00343     return (*prop != NULL);
00344 }
00345 
00346 /* Settings ------------------------------------------- */
00347 
00348 #if 0
00349 /* channel type has no settings */
00350 static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
00351 {
00352     return 0;
00353 }
00354 #endif
00355 
00356 /* check if some setting exists for this object-based data-expander (datablock only) */
00357 static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
00358 {
00359     switch (setting) {
00360         /* expand is always supported */
00361         case ACHANNEL_SETTING_EXPAND:
00362             return 1;
00363             
00364         /* mute is only supported for NLA */
00365         case ACHANNEL_SETTING_MUTE:
00366             return ((ac) && (ac->spacetype == SPACE_NLA));
00367             
00368         /* other flags are never supported */
00369         default:
00370             return 0;
00371     }
00372 }
00373 
00374 /* *********************************************** */
00375 /* Type Specific Functions + Defines */
00376 
00377 /* Animation Summary ----------------------------------- */
00378 
00379 /* get backdrop color for summary widget */
00380 static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
00381 {
00382     // FIXME: hardcoded color - same as the 'action' line in NLA
00383         // reddish color 
00384     color[0] = 0.8f;
00385     color[1] = 0.2f;
00386     color[2] = 0.0f;
00387 }
00388 
00389 /* backdrop for summary widget */
00390 static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
00391 {
00392     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00393     View2D *v2d= &ac->ar->v2d;
00394     float color[3];
00395     
00396     /* set backdrop drawing color */
00397     acf->get_backdrop_color(ac, ale, color);
00398     glColor3fv(color);
00399     
00400     /* rounded corners on LHS only 
00401      *  - top and bottom 
00402      *  - special hack: make the top a bit higher, since we are first... 
00403      */
00404     uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
00405     uiDrawBox(GL_POLYGON, 0,  yminc-2, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
00406 }
00407 
00408 /* name for summary entries */
00409 static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
00410 {
00411     if (name)
00412         BLI_strncpy(name, "DopeSheet Summary", ANIM_CHAN_NAME_SIZE);
00413 }
00414 
00415 // TODO: this is really a temp icon I think
00416 static int acf_summary_icon(bAnimListElem *UNUSED(ale))
00417 {
00418     return ICON_BORDERMOVE;
00419 }
00420 
00421 /* check if some setting exists for this channel */
00422 static short acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
00423 {
00424     /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
00425     return (setting == ACHANNEL_SETTING_EXPAND);
00426 }
00427 
00428 /* get the appropriate flag(s) for the setting when it is valid  */
00429 static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
00430 {
00431     if (setting == ACHANNEL_SETTING_EXPAND) {
00432         /* expanded */
00433         *neg= 1;
00434         return ADS_FLAG_SUMMARY_COLLAPSED;
00435     }
00436     else {
00437         /* unsupported */
00438         *neg= 0;
00439         return 0;
00440     }
00441 }
00442 
00443 /* get pointer to the setting */
00444 static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *type)
00445 {
00446     bAnimContext *ac= (bAnimContext *)ale->data;
00447     
00448     /* if data is valid, return pointer to active dopesheet's relevant flag 
00449      *  - this is restricted to DopeSheet/Action Editor only
00450      */
00451     if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
00452         SpaceAction *saction= (SpaceAction *)ac->sl;
00453         bDopeSheet *ads= &saction->ads;
00454         
00455         /* return pointer to DopeSheet's flag */
00456         GET_ACF_FLAG_PTR(ads->flag);
00457     }
00458     else {
00459         /* can't return anything useful - unsupported */
00460         *type= 0;
00461         return NULL;
00462     }
00463 }
00464 
00465 /* all animation summary (DopeSheet only) type define */
00466 static bAnimChannelType ACF_SUMMARY = 
00467 {
00468     "Summary",                          /* type name */
00469 
00470     acf_summary_color,                  /* backdrop color */
00471     acf_summary_backdrop,               /* backdrop */
00472     acf_generic_indention_0,            /* indent level */
00473     NULL,                               /* offset */
00474     
00475     acf_summary_name,                   /* name */
00476     NULL,                               /* name prop */
00477     acf_summary_icon,                   /* icon */
00478     
00479     acf_summary_setting_valid,          /* has setting */
00480     acf_summary_setting_flag,           /* flag for setting */
00481     acf_summary_setting_ptr             /* pointer for setting */
00482 };
00483 
00484 /* Scene ------------------------------------------- */
00485 
00486 // TODO: just get this from RNA?
00487 static int acf_scene_icon(bAnimListElem *UNUSED(ale))
00488 {
00489     return ICON_SCENE_DATA;
00490 }
00491 
00492 /* check if some setting exists for this channel */
00493 static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
00494 {
00495     switch (setting) {
00496         /* muted only in NLA */
00497         case ACHANNEL_SETTING_MUTE: 
00498             return ((ac) && (ac->spacetype == SPACE_NLA));
00499             
00500         /* visible only in Graph Editor */
00501         case ACHANNEL_SETTING_VISIBLE: 
00502             return ((ac) && (ac->spacetype == SPACE_IPO));
00503         
00504         /* only select and expand supported otherwise */
00505         case ACHANNEL_SETTING_SELECT:
00506         case ACHANNEL_SETTING_EXPAND:
00507             return 1;
00508             
00509         default:
00510             return 0;
00511     }
00512 }
00513 
00514 /* get the appropriate flag(s) for the setting when it is valid  */
00515 static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
00516 {
00517     /* clear extra return data first */
00518     *neg= 0;
00519     
00520     switch (setting) {
00521         case ACHANNEL_SETTING_SELECT: /* selected */
00522             return SCE_DS_SELECTED;
00523             
00524         case ACHANNEL_SETTING_EXPAND: /* expanded */
00525             *neg= 1;
00526             return SCE_DS_COLLAPSED;
00527             
00528         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
00529             return ADT_NLA_EVAL_OFF;
00530             
00531         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
00532             *neg= 1;
00533             return ADT_CURVES_NOT_VISIBLE;
00534             
00535         default: /* unsupported */
00536             return 0;
00537     }
00538 }
00539 
00540 /* get pointer to the setting */
00541 static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type)
00542 {
00543     Scene *scene= (Scene *)ale->data;
00544     
00545     /* clear extra return data first */
00546     *type= 0;
00547     
00548     switch (setting) {
00549         case ACHANNEL_SETTING_SELECT: /* selected */
00550             GET_ACF_FLAG_PTR(scene->flag);
00551             
00552         case ACHANNEL_SETTING_EXPAND: /* expanded */
00553             GET_ACF_FLAG_PTR(scene->flag);
00554             
00555         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
00556         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
00557             if (scene->adt)
00558                 GET_ACF_FLAG_PTR(scene->adt->flag)
00559             else
00560                 return NULL;
00561             
00562         default: /* unsupported */
00563             return NULL;
00564     }
00565 }
00566 
00567 /* scene type define */
00568 static bAnimChannelType ACF_SCENE = 
00569 {
00570     "Scene",                        /* type name */
00571 
00572     acf_generic_root_color,         /* backdrop color */
00573     acf_generic_root_backdrop,      /* backdrop */
00574     acf_generic_indention_0,        /* indent level */
00575     NULL,                           /* offset */
00576     
00577     acf_generic_idblock_name,       /* name */
00578     acf_generic_idblock_nameprop,   /* name prop */
00579     acf_scene_icon,                 /* icon */
00580     
00581     acf_scene_setting_valid,        /* has setting */
00582     acf_scene_setting_flag,         /* flag for setting */
00583     acf_scene_setting_ptr           /* pointer for setting */
00584 };
00585 
00586 /* Object ------------------------------------------- */
00587 
00588 static int acf_object_icon(bAnimListElem *ale)
00589 {
00590     Base *base= (Base *)ale->data;
00591     Object *ob= base->object;
00592     
00593     /* icon depends on object-type */
00594 
00595     switch (ob->type) {
00596         case OB_LAMP:
00597             return ICON_OUTLINER_OB_LAMP;
00598         case OB_MESH: 
00599             return ICON_OUTLINER_OB_MESH;
00600         case OB_CAMERA: 
00601             return ICON_OUTLINER_OB_CAMERA;
00602         case OB_CURVE: 
00603             return ICON_OUTLINER_OB_CURVE;
00604         case OB_MBALL: 
00605             return ICON_OUTLINER_OB_META;
00606         case OB_LATTICE: 
00607             return ICON_OUTLINER_OB_LATTICE;
00608         case OB_SPEAKER:
00609             return ICON_OUTLINER_OB_SPEAKER;
00610         case OB_ARMATURE:
00611             return ICON_OUTLINER_OB_ARMATURE;
00612         case OB_FONT: 
00613             return ICON_OUTLINER_OB_FONT;
00614         case OB_SURF: 
00615             return ICON_OUTLINER_OB_SURFACE;
00616         case OB_EMPTY: 
00617             return ICON_OUTLINER_OB_EMPTY;
00618         default:
00619             return ICON_OBJECT_DATA;
00620     }
00621     
00622 }
00623 
00624 /* name for object */
00625 static void acf_object_name(bAnimListElem *ale, char *name)
00626 {
00627     Base *base= (Base *)ale->data;
00628     Object *ob= base->object;
00629     
00630     /* just copy the name... */
00631     if (ob && name)
00632         BLI_strncpy(name, ob->id.name+2, ANIM_CHAN_NAME_SIZE);
00633 }
00634 
00635 /* check if some setting exists for this channel */
00636 static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
00637 {
00638     Base *base= (Base *)ale->data;
00639     Object *ob= base->object;
00640     
00641     switch (setting) {
00642         /* muted only in NLA */
00643         case ACHANNEL_SETTING_MUTE: 
00644             return ((ac) && (ac->spacetype == SPACE_NLA));
00645             
00646         /* visible only in Graph Editor */
00647         case ACHANNEL_SETTING_VISIBLE: 
00648             return ((ac) && (ac->spacetype == SPACE_IPO) && (ob->adt));
00649         
00650         /* only select and expand supported otherwise */
00651         case ACHANNEL_SETTING_SELECT:
00652         case ACHANNEL_SETTING_EXPAND:
00653             return 1;
00654             
00655         default:
00656             return 0;
00657     }
00658 }
00659 
00660 /* get the appropriate flag(s) for the setting when it is valid  */
00661 static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
00662 {
00663     /* clear extra return data first */
00664     *neg= 0;
00665     
00666     switch (setting) {
00667         case ACHANNEL_SETTING_SELECT: /* selected */
00668             return SELECT;
00669             
00670         case ACHANNEL_SETTING_EXPAND: /* expanded */
00671             *neg= 1;
00672             return OB_ADS_COLLAPSED;
00673             
00674         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
00675             return ADT_NLA_EVAL_OFF;
00676             
00677         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
00678             *neg= 1;
00679             return ADT_CURVES_NOT_VISIBLE;
00680             
00681         default: /* unsupported */
00682             return 0;
00683     }
00684 }
00685 
00686 /* get pointer to the setting */
00687 static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type)
00688 {
00689     Base *base= (Base *)ale->data;
00690     Object *ob= base->object;
00691     
00692     /* clear extra return data first */
00693     *type= 0;
00694     
00695     switch (setting) {
00696         case ACHANNEL_SETTING_SELECT: /* selected */
00697             GET_ACF_FLAG_PTR(ob->flag);
00698             
00699         case ACHANNEL_SETTING_EXPAND: /* expanded */
00700             GET_ACF_FLAG_PTR(ob->nlaflag); // xxx
00701             
00702         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
00703         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
00704             if (ob->adt)
00705                 GET_ACF_FLAG_PTR(ob->adt->flag)
00706             else
00707                 return NULL;
00708             
00709         default: /* unsupported */
00710             return NULL;
00711     }
00712 }
00713 
00714 /* object type define */
00715 static bAnimChannelType ACF_OBJECT = 
00716 {
00717     "Object",                       /* type name */
00718     
00719     acf_generic_root_color,         /* backdrop color */
00720     acf_generic_root_backdrop,      /* backdrop */
00721     acf_generic_indention_0,        /* indent level */
00722     NULL,                           /* offset */
00723     
00724     acf_object_name,                /* name */
00725     acf_generic_idblock_nameprop,   /* name prop */
00726     acf_object_icon,                /* icon */
00727     
00728     acf_object_setting_valid,       /* has setting */
00729     acf_object_setting_flag,        /* flag for setting */
00730     acf_object_setting_ptr          /* pointer for setting */
00731 };
00732 
00733 /* Group ------------------------------------------- */
00734 
00735 /* get backdrop color for group widget */
00736 static void acf_group_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float *color)
00737 {
00738     /* highlight only for action group channels */
00739     if (ale->flag & AGRP_ACTIVE)
00740         UI_GetThemeColorShade3fv(TH_GROUP_ACTIVE, 10, color);
00741     else
00742         UI_GetThemeColorShade3fv(TH_GROUP, 20, color);
00743 }
00744 
00745 /* backdrop for group widget */
00746 static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
00747 {
00748     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
00749     View2D *v2d= &ac->ar->v2d;
00750     short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
00751     short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
00752     float color[3];
00753     
00754     /* set backdrop drawing color */
00755     acf->get_backdrop_color(ac, ale, color);
00756     glColor3fv(color);
00757     
00758     /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
00759     uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
00760     uiDrawBox(GL_POLYGON, offset,  yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8);
00761 }
00762 
00763 /* name for group entries */
00764 static void acf_group_name(bAnimListElem *ale, char *name)
00765 {
00766     bActionGroup *agrp= (bActionGroup *)ale->data;
00767     
00768     /* just copy the name... */
00769     if (agrp && name)
00770         BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE);
00771 }
00772 
00773 /* name property for group entries */
00774 static short acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
00775 {
00776     RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr);
00777     *prop = RNA_struct_name_property(ptr->type);
00778     
00779     return (*prop != NULL);
00780 }
00781 
00782 /* check if some setting exists for this channel */
00783 static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
00784 {
00785     /* for now, all settings are supported, though some are only conditionally */
00786     switch (setting) {
00787         case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
00788             return (ac->spacetype==SPACE_IPO);
00789             
00790         default: /* always supported */
00791             return 1;
00792     }
00793 }
00794 
00795 /* get the appropriate flag(s) for the setting when it is valid  */
00796 static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg)
00797 {
00798     /* clear extra return data first */
00799     *neg= 0;
00800     
00801     switch (setting) {
00802         case ACHANNEL_SETTING_SELECT: /* selected */
00803             return AGRP_SELECTED;
00804             
00805         case ACHANNEL_SETTING_EXPAND: /* expanded */
00806         {
00807             /* NOTE: Graph Editor uses a different flag to everywhere else for this,
00808              * allowing different collapsing of groups there, since sharing the flag
00809              * proved to be a hazard for workflows...
00810              */
00811             return (ac->spacetype == SPACE_IPO) ? 
00812                         AGRP_EXPANDED_G :   /* Graph Editor case */
00813                         AGRP_EXPANDED;      /* DopeSheet and elsewhere */
00814         }
00815             
00816         case ACHANNEL_SETTING_MUTE: /* muted */
00817             return AGRP_MUTED;
00818             
00819         case ACHANNEL_SETTING_PROTECT: /* protected */
00820             //*neg= 1; - if we change this to edtiability
00821             return AGRP_PROTECTED;
00822             
00823         case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
00824             *neg= 1;
00825             return AGRP_NOTVISIBLE;
00826     }
00827     
00828     /* this shouldn't happen */
00829     return 0;
00830 }
00831 
00832 /* get pointer to the setting */
00833 static void *acf_group_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
00834 {
00835     bActionGroup *agrp= (bActionGroup *)ale->data;
00836     
00837     /* all flags are just in agrp->flag for now... */
00838     GET_ACF_FLAG_PTR(agrp->flag);
00839 }
00840 
00841 /* group type define */
00842 static bAnimChannelType ACF_GROUP = 
00843 {
00844     "Group",                        /* type name */
00845     
00846     acf_group_color,                /* backdrop color */
00847     acf_group_backdrop,             /* backdrop */
00848     acf_generic_indention_0,        /* indent level */
00849     acf_generic_group_offset,       /* offset */
00850     
00851     acf_group_name,                 /* name */
00852     acf_group_name_prop,            /* name prop */
00853     NULL,                           /* icon */
00854     
00855     acf_group_setting_valid,        /* has setting */
00856     acf_group_setting_flag,         /* flag for setting */
00857     acf_group_setting_ptr           /* pointer for setting */
00858 };
00859 
00860 /* F-Curve ------------------------------------------- */
00861 
00862 /* name for fcurve entries */
00863 static void acf_fcurve_name(bAnimListElem *ale, char *name)
00864 {
00865     getname_anim_fcurve(name, ale->id, ale->data);
00866 }
00867 
00868 /* check if some setting exists for this channel */
00869 static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
00870 {
00871     FCurve *fcu= (FCurve *)ale->data;
00872     
00873     switch (setting) {
00874         /* unsupported */
00875         case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
00876             return 0;
00877         
00878         /* conditionally available */
00879         case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
00880             if (fcu->bezt)
00881                 return 1;
00882             else
00883                 return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
00884                 
00885         case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
00886             return (ac->spacetype==SPACE_IPO);
00887             
00888         /* always available */
00889         default:
00890             return 1;
00891     }
00892 }
00893 
00894 /* get the appropriate flag(s) for the setting when it is valid  */
00895 static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
00896 {
00897     /* clear extra return data first */
00898     *neg= 0;
00899     
00900     switch (setting) {
00901         case ACHANNEL_SETTING_SELECT: /* selected */
00902             return FCURVE_SELECTED;
00903             
00904         case ACHANNEL_SETTING_MUTE: /* muted */
00905             return FCURVE_MUTED;
00906             
00907         case ACHANNEL_SETTING_PROTECT: /* protected */
00908             //*neg= 1; - if we change this to edtiability
00909             return FCURVE_PROTECTED;
00910             
00911         case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */
00912             return FCURVE_VISIBLE;
00913             
00914         default: /* unsupported */
00915             return 0;
00916     }
00917 }
00918 
00919 /* get pointer to the setting */
00920 static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
00921 {
00922     FCurve *fcu= (FCurve *)ale->data;
00923     
00924     /* all flags are just in agrp->flag for now... */
00925     GET_ACF_FLAG_PTR(fcu->flag);
00926 }
00927 
00928 /* fcurve type define */
00929 static bAnimChannelType ACF_FCURVE = 
00930 {
00931     "F-Curve",                      /* type name */
00932     
00933     acf_generic_channel_color,      /* backdrop color */
00934     acf_generic_channel_backdrop,   /* backdrop */
00935     acf_generic_indention_flexible, /* indent level */      // xxx rename this to f-curves only?
00936     acf_generic_group_offset,       /* offset */
00937     
00938     acf_fcurve_name,                /* name */
00939     NULL,                           /* name prop */
00940     NULL,                           /* icon */
00941     
00942     acf_fcurve_setting_valid,       /* has setting */
00943     acf_fcurve_setting_flag,        /* flag for setting */
00944     acf_fcurve_setting_ptr          /* pointer for setting */
00945 };
00946 
00947 /* Object Action Expander  ------------------------------------------- */
00948 
00949 // TODO: just get this from RNA?
00950 static int acf_fillactd_icon(bAnimListElem *UNUSED(ale))
00951 {
00952     return ICON_ACTION;
00953 }
00954 
00955 /* check if some setting exists for this channel */
00956 static short acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
00957 {
00958     switch (setting) {
00959         /* only select and expand supported */
00960         case ACHANNEL_SETTING_SELECT:
00961         case ACHANNEL_SETTING_EXPAND:
00962             return 1;
00963             
00964         default:
00965             return 0;
00966     }
00967 }
00968 
00969 /* get the appropriate flag(s) for the setting when it is valid  */
00970 static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
00971 {
00972     /* clear extra return data first */
00973     *neg= 0;
00974     
00975     switch (setting) {
00976         case ACHANNEL_SETTING_SELECT: /* selected */
00977             return ADT_UI_SELECTED;
00978             
00979         case ACHANNEL_SETTING_EXPAND: /* expanded */
00980             *neg= 1;
00981             return ACT_COLLAPSED;
00982         
00983         default: /* unsupported */
00984             return 0;
00985     }
00986 }
00987 
00988 /* get pointer to the setting */
00989 static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
00990 {
00991     bAction *act= (bAction *)ale->data;
00992     AnimData *adt= ale->adt;
00993     
00994     /* clear extra return data first */
00995     *type= 0;
00996     
00997     switch (setting) {
00998         case ACHANNEL_SETTING_SELECT: /* selected */
00999             if (adt) {
01000                 GET_ACF_FLAG_PTR(adt->flag);
01001             }
01002             else
01003                 return NULL;
01004             
01005         case ACHANNEL_SETTING_EXPAND: /* expanded */
01006             GET_ACF_FLAG_PTR(act->flag);
01007         
01008         default: /* unsupported */
01009             return NULL;
01010     }
01011 }
01012 
01013 /* object action expander type define */
01014 static bAnimChannelType ACF_FILLACTD = 
01015 {
01016     "Ob-Action Filler",             /* type name */
01017     
01018     acf_generic_dataexpand_color,   /* backdrop color */
01019     acf_generic_dataexpand_backdrop,/* backdrop */
01020     acf_generic_indention_1,        /* indent level */
01021     acf_generic_basic_offset,       /* offset */
01022     
01023     acf_generic_idblock_name,       /* name */
01024     acf_generic_idfill_nameprop,    /* name prop */
01025     acf_fillactd_icon,              /* icon */
01026     
01027     acf_fillactd_setting_valid,     /* has setting */
01028     acf_fillactd_setting_flag,      /* flag for setting */
01029     acf_fillactd_setting_ptr        /* pointer for setting */
01030 };
01031 
01032 /* Drivers Expander  ------------------------------------------- */
01033 
01034 // TODO: just get this from RNA?
01035 static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
01036 {
01037     return ICON_DRIVER;
01038 }
01039 
01040 static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
01041 {
01042     BLI_strncpy(name, "Drivers", ANIM_CHAN_NAME_SIZE);
01043 }
01044 
01045 /* check if some setting exists for this channel */
01046 // TODO: this could be made more generic
01047 static short acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
01048 {
01049     switch (setting) {
01050         /* only expand supported */
01051         case ACHANNEL_SETTING_EXPAND:
01052             return 1;
01053             
01054         default:
01055             return 0;
01056     }
01057 }
01058 
01059 /* get the appropriate flag(s) for the setting when it is valid  */
01060 static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01061 {
01062     /* clear extra return data first */
01063     *neg= 0;
01064     
01065     switch (setting) {
01066         case ACHANNEL_SETTING_EXPAND: /* expanded */
01067             *neg= 1;
01068             return ADT_DRIVERS_COLLAPSED;
01069         
01070         default: /* unsupported */
01071             return 0;
01072     }
01073 }
01074 
01075 /* get pointer to the setting */
01076 static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short *type)
01077 {
01078     AnimData *adt= (AnimData *)ale->data;
01079     
01080     /* clear extra return data first */
01081     *type= 0;
01082     
01083     switch (setting) {
01084         case ACHANNEL_SETTING_EXPAND: /* expanded */
01085             GET_ACF_FLAG_PTR(adt->flag);
01086         
01087         default: /* unsupported */
01088             return NULL;
01089     }
01090 }
01091 
01092 /* drivers expander type define */
01093 static bAnimChannelType ACF_FILLDRIVERS = 
01094 {
01095     "Drivers Filler",               /* type name */
01096     
01097     acf_generic_dataexpand_color,   /* backdrop color */
01098     acf_generic_dataexpand_backdrop,/* backdrop */
01099     acf_generic_indention_1,        /* indent level */
01100     acf_generic_basic_offset,       /* offset */
01101     
01102     acf_filldrivers_name,           /* name */
01103     NULL,                           /* name prop */
01104     acf_filldrivers_icon,           /* icon */
01105     
01106     acf_filldrivers_setting_valid,  /* has setting */
01107     acf_filldrivers_setting_flag,   /* flag for setting */
01108     acf_filldrivers_setting_ptr     /* pointer for setting */
01109 };
01110 
01111 
01112 /* Material Expander  ------------------------------------------- */
01113 
01114 // TODO: just get this from RNA?
01115 static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
01116 {
01117     return ICON_MATERIAL_DATA;
01118 }
01119 
01120 /* get the appropriate flag(s) for the setting when it is valid  */
01121 static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01122 {
01123     /* clear extra return data first */
01124     *neg= 0;
01125     
01126     switch (setting) {
01127         case ACHANNEL_SETTING_EXPAND: /* expanded */
01128             return MA_DS_EXPAND;
01129             
01130         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01131             return ADT_NLA_EVAL_OFF;
01132             
01133         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01134             *neg= 1;
01135             return ADT_CURVES_NOT_VISIBLE;
01136             
01137         case ACHANNEL_SETTING_SELECT: /* selected */
01138             return ADT_UI_SELECTED;
01139         
01140         default: /* unsupported */
01141             return 0;
01142     }
01143 }
01144 
01145 /* get pointer to the setting */
01146 static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
01147 {
01148     Material *ma= (Material *)ale->data;
01149     
01150     /* clear extra return data first */
01151     *type= 0;
01152     
01153     switch (setting) {
01154         case ACHANNEL_SETTING_EXPAND: /* expanded */
01155             GET_ACF_FLAG_PTR(ma->flag);
01156             
01157         case ACHANNEL_SETTING_SELECT: /* selected */
01158         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01159         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01160             if (ma->adt)
01161                 GET_ACF_FLAG_PTR(ma->adt->flag)
01162             else
01163                 return NULL;    
01164         
01165         default: /* unsupported */
01166             return NULL;
01167     }
01168 }
01169 
01170 /* material expander type define */
01171 static bAnimChannelType ACF_DSMAT= 
01172 {
01173     "Material Data Expander",       /* type name */
01174     
01175     acf_generic_dataexpand_color,   /* backdrop color */
01176     acf_generic_dataexpand_backdrop,/* backdrop */
01177     acf_generic_indention_1,        /* indent level */
01178     acf_generic_basic_offset,       /* offset */
01179     
01180     acf_generic_idblock_name,       /* name */
01181     acf_generic_idblock_nameprop,   /* name prop */
01182     acf_dsmat_icon,                 /* icon */
01183     
01184     acf_generic_dataexpand_setting_valid,   /* has setting */
01185     acf_dsmat_setting_flag,                 /* flag for setting */
01186     acf_dsmat_setting_ptr                   /* pointer for setting */
01187 };
01188 
01189 /* Lamp Expander  ------------------------------------------- */
01190 
01191 // TODO: just get this from RNA?
01192 static int acf_dslam_icon(bAnimListElem *UNUSED(ale))
01193 {
01194     return ICON_LAMP_DATA;
01195 }
01196 
01197 /* get the appropriate flag(s) for the setting when it is valid  */
01198 static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01199 {
01200     /* clear extra return data first */
01201     *neg= 0;
01202     
01203     switch (setting) {
01204         case ACHANNEL_SETTING_EXPAND: /* expanded */
01205             return LA_DS_EXPAND;
01206             
01207         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01208             return ADT_NLA_EVAL_OFF;
01209             
01210         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01211             *neg= 1;
01212             return ADT_CURVES_NOT_VISIBLE;
01213             
01214         case ACHANNEL_SETTING_SELECT: /* selected */
01215             return ADT_UI_SELECTED;
01216         
01217         default: /* unsupported */
01218             return 0;
01219     }
01220 }
01221 
01222 /* get pointer to the setting */
01223 static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
01224 {
01225     Lamp *la= (Lamp *)ale->data;
01226     
01227     /* clear extra return data first */
01228     *type= 0;
01229     
01230     switch (setting) {
01231         case ACHANNEL_SETTING_EXPAND: /* expanded */
01232             GET_ACF_FLAG_PTR(la->flag);
01233             
01234         case ACHANNEL_SETTING_SELECT: /* selected */
01235         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01236         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01237             if (la->adt)
01238                 GET_ACF_FLAG_PTR(la->adt->flag)
01239             else
01240                 return NULL;    
01241         
01242         default: /* unsupported */
01243             return NULL;
01244     }
01245 }
01246 
01247 /* lamp expander type define */
01248 static bAnimChannelType ACF_DSLAM= 
01249 {
01250     "Lamp Expander",                /* type name */
01251     
01252     acf_generic_dataexpand_color,   /* backdrop color */
01253     acf_generic_dataexpand_backdrop,/* backdrop */
01254     acf_generic_indention_1,        /* indent level */
01255     acf_generic_basic_offset,       /* offset */
01256     
01257     acf_generic_idblock_name,       /* name */
01258     acf_generic_idblock_nameprop,   /* name prop */
01259     acf_dslam_icon,                 /* icon */
01260     
01261     acf_generic_dataexpand_setting_valid,   /* has setting */
01262     acf_dslam_setting_flag,                 /* flag for setting */
01263     acf_dslam_setting_ptr                   /* pointer for setting */
01264 };
01265 
01266 /* Texture Expander  ------------------------------------------- */
01267 
01268 // TODO: just get this from RNA?
01269 static int acf_dstex_icon(bAnimListElem *UNUSED(ale))
01270 {
01271     return ICON_TEXTURE_DATA;
01272 }
01273 
01274 /* offset for texture expanders */
01275 // FIXME: soon to be obsolete?
01276 static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
01277 {
01278     return 14; // XXX: simply include this in indention instead?
01279 }
01280 
01281 /* get the appropriate flag(s) for the setting when it is valid  */
01282 static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01283 {
01284     /* clear extra return data first */
01285     *neg= 0;
01286     
01287     switch (setting) {
01288         case ACHANNEL_SETTING_EXPAND: /* expanded */
01289             return TEX_DS_EXPAND;
01290             
01291         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01292             return ADT_NLA_EVAL_OFF;
01293             
01294         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01295             *neg= 1;
01296             return ADT_CURVES_NOT_VISIBLE;
01297             
01298         case ACHANNEL_SETTING_SELECT: /* selected */
01299             return ADT_UI_SELECTED;
01300         
01301         default: /* unsupported */
01302             return 0;
01303     }
01304 }
01305 
01306 /* get pointer to the setting */
01307 static void *acf_dstex_setting_ptr(bAnimListElem *ale, int setting, short *type)
01308 {
01309     Tex *tex= (Tex *)ale->data;
01310     
01311     /* clear extra return data first */
01312     *type= 0;
01313     
01314     switch (setting) {
01315         case ACHANNEL_SETTING_EXPAND: /* expanded */
01316             GET_ACF_FLAG_PTR(tex->flag);
01317             
01318         case ACHANNEL_SETTING_SELECT: /* selected */
01319         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01320         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01321             if (tex->adt)
01322                 GET_ACF_FLAG_PTR(tex->adt->flag)
01323             else
01324                 return NULL;    
01325         
01326         default: /* unsupported */
01327             return NULL;
01328     }
01329 }
01330 
01331 /* texture expander type define */
01332 static bAnimChannelType ACF_DSTEX= 
01333 {
01334     "Texture Data Expander",        /* type name */
01335     
01336     acf_generic_dataexpand_color,   /* backdrop color */
01337     acf_generic_dataexpand_backdrop,/* backdrop */
01338     acf_generic_indention_1,        /* indent level */
01339     acf_dstex_offset,               /* offset */
01340     
01341     acf_generic_idblock_name,       /* name */
01342     acf_generic_idfill_nameprop,    /* name prop */
01343     acf_dstex_icon,                 /* icon */
01344     
01345     acf_generic_dataexpand_setting_valid,   /* has setting */
01346     acf_dstex_setting_flag,                 /* flag for setting */
01347     acf_dstex_setting_ptr                   /* pointer for setting */
01348 };
01349 
01350 /* Camera Expander  ------------------------------------------- */
01351 
01352 // TODO: just get this from RNA?
01353 static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
01354 {
01355     return ICON_CAMERA_DATA;
01356 }
01357 
01358 /* get the appropriate flag(s) for the setting when it is valid  */
01359 static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01360 {
01361     /* clear extra return data first */
01362     *neg= 0;
01363     
01364     switch (setting) {
01365         case ACHANNEL_SETTING_EXPAND: /* expanded */
01366             return CAM_DS_EXPAND;
01367             
01368         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01369             return ADT_NLA_EVAL_OFF;
01370             
01371         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01372             *neg= 1;
01373             return ADT_CURVES_NOT_VISIBLE;
01374             
01375         case ACHANNEL_SETTING_SELECT: /* selected */
01376             return ADT_UI_SELECTED;
01377         
01378         default: /* unsupported */
01379             return 0;
01380     }
01381 }
01382 
01383 /* get pointer to the setting */
01384 static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
01385 {
01386     Camera *ca= (Camera *)ale->data;
01387     
01388     /* clear extra return data first */
01389     *type= 0;
01390     
01391     switch (setting) {
01392         case ACHANNEL_SETTING_EXPAND: /* expanded */
01393             GET_ACF_FLAG_PTR(ca->flag);
01394             
01395         case ACHANNEL_SETTING_SELECT: /* selected */
01396         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01397         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01398             if (ca->adt)
01399                 GET_ACF_FLAG_PTR(ca->adt->flag)
01400             else
01401                 return NULL;
01402         
01403         default: /* unsupported */
01404             return NULL;
01405     }
01406 }
01407 
01408 /* camera expander type define */
01409 static bAnimChannelType ACF_DSCAM= 
01410 {
01411     "Camera Expander",              /* type name */
01412     
01413     acf_generic_dataexpand_color,   /* backdrop color */
01414     acf_generic_dataexpand_backdrop,/* backdrop */
01415     acf_generic_indention_1,        /* indent level */
01416     acf_generic_basic_offset,       /* offset */
01417     
01418     acf_generic_idblock_name,       /* name */
01419     acf_generic_idfill_nameprop,    /* name prop */
01420     acf_dscam_icon,                 /* icon */
01421     
01422     acf_generic_dataexpand_setting_valid,   /* has setting */
01423     acf_dscam_setting_flag,                 /* flag for setting */
01424     acf_dscam_setting_ptr                   /* pointer for setting */
01425 };
01426 
01427 /* Curve Expander  ------------------------------------------- */
01428 
01429 // TODO: just get this from RNA?
01430 static int acf_dscur_icon(bAnimListElem *ale)
01431 {
01432     Curve *cu= (Curve *)ale->data;
01433     short obtype= curve_type(cu);
01434     
01435     switch (obtype) {
01436         case OB_FONT:
01437             return ICON_FONT_DATA;
01438         case OB_SURF:
01439             return ICON_SURFACE_DATA;
01440         default:
01441             return ICON_CURVE_DATA;
01442     }
01443 }
01444 
01445 /* get the appropriate flag(s) for the setting when it is valid  */
01446 static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01447 {
01448     /* clear extra return data first */
01449     *neg= 0;
01450     
01451     switch (setting) {
01452         case ACHANNEL_SETTING_EXPAND: /* expanded */
01453             return CU_DS_EXPAND;
01454             
01455         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01456             return ADT_NLA_EVAL_OFF;
01457             
01458         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01459             *neg= 1;
01460             return ADT_CURVES_NOT_VISIBLE;
01461             
01462         case ACHANNEL_SETTING_SELECT: /* selected */
01463             return ADT_UI_SELECTED;
01464         
01465         default: /* unsupported */
01466             return 0;
01467     }
01468 }
01469 
01470 /* get pointer to the setting */
01471 static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
01472 {
01473     Curve *cu= (Curve *)ale->data;
01474     
01475     /* clear extra return data first */
01476     *type= 0;
01477     
01478     switch (setting) {
01479         case ACHANNEL_SETTING_EXPAND: /* expanded */
01480             GET_ACF_FLAG_PTR(cu->flag);
01481             
01482         case ACHANNEL_SETTING_SELECT: /* selected */
01483         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01484         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01485             if (cu->adt)
01486                 GET_ACF_FLAG_PTR(cu->adt->flag)
01487             else
01488                 return NULL;
01489         
01490         default: /* unsupported */
01491             return NULL;
01492     }
01493 }
01494 
01495 /* curve expander type define */
01496 static bAnimChannelType ACF_DSCUR= 
01497 {
01498     "Curve Expander",               /* type name */
01499     
01500     acf_generic_dataexpand_color,   /* backdrop color */
01501     acf_generic_dataexpand_backdrop,/* backdrop */
01502     acf_generic_indention_1,        /* indent level */
01503     acf_generic_basic_offset,       /* offset */
01504     
01505     acf_generic_idblock_name,       /* name */
01506     acf_generic_idblock_nameprop,   /* name prop */
01507     acf_dscur_icon,                 /* icon */
01508     
01509     acf_generic_dataexpand_setting_valid,   /* has setting */
01510     acf_dscur_setting_flag,                 /* flag for setting */
01511     acf_dscur_setting_ptr                   /* pointer for setting */
01512 };
01513 
01514 /* Shape Key Expander  ------------------------------------------- */
01515 
01516 // TODO: just get this from RNA?
01517 static int acf_dsskey_icon(bAnimListElem *UNUSED(ale))
01518 {
01519     return ICON_SHAPEKEY_DATA;
01520 }
01521 
01522 /* get the appropriate flag(s) for the setting when it is valid  */
01523 static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01524 {
01525     /* clear extra return data first */
01526     *neg= 0;
01527     
01528     switch (setting) {
01529         case ACHANNEL_SETTING_EXPAND: /* expanded */
01530             return KEY_DS_EXPAND;
01531             
01532         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01533             return ADT_NLA_EVAL_OFF;
01534             
01535         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01536             *neg= 1;
01537             return ADT_CURVES_NOT_VISIBLE;
01538             
01539         case ACHANNEL_SETTING_SELECT: /* selected */
01540             return ADT_UI_SELECTED;
01541         
01542         default: /* unsupported */
01543             return 0;
01544     }
01545 }
01546 
01547 /* get pointer to the setting */
01548 static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type)
01549 {
01550     Key *key= (Key *)ale->data;
01551     
01552     /* clear extra return data first */
01553     *type= 0;
01554     
01555     switch (setting) {
01556         case ACHANNEL_SETTING_EXPAND: /* expanded */
01557             GET_ACF_FLAG_PTR(key->flag);
01558             
01559         case ACHANNEL_SETTING_SELECT: /* selected */
01560         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01561         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01562             if (key->adt)
01563                 GET_ACF_FLAG_PTR(key->adt->flag)
01564             else
01565                 return NULL;
01566         
01567         default: /* unsupported */
01568             return NULL;
01569     }
01570 }
01571 
01572 /* shapekey expander type define */
01573 static bAnimChannelType ACF_DSSKEY= 
01574 {
01575     "Shape Key Expander",           /* type name */
01576     
01577     acf_generic_dataexpand_color,   /* backdrop color */
01578     acf_generic_dataexpand_backdrop,/* backdrop */
01579     acf_generic_indention_1,        /* indent level */
01580     acf_generic_basic_offset,       /* offset */
01581     
01582     acf_generic_idblock_name,       /* name */
01583     acf_generic_idblock_nameprop,   /* name prop */
01584     acf_dsskey_icon,                /* icon */
01585     
01586     acf_generic_dataexpand_setting_valid,   /* has setting */
01587     acf_dsskey_setting_flag,                /* flag for setting */
01588     acf_dsskey_setting_ptr                  /* pointer for setting */
01589 };
01590 
01591 /* World Expander  ------------------------------------------- */
01592 
01593 // TODO: just get this from RNA?
01594 static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
01595 {
01596     return ICON_WORLD_DATA;
01597 }
01598 
01599 /* get the appropriate flag(s) for the setting when it is valid  */
01600 static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01601 {
01602     /* clear extra return data first */
01603     *neg= 0;
01604     
01605     switch (setting) {
01606         case ACHANNEL_SETTING_EXPAND: /* expanded */
01607             return WO_DS_EXPAND;
01608             
01609         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01610             return ADT_NLA_EVAL_OFF;
01611             
01612         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01613             *neg= 1;
01614             return ADT_CURVES_NOT_VISIBLE;
01615             
01616         case ACHANNEL_SETTING_SELECT: /* selected */
01617             return ADT_UI_SELECTED;
01618         
01619         default: /* unsupported */
01620             return 0;
01621     }
01622 }
01623 
01624 /* get pointer to the setting */
01625 static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
01626 {
01627     World *wo= (World *)ale->data;
01628     
01629     /* clear extra return data first */
01630     *type= 0;
01631     
01632     switch (setting) {
01633         case ACHANNEL_SETTING_EXPAND: /* expanded */
01634             GET_ACF_FLAG_PTR(wo->flag);
01635             
01636         case ACHANNEL_SETTING_SELECT: /* selected */
01637         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01638         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01639             if (wo->adt)
01640                 GET_ACF_FLAG_PTR(wo->adt->flag)
01641             else
01642                 return NULL;
01643         
01644         default: /* unsupported */
01645             return NULL;
01646     }
01647 }
01648 
01649 /* world expander type define */
01650 static bAnimChannelType ACF_DSWOR= 
01651 {
01652     "World Expander",               /* type name */
01653     
01654     acf_generic_dataexpand_color,   /* backdrop color */
01655     acf_generic_dataexpand_backdrop,/* backdrop */
01656     acf_generic_indention_1,        /* indent level */
01657     acf_generic_basic_offset,       /* offset */
01658     
01659     acf_generic_idblock_name,       /* name */
01660     acf_generic_idfill_nameprop,    /* name prop */
01661     acf_dswor_icon,                 /* icon */
01662     
01663     acf_generic_dataexpand_setting_valid,   /* has setting */
01664     acf_dswor_setting_flag,                 /* flag for setting */
01665     acf_dswor_setting_ptr                   /* pointer for setting */
01666 };
01667 
01668 /* Particle Expander  ------------------------------------------- */
01669 
01670 // TODO: just get this from RNA?
01671 static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
01672 {
01673     return ICON_PARTICLE_DATA;
01674 }
01675 
01676 /* get the appropriate flag(s) for the setting when it is valid  */
01677 static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01678 {
01679     /* clear extra return data first */
01680     *neg= 0;
01681     
01682     switch (setting) {
01683         case ACHANNEL_SETTING_EXPAND: /* expanded */
01684             return PART_DS_EXPAND;
01685             
01686         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01687             return ADT_NLA_EVAL_OFF;
01688             
01689         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01690             *neg= 1;
01691             return ADT_CURVES_NOT_VISIBLE;
01692             
01693         case ACHANNEL_SETTING_SELECT: /* selected */
01694             return ADT_UI_SELECTED;
01695         
01696         default: /* unsupported */
01697             return 0;
01698     }
01699 }
01700 
01701 /* get pointer to the setting */
01702 static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type)
01703 {
01704     ParticleSettings *part= (ParticleSettings *)ale->data;
01705     
01706     /* clear extra return data first */
01707     *type= 0;
01708     
01709     switch (setting) {
01710         case ACHANNEL_SETTING_EXPAND: /* expanded */
01711             GET_ACF_FLAG_PTR(part->flag);
01712             
01713         case ACHANNEL_SETTING_SELECT: /* selected */
01714         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01715         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01716             if (part->adt)
01717                 GET_ACF_FLAG_PTR(part->adt->flag)
01718             else
01719                 return NULL;
01720         
01721         default: /* unsupported */
01722             return NULL;
01723     }
01724 }
01725 
01726 /* particle expander type define */
01727 static bAnimChannelType ACF_DSPART= 
01728 {
01729     "Particle Data Expander",       /* type name */
01730     
01731     acf_generic_dataexpand_color,   /* backdrop color */
01732     acf_generic_dataexpand_backdrop,/* backdrop */
01733     acf_generic_indention_1,        /* indent level */
01734     acf_generic_basic_offset,       /* offset */
01735     
01736     acf_generic_idblock_name,       /* name */
01737     acf_generic_idblock_nameprop,   /* name prop */
01738     acf_dspart_icon,                /* icon */
01739     
01740     acf_generic_dataexpand_setting_valid,   /* has setting */
01741     acf_dspart_setting_flag,                /* flag for setting */
01742     acf_dspart_setting_ptr                  /* pointer for setting */
01743 };
01744 
01745 /* MetaBall Expander  ------------------------------------------- */
01746 
01747 // TODO: just get this from RNA?
01748 static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
01749 {
01750     return ICON_META_DATA;
01751 }
01752 
01753 /* get the appropriate flag(s) for the setting when it is valid  */
01754 static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01755 {
01756     /* clear extra return data first */
01757     *neg= 0;
01758     
01759     switch (setting) {
01760         case ACHANNEL_SETTING_EXPAND: /* expanded */
01761             return MB_DS_EXPAND;
01762             
01763         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01764             return ADT_NLA_EVAL_OFF;
01765             
01766         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01767             *neg= 1;
01768             return ADT_CURVES_NOT_VISIBLE;
01769         
01770         case ACHANNEL_SETTING_SELECT: /* selected */
01771             return ADT_UI_SELECTED;
01772         
01773         default: /* unsupported */
01774             return 0;
01775     }
01776 }
01777 
01778 /* get pointer to the setting */
01779 static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *type)
01780 {
01781     MetaBall *mb= (MetaBall *)ale->data;
01782     
01783     /* clear extra return data first */
01784     *type= 0;
01785     
01786     switch (setting) {
01787         case ACHANNEL_SETTING_EXPAND: /* expanded */
01788             GET_ACF_FLAG_PTR(mb->flag);
01789             
01790         case ACHANNEL_SETTING_SELECT: /* selected */
01791         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01792         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01793             if (mb->adt)
01794                 GET_ACF_FLAG_PTR(mb->adt->flag)
01795             else
01796                 return NULL;
01797         
01798         default: /* unsupported */
01799             return NULL;
01800     }
01801 }
01802 
01803 /* metaball expander type define */
01804 static bAnimChannelType ACF_DSMBALL= 
01805 {
01806     "Metaball Expander",            /* type name */
01807     
01808     acf_generic_dataexpand_color,   /* backdrop color */
01809     acf_generic_dataexpand_backdrop,/* backdrop */
01810     acf_generic_indention_1,        /* indent level */
01811     acf_generic_basic_offset,       /* offset */
01812     
01813     acf_generic_idblock_name,       /* name */
01814     acf_generic_idblock_nameprop,   /* name prop */
01815     acf_dsmball_icon,               /* icon */
01816     
01817     acf_generic_dataexpand_setting_valid,   /* has setting */
01818     acf_dsmball_setting_flag,               /* flag for setting */
01819     acf_dsmball_setting_ptr                 /* pointer for setting */
01820 };
01821 
01822 /* Armature Expander  ------------------------------------------- */
01823 
01824 // TODO: just get this from RNA?
01825 static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
01826 {
01827     return ICON_ARMATURE_DATA;
01828 }
01829 
01830 /* get the appropriate flag(s) for the setting when it is valid  */
01831 static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01832 {
01833     /* clear extra return data first */
01834     *neg= 0;
01835     
01836     switch (setting) {
01837         case ACHANNEL_SETTING_EXPAND: /* expanded */
01838             return ARM_DS_EXPAND;
01839             
01840         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01841             return ADT_NLA_EVAL_OFF;
01842             
01843         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01844             *neg= 1;
01845             return ADT_CURVES_NOT_VISIBLE;
01846             
01847         case ACHANNEL_SETTING_SELECT: /* selected */
01848             return ADT_UI_SELECTED;
01849         
01850         default: /* unsupported */
01851             return 0;
01852     }
01853 }
01854 
01855 /* get pointer to the setting */
01856 static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
01857 {
01858     bArmature *arm= (bArmature *)ale->data;
01859     
01860     /* clear extra return data first */
01861     *type= 0;
01862     
01863     switch (setting) {
01864         case ACHANNEL_SETTING_EXPAND: /* expanded */
01865             GET_ACF_FLAG_PTR(arm->flag);
01866             
01867         case ACHANNEL_SETTING_SELECT: /* selected */
01868         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01869         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01870             if (arm->adt)
01871                 GET_ACF_FLAG_PTR(arm->adt->flag)
01872             else
01873                 return NULL;
01874         
01875         default: /* unsupported */
01876             return NULL;
01877     }
01878 }
01879 
01880 /* metaball expander type define */
01881 static bAnimChannelType ACF_DSARM= 
01882 {
01883     "Armature Expander",            /* type name */
01884     
01885     acf_generic_dataexpand_color,   /* backdrop color */
01886     acf_generic_dataexpand_backdrop,/* backdrop */
01887     acf_generic_indention_1,        /* indent level */
01888     acf_generic_basic_offset,       /* offset */
01889     
01890     acf_generic_idblock_name,       /* name */
01891     acf_generic_idblock_nameprop,   /* name prop */
01892     acf_dsarm_icon,             /* icon */
01893     
01894     acf_generic_dataexpand_setting_valid,   /* has setting */
01895     acf_dsarm_setting_flag,                 /* flag for setting */
01896     acf_dsarm_setting_ptr                   /* pointer for setting */
01897 };
01898 
01899 /* NodeTree Expander  ------------------------------------------- */
01900 
01901 // TODO: just get this from RNA?
01902 static int acf_dsntree_icon(bAnimListElem *UNUSED(ale))
01903 {
01904     return ICON_NODETREE;
01905 }
01906 
01907 /* offset for nodetree expanders */
01908 static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
01909 {
01910     bNodeTree *ntree = (bNodeTree *)ale->data;
01911     short offset= acf_generic_basic_offset(ac, ale);
01912     
01913     offset += acf_nodetree_rootType_offset(ntree); 
01914     
01915     return offset;
01916 }
01917 
01918 /* get the appropriate flag(s) for the setting when it is valid  */
01919 static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01920 {
01921     /* clear extra return data first */
01922     *neg= 0;
01923     
01924     switch (setting) {
01925         case ACHANNEL_SETTING_EXPAND: /* expanded */
01926             return NTREE_DS_EXPAND;
01927             
01928         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
01929             return ADT_NLA_EVAL_OFF;
01930             
01931         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
01932             *neg= 1;
01933             return ADT_CURVES_NOT_VISIBLE;
01934             
01935         case ACHANNEL_SETTING_SELECT: /* selected */
01936             return ADT_UI_SELECTED;
01937             
01938         default: /* unsupported */
01939             return 0;
01940     }
01941 }
01942 
01943 /* get pointer to the setting */
01944 static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *type)
01945 {
01946     bNodeTree *ntree= (bNodeTree *)ale->data;
01947     
01948     /* clear extra return data first */
01949     *type= 0;
01950     
01951     switch (setting) {
01952         case ACHANNEL_SETTING_EXPAND: /* expanded */
01953             GET_ACF_FLAG_PTR(ntree->flag);
01954             
01955         case ACHANNEL_SETTING_SELECT: /* selected */
01956         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
01957         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
01958             if (ntree->adt)
01959                 GET_ACF_FLAG_PTR(ntree->adt->flag)
01960                 else
01961                     return NULL;
01962             
01963         default: /* unsupported */
01964             return NULL;
01965     }
01966 }
01967 
01968 /* node tree expander type define */
01969 static bAnimChannelType ACF_DSNTREE= 
01970 {
01971     "Node Tree Expander",           /* type name */
01972     
01973     acf_generic_dataexpand_color,   /* backdrop color */
01974     acf_generic_dataexpand_backdrop,/* backdrop */
01975     acf_generic_indention_1,        /* indent level */
01976     acf_dsntree_offset,             /* offset */
01977     
01978     acf_generic_idblock_name,       /* name */
01979     acf_generic_idblock_nameprop,   /* name prop */
01980     acf_dsntree_icon,               /* icon */
01981     
01982     acf_generic_dataexpand_setting_valid,   /* has setting */
01983     acf_dsntree_setting_flag,               /* flag for setting */
01984     acf_dsntree_setting_ptr                 /* pointer for setting */
01985 };
01986 
01987 /* Mesh Expander  ------------------------------------------- */
01988 
01989 // TODO: just get this from RNA?
01990 static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
01991 {
01992     return ICON_MESH_DATA;
01993 }
01994 
01995 /* get the appropriate flag(s) for the setting when it is valid  */
01996 static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
01997 {
01998     /* clear extra return data first */
01999     *neg= 0;
02000     
02001     switch (setting) {
02002         case ACHANNEL_SETTING_EXPAND: /* expanded */
02003             return ME_DS_EXPAND;
02004             
02005         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
02006             return ADT_NLA_EVAL_OFF;
02007             
02008         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
02009             *neg= 1;
02010             return ADT_CURVES_NOT_VISIBLE;
02011             
02012         case ACHANNEL_SETTING_SELECT: /* selected */
02013             return ADT_UI_SELECTED;
02014             
02015         default: /* unsupported */
02016             return 0;
02017     }
02018 }
02019 
02020 /* get pointer to the setting */
02021 static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type)
02022 {
02023     Mesh *me= (Mesh *)ale->data;
02024     
02025     /* clear extra return data first */
02026     *type= 0;
02027     
02028     switch (setting) {
02029         case ACHANNEL_SETTING_EXPAND: /* expanded */
02030             GET_ACF_FLAG_PTR(me->flag);
02031             
02032         case ACHANNEL_SETTING_SELECT: /* selected */
02033         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
02034         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
02035             if (me->adt)
02036                 GET_ACF_FLAG_PTR(me->adt->flag)
02037                 else
02038                     return NULL;
02039             
02040         default: /* unsupported */
02041             return NULL;
02042     }
02043 }
02044 
02045 /* node tree expander type define */
02046 static bAnimChannelType ACF_DSMESH= 
02047 {
02048     "Mesh Expander",                /* type name */
02049     
02050     acf_generic_dataexpand_color,   /* backdrop color */
02051     acf_generic_dataexpand_backdrop,/* backdrop */
02052     acf_generic_indention_1,        /* indent level */      // XXX this only works for compositing
02053     acf_generic_basic_offset,       /* offset */
02054     
02055     acf_generic_idblock_name,       /* name */
02056     acf_generic_idblock_nameprop,   /* name prop */
02057     acf_dsmesh_icon,                /* icon */
02058     
02059     acf_generic_dataexpand_setting_valid,   /* has setting */
02060     acf_dsmesh_setting_flag,                /* flag for setting */
02061     acf_dsmesh_setting_ptr                  /* pointer for setting */
02062 };
02063 
02064 /* Lattice Expander  ------------------------------------------- */
02065 
02066 // TODO: just get this from RNA?
02067 static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
02068 {
02069     return ICON_LATTICE_DATA;
02070 }
02071 
02072 /* get the appropriate flag(s) for the setting when it is valid  */
02073 static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
02074 {
02075     /* clear extra return data first */
02076     *neg= 0;
02077     
02078     switch (setting) {
02079         case ACHANNEL_SETTING_EXPAND: /* expanded */
02080             return LT_DS_EXPAND;
02081             
02082         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
02083             return ADT_NLA_EVAL_OFF;
02084             
02085         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
02086             *neg= 1;
02087             return ADT_CURVES_NOT_VISIBLE;
02088             
02089         case ACHANNEL_SETTING_SELECT: /* selected */
02090             return ADT_UI_SELECTED;
02091             
02092         default: /* unsupported */
02093             return 0;
02094     }
02095 }
02096 
02097 /* get pointer to the setting */
02098 static void *acf_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type)
02099 {
02100     Lattice *lt= (Lattice *)ale->data;
02101     
02102     /* clear extra return data first */
02103     *type= 0;
02104     
02105     switch (setting) {
02106         case ACHANNEL_SETTING_EXPAND: /* expanded */
02107             GET_ACF_FLAG_PTR(lt->flag);
02108             
02109         case ACHANNEL_SETTING_SELECT: /* selected */
02110         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
02111         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
02112             if (lt->adt)
02113                 GET_ACF_FLAG_PTR(lt->adt->flag)
02114                 else
02115                     return NULL;
02116             
02117         default: /* unsupported */
02118             return NULL;
02119     }
02120 }
02121 
02122 /* node tree expander type define */
02123 static bAnimChannelType ACF_DSLAT= 
02124 {
02125     "Lattice Expander",             /* type name */
02126     
02127     acf_generic_dataexpand_color,   /* backdrop color */
02128     acf_generic_dataexpand_backdrop,/* backdrop */
02129     acf_generic_indention_1,        /* indent level */      // XXX this only works for compositing
02130     acf_generic_basic_offset,       /* offset */
02131     
02132     acf_generic_idblock_name,       /* name */
02133     acf_generic_idblock_nameprop,   /* name prop */
02134     acf_dslat_icon,                 /* icon */
02135     
02136     acf_generic_dataexpand_setting_valid,   /* has setting */
02137     acf_dslat_setting_flag,                 /* flag for setting */
02138     acf_dslat_setting_ptr                   /* pointer for setting */
02139 };
02140 
02141 /* Speaker Expander  ------------------------------------------- */
02142 
02143 // TODO: just get this from RNA?
02144 static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
02145 {
02146     return ICON_SPEAKER;
02147 }
02148 
02149 /* get the appropriate flag(s) for the setting when it is valid  */
02150 static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
02151 {
02152     /* clear extra return data first */
02153     *neg= 0;
02154 
02155     switch (setting) {
02156         case ACHANNEL_SETTING_EXPAND: /* expanded */
02157             return SPK_DS_EXPAND;
02158         
02159         case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
02160             return ADT_NLA_EVAL_OFF;
02161         
02162         case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
02163             *neg= 1;
02164             return ADT_CURVES_NOT_VISIBLE;
02165         
02166         case ACHANNEL_SETTING_SELECT: /* selected */
02167             return ADT_UI_SELECTED;
02168         
02169         default: /* unsupported */
02170             return 0;
02171     }
02172 }
02173 
02174 /* get pointer to the setting */
02175 static void *acf_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type)
02176 {
02177     Speaker *spk= (Speaker *)ale->data;
02178 
02179     /* clear extra return data first */
02180     *type= 0;
02181 
02182     switch (setting) {
02183         case ACHANNEL_SETTING_EXPAND: /* expanded */
02184             GET_ACF_FLAG_PTR(spk->flag);
02185         
02186         case ACHANNEL_SETTING_SELECT: /* selected */
02187         case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
02188         case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
02189             if (spk->adt)
02190                 GET_ACF_FLAG_PTR(spk->adt->flag)
02191             else
02192                 return NULL;
02193         
02194         default: /* unsupported */
02195             return NULL;
02196     }
02197 }
02198 
02199 /* speaker expander type define */
02200 static bAnimChannelType ACF_DSSPK=
02201 {
02202     "Speaker Expander",             /* type name */
02203     
02204     acf_generic_dataexpand_color,   /* backdrop color */
02205     acf_generic_dataexpand_backdrop,/* backdrop */
02206     acf_generic_indention_1,        /* indent level */
02207     acf_generic_basic_offset,       /* offset */
02208     
02209     acf_generic_idblock_name,       /* name */
02210     acf_generic_idblock_nameprop,   /* name prop */
02211     acf_dsspk_icon,                 /* icon */
02212     
02213     acf_generic_dataexpand_setting_valid,   /* has setting */
02214     acf_dsspk_setting_flag,                 /* flag for setting */
02215     acf_dsspk_setting_ptr                   /* pointer for setting */
02216 };
02217 
02218 /* ShapeKey Entry  ------------------------------------------- */
02219 
02220 /* name for ShapeKey */
02221 static void acf_shapekey_name(bAnimListElem *ale, char *name)
02222 {
02223     KeyBlock *kb= (KeyBlock *)ale->data;
02224     
02225     /* just copy the name... */
02226     if (kb && name) {
02227         /* if the KeyBlock had a name, use it, otherwise use the index */
02228         if (kb->name[0])
02229             BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
02230         else
02231             BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, "Key %d", ale->index);
02232     }
02233 }
02234 
02235 /* name property for ShapeKey entries */
02236 static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
02237 {
02238     KeyBlock *kb= (KeyBlock *)ale->data;
02239     
02240     /* if the KeyBlock had a name, use it, otherwise use the index */
02241     if (kb && kb->name[0]) {
02242         RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
02243         *prop = RNA_struct_name_property(ptr->type);
02244         
02245         return (*prop != NULL);
02246     }
02247     
02248     return 0;
02249 }
02250 
02251 /* check if some setting exists for this channel */
02252 static short acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
02253 {
02254     switch (setting) {
02255         case ACHANNEL_SETTING_SELECT: /* selected */
02256         case ACHANNEL_SETTING_MUTE: /* muted */
02257         case ACHANNEL_SETTING_PROTECT: /* protected */
02258             return 1;
02259             
02260         /* nothing else is supported */
02261         default:
02262             return 0;
02263     }
02264 }
02265 
02266 /* get the appropriate flag(s) for the setting when it is valid  */
02267 static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
02268 {
02269     /* clear extra return data first */
02270     *neg= 0;
02271     
02272     switch (setting) {
02273         case ACHANNEL_SETTING_MUTE: /* mute */
02274             return KEYBLOCK_MUTE;
02275         
02276         case ACHANNEL_SETTING_SELECT: /* selected */
02277             return KEYBLOCK_SEL;
02278         
02279         case ACHANNEL_SETTING_PROTECT: /* locked */
02280             return KEYBLOCK_LOCKED;
02281         
02282         default: /* unsupported */
02283             return 0;
02284     }
02285 }
02286 
02287 /* get pointer to the setting */
02288 static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
02289 {
02290     KeyBlock *kb= (KeyBlock *)ale->data;
02291     
02292     /* clear extra return data first */
02293     *type= 0;
02294     
02295     switch (setting) {
02296         case ACHANNEL_SETTING_SELECT: /* selected */
02297         case ACHANNEL_SETTING_MUTE: /* muted */
02298         case ACHANNEL_SETTING_PROTECT: /* protected */
02299             GET_ACF_FLAG_PTR(kb->flag)
02300         
02301         default: /* unsupported */
02302             return NULL;
02303     }
02304 }
02305 
02306 /* shapekey expander type define */
02307 static bAnimChannelType ACF_SHAPEKEY= 
02308 {
02309     "Shape Key",                    /* type name */
02310     
02311     acf_generic_channel_color,      /* backdrop color */
02312     acf_generic_channel_backdrop,   /* backdrop */
02313     acf_generic_indention_0,        /* indent level */
02314     acf_generic_basic_offset,       /* offset */
02315     
02316     acf_shapekey_name,              /* name */
02317     acf_shapekey_nameprop,          /* name prop */
02318     NULL,                           /* icon */
02319     
02320     acf_shapekey_setting_valid,     /* has setting */
02321     acf_shapekey_setting_flag,      /* flag for setting */
02322     acf_shapekey_setting_ptr        /* pointer for setting */
02323 };
02324 
02325 /* GPencil Datablock ------------------------------------------- */
02326 
02327 /* get backdrop color for gpencil datablock widget */
02328 static void acf_gpd_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float *color)
02329 {
02330     /* these are ID-blocks, but not exactly standalone... */
02331     UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, color);
02332 }
02333 
02334 // TODO: just get this from RNA?
02335 static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
02336 {
02337     return ICON_GREASEPENCIL;
02338 }
02339 
02340 /* check if some setting exists for this channel */
02341 static short acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
02342 {
02343     switch (setting) {
02344         /* only select and expand supported */
02345         case ACHANNEL_SETTING_SELECT:
02346         case ACHANNEL_SETTING_EXPAND:
02347             return 1;
02348             
02349         default:
02350             return 0;
02351     }
02352 }
02353 
02354 /* get the appropriate flag(s) for the setting when it is valid  */
02355 static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
02356 {
02357     /* clear extra return data first */
02358     *neg= 0;
02359     
02360     switch (setting) {
02361         case ACHANNEL_SETTING_SELECT: /* selected */
02362             return AGRP_SELECTED;
02363             
02364         case ACHANNEL_SETTING_EXPAND: /* expanded */
02365             return GP_DATA_EXPAND;
02366     }
02367     
02368     /* this shouldn't happen */
02369     return 0;
02370 }
02371 
02372 /* get pointer to the setting */
02373 static void *acf_gpd_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
02374 {
02375     bGPdata *gpd= (bGPdata *)ale->data;
02376     
02377     /* all flags are just in gpd->flag for now... */
02378     GET_ACF_FLAG_PTR(gpd->flag);
02379 }
02380 
02381 /* gpencil datablock type define */
02382 static bAnimChannelType ACF_GPD = 
02383 {
02384     "GPencil Datablock",            /* type name */
02385     
02386     acf_gpd_color,                  /* backdrop color */
02387     acf_group_backdrop,             /* backdrop */
02388     acf_generic_indention_0,        /* indent level */
02389     acf_generic_group_offset,       /* offset */
02390     
02391     acf_generic_idblock_name,       /* name */
02392     acf_generic_idfill_nameprop,    /* name prop */
02393     acf_gpd_icon,                   /* icon */
02394     
02395     acf_gpd_setting_valid,          /* has setting */
02396     acf_gpd_setting_flag,           /* flag for setting */
02397     acf_gpd_setting_ptr             /* pointer for setting */
02398 };
02399 
02400 /* GPencil Layer ------------------------------------------- */
02401 
02402 /* name for grase pencil layer entries */
02403 static void acf_gpl_name(bAnimListElem *ale, char *name)
02404 {
02405     bGPDlayer *gpl = (bGPDlayer *)ale->data;
02406     
02407     if (gpl && name)
02408         BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
02409 }
02410 
02411 /* name property for grease pencil layer entries */
02412 static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
02413 {
02414     if (ale->data) {
02415         RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
02416         *prop = RNA_struct_name_property(ptr->type);
02417         
02418         return (*prop != NULL);
02419     }
02420     
02421     return 0;
02422 }
02423 
02424 /* check if some setting exists for this channel */
02425 static short acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting)
02426 {
02427     switch (setting) {
02428         /* unsupported */
02429         case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
02430         case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
02431             return 0;
02432         
02433         /* always available */
02434         default:
02435             return 1;
02436     }
02437 }
02438 
02439 /* get the appropriate flag(s) for the setting when it is valid  */
02440 static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
02441 {
02442     /* clear extra return data first */
02443     *neg= 0;
02444     
02445     switch (setting) {
02446         case ACHANNEL_SETTING_SELECT: /* selected */
02447             return GP_LAYER_SELECT;
02448             
02449         case ACHANNEL_SETTING_MUTE: /* muted */
02450             return GP_LAYER_HIDE;
02451             
02452         case ACHANNEL_SETTING_PROTECT: /* protected */
02453             //*neg= 1; - if we change this to edtiability
02454             return GP_LAYER_LOCKED;
02455             
02456         default: /* unsupported */
02457             return 0;
02458     }
02459 }
02460 
02461 /* get pointer to the setting */
02462 static void *acf_gpl_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
02463 {
02464     bGPDlayer *gpl= (bGPDlayer *)ale->data;
02465     
02466     /* all flags are just in agrp->flag for now... */
02467     GET_ACF_FLAG_PTR(gpl->flag);
02468 }
02469 
02470 /* grease pencil layer type define */
02471 static bAnimChannelType ACF_GPL = 
02472 {
02473     "GPencil Layer",                /* type name */
02474     
02475     acf_generic_channel_color,      /* backdrop color */
02476     acf_generic_channel_backdrop,   /* backdrop */
02477     acf_generic_indention_flexible, /* indent level */
02478     acf_generic_group_offset,       /* offset */
02479     
02480     acf_gpl_name,                   /* name */
02481     acf_gpl_name_prop,              /* name prop */
02482     NULL,                           /* icon */
02483     
02484     acf_gpl_setting_valid,          /* has setting */
02485     acf_gpl_setting_flag,           /* flag for setting */
02486     acf_gpl_setting_ptr             /* pointer for setting */
02487 };
02488 
02489 /* *********************************************** */
02490 /* Type Registration and General Access */
02491 
02492 /* These globals only ever get directly accessed in this file */
02493 static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES];
02494 static short ACF_INIT= 1; /* when non-zero, the list needs to be updated */
02495 
02496 /* Initialise type info definitions */
02497 static void ANIM_init_channel_typeinfo_data (void)
02498 {
02499     int type= 0;
02500     
02501     /* start initialising if necessary... */
02502     if (ACF_INIT) {
02503         ACF_INIT= 0;
02504         
02505         animchannelTypeInfo[type++]= NULL;              /* None */
02506         animchannelTypeInfo[type++]= NULL;              /* AnimData */
02507         animchannelTypeInfo[type++]= NULL;              /* Special */
02508         
02509         animchannelTypeInfo[type++]= &ACF_SUMMARY;      /* Motion Summary */
02510         
02511         animchannelTypeInfo[type++]= &ACF_SCENE;        /* Scene */
02512         animchannelTypeInfo[type++]= &ACF_OBJECT;       /* Object */
02513         animchannelTypeInfo[type++]= &ACF_GROUP;        /* Group */
02514         animchannelTypeInfo[type++]= &ACF_FCURVE;       /* F-Curve */
02515         
02516         animchannelTypeInfo[type++]= &ACF_FILLACTD;     /* Object Action Expander */
02517         animchannelTypeInfo[type++]= &ACF_FILLDRIVERS;  /* Drivers Expander */
02518         
02519         animchannelTypeInfo[type++]= &ACF_DSMAT;        /* Material Channel */
02520         animchannelTypeInfo[type++]= &ACF_DSLAM;        /* Lamp Channel */
02521         animchannelTypeInfo[type++]= &ACF_DSCAM;        /* Camera Channel */
02522         animchannelTypeInfo[type++]= &ACF_DSCUR;        /* Curve Channel */
02523         animchannelTypeInfo[type++]= &ACF_DSSKEY;       /* ShapeKey Channel */
02524         animchannelTypeInfo[type++]= &ACF_DSWOR;        /* World Channel */
02525         animchannelTypeInfo[type++]= &ACF_DSNTREE;      /* NodeTree Channel */
02526         animchannelTypeInfo[type++]= &ACF_DSPART;       /* Particle Channel */
02527         animchannelTypeInfo[type++]= &ACF_DSMBALL;      /* MetaBall Channel */
02528         animchannelTypeInfo[type++]= &ACF_DSARM;        /* Armature Channel */
02529         animchannelTypeInfo[type++]= &ACF_DSMESH;       /* Mesh Channel */
02530         animchannelTypeInfo[type++]= &ACF_DSTEX;        /* Texture Channel */
02531         animchannelTypeInfo[type++]= &ACF_DSLAT;        /* Lattice Channel */
02532         animchannelTypeInfo[type++]= &ACF_DSSPK;        /* Speaker Channel */
02533         
02534         animchannelTypeInfo[type++]= &ACF_SHAPEKEY;     /* ShapeKey */
02535         
02536         animchannelTypeInfo[type++]= &ACF_GPD;          /* Grease Pencil Datablock */ 
02537         animchannelTypeInfo[type++]= &ACF_GPL;          /* Grease Pencil Layer */ 
02538         
02539             // TODO: these types still need to be implemented!!!
02540             // probably need a few extra flags for these special cases...
02541         animchannelTypeInfo[type++]= NULL;              /* NLA Track */ 
02542         animchannelTypeInfo[type++]= NULL;              /* NLA Action */ 
02543     }
02544 } 
02545 
02546 /* Get type info from given channel type */
02547 bAnimChannelType *ANIM_channel_get_typeinfo (bAnimListElem *ale)
02548 {
02549     /* santiy checks */
02550     if (ale == NULL)
02551         return NULL;
02552         
02553     /* init the typeinfo if not available yet... */
02554     ANIM_init_channel_typeinfo_data();
02555     
02556     /* check if type is in bounds... */
02557     if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
02558         return animchannelTypeInfo[ale->type];
02559     else
02560         return NULL;
02561 }
02562 
02563 /* --------------------------- */
02564 
02565 /* Print debug info string for the given channel */
02566 void ANIM_channel_debug_print_info (bAnimListElem *ale, short indent_level)
02567 {
02568     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
02569     
02570     /* print indents */
02571     for (; indent_level > 0; indent_level--)
02572         printf("  ");
02573     
02574     /* print info */
02575     if (acf) {
02576         char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
02577         
02578         /* get UI name */
02579         if (acf->name)
02580             acf->name(ale, name);
02581         else
02582             BLI_strncpy(name, "<No name>", sizeof(name));
02583 
02584         /* print type name + ui name */
02585         printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
02586     }
02587     else if (ale)
02588         printf("ChanType: <Unknown - %d>\n", ale->type);
02589     else
02590         printf("<Invalid channel - NULL>\n");
02591 }
02592 
02593 /* --------------------------- */
02594 
02595 /* Check if some setting for a channel is enabled 
02596  * Returns: 1 = On, 0 = Off, -1 = Invalid
02597  */
02598 short ANIM_channel_setting_get (bAnimContext *ac, bAnimListElem *ale, int setting)
02599 {
02600     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
02601     
02602     /* 1) check that the setting exists for the current context */
02603     if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
02604     {
02605         /* 2) get pointer to check for flag in, and the flag to check for */
02606         short negflag, ptrsize;
02607         int flag;
02608         void *ptr;
02609         
02610         flag= acf->setting_flag(ac, setting, &negflag);
02611         ptr= acf->setting_ptr(ale, setting, &ptrsize);
02612         
02613         /* check if flag is enabled */
02614         if (ptr && flag) {
02615             switch (ptrsize) {
02616                 case sizeof(int):   /* integer pointer for setting */
02617                 {
02618                     int *val= (int *)ptr;
02619                     
02620                     if (negflag)
02621                         return ((*val) & flag) == 0;
02622                     else
02623                         return ((*val) & flag) != 0;
02624                 }
02625                     break;
02626                     
02627                 case sizeof(short): /* short pointer for setting */
02628                 {
02629                     short *val= (short *)ptr;
02630                     
02631                     if (negflag)
02632                         return ((*val) & flag) == 0;
02633                     else
02634                         return ((*val) & flag) != 0;
02635                 }
02636                     break;
02637                     
02638                 case sizeof(char):  /* char pointer for setting */
02639                 {
02640                     char *val= (char *)ptr;
02641                     
02642                     if (negflag)
02643                         return ((*val) & flag) == 0;
02644                     else
02645                         return ((*val) & flag) != 0;
02646                 }
02647                     break;
02648             }
02649         }
02650     }
02651     
02652     /* not found... */
02653     return -1;
02654 }   
02655 
02656 
02657 /* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
02658 #define ACF_SETTING_SET(sval, sflag, smode) \
02659     {\
02660         if (negflag) {\
02661             if (smode == ACHANNEL_SETFLAG_INVERT)   (sval) ^= (sflag); \
02662             else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \
02663             else                                    (sval) |= (sflag); \
02664         } \
02665         else {\
02666             if (smode == ACHANNEL_SETFLAG_INVERT)   (sval) ^= (sflag); \
02667             else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \
02668             else                                    (sval) &= ~(sflag); \
02669         }\
02670     }
02671 
02672 /* Change value of some setting for a channel 
02673  *  - setting: eAnimChannel_Settings
02674  *  - mode: eAnimChannels_SetFlag
02675  */
02676 void ANIM_channel_setting_set (bAnimContext *ac, bAnimListElem *ale, int setting, short mode)
02677 {
02678     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
02679     
02680     /* 1) check that the setting exists for the current context */
02681     if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) 
02682     {
02683         /* 2) get pointer to check for flag in, and the flag to check for */
02684         short negflag, ptrsize;
02685         int flag;
02686         void *ptr;
02687         
02688         flag= acf->setting_flag(ac, setting, &negflag);
02689         ptr= acf->setting_ptr(ale, setting, &ptrsize);
02690         
02691         /* check if flag is enabled */
02692         if (ptr && flag) {
02693             switch (ptrsize) {
02694                 case sizeof(int):   /* integer pointer for setting */
02695                 {
02696                     int *val= (int *)ptr;
02697                     ACF_SETTING_SET(*val, flag, mode);
02698                 }
02699                     break;
02700                     
02701                 case sizeof(short): /* short pointer for setting */
02702                 {
02703                     short *val= (short *)ptr;
02704                     ACF_SETTING_SET(*val, flag, mode);
02705                 }
02706                     break;
02707                     
02708                 case sizeof(char):  /* char pointer for setting */
02709                 {
02710                     char *val= (char *)ptr;
02711                     ACF_SETTING_SET(*val, flag, mode);
02712                 }
02713                     break;
02714             }
02715         }
02716     }
02717 }
02718 
02719 /* --------------------------- */
02720 
02721 // XXX hardcoded size of icons
02722 #define ICON_WIDTH      17
02723 // XXX hardcoded width of sliders
02724 #define SLIDER_WIDTH    80
02725 // XXX hardcoded width of rename textboxes
02726 #define RENAME_TEXT_WIDTH 100
02727 
02728 /* Draw the given channel */
02729 // TODO: make this use UI controls for the buttons
02730 void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
02731 {
02732     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
02733     View2D *v2d= &ac->ar->v2d;
02734     short selected, offset;
02735     float y, ymid, ytext;
02736     
02737     /* sanity checks - don't draw anything */
02738     if ELEM(NULL, acf, ale)
02739         return;
02740     
02741     /* get initial offset */
02742     if (acf->get_offset)
02743         offset= acf->get_offset(ac, ale);
02744     else
02745         offset= 0;
02746         
02747     /* calculate appropriate y-coordinates for icon buttons 
02748      *  7 is hardcoded factor for half-height of icons
02749      */
02750     y= (ymaxc - yminc)/2 + yminc;
02751     ymid= y - 7;
02752     /* y-coordinates for text is only 4 down from middle */
02753     ytext= y - 4;
02754     
02755     /* check if channel is selected */
02756     if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
02757         selected= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
02758     else
02759         selected= 0;
02760         
02761     /* set blending again, as may not be set in previous step */
02762     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
02763     glEnable(GL_BLEND);
02764     
02765     /* step 1) draw backdrop ...........................................  */
02766     if (acf->draw_backdrop)
02767         acf->draw_backdrop(ac, ale, yminc, ymaxc);
02768         
02769     /* step 2) draw expand widget ....................................... */
02770     if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
02771         /* just skip - drawn as widget now */
02772         offset += ICON_WIDTH; 
02773     }
02774         
02775     /* step 3) draw icon ............................................... */
02776     if (acf->icon) {
02777         UI_icon_draw(offset, ymid, acf->icon(ale));
02778         offset += ICON_WIDTH; 
02779     }
02780     
02781     /* turn off blending, since not needed anymore... */
02782     glDisable(GL_BLEND);
02783         
02784     /* step 4) draw special toggles  .................................
02785      *  - in Graph Editor, checkboxes for visibility in curves area
02786      *  - in NLA Editor, glowing dots for solo/not solo...
02787      */
02788     if (ac->sl) {
02789         if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
02790             /* for F-Curves, draw color-preview of curve behind checkbox */
02791             if (ale->type == ANIMTYPE_FCURVE) {
02792                 FCurve *fcu= (FCurve *)ale->data;
02793                 
02794                 /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever 
02795                  * color the curve has stored 
02796                  */
02797                 glColor3fv(fcu->color);
02798                 
02799                 /* just a solid color rect
02800                  *  hardcoded 17 pixels width is slightly wider than icon width, so that 
02801                  *  there's a slight border around it 
02802                  */
02803                 glRectf(offset, yminc, offset+17, ymaxc);
02804             }
02805             
02806             /* icon is drawn as widget now... */
02807             offset += ICON_WIDTH; 
02808         }
02809         else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
02810             /* just skip - drawn as widget now */
02811             offset += ICON_WIDTH; 
02812         }
02813     }
02814     
02815     /* step 5) draw name ............................................... */
02816     // TODO: when renaming, we might not want to draw this, especially if name happens to be longer than channel
02817     if (acf->name) {
02818         char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
02819         
02820         /* set text color */
02821         // XXX: if active, highlight differently?
02822         if (selected)
02823             UI_ThemeColor(TH_TEXT_HI);
02824         else
02825             UI_ThemeColor(TH_TEXT);
02826             
02827         /* get name */
02828         acf->name(ale, name);
02829         
02830         offset += 3;
02831         UI_DrawString(offset, ytext, name);
02832         
02833         /* draw red underline if channel is disabled */
02834         if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) 
02835         {
02836             // FIXME: replace hardcoded color here, and check on extents!
02837             glColor3f(1.0f, 0.0f, 0.0f);
02838             glLineWidth(2.0);
02839                 fdrawline((float)(offset), yminc, 
02840                           (float)(v2d->cur.xmax), yminc);
02841             glLineWidth(1.0);
02842         }
02843     }
02844     
02845     /* step 6) draw backdrops behidn mute+protection toggles + (sliders) ....................... */
02846     /* reset offset - now goes from RHS of panel */
02847     offset = 0;
02848     
02849     // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
02850     
02851     if (v2d) {
02852         short draw_sliders = 0;
02853         float color[3];
02854         
02855         /* get and set backdrop color */
02856         acf->get_backdrop_color(ac, ale, color);
02857         glColor3fv(color);
02858         
02859         /* check if we need to show the sliders */
02860         if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
02861             switch (ac->spacetype) {
02862                 case SPACE_ACTION:
02863                 {
02864                     SpaceAction *saction= (SpaceAction *)ac->sl;
02865                     draw_sliders= (saction->flag & SACTION_SLIDERS);
02866                 }
02867                     break;
02868                 case SPACE_IPO:
02869                 {
02870                     SpaceIpo *sipo= (SpaceIpo *)ac->sl;
02871                     draw_sliders= (sipo->flag & SIPO_SLIDERS);
02872                 }
02873                     break;
02874             }
02875         }
02876         
02877         /* check if there's enough space for the toggles if the sliders are drawn too */
02878         if ( !(draw_sliders) || ((v2d->mask.xmax-v2d->mask.xmin) > ACHANNEL_BUTTON_WIDTH/2) ) {
02879             /* protect... */
02880             if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
02881                 offset += ICON_WIDTH;
02882             /* mute... */
02883             if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
02884                 offset += ICON_WIDTH;
02885         }
02886         
02887         /* draw slider
02888          *  - even if we can draw sliders for this view, we must also check that the channel-type supports them
02889          *    (only only F-Curves really can support them for now)
02890          *  - slider should start before the toggles (if they're visible) to keep a clean line down the side
02891          */
02892         if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
02893             /* adjust offset */
02894             offset += SLIDER_WIDTH;
02895         }
02896         
02897         
02898         /* finally draw a backdrop rect behind these 
02899          *  - starts from the point where the first toggle/slider starts, 
02900          *  - ends past the space that might be reserved for a scroller
02901          */
02902         glRectf(v2d->cur.xmax-(float)offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc);
02903     }
02904 }
02905 
02906 /* ------------------ */
02907 
02908 /* callback for (normal) widget settings - send notifiers */
02909 static void achannel_setting_widget_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
02910 {
02911     WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
02912 }
02913 
02914 /* callback for widget settings that need flushing */
02915 static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void *setting_wrap)
02916 {
02917     bAnimListElem *ale_setting= (bAnimListElem *)ale_npoin;
02918     bAnimContext ac;
02919     ListBase anim_data = {NULL, NULL};
02920     int filter;
02921     int setting = GET_INT_FROM_POINTER(setting_wrap);
02922     short on = 0;
02923     
02924     /* send notifiers before doing anything else... */
02925     WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
02926     
02927     /* verify animation context */
02928     if (ANIM_animdata_get_context(C, &ac) == 0)
02929         return;
02930     
02931     /* verify that we have a channel to operate on, and that it has all we need */
02932     if (ale_setting) {
02933         /* check if the setting is on... */
02934         on= ANIM_channel_setting_get(&ac, ale_setting, setting);
02935         
02936         /* on == -1 means setting not found... */
02937         if (on == -1)
02938             return;
02939     }
02940     else
02941         return;
02942     
02943     /* get all channels that can possibly be chosen - but ignore hierarchy */
02944     filter= ANIMFILTER_DATA_VISIBLE|ANIMFILTER_LIST_CHANNELS;
02945     ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
02946     
02947     /* call API method to flush the setting */
02948     ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
02949     
02950     /* free temp data */
02951     BLI_freelistN(&anim_data);
02952 }
02953 
02954 /* callback for rename widgets - clear rename-in-progress */
02955 static void achannel_setting_rename_done_cb(bContext *C, void *ads_poin, void *UNUSED(arg2))
02956 {
02957     bDopeSheet *ads = (bDopeSheet *)ads_poin;
02958     
02959     /* reset rename index so that edit box disappears now that editing is done */
02960     ads->renameIndex = 0;
02961     
02962     /* send notifiers */
02963     // XXX: right notifier?
02964     WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_RENAME, NULL);
02965 }
02966 
02967 /* callback for widget sliders - insert keyframes */
02968 static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
02969 {
02970     ID *id= (ID *)id_poin;
02971     FCurve *fcu= (FCurve *)fcu_poin;
02972     
02973     ReportList *reports = CTX_wm_reports(C);
02974     Scene *scene= CTX_data_scene(C);
02975     PointerRNA id_ptr, ptr;
02976     PropertyRNA *prop;
02977     short flag=0, done=0;
02978     float cfra;
02979     
02980     /* get current frame */
02981     // NOTE: this will do for now...
02982     cfra= (float)CFRA;
02983     
02984     /* get flags for keyframing */
02985     flag = ANIM_get_keyframing_flags(scene, 1);
02986     
02987     /* get RNA pointer, and resolve the path */
02988     RNA_id_pointer_create(id, &id_ptr);
02989     
02990     /* try to resolve the path stored in the F-Curve */
02991     if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
02992         /* set the special 'replace' flag if on a keyframe */
02993         if (fcurve_frame_has_keyframe(fcu, cfra, 0))
02994             flag |= INSERTKEY_REPLACE;
02995         
02996         /* insert a keyframe for this F-Curve */
02997         done= insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag);
02998         
02999         if (done)
03000             WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
03001     }
03002 }
03003 
03004 /* callback for shapekey widget sliders - insert keyframes */
03005 static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
03006 {
03007     Key *key= (Key *)key_poin;
03008     KeyBlock *kb= (KeyBlock *)kb_poin;
03009     char *rna_path= key_get_curValue_rnaPath(key, kb);
03010     
03011     ReportList *reports = CTX_wm_reports(C);
03012     Scene *scene= CTX_data_scene(C);
03013     PointerRNA id_ptr, ptr;
03014     PropertyRNA *prop;
03015     short flag=0, done=0;
03016     float cfra;
03017     
03018     /* get current frame */
03019     // NOTE: this will do for now...
03020     cfra= (float)CFRA;
03021     
03022     /* get flags for keyframing */
03023     flag = ANIM_get_keyframing_flags(scene, 1);
03024     
03025     /* get RNA pointer, and resolve the path */
03026     RNA_id_pointer_create((ID *)key, &id_ptr);
03027     
03028     /* try to resolve the path stored in the F-Curve */
03029     if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
03030         /* find or create new F-Curve */
03031         // XXX is the group name for this ok?
03032         bAction *act= verify_adt_action((ID *)key, 1);
03033         FCurve *fcu= verify_fcurve(act, NULL, rna_path, 0, 1);
03034         
03035         /* set the special 'replace' flag if on a keyframe */
03036         if (fcurve_frame_has_keyframe(fcu, cfra, 0))
03037             flag |= INSERTKEY_REPLACE;
03038         
03039         /* insert a keyframe for this F-Curve */
03040         done= insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag);
03041         
03042         if (done)
03043             WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
03044     }
03045     
03046     /* free the path */
03047     if (rna_path)
03048         MEM_freeN(rna_path);
03049 }
03050 
03051 /* Draw a widget for some setting */
03052 static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting)
03053 {
03054     short negflag, ptrsize /* , enabled */ /* UNUSED */, butType;
03055     int flag, icon;
03056     void *ptr;
03057     const char *tooltip;
03058     uiBut *but = NULL;
03059     
03060     /* get the flag and the pointer to that flag */
03061     flag= acf->setting_flag(ac, setting, &negflag);
03062     ptr= acf->setting_ptr(ale, setting, &ptrsize);
03063     /* enabled= ANIM_channel_setting_get(ac, ale, setting); */ /* UNUSED */
03064     
03065     /* get the base icon for the setting */
03066     switch (setting) {
03067         case ACHANNEL_SETTING_VISIBLE:  /* visibility eyes */
03068             //icon= ((enabled)? ICON_VISIBLE_IPO_ON : ICON_VISIBLE_IPO_OFF);
03069             icon= ICON_VISIBLE_IPO_OFF;
03070             
03071             if (ale->type == ANIMTYPE_FCURVE)
03072                 tooltip= "Channel is visible in Graph Editor for editing";
03073             else
03074                 tooltip= "Channel(s) are visible in Graph Editor for editing";
03075             break;
03076             
03077         case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
03078             //icon= ((enabled)? ICON_TRIA_DOWN : ICON_TRIA_RIGHT);
03079             icon= ICON_TRIA_RIGHT;
03080             tooltip= "Make channels grouped under this channel visible";
03081             break;
03082             
03083         case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
03084             //icon= ((enabled)? ICON_LAYER_ACTIVE : ICON_LAYER_USED);
03085             icon= ICON_LAYER_USED;
03086             tooltip= "NLA Track is the only one evaluated for the AnimData block it belongs to";
03087             break;
03088         
03089         /* --- */
03090         
03091         case ACHANNEL_SETTING_PROTECT: /* protected lock */
03092             // TODO: what about when there's no protect needed?
03093             //icon= ((enabled)? ICON_LOCKED : ICON_UNLOCKED);
03094             icon= ICON_UNLOCKED;
03095             tooltip= "Editability of keyframes for this channel";
03096             break;
03097             
03098         case ACHANNEL_SETTING_MUTE: /* muted speaker */
03099             //icon= ((enabled)? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF);
03100             icon= ICON_MUTE_IPO_OFF;
03101             
03102             if (ale->type == ALE_FCURVE) 
03103                 tooltip= "Does F-Curve contribute to result";
03104             else
03105                 tooltip= "Do channels contribute to result";
03106             break;
03107             
03108         default:
03109             tooltip= NULL;
03110             icon= 0;
03111             break;
03112     }
03113     
03114     /* type of button */
03115     if (negflag)
03116         butType= ICONTOGN;
03117     else
03118         butType= ICONTOG;
03119     
03120     /* draw button for setting */
03121     if (ptr && flag) {
03122         switch (ptrsize) {
03123             case sizeof(int):   /* integer pointer for setting */
03124                 but= uiDefIconButBitI(block, butType, flag, 0, icon, 
03125                         xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
03126                 break;
03127                 
03128             case sizeof(short): /* short pointer for setting */
03129                 but= uiDefIconButBitS(block, butType, flag, 0, icon, 
03130                         xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
03131                 break;
03132                 
03133             case sizeof(char):  /* char pointer for setting */
03134                 but= uiDefIconButBitC(block, butType, flag, 0, icon, 
03135                         xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
03136                 break;
03137         }
03138         
03139         /* set call to send relevant notifiers and/or perform type-specific updates */
03140         if (but) {
03141             switch (setting) {
03142                 /* settings needing flushing up/down hierarchy  */
03143                 case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
03144                 case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
03145                 case ACHANNEL_SETTING_MUTE: /* General - muting flags */
03146                     uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
03147                     break;
03148                     
03149                 /* no flushing */
03150                 case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */
03151                 default:
03152                     uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
03153             }
03154         }
03155     }
03156 }
03157 
03158 /* Draw UI widgets the given channel */
03159 void ANIM_channel_draw_widgets (bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, float yminc, float ymaxc, size_t channel_index)
03160 {
03161     bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
03162     View2D *v2d= &ac->ar->v2d;
03163     float y, ymid/*, ytext*/;
03164     short offset;
03165     
03166     /* sanity checks - don't draw anything */
03167     if ELEM3(NULL, acf, ale, block)
03168         return;
03169     
03170     /* get initial offset */
03171     if (acf->get_offset)
03172         offset= acf->get_offset(ac, ale);
03173     else
03174         offset= 0;
03175         
03176     /* calculate appropriate y-coordinates for icon buttons 
03177      *  7 is hardcoded factor for half-height of icons
03178      */
03179     y= (ymaxc - yminc)/2 + yminc;
03180     ymid= y - 7;
03181     /* y-coordinates for text is only 4 down from middle */
03182     /* ytext= y - 4; */
03183     
03184     /* no button backdrop behind icons */
03185     uiBlockSetEmboss(block, UI_EMBOSSN);
03186     
03187     /* step 1) draw expand widget ....................................... */
03188     if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
03189         draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_EXPAND);
03190         offset += ICON_WIDTH; 
03191     }
03192         
03193     /* step 2) draw icon ............................................... */
03194     if (acf->icon) {
03195         /* icon is not drawn here (not a widget) */
03196         offset += ICON_WIDTH; 
03197     }
03198         
03199     /* step 3) draw special toggles  .................................
03200      *  - in Graph Editor, checkboxes for visibility in curves area
03201      *  - in NLA Editor, glowing dots for solo/not solo...
03202      */
03203     if (ac->sl) {
03204         if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
03205             /* visibility toggle  */
03206             draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
03207             offset += ICON_WIDTH; 
03208         }
03209         else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
03210             /* 'solo' setting for NLA Tracks */
03211             draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
03212             offset += ICON_WIDTH; 
03213         }
03214     }
03215     
03216     /* step 4) draw text - check if renaming widget is in use... */
03217     if (acf->name_prop && ac->ads) {
03218         float channel_height = ymaxc - yminc;
03219         
03220         /* if rename index matches, add widget for this */
03221         if (ac->ads->renameIndex == channel_index+1) {
03222             PointerRNA ptr;
03223             PropertyRNA *prop;
03224             
03225             /* draw renaming widget if we can get RNA pointer for it */
03226             if (acf->name_prop(ale, &ptr, &prop)) {
03227                 uiBut *but;
03228                 
03229                 uiBlockSetEmboss(block, UI_EMBOSS);
03230                 
03231                 but = uiDefButR(block, TEX, 1, "", offset+3, yminc, RENAME_TEXT_WIDTH, channel_height, &ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL);
03232                 uiButSetFunc(but, achannel_setting_rename_done_cb, ac->ads, NULL);
03233                 uiButActiveOnly(C, block, but);
03234                 
03235                 uiBlockSetEmboss(block, UI_EMBOSSN);
03236             }
03237         }
03238     }
03239     
03240     /* step 5) draw mute+protection toggles + (sliders) ....................... */
03241     /* reset offset - now goes from RHS of panel */
03242     offset = 0;
03243     
03244     // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
03245     
03246     if (v2d) {
03247         short draw_sliders = 0;
03248         
03249         /* check if we need to show the sliders */
03250         if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
03251             switch (ac->spacetype) {
03252                 case SPACE_ACTION:
03253                 {
03254                     SpaceAction *saction= (SpaceAction *)ac->sl;
03255                     draw_sliders= (saction->flag & SACTION_SLIDERS);
03256                 }
03257                     break;
03258                 case SPACE_IPO:
03259                 {
03260                     SpaceIpo *sipo= (SpaceIpo *)ac->sl;
03261                     draw_sliders= (sipo->flag & SIPO_SLIDERS);
03262                 }
03263                     break;
03264             }
03265         }
03266         
03267         /* check if there's enough space for the toggles if the sliders are drawn too */
03268         if ( !(draw_sliders) || ((v2d->mask.xmax-v2d->mask.xmin) > ACHANNEL_BUTTON_WIDTH/2) ) {
03269             /* protect... */
03270             if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
03271                 offset += ICON_WIDTH; 
03272                 draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax-offset, ymid, ACHANNEL_SETTING_PROTECT);
03273             }
03274             /* mute... */
03275             if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
03276                 offset += ICON_WIDTH;
03277                 draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax-offset, ymid, ACHANNEL_SETTING_MUTE);
03278             }
03279         }
03280         
03281         /* draw slider
03282          *  - even if we can draw sliders for this view, we must also check that the channel-type supports them
03283          *    (only only F-Curves really can support them for now)
03284          *  - to make things easier, we use RNA-autobuts for this so that changes are reflected immediately, 
03285          *    whereever they occurred. BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
03286          *    and wouldn't be able to auto-keyframe...
03287          *  - slider should start before the toggles (if they're visible) to keep a clean line down the side
03288          */
03289         if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
03290             /* adjust offset */
03291             // TODO: make slider width dynamic, so that they can be easier to use when the view is wide enough
03292             offset += SLIDER_WIDTH;
03293             
03294             /* need backdrop behind sliders... */
03295             uiBlockSetEmboss(block, UI_EMBOSS);
03296             
03297             if (ale->id) { /* Slider using RNA Access -------------------- */
03298                 PointerRNA id_ptr, ptr;
03299                 PropertyRNA *prop;
03300                 char *rna_path = NULL;
03301                 int array_index = 0;
03302                 short free_path = 0;
03303                 
03304                 /* get destination info */
03305                 if (ale->type == ANIMTYPE_FCURVE) {
03306                     FCurve *fcu= (FCurve *)ale->data;
03307                     
03308                     rna_path= fcu->rna_path;
03309                     array_index= fcu->array_index;
03310                 }
03311                 else if (ale->type == ANIMTYPE_SHAPEKEY) {
03312                     KeyBlock *kb= (KeyBlock *)ale->data;
03313                     Key *key= (Key *)ale->id;
03314                     
03315                     rna_path= key_get_curValue_rnaPath(key, kb);
03316                     free_path= 1;
03317                 }
03318                 
03319                 /* only if RNA-Path found */
03320                 if (rna_path) {
03321                     /* get RNA pointer, and resolve the path */
03322                     RNA_id_pointer_create(ale->id, &id_ptr);
03323                     
03324                     /* try to resolve the path */
03325                     if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
03326                         uiBut *but;
03327                         
03328                         /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
03329                         but= uiDefAutoButR(block, &ptr, prop, array_index, "", ICON_NONE, (int)v2d->cur.xmax-offset, ymid, SLIDER_WIDTH, (int)ymaxc-yminc);
03330                         
03331                         /* assign keyframing function according to slider type */
03332                         if (ale->type == ANIMTYPE_SHAPEKEY)
03333                             uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
03334                         else
03335                             uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data);
03336                     }
03337                     
03338                     /* free the path if necessary */
03339                     if (free_path)
03340                         MEM_freeN(rna_path);
03341                 }
03342             }
03343             else { /* Special Slider for stuff without RNA Access ---------- */
03344                 // TODO: only implement this case when we really need it...
03345             }
03346         }
03347     }
03348 }
03349 
03350 /* *********************************************** */