diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-08-11 15:52:23 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-08-11 15:52:23 +0400 |
commit | b9584607c57720da9e443a42eff30d758c4075a0 (patch) | |
tree | f1eb2e01fb6af22a6c7f908b3e933c897799080e /source/blender/editors/animation/anim_channels_defines.c | |
parent | 911078aaaddfab72eeea564f671f7e1a1c392300 (diff) |
Animation Editors: Code Cleanup Part 1 - Drawing
Finally started refactoring the drawing code for animation editors so that all the drawing (of the channels/names list) is done using standardised code for all the editors.
A little specialised system for this has been made, and is now used for DopeSheet and Graph Editor drawing. This should make it easier to add new channel types with less effort.
Protect/mute toggles are now always clamped to the right-hand edge of the channels list. So you can now make the list wider to view longer names fully. However, since the mouse-handling hasn't been fixed yet, this won't always work.
TODOs:
* make mouse-click handling code use this system too, simplifying things to 1-2 lines of code there. Maybe this could be made to use UI widgets instead at a later date?
* NLA still needs to be ported to this system
Diffstat (limited to 'source/blender/editors/animation/anim_channels_defines.c')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 1946 |
1 files changed, 1946 insertions, 0 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c new file mode 100644 index 00000000000..8132d83fd7b --- /dev/null +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -0,0 +1,1946 @@ +/** + * $Id: $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung + * All rights reserved. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <float.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_listBase.h" +#include "DNA_anim_types.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_constraint_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_meta_types.h" +#include "DNA_userdef_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_windowmanager_types.h" +#include "DNA_world_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "BKE_animsys.h" +#include "BKE_action.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_key.h" +#include "BKE_material.h" +#include "BKE_object.h" +#include "BKE_context.h" +#include "BKE_utildefines.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "ED_anim_api.h" +#include "ED_keyframes_edit.h" // XXX move the select modes out of there! +#include "ED_screen.h" +#include "ED_space_api.h" + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* *********************************************** */ +// XXX constant defines to be moved elsewhere? + +/* extra padding for lengths (to go under scrollers) */ +#define EXTRA_SCROLL_PAD 100.0f + +/* size of indent steps */ +#define INDENT_STEP_SIZE 7 + +/* macros used for type defines */ + /* get the pointer used for some flag */ +#define GET_ACF_FLAG_PTR(ptr) \ + { \ + *type= sizeof((ptr)); \ + return &(ptr); \ + } + + +/* XXX */ +extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); +extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown); + + +/* *********************************************** */ +/* Generic Functions (Type independent) */ + +/* Draw Backdrop ---------------------------------- */ + +/* backdrop for top-level widgets (Scene and Object only) */ +static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + View2D *v2d= &ac->ar->v2d; + short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0; + short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0; + + /* darker blue for top-level widgets */ + UI_ThemeColor(TH_DOPESHEET_CHANNELOB); + + /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ + uiSetRoundBox((expanded)? (1):(1|8)); + gl_round_box(GL_POLYGON, offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); +} + +/* backdrop for data expanders under top-level Scene/Object */ +static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + View2D *v2d= &ac->ar->v2d; + short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0; + + /* lighter color than top-level widget */ + UI_ThemeColor(TH_DOPESHEET_CHANNELSUBOB); + + /* no rounded corner - just rectangular box */ + glRectf(offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc); +} + +/* backdrop for generic channels */ +static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + View2D *v2d= &ac->ar->v2d; + SpaceAction *saction = NULL; + bActionGroup *grp = NULL; + short indent= (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0; + short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0; + + /* get context info needed... */ + if ((ac->sa) && (ac->sa->spacetype == SPACE_ACTION)) + saction= (SpaceAction *)ac->sa->spacedata.first; + + if (ale->type == ANIMTYPE_FCURVE) { + FCurve *fcu= (FCurve *)ale->data; + grp= fcu->grp; + } + + /* set color for normal channels + * - use 3 shades of color group/standard color for 3 indention level + * - only use group colors if allowed to, and if actually feasible + */ + if ( (saction && !(saction->flag & SACTION_NODRAWGCOLORS)) && + ((grp) && (grp->customCol)) ) + { + char cp[3]; + + if (indent == 2) { + VECCOPY(cp, grp->cs.solid); + } + else if (indent == 1) { + VECCOPY(cp, grp->cs.select); + } + else { + VECCOPY(cp, grp->cs.active); + } + + glColor3ub(cp[0], cp[1], cp[2]); + } + else // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)? + UI_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40)); + + /* no rounded corners - just rectangular box */ + glRectf(offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc); +} + +/* Indention + Offset ------------------------------------------- */ + +/* indention level is always the value in the name */ +static short acf_generic_indention_0(bAnimContext *ac, bAnimListElem *ale) +{ + return 0; +} +static short acf_generic_indention_1(bAnimContext *ac, bAnimListElem *ale) +{ + return 1; +} +#if 0 // XXX not used +static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale) +{ + return 2; +} +#endif + +/* indention which varies with the grouping status */ +static short acf_generic_indention_flexible(bAnimContext *ac, bAnimListElem *ale) +{ + short indent= 0; + + if (ale->id) { + /* special exception for materials and particles */ + if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) + indent++; + } + + /* grouped F-Curves need extra level of indention */ + if (ale->type == ANIMTYPE_FCURVE) { + FCurve *fcu= (FCurve *)ale->data; + + // TODO: we need some way of specifying that the indention color should be one less... + if (fcu->grp) + indent++; + } + + /* no indention */ + return indent; +} + +/* basic offset for channels derived from indention */ +static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + + if (acf && acf->get_indent_level) + return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE; + else + return 0; +} + +/* offset for groups + grouped entities */ +static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale) +{ + short offset= acf_generic_basic_offset(ac, ale); + + if (ale->id) { + /* special exception for materials and particles */ + if (ELEM(GS(ale->id->name),ID_MA,ID_PA)) + offset += 21; + + /* if not in Action Editor mode, groupings must carry some offset too... */ + else if (ac->datatype != ANIMCONT_ACTION) + offset += 14; + } + + /* offset is just the normal type - i.e. based on indention */ + return offset; +} + +/* Name ------------------------------------------- */ + +/* name for ID block entries */ +static void acf_generic_idblock_name(bAnimListElem *ale, char *name) +{ + ID *id= (ID *)ale->data; /* data pointed to should be an ID block */ + + /* just copy the name... */ + if (id && name) + sprintf(name, id->name+2); +} + +/* Settings ------------------------------------------- */ + +/* check if some setting exists for this object-based data-expander (category only) */ +static short acf_generic_dsexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* only expand supported */ + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get pointer to the setting (category only) */ +static void *acf_generic_dsexpand_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Object *ob= (Object *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(ob->nlaflag); // XXX + + default: /* unsupported */ + return NULL; + } +} + +/* check if some setting exists for this object-based data-expander (datablock only) */ +static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* expand is always supported */ + case ACHANNEL_SETTING_EXPAND: + return 1; + + /* mute is only supported for NLA */ + case ACHANNEL_SETTING_MUTE: + return ((ac) && (ac->spacetype == SPACE_NLA)); + + /* other flags are never supported */ + default: + return 0; + } +} + +/* *********************************************** */ +/* Type Specific Functions + Defines */ + +/* Scene ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_scene_icon(bAnimListElem *ale) +{ + return ICON_SCENE_DATA; +} + +/* check if some setting exists for this channel */ +static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* muted only in NLA */ + case ACHANNEL_SETTING_MUTE: + return ((ac) && (ac->spacetype == SPACE_NLA)); + + /* only select and expand supported otherwise */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_scene_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return SCE_DS_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return SCE_DS_COLLAPSED; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Scene *scene= (Scene *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + GET_ACF_FLAG_PTR(scene->flag); + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(scene->flag); + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + if (scene->adt) + GET_ACF_FLAG_PTR(scene->adt->flag) + else + return NULL; + + default: /* unsupported */ + return 0; + } +} + +/* scene type define */ +static bAnimChannelType ACF_SCENE = +{ + acf_generic_root_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + NULL, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_scene_icon, /* icon */ + + acf_scene_setting_valid, /* has setting */ + acf_scene_setting_flag, /* flag for setting */ + acf_scene_setting_ptr /* pointer for setting */ +}; + +/* Object ------------------------------------------- */ + +static int acf_object_icon(bAnimListElem *ale) +{ + Base *base= (Base *)ale->data; + Object *ob= base->object; + + /* icon depends on object-type */ + if (ob->type == OB_ARMATURE) + return ICON_ARMATURE_DATA; + else + return ICON_OBJECT_DATA; +} + +/* name for object */ +static void acf_object_name(bAnimListElem *ale, char *name) +{ + Base *base= (Base *)ale->data; + Object *ob= base->object; + + /* just copy the name... */ + if (ob && name) + sprintf(name, ob->id.name+2); +} + +/* check if some setting exists for this channel */ +static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* muted only in NLA */ + case ACHANNEL_SETTING_MUTE: + return ((ac) && (ac->spacetype == SPACE_NLA)); + + /* only select and expand supported otherwise */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_object_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return SELECT; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return OB_ADS_COLLAPSED; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Base *base= (Base *)ale->data; + Object *ob= base->object; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + GET_ACF_FLAG_PTR(ob->flag); + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(ob->nlaflag); // xxx + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + if (ob->adt) + GET_ACF_FLAG_PTR(ob->adt->flag) + else + return NULL; + + default: /* unsupported */ + return 0; + } +} + +/* object type define */ +static bAnimChannelType ACF_OBJECT = +{ + acf_generic_root_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + NULL, /* offset */ + + acf_object_name, /* name */ + acf_object_icon, /* icon */ + + acf_object_setting_valid, /* has setting */ + acf_object_setting_flag, /* flag for setting */ + acf_object_setting_ptr /* pointer for setting */ +}; + +/* Group ------------------------------------------- */ + +/* backdrop for group widget */ +static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + View2D *v2d= &ac->ar->v2d; + short expanded= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0; + short offset= (acf->get_offset) ? acf->get_offset(ac, ale) : 0; + + /* only for action group channels */ + if (ale->flag & AGRP_ACTIVE) + UI_ThemeColorShade(TH_GROUP_ACTIVE, 10); + else + UI_ThemeColorShade(TH_GROUP, 20); + + /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ + uiSetRoundBox((expanded)? (1):(1|8)); + gl_round_box(GL_POLYGON, offset, yminc, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); +} + +/* name for group entries */ +static void acf_group_name(bAnimListElem *ale, char *name) +{ + bActionGroup *agrp= (bActionGroup *)ale->data; + + /* just copy the name... */ + if (agrp && name) + sprintf(name, agrp->name); +} + +/* check if some setting exists for this channel */ +static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + /* for now, all settings are supported */ + return 1; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_group_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return AGRP_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return AGRP_EXPANDED; + + case ACHANNEL_SETTING_MUTE: /* muted */ + return AGRP_MUTED; + + case ACHANNEL_SETTING_PROTECT: /* protected */ + //*neg= 1; - if we change this to edtiability + return AGRP_PROTECTED; + + case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */ + *neg= 1; + return AGRP_NOTVISIBLE; + } + + /* this shouldn't happen */ + return 0; +} + +/* get pointer to the setting */ +static void *acf_group_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + bActionGroup *agrp= (bActionGroup *)ale->data; + + /* all flags are just in agrp->flag for now... */ + GET_ACF_FLAG_PTR(agrp->flag); +} + +/* group type define */ +static bAnimChannelType ACF_GROUP = +{ + acf_group_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_group_name, /* name */ + NULL, /* icon */ + + acf_group_setting_valid, /* has setting */ + acf_group_setting_flag, /* flag for setting */ + acf_group_setting_ptr /* pointer for setting */ +}; + +/* F-Curve ------------------------------------------- */ + +/* name for fcurve entries */ +static void acf_fcurve_name(bAnimListElem *ale, char *name) +{ + getname_anim_fcurve(name, ale->id, ale->data); +} + +/* check if some setting exists for this channel */ +static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + FCurve *fcu= (FCurve *)ale->data; + + switch (setting) { + /* unsupported */ + case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */ + return 0; + + /* conditionally available */ + case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */ + if (fcu->bezt) + return 1; + else + return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT + + /* always available */ + default: + return 1; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_fcurve_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return FCURVE_SELECTED; + + case ACHANNEL_SETTING_MUTE: /* muted */ + return FCURVE_MUTED; + + case ACHANNEL_SETTING_PROTECT: /* protected */ + //*neg= 1; - if we change this to edtiability + return FCURVE_PROTECTED; + + case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */ + return FCURVE_VISIBLE; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_fcurve_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + FCurve *fcu= (FCurve *)ale->data; + + /* all flags are just in agrp->flag for now... */ + GET_ACF_FLAG_PTR(fcu->flag); +} + +/* fcurve type define */ +static bAnimChannelType ACF_FCURVE = +{ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_flexible, /* indent level */ // xxx rename this to f-curves only? + acf_generic_group_offset, /* offset */ + + acf_fcurve_name, /* name */ + NULL, /* icon */ + + acf_fcurve_setting_valid, /* has setting */ + acf_fcurve_setting_flag, /* flag for setting */ + acf_fcurve_setting_ptr /* pointer for setting */ +}; + +/* Object Action Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_fillactd_icon(bAnimListElem *ale) +{ + return ICON_ACTION; +} + +/* check if some setting exists for this channel */ +static short acf_fillactd_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* only select and expand supported */ + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_fillactd_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return ACT_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return ACT_COLLAPSED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + bAction *act= (bAction *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + GET_ACF_FLAG_PTR(act->flag); + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(act->flag); + + default: /* unsupported */ + return 0; + } +} + +/* object action expander type define */ +static bAnimChannelType ACF_FILLACTD = +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_fillactd_icon, /* icon */ + + acf_fillactd_setting_valid, /* has setting */ + acf_fillactd_setting_flag, /* flag for setting */ + acf_fillactd_setting_ptr /* pointer for setting */ +}; + +/* Drivers Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_filldrivers_icon(bAnimListElem *ale) +{ + return ICON_ANIM_DATA; +} + +static void acf_filldrivers_name(bAnimListElem *ale, char *name) +{ + sprintf(name, "Drivers"); +} + +/* check if some setting exists for this channel */ +// TODO: this could be made more generic +static short acf_filldrivers_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + switch (setting) { + /* only expand supported */ + case ACHANNEL_SETTING_EXPAND: + return 1; + + default: + return 0; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_filldrivers_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return ADT_DRIVERS_COLLAPSED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + AnimData *adt= (AnimData *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(adt->flag); + + default: /* unsupported */ + return 0; + } +} + +/* drivers expander type define */ +static bAnimChannelType ACF_FILLDRIVERS = +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_filldrivers_name, /* name */ + acf_filldrivers_icon, /* icon */ + + acf_filldrivers_setting_valid, /* has setting */ + acf_filldrivers_setting_flag, /* flag for setting */ + acf_filldrivers_setting_ptr /* pointer for setting */ +}; + +/* Materials Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_fillmatd_icon(bAnimListElem *ale) +{ + return ICON_MATERIAL_DATA; +} + +static void acf_fillmatd_name(bAnimListElem *ale, char *name) +{ + sprintf(name, "Materials"); +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_fillmatd_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return OB_ADS_SHOWMATS; + + default: /* unsupported */ + return 0; + } +} + +/* materials expander type define */ +static bAnimChannelType ACF_FILLMATD= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_fillmatd_name, /* name */ + acf_fillmatd_icon, /* icon */ + + acf_generic_dsexpand_setting_valid, /* has setting */ + acf_fillmatd_setting_flag, /* flag for setting */ + acf_generic_dsexpand_setting_ptr /* pointer for setting */ +}; + +/* Particles Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_fillpartd_icon(bAnimListElem *ale) +{ + return ICON_PARTICLE_DATA; +} + +static void acf_fillpartd_name(bAnimListElem *ale, char *name) +{ + sprintf(name, "Particles"); +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_fillpartd_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg= 1; + return OB_ADS_SHOWPARTS; + + default: /* unsupported */ + return 0; + } +} + +/* particles expander type define */ +static bAnimChannelType ACF_FILLPARTD= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_fillpartd_name, /* name */ + acf_fillpartd_icon, /* icon */ + + acf_generic_dsexpand_setting_valid, /* has setting */ + acf_fillpartd_setting_flag, /* flag for setting */ + acf_generic_dsexpand_setting_ptr /* pointer for setting */ +}; + +/* Material Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsmat_icon(bAnimListElem *ale) +{ + return ICON_MATERIAL_DATA; +} + +/* offset for material expanders */ +static short acf_dsmat_offset(bAnimContext *ac, bAnimListElem *ale) +{ + return 21; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsmat_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return MA_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Material *ma= (Material *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(ma->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (ma->adt) + GET_ACF_FLAG_PTR(ma->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* material expander type define */ +static bAnimChannelType ACF_DSMAT= +{ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + acf_dsmat_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dsmat_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsmat_setting_flag, /* flag for setting */ + acf_dsmat_setting_ptr /* pointer for setting */ +}; + +/* Lamp Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dslam_icon(bAnimListElem *ale) +{ + return ICON_LAMP_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dslam_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return LA_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Lamp *la= (Lamp *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(la->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (la->adt) + GET_ACF_FLAG_PTR(la->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* lamp expander type define */ +static bAnimChannelType ACF_DSLAM= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dslam_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dslam_setting_flag, /* flag for setting */ + acf_dslam_setting_ptr /* pointer for setting */ +}; + +/* Camera Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dscam_icon(bAnimListElem *ale) +{ + return ICON_CAMERA_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dscam_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return CAM_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Camera *ca= (Camera *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(ca->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (ca->adt) + GET_ACF_FLAG_PTR(ca->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* camera expander type define */ +static bAnimChannelType ACF_DSCAM= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dscam_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dscam_setting_flag, /* flag for setting */ + acf_dscam_setting_ptr /* pointer for setting */ +}; + +/* Curve Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dscur_icon(bAnimListElem *ale) +{ + return ICON_CURVE_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dscur_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return CU_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Curve *cu= (Curve *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(cu->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (cu->adt) + GET_ACF_FLAG_PTR(cu->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* curve expander type define */ +static bAnimChannelType ACF_DSCUR= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dscur_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dscur_setting_flag, /* flag for setting */ + acf_dscur_setting_ptr /* pointer for setting */ +}; + +/* Shape Key Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsskey_icon(bAnimListElem *ale) +{ + return ICON_SHAPEKEY_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsskey_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return KEYBLOCK_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + Key *key= (Key *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(key->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (key->adt) + GET_ACF_FLAG_PTR(key->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* shapekey expander type define */ +static bAnimChannelType ACF_DSSKEY= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dsskey_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsskey_setting_flag, /* flag for setting */ + acf_dsskey_setting_ptr /* pointer for setting */ +}; + +/* World Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dswor_icon(bAnimListElem *ale) +{ + return ICON_WORLD_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dswor_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return WO_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + World *wo= (World *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(wo->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (wo->adt) + GET_ACF_FLAG_PTR(wo->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* world expander type define */ +static bAnimChannelType ACF_DSWOR= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dswor_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dswor_setting_flag, /* flag for setting */ + acf_dswor_setting_ptr /* pointer for setting */ +}; + +/* Particle Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dspart_icon(bAnimListElem *ale) +{ + return ICON_PARTICLE_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dspart_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return PART_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + ParticleSettings *part= (ParticleSettings *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(part->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (part->adt) + GET_ACF_FLAG_PTR(part->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* particle expander type define */ +static bAnimChannelType ACF_DSPART= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dspart_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dspart_setting_flag, /* flag for setting */ + acf_dspart_setting_ptr /* pointer for setting */ +}; + +/* MetaBall Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsmball_icon(bAnimListElem *ale) +{ + return ICON_META_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsmball_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return MB_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + MetaBall *mb= (MetaBall *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(mb->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + if (mb->adt) + GET_ACF_FLAG_PTR(mb->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* metaball expander type define */ +static bAnimChannelType ACF_DSMBALL= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dsmball_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsmball_setting_flag, /* flag for setting */ + acf_dsmball_setting_ptr /* pointer for setting */ +}; + +/* ShapeKey Entry ------------------------------------------- */ +// XXX ... this is currently obsolete... + +#if 0 +static void dummy_olddraw_shapekeys () +{ + case ANIMTYPE_SHAPEKEY: /* shapekey channel */ + { + KeyBlock *kb = (KeyBlock *)ale->data; + + indent = 0; + special = -1; + + offset= (ale->id) ? 21 : 0; + + if (kb->name[0] == '\0') + sprintf(name, "Key %d", ale->index); + else + strcpy(name, kb->name); + } + break; +} +#endif + +/* Grease Pencil entries ------------------------------------------- */ +// XXX ... this is currently not restored yet + +#if 0 +static void dummy_olddraw_gpencil () +{ + /* determine what needs to be drawn */ + switch (ale->type) { + case ANIMTYPE_GPDATABLOCK: /* gpencil datablock */ + { + bGPdata *gpd = (bGPdata *)ale->data; + ScrArea *sa = (ScrArea *)ale->owner; + + indent = 0; + group= 3; + + /* only show expand if there are any channels */ + if (gpd->layers.first) { + if (gpd->flag & GP_DATA_EXPAND) + expand = ICON_TRIA_DOWN; + else + expand = ICON_TRIA_RIGHT; + } + + switch (sa->spacetype) { + case SPACE_VIEW3D: + { + /* this shouldn't cause any overflow... */ + //sprintf(name, "3DView:%s", view3d_get_name(sa->spacedata.first)); // XXX missing func.. + strcpy(name, "3dView"); + special= ICON_VIEW3D; + } + break; + case SPACE_NODE: + { + SpaceNode *snode= sa->spacedata.first; + char treetype[12]; + + if (snode->treetype == 1) + strcpy(treetype, "Composite"); + else + strcpy(treetype, "Material"); + sprintf(name, "Nodes:%s", treetype); + + special= ICON_NODE; + } + break; + case SPACE_SEQ: + { + SpaceSeq *sseq= sa->spacedata.first; + char imgpreview[10]; + + switch (sseq->mainb) { + case 1: sprintf(imgpreview, "Image..."); break; + case 2: sprintf(imgpreview, "Luma..."); break; + case 3: sprintf(imgpreview, "Chroma..."); break; + case 4: sprintf(imgpreview, "Histogram"); break; + + default: sprintf(imgpreview, "Sequence"); break; + } + sprintf(name, "Sequencer:%s", imgpreview); + + special= ICON_SEQUENCE; + } + break; + case SPACE_IMAGE: + { + SpaceImage *sima= sa->spacedata.first; + + if (sima->image) + sprintf(name, "Image:%s", sima->image->id.name+2); + else + strcpy(name, "Image:<None>"); + + special= ICON_IMAGE_COL; + } + break; + + default: + { + sprintf(name, "<Unknown GP-Data Source>"); + special= -1; + } + break; + } + } + break; + case ANIMTYPE_GPLAYER: /* gpencil layer */ + { + bGPDlayer *gpl = (bGPDlayer *)ale->data; + + indent = 0; + special = -1; + expand = -1; + group = 1; + + if (EDITABLE_GPL(gpl)) + protect = ICON_UNLOCKED; + else + protect = ICON_LOCKED; + + if (gpl->flag & GP_LAYER_HIDE) + mute = ICON_MUTE_IPO_ON; + else + mute = ICON_MUTE_IPO_OFF; + + sel = SEL_GPL(gpl); + BLI_snprintf(name, 32, gpl->info); + } + break; + } + + if (group == 3) { + /* only for gp-data channels */ + UI_ThemeColorShade(TH_GROUP, 20); + uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8)); + gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8); + } +} +#endif + +/* *********************************************** */ +/* Type Registration and General Access */ + +/* These globals only ever get directly accessed in this file */ +static bAnimChannelType *animchannelTypeInfo[ANIMTYPE_NUM_TYPES]; +static short ACF_INIT= 1; /* when non-zero, the list needs to be updated */ + +/* Initialise type info definitions */ +void ANIM_init_channel_typeinfo_data (void) +{ + int type= 0; + + /* start initialising if necessary... */ + if (ACF_INIT) { + ACF_INIT= 0; + + animchannelTypeInfo[type++]= NULL; /* None */ + animchannelTypeInfo[type++]= NULL; /* AnimData */ + animchannelTypeInfo[type++]= NULL; /* Special */ + + animchannelTypeInfo[type++]= &ACF_SCENE; /* Scene */ + animchannelTypeInfo[type++]= &ACF_OBJECT; /* Object */ + animchannelTypeInfo[type++]= &ACF_GROUP; /* Group */ + animchannelTypeInfo[type++]= &ACF_FCURVE; /* F-Curve */ + + animchannelTypeInfo[type++]= &ACF_FILLACTD; /* Object Action Expander */ + animchannelTypeInfo[type++]= &ACF_FILLDRIVERS; /* Drivers Expander */ + animchannelTypeInfo[type++]= &ACF_FILLMATD; /* Materials Expander */ + animchannelTypeInfo[type++]= &ACF_FILLPARTD; /* Particles Expander */ + + animchannelTypeInfo[type++]= &ACF_DSMAT; /* Material Channel */ + animchannelTypeInfo[type++]= &ACF_DSLAM; /* Lamp Channel */ + animchannelTypeInfo[type++]= &ACF_DSCAM; /* Camera Channel */ + animchannelTypeInfo[type++]= &ACF_DSCUR; /* Curve Channel */ + animchannelTypeInfo[type++]= &ACF_DSSKEY; /* ShapeKey Channel */ + animchannelTypeInfo[type++]= &ACF_DSWOR; /* World Channel */ + animchannelTypeInfo[type++]= &ACF_DSPART; /* Particle Channel */ + animchannelTypeInfo[type++]= &ACF_DSMBALL; /* MetaBall Channel */ + + animchannelTypeInfo[type++]= NULL; /* ShapeKey */ // XXX this is no longer used for now... + + // XXX not restored yet + animchannelTypeInfo[type++]= NULL; /* Grease Pencil Datablock */ + animchannelTypeInfo[type++]= NULL; /* Grease Pencil Layer */ + + // TODO: these types still need to be implemented!!! + // probably need a few extra flags for these special cases... + animchannelTypeInfo[type++]= NULL; /* NLA Track */ + animchannelTypeInfo[type++]= NULL; /* NLA Action */ + } +} + +/* Get type info from given channel type */ +bAnimChannelType *ANIM_channel_get_typeinfo (bAnimListElem *ale) +{ + /* santiy checks */ + if (ale == NULL) + return NULL; + + /* init the typeinfo if not available yet... */ + ANIM_init_channel_typeinfo_data(); + + /* check if type is in bounds... */ + if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES)) + return animchannelTypeInfo[ale->type]; + else + return NULL; +} + +/* --------------------------- */ + +/* Check if some setting for a channel is enabled + * Returns: 1 = On, 0 = Off, -1 = Invalid + */ +short ANIM_channel_setting_get (bAnimContext *ac, bAnimListElem *ale, int setting) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + + /* 1) check that the setting exists for the current context */ + if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) + { + /* 2) get pointer to check for flag in, and the flag to check for */ + short negflag, ptrsize; + int flag; + void *ptr; + + flag= acf->setting_flag(setting, &negflag); + ptr= acf->setting_ptr(ale, setting, &ptrsize); + + /* check if flag is enabled */ + if (ptr && flag) { + switch (ptrsize) { + case sizeof(int): /* integer pointer for setting */ + { + int *val= (int *)ptr; + + if (negflag) + return ((*val) & flag) == 0; + else + return ((*val) & flag) != 0; + } + break; + + case sizeof(short): /* short pointer for setting */ + { + short *val= (short *)ptr; + + if (negflag) + return ((*val) & flag) == 0; + else + return ((*val) & flag) != 0; + } + break; + + case sizeof(char): /* char pointer for setting */ + { + char *val= (char *)ptr; + + if (negflag) + return ((*val) & flag) == 0; + else + return ((*val) & flag) != 0; + } + break; + } + } + } + + /* not found... */ + return -1; +} + + +/* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */ +#define ACF_SETTING_SET(sval, sflag, smode) \ + {\ + if (negflag) {\ + if (smode == ACHANNEL_SETFLAG_TOGGLE) (sval) ^= (sflag); \ + else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \ + else (sval) |= (sflag); \ + } \ + else {\ + if (smode == ACHANNEL_SETFLAG_TOGGLE) (sval) ^= (sflag); \ + else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \ + else (sval) &= ~(sflag); \ + }\ + } + +/* Change value of some setting for a channel + * - setting: eAnimChannel_Settings + * - mode: eAnimChannels_SetFlag + */ +void ANIM_channel_setting_set (bAnimContext *ac, bAnimListElem *ale, int setting, short mode) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + + /* 1) check that the setting exists for the current context */ + if ( (acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting)) ) + { + /* 2) get pointer to check for flag in, and the flag to check for */ + short negflag, ptrsize; + int flag; + void *ptr; + + flag= acf->setting_flag(setting, &negflag); + ptr= acf->setting_ptr(ale, setting, &ptrsize); + + /* check if flag is enabled */ + if (ptr && flag) { + switch (ptrsize) { + case sizeof(int): /* integer pointer for setting */ + { + int *val= (int *)ptr; + ACF_SETTING_SET(*val, flag, mode); + } + break; + + case sizeof(short): /* short pointer for setting */ + { + short *val= (short *)ptr; + ACF_SETTING_SET(*val, flag, mode); + } + break; + + case sizeof(char): /* char pointer for setting */ + { + char *val= (char *)ptr; + ACF_SETTING_SET(*val, flag, mode); + } + break; + } + } + } +} + +/* --------------------------- */ + +// XXX hardcoded size of icons +#define ICON_WIDTH 17 + +/* Draw the given channel */ +// TODO: make this use UI controls for the buttons +void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); + View2D *v2d= &ac->ar->v2d; + short selected, offset, enabled; + float y, ymid, ytext; + + /* sanity checks - don't draw anything */ + if ELEM(NULL, acf, ale) + return; + + /* get initial offset */ + if (acf->get_offset) + offset= acf->get_offset(ac, ale); + else if (acf->get_indent_level) + offset= acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE; + else + offset= 0; + + /* calculate appropriate y-coordinates for icon buttons + * 7 is hardcoded factor for half-height of icons + */ + y= (ymaxc - yminc)/2 + yminc; + ymid= y - 7; + /* y-coordinates for text is only 4 down from middle */ + ytext= y - 4; + + /* check if channel is selected */ + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) + selected= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT); + else + selected= 0; + + /* enable correct blending mode for icons to work... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + /* step 1) draw backdrop ........................................... */ + if (acf->draw_backdrop) + acf->draw_backdrop(ac, ale, yminc, ymaxc); + + /* step 2) draw expand widget ....................................... */ + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) { + enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND); + + UI_icon_draw(offset, ymid, ((enabled)? ICON_TRIA_DOWN : ICON_TRIA_RIGHT)); + offset += ICON_WIDTH; + } + + /* step 3) draw icon ............................................... */ + if (acf->icon) { + UI_icon_draw(offset, ymid, acf->icon(ale)); + offset += ICON_WIDTH; + } + + /* step 4) draw special toggles ................................. + * - in Graph Editor, checkboxes for visibility in curves area + * - in NLA Editor, glowing dots for solo/not solo... + */ + if (ac->sa) { + if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { + enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_VISIBLE); + + /* for F-Curves, draw color-preview of curve behind checkbox */ + if (ale->type == ANIMTYPE_FCURVE) { + FCurve *fcu= (FCurve *)ale->data; + + /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever + * color the curve has stored + */ + glColor3fv(fcu->color); + + /* just a solid color rect + * hardcoded 18 pixels width is slightly wider than icon width, so that + * there's a slight border around it + */ + glRectf(offset, yminc, offset+18, ymaxc); + } + + /* finally the icon itself */ + UI_icon_draw(offset, ymid, ((enabled)? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT)); + offset += ICON_WIDTH; + } + else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) { + /* simply draw glowing dot in NLA for whether the track is enabled or not... */ + // NOTE: assumed to be for NLA track only for now... + enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SOLO); + + UI_icon_draw(offset, ymid, ((enabled)? ICON_LAYER_ACTIVE : ICON_LAYER_USED)); + offset += ICON_WIDTH; + } + } + + glDisable(GL_BLEND); /* End of blending with background (text now gets drawn) */ + + /* step 5) draw name ............................................... */ + if (acf->name) { + char name[256]; /* hopefully this will be enough! */ + + /* set text color */ + if (selected) + UI_ThemeColor(TH_TEXT_HI); + else + UI_ThemeColor(TH_TEXT); + + /* get name */ + acf->name(ale, name); + + offset += 3; + UI_DrawString(offset, ytext, name); + } + + /* step 6) draw mute+protection toggles ............................. */ + /* reset offset - now goes from RHS of panel */ + offset = 0; + + // TODO: we need a mechanism of drawing over (and hiding) stuff from here... + + /* set blending again, as text drawing may clear it */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + /* protect... */ + // XXX v2d might not be valid + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) { + enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_PROTECT); + + offset += ICON_WIDTH; + UI_icon_draw(v2d->cur.xmax-(float)offset, ymid, ((enabled)? ICON_LOCKED : ICON_UNLOCKED)); + } + /* mute... */ + // XXX v2d might not be valid + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) { + enabled= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_MUTE); + + offset += ICON_WIDTH; + UI_icon_draw(v2d->cur.xmax-(float)offset, ymid, ((enabled)? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF)); + } + + glDisable(GL_BLEND); /* End of blending with background */ +} + +/* *********************************************** */ |