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