Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editaction.c')
-rw-r--r--source/blender/src/editaction.c3097
1 files changed, 0 insertions, 3097 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
deleted file mode 100644
index cb032ddfb61..00000000000
--- a/source/blender/src/editaction.c
+++ /dev/null
@@ -1,3097 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL 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. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * 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) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): 2007, Joshua Leung (major rewrite of Action Editor)
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <string.h>
-#include <math.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "PIL_time.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
-
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_key_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_lattice_types.h"
-
-#include "BKE_action.h"
-#include "BKE_armature.h"
-#include "BKE_constraint.h"
-#include "BKE_curve.h"
-#include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_ipo.h"
-#include "BKE_key.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_utildefines.h"
-#include "BKE_object.h" /* for where_is_object in obanim -> action baking */
-
-#include "BIF_butspace.h"
-#include "BIF_editaction.h"
-#include "BIF_editarmature.h"
-#include "BIF_editnla.h"
-#include "BIF_editview.h"
-#include "BIF_gl.h"
-#include "BIF_interface.h"
-#include "BIF_mywindow.h"
-#include "BIF_poseobject.h"
-#include "BIF_screen.h"
-#include "BIF_space.h"
-#include "BIF_toolbox.h"
-#include "BIF_transform.h"
-
-#include "BSE_edit.h"
-#include "BSE_drawipo.h"
-#include "BSE_headerbuttons.h"
-#include "BSE_editaction_types.h"
-#include "BSE_editipo.h"
-#include "BSE_time.h"
-#include "BSE_trans_types.h"
-
-#include "BDR_drawaction.h"
-#include "BDR_editobject.h"
-
-#include "mydevice.h"
-#include "blendef.h"
-#include "nla.h"
-
-/* **************************************************** */
-/* ACTION API */
-
-/* this function adds a new Action block */
-bAction *add_empty_action (char *name)
-{
- bAction *act;
-
- act= alloc_libblock(&G.main->action, ID_AC, name);
- act->id.flag |= LIB_FAKEUSER;
- act->id.us++;
-
- return act;
-}
-
-/* generic get current action call, for action window context */
-bAction *ob_get_action (Object *ob)
-{
- bActionStrip *strip;
-
- if(ob->action)
- return ob->action;
-
- for (strip=ob->nlastrips.first; strip; strip=strip->next) {
- if (strip->flag & ACTSTRIP_SELECT)
- return strip->act;
- }
- return NULL;
-}
-
-/* used by ipo, outliner, buttons to find the active channel */
-bActionChannel *get_hilighted_action_channel (bAction *action)
-{
- bActionChannel *achan;
-
- if (!action)
- return NULL;
-
- for (achan= action->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && (achan->flag & ACHAN_HILIGHTED))
- return achan;
- }
- }
-
- return NULL;
-}
-
-/* ----------------------------------------- */
-
-void remake_action_ipos (bAction *act)
-{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
-
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if (achan->ipo) {
- for (icu = achan->ipo->curve.first; icu; icu=icu->next) {
- sort_time_ipocurve(icu);
- testhandles_ipocurve(icu);
- }
- }
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
- if (conchan->ipo) {
- for (icu = conchan->ipo->curve.first; icu; icu=icu->next){
- sort_time_ipocurve(icu);
- testhandles_ipocurve(icu);
- }
- }
- }
- }
-
- synchronize_action_strips();
-}
-
-/* **************************************************** */
-/* FILTER->EDIT STRUCTURES */
-/*
- * This method involves generating a list of edit structures which enable
- * tools to naively perform the actions they require without all the boiler-plate
- * associated with loops within loops and checking for cases to ignore.
- */
-
-/* this function allocates memory for a new bActListElem struct for the
- * provided action channel-data.
- */
-bActListElem *make_new_actlistelem (void *data, short datatype, void *owner, short ownertype)
-{
- bActListElem *ale= NULL;
-
- /* only allocate memory if there is data to convert */
- if (data) {
- /* allocate and set generic data */
- ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
-
- ale->data= data;
- ale->type= datatype;
- ale->owner= owner;
- ale->ownertype= ownertype;
-
- /* do specifics */
- switch (datatype) {
- case ACTTYPE_ACHAN:
- {
- bActionChannel *achan= (bActionChannel *)data;
-
- ale->flag= achan->flag;
-
- if (achan->ipo) {
- ale->key_data= achan->ipo;
- ale->datatype= ALE_IPO;
- }
- else {
- ale->key_data= NULL;
- ale->datatype= ALE_NONE;
- }
- }
- break;
- case ACTTYPE_CONCHAN:
- {
- bConstraintChannel *conchan= (bConstraintChannel *)data;
-
- ale->flag= conchan->flag;
-
- if (conchan->ipo && conchan->ipo->curve.first) {
- /* we assume that constraint ipo blocks only have 1 curve:
- * INFLUENCE, so we pretend that a constraint channel is
- * really just a Ipo-Curve channel instead.
- */
- ale->key_data= conchan->ipo->curve.first;
- ale->datatype= ALE_ICU;
- }
- else {
- ale->key_data= NULL;
- ale->datatype= ALE_NONE;
- }
- }
- break;
- case ACTTYPE_ICU:
- {
- IpoCurve *icu= (IpoCurve *)data;
-
- ale->flag= icu->flag;
- ale->key_data= icu;
- ale->datatype= ALE_ICU;
- }
- break;
-
- case ACTTYPE_FILLIPO:
- case ACTTYPE_FILLCON:
- {
- bActionChannel *achan= (bActionChannel *)data;
-
- if (datatype == ACTTYPE_FILLIPO)
- ale->flag= FILTER_IPO_ACHAN(achan);
- else
- ale->flag= FILTER_CON_ACHAN(achan);
-
- ale->key_data= NULL;
- ale->datatype= ALE_NONE;
- }
- break;
- case ACTTYPE_IPO:
- {
- ale->flag= 0;
- ale->key_data= data;
- ale->datatype= ALE_IPO;
- }
- break;
- }
- }
-
- /* return created datatype */
- return ale;
-}
-
-/* ----------------------------------------- */
-
-static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
-{
- bActListElem *ale;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
-
- /* loop over action channels, performing the necessary checks */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- /* only work with this channel and its subchannels if it is visible */
- if (!(filter_mode & ACTFILTER_VISIBLE) || VISIBLE_ACHAN(achan)) {
- /* only work with this channel and its subchannels if it is editable */
- if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_ACHAN(achan)) {
- /* check if this achan should only be included if it is selected */
- if (!(filter_mode & ACTFILTER_SEL) || SEL_ACHAN(achan)) {
- /* are we only interested in the ipo-curves? */
- if ((filter_mode & ACTFILTER_ONLYICU)==0) {
- ale= make_new_actlistelem(achan, ACTTYPE_ACHAN, achan, ACTTYPE_ACHAN);
- if (ale) BLI_addtail(act_data, ale);
- }
- }
- else {
- /* only consider selected channels - achan not selected */
- continue;
- }
-
- /* check if expanded - if not, continue on to next action channel */
- if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ACTFILTER_ONLYICU)==0)
- continue;
-
- /* ipo channels */
- if (achan->ipo) {
- /* include ipo-expand widget? */
- if ((filter_mode & ACTFILTER_CHANNELS) && (filter_mode & ACTFILTER_ONLYICU)==0) {
- ale= make_new_actlistelem(achan, ACTTYPE_FILLIPO, achan, ACTTYPE_ACHAN);
- if (ale) BLI_addtail(act_data, ale);
- }
-
- /* add ipo-curve channels? */
- if (FILTER_IPO_ACHAN(achan) || (filter_mode & ACTFILTER_ONLYICU)) {
- /* loop through ipo-curve channels, adding them */
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- ale= make_new_actlistelem(icu, ACTTYPE_ICU, achan, ACTTYPE_ACHAN);
- if (ale) BLI_addtail(act_data, ale);
- }
- }
- }
-
- /* constraint channels */
- if (achan->constraintChannels.first) {
- /* include constraint-expand widget? */
- if ((filter_mode & ACTFILTER_CHANNELS) && (filter_mode & ACTFILTER_ONLYICU)==0) {
- ale= make_new_actlistelem(achan, ACTTYPE_FILLCON, achan, ACTTYPE_ACHAN);
- if (ale) BLI_addtail(act_data, ale);
- }
-
- /* add constaint channels? */
- if (FILTER_CON_ACHAN(achan)) {
- /* loop through constraint channels, checking and adding them */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- /* only work with this channel and its subchannels if it is editable */
- if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_CONCHAN(conchan)) {
- /* check if this conchan should only be included if it is selected */
- if (!(filter_mode & ACTFILTER_SEL) || SEL_CONCHAN(conchan)) {
- if ((filter_mode & ACTFILTER_ONLYICU)==0) {
- ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN, achan, ACTTYPE_ACHAN);
- if (ale) BLI_addtail(act_data, ale);
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mode)
-{
- bActListElem *ale;
- KeyBlock *kb;
- IpoCurve *icu;
- int i;
-
- /* are we filtering for display or editing */
- if (filter_mode & ACTFILTER_FORDRAWING) {
- /* for display - loop over shapekeys, adding ipo-curve references where needed */
- kb= key->block.first;
-
- /* loop through possible shapekeys, manually creating entries */
- for (i= 1; i < key->totkey; i++) {
- ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
- kb = kb->next;
-
- ale->data= kb;
- ale->type= ACTTYPE_SHAPEKEY; /* 'abused' usage of this type */
- ale->owner= key;
- ale->ownertype= ACTTYPE_SHAPEKEY;
- ale->datatype= ALE_NONE;
- ale->index = i;
-
- if (key->ipo) {
- for (icu= key->ipo->curve.first; icu; icu=icu->next) {
- if (icu->adrcode == i) {
- ale->key_data= icu;
- ale->datatype= ALE_ICU;
- break;
- }
- }
- }
-
- BLI_addtail(act_data, ale);
- }
- }
- else {
- /* loop over ipo curves if present - for editing */
- if (key->ipo) {
- if (filter_mode & ACTFILTER_IPOKEYS) {
- ale= make_new_actlistelem(key->ipo, ACTTYPE_IPO, key, ACTTYPE_SHAPEKEY);
- if (ale) BLI_addtail(act_data, ale);
- }
- else {
- for (icu= key->ipo->curve.first; icu; icu=icu->next) {
- ale= make_new_actlistelem(icu, ACTTYPE_ICU, key, ACTTYPE_SHAPEKEY);
- if (ale) BLI_addtail(act_data, ale);
- }
- }
- }
- }
-}
-
-/* This function filters the active data source to leave only the desired
- * data types. 'Public' api call.
- * *act_data: is a pointer to a ListBase, to which the filtered action data
- * will be placed for use.
- * filter_mode: how should the data be filtered - bitmapping accessed flags
- */
-void actdata_filter (ListBase *act_data, int filter_mode, void *data, short datatype)
-{
- /* only filter data if there's somewhere to put it */
- if (data && act_data) {
- bActListElem *ale, *next;
-
- /* firstly filter the data */
- switch (datatype) {
- case ACTCONT_ACTION:
- actdata_filter_action(act_data, data, filter_mode);
- break;
- case ACTCONT_SHAPEKEY:
- actdata_filter_shapekey(act_data, data, filter_mode);
- break;
- }
-
- /* remove any weedy entries */
- for (ale= act_data->first; ale; ale= next) {
- next= ale->next;
-
- if (ale->type == ACTTYPE_NONE)
- BLI_freelinkN(act_data, ale);
-
- if (filter_mode & ACTFILTER_IPOKEYS) {
- if (ale->datatype != ALE_IPO)
- BLI_freelinkN(act_data, ale);
- else if (ale->key_data == NULL)
- BLI_freelinkN(act_data, ale);
- }
- }
- }
-}
-
-/* **************************************************** */
-/* GENERAL ACTION TOOLS */
-
-
-/* gets the key data from the currently selected
- * mesh/lattice. If a mesh is not selected, or does not have
- * key data, then we return NULL (currently only
- * returns key data for RVK type meshes). If there
- * is an action that is pinned, return null
- */
-/* Note: there's a similar function in key.c (ob_get_key) */
-Key *get_action_mesh_key(void)
-{
- Object *ob;
- Key *key;
-
- ob = OBACT;
- if (ob == NULL)
- return NULL;
-
- if (G.saction->pin) return NULL;
-
- if (ob->type==OB_MESH)
- key = ((Mesh *)ob->data)->key;
- else if (ob->type==OB_LATTICE)
- key = ((Lattice *)ob->data)->key;
- else
- return NULL;
-
- if (key) {
- if (key->type == KEY_RELATIVE)
- return key;
- }
-
- return NULL;
-}
-
-/* TODO: kill this! */
-int get_nearest_key_num (Key *key, short *mval, float *x)
-{
- /* returns the key num that cooresponds to the
- * y value of the mouse click. Does not check
- * if this is a valid keynum. Also gives the Ipo
- * x coordinate.
- */
- int num;
- float y;
-
- areamouseco_to_ipoco(G.v2d, mval, x, &y);
- num = (int) ((CHANNELHEIGHT/2 - y) / (CHANNELHEIGHT+CHANNELSKIP));
-
- return (num + 1);
-}
-
-/* this function is used to get a pointer to an action or shapekey
- * datablock, thus simplying that process.
- */
-/* this function is intended for use */
-void *get_nearest_act_channel (short mval[], short *ret_type)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
- int filter;
-
- int clickmin, clickmax;
- float x,y;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
- clickmax = clickmin;
-
- if (clickmax < 0) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- /* filter data */
- filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
- actdata_filter(&act_data, filter, data, datatype);
-
- for (ale= act_data.first; ale; ale= ale->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match */
- *ret_type= ale->type;
- data= ale->data;
-
- BLI_freelistN(&act_data);
-
- return data;
- }
- --clickmin;
- --clickmax;
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
-
- *ret_type= ACTTYPE_NONE;
- return NULL;
-}
-
-/* used only by mouse_action. It is used to find the location of the nearest
- * keyframe to where the mouse clicked,
- */
-static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
-{
- ListBase act_data = {NULL, NULL};
- ListBase act_keys = {NULL, NULL};
- bActListElem *ale;
- ActKeyColumn *ak;
- void *data;
- short datatype;
- int filter;
-
- rctf rectf;
- float xmin, xmax, x, y;
- int clickmin, clickmax;
- short mval[2];
- short found = 0;
-
- getmouseco_areawin (mval);
-
- /* action-channel */
- *par= NULL;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
- clickmax = clickmin;
-
- mval[0]-=7;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]+=14;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- /* if action is mapped in NLA, it returns a correction */
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- xmin= get_action_frame(OBACT, rectf.xmin);
- xmax= get_action_frame(OBACT, rectf.xmax);
- }
- else {
- xmin= rectf.xmin;
- xmax= rectf.xmax;
- }
-
- if (clickmax < 0) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- /* filter data */
- filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
- actdata_filter(&act_data, filter, data, datatype);
-
- for (ale= act_data.first; ale; ale= ale->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match */
-
- /* make list of keyframes */
- if (ale->key_data) {
- switch (ale->datatype) {
- case ALE_IPO:
- {
- Ipo *ipo= (Ipo *)ale->key_data;
- ipo_to_keylist(ipo, &act_keys, NULL);
- }
- break;
- case ALE_ICU:
- {
- IpoCurve *icu= (IpoCurve *)ale->key_data;
- icu_to_keylist(icu, &act_keys, NULL);
- }
- break;
- }
- }
-
- /* loop through keyframes, finding one that was clicked on */
- for (ak= act_keys.first; ak; ak= ak->next) {
- if (IN_RANGE(ak->cfra, xmin, xmax)) {
- *selx= ak->cfra;
- found= 1;
- break;
- }
- }
- /* no matching keyframe found - set to mean frame value so it doesn't actually select anything */
- if (found == 0)
- *selx= ((xmax+xmin) / 2);
-
- /* figure out what to return */
- if (datatype == ACTCONT_ACTION) {
- *par= ale->owner; /* assume that this is an action channel */
- *ret_type= ale->type;
- data = ale->data;
- }
- else if (datatype == ACTCONT_SHAPEKEY) {
- data = ale->key_data;
- *ret_type= ACTTYPE_ICU;
- }
-
- /* cleanup tempolary lists */
- BLI_freelistN(&act_keys);
- act_keys.first = act_keys.last = NULL;
-
- BLI_freelistN(&act_data);
-
- return data;
- }
- --clickmin;
- --clickmax;
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
-
- *ret_type= ACTTYPE_NONE;
- return NULL;
-}
-
-void *get_action_context (short *datatype)
-{
- bAction *act;
- Key *key;
-
- /* get pointers to active action/shapekey blocks */
- act = (G.saction)? G.saction->action: NULL;
- key = get_action_mesh_key();
-
- if (act) {
- *datatype= ACTCONT_ACTION;
- return act;
- }
- else if (key) {
- *datatype= ACTCONT_SHAPEKEY;
- return key;
- }
- else {
- *datatype= ACTCONT_NONE;
- return NULL;
- }
-}
-
-/* **************************************************** */
-/* TRANSFORM TOOLS */
-
-/* main call to start transforming keyframes */
-void transform_action_keys (int mode, int dummy)
-{
- void *data;
- short datatype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- switch (mode) {
- case 'g':
- {
- initTransform(TFM_TIME_TRANSLATE, CTX_NONE);
- Transform();
- }
- break;
- case 's':
- {
- initTransform(TFM_TIME_SCALE, CTX_NONE);
- Transform();
- }
- break;
- case 't':
- {
- initTransform(TFM_TIME_SLIDE, CTX_NONE);
- Transform();
- }
- break;
- case 'e':
- {
- initTransform(TFM_TIME_EXTEND, CTX_NONE);
- Transform();
- }
- break;
- }
-}
-
-/* ----------------------------------------- */
-
-/* duplicate keyframes */
-void duplicate_action_keys (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through filtered data and duplicate selected keys */
- for (ale= act_data.first; ale; ale= ale->next) {
- duplicate_ipo_keys((Ipo *)ale->key_data);
- }
-
- /* free filtered list */
- BLI_freelistN(&act_data);
-
- /* now, go into transform-grab mode, to move keys */
- transform_action_keys('g', 0);
-}
-
-/* this function is responsible for snapping the current frame to selected data */
-void snap_cfra_action()
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* snap current frame to selected data */
- snap_cfra_ipo_keys(NULL, -1);
-
- for (ale= act_data.first; ale; ale= ale->next) {
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
- snap_cfra_ipo_keys(ale->key_data, 0);
- actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
- }
- else
- snap_cfra_ipo_keys(ale->key_data, 0);
- }
- BLI_freelistN(&act_data);
-
- snap_cfra_ipo_keys(NULL, 1);
-
- BIF_undo_push("Snap Current Frame to Keys");
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* this function is responsible for snapping keyframes to frame-times */
-void snap_action_keys(short mode)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
- char str[32];
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
-
- /* determine mode */
- switch (mode) {
- case 1:
- strcpy(str, "Snap Keys To Nearest Frame");
- break;
- case 2:
- if (G.saction->flag & SACTION_DRAWTIME)
- strcpy(str, "Snap Keys To Current Time");
- else
- strcpy(str, "Snap Keys To Current Frame");
- break;
- case 3:
- strcpy(str, "Snap Keys To Nearest Marker");
- break;
- case 4:
- strcpy(str, "Snap Keys To Nearest Second");
- break;
- default:
- return;
- }
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* snap to frame */
- for (ale= act_data.first; ale; ale= ale->next) {
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
- snap_ipo_keys(ale->key_data, mode);
- actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
- }
- else
- snap_ipo_keys(ale->key_data, mode);
- }
- BLI_freelistN(&act_data);
-
- if (datatype == ACTCONT_ACTION)
- remake_action_ipos(data);
-
- BIF_undo_push(str);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* this function is responsible for snapping keyframes to frame-times */
-void mirror_action_keys(short mode)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
- char str[32];
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
-
- /* determine mode */
- switch (mode) {
- case 1:
- strcpy(str, "Mirror Keys Over Current Frame");
- break;
- case 2:
- strcpy(str, "Mirror Keys Over Y-Axis");
- break;
- case 3:
- strcpy(str, "Mirror Keys Over X-Axis");
- break;
- case 4:
- strcpy(str, "Mirror Keys Over Marker");
- break;
- default:
- return;
- }
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* mirror */
- for (ale= act_data.first; ale; ale= ale->next) {
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
- mirror_ipo_keys(ale->key_data, mode);
- actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
- }
- else
- mirror_ipo_keys(ale->key_data, mode);
- }
- BLI_freelistN(&act_data);
-
- if (datatype == ACTCONT_ACTION)
- remake_action_ipos(data);
-
- BIF_undo_push(str);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* **************************************************** */
-/* ADD/REMOVE KEYFRAMES */
-
-/* This function allows the user to insert keyframes on the current
- * frame from the Action Editor, using the current values of the channels
- * to be keyframed.
- */
-void insertkey_action(void)
-{
- void *data;
- short datatype;
-
- Object *ob= OBACT;
- short mode;
- float cfra;
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
- cfra = frame_to_float(CFRA);
-
- if (datatype == ACTCONT_ACTION) {
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
-
- /* ask user what to keyframe */
- mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
- if (mode <= 0) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU );
- if (mode == 2) filter |= ACTFILTER_SEL;
-
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through ipo curves retrieved */
- for (ale= act_data.first; ale; ale= ale->next) {
- /* verify that this is indeed an ipo curve */
- if (ale->key_data && ale->owner) {
- bActionChannel *achan= (bActionChannel *)ale->owner;
- IpoCurve *icu= (IpoCurve *)ale->key_data;
-
- if (ob)
- insertkey((ID *)ob, icu->blocktype, achan->name, NULL, icu->adrcode, 0);
- else
- insert_vert_icu(icu, cfra, icu->curval, 0);
- }
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
- }
- else if (datatype == ACTCONT_SHAPEKEY) {
- Key *key= (Key *)data;
- IpoCurve *icu;
-
- /* ask user if they want to insert a keyframe */
- mode = okee("Insert Keyframe?");
- if (mode <= 0) return;
-
- if (key->ipo) {
- for (icu= key->ipo->curve.first; icu; icu=icu->next) {
- insert_vert_icu(icu, cfra, icu->curval, 0);
- }
- }
- }
-
- BIF_undo_push("Insert Key");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* delete selected keyframes */
-void delete_action_keys (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through filtered data and delete selected keys */
- for (ale= act_data.first; ale; ale= ale->next) {
- delete_ipo_keys((Ipo *)ale->key_data);
- }
-
- /* free filtered list */
- BLI_freelistN(&act_data);
-
- if (datatype == ACTCONT_ACTION)
- remake_action_ipos(data);
-
- BIF_undo_push("Delete Action Keys");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* delete selected keyframes */
-void delete_action_channels (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale, *next;
- bAction *act;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
- if (datatype != ACTCONT_ACTION) return;
- act= (bAction *)data;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_CHANNELS | ACTFILTER_SEL);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* remove irrelevant entries */
- for (ale= act_data.first; ale; ale= next) {
- next= ale->next;
-
- if (ale->type != ACTTYPE_ACHAN)
- BLI_freelinkN(&act_data, ale);
- }
-
- /* clean up action channels */
- for (ale= act_data.first; ale; ale= next) {
- bActionChannel *achan= (bActionChannel *)ale->data;
- bConstraintChannel *conchan, *cnext;
- next= ale->next;
-
- /* release reference to ipo users */
- if (achan->ipo)
- achan->ipo->id.us--;
-
- for (conchan= achan->constraintChannels.first; conchan; conchan=cnext) {
- cnext= conchan->next;
-
- if (conchan->ipo)
- conchan->ipo->id.us--;
- }
-
- /* free memory */
- BLI_freelistN(&achan->constraintChannels);
- BLI_freelinkN(&act->chanbase, achan);
- BLI_freelinkN(&act_data, ale);
- }
-
- remake_action_ipos(data);
-
- BIF_undo_push("Delete Action Channels");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* 'Clean' IPO curves - remove any unnecessary keyframes */
-void clean_action (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype, ok;
-
- /* don't proceed any further if nothing to work on or user refuses */
- data= get_action_context(&datatype);
- ok= fbutton(&G.scene->toolsettings->clean_thresh,
- 0.0000001f, 1.0, 0.001, 0.1,
- "Clean Threshold");
- if (!ok) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_SEL | ACTFILTER_ONLYICU);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through filtered data and clean curves */
- for (ale= act_data.first; ale; ale= ale->next) {
- clean_ipo_curve((IpoCurve *)ale->key_data);
- }
-
- /* admin and redraws */
- BLI_freelistN(&act_data);
-
- BIF_undo_push("Clean Action");
- allqueue(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* **************************************************** */
-/* COPY/PASTE FOR ACTIONS */
-/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
- * IPO-blocks, and also temporary IpoCurves which only contain the selected keyframes.
- * - Only pastes between compatable data is possible (i.e. same achan->name, ipo-curve type, etc.)
- */
-
-/* globals for copy/paste data (like for other copy/paste buffers) */
-ListBase actcopybuf = {NULL, NULL};
-
-/* This function frees any MEM_calloc'ed copy/paste buffer data */
-void free_actcopybuf ()
-{
- bActionChannel *achan, *anext;
- bConstraintChannel *conchan, *cnext;
-
- for (achan= actcopybuf.first; achan; achan= anext) {
- anext= achan->next;
-
- if (achan->ipo) {
- free_ipo(achan->ipo);
- MEM_freeN(achan->ipo);
- }
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) {
- cnext= conchan->next;
-
- if (conchan->ipo) {
- free_ipo(conchan->ipo);
- MEM_freeN(conchan->ipo);
- }
-
- BLI_freelinkN(&achan->constraintChannels, conchan);
- }
-
- BLI_freelinkN(&actcopybuf, achan);
- }
-}
-
-/* This function adds data to the copy/paste buffer, freeing existing data first
- * Only the selected action channels gets their selected keyframes copied.
- */
-void copy_actdata ()
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* clear buffer first */
- free_actcopybuf();
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* assume that each of these is an ipo-block */
- for (ale= act_data.first; ale; ale= ale->next) {
- bActionChannel *achan;
- Ipo *ipo= ale->key_data;
- Ipo *ipn;
- IpoCurve *icu, *icn;
- BezTriple *bezt;
- int i;
-
- /* coerce an action-channel out of owner */
- if (ale->ownertype == ACTTYPE_ACHAN) {
- bActionChannel *achanO= ale->owner;
- achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
- strcpy(achan->name, achanO->name);
- }
- else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
- achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
- strcpy(achan->name, "#ACP_ShapeKey");
- }
- else
- continue;
- BLI_addtail(&actcopybuf, achan);
-
- /* add constraint channel if needed, then add new ipo-block */
- if (ale->type == ACTTYPE_CONCHAN) {
- bConstraintChannel *conchanO= ale->data;
- bConstraintChannel *conchan;
-
- conchan= MEM_callocN(sizeof(bConstraintChannel), "ActCopyPasteConchan");
- strcpy(conchan->name, conchanO->name);
- BLI_addtail(&achan->constraintChannels, conchan);
-
- conchan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
- }
- else {
- achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
- }
- ipn->blocktype = ipo->blocktype;
-
- /* now loop through curves, and only copy selected keyframes */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- /* allocate a new curve */
- icn= MEM_callocN(sizeof(IpoCurve), "ActCopyPasteIcu");
- icn->blocktype = icu->blocktype;
- icn->adrcode = icu->adrcode;
- BLI_addtail(&ipn->curve, icn);
-
- /* find selected BezTriples to add to the buffer */
- for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
- if (BEZSELECTED(bezt))
- insert_bezt_icu(icn, bezt);
- }
- }
- }
-
- /* check if anything ended up in the buffer */
- if (actcopybuf.first==NULL || actcopybuf.last==NULL)
- error("Nothing copied to buffer");
-
- /* free temp memory */
- BLI_freelistN(&act_data);
-}
-
-void paste_actdata ()
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* check if buffer is empty */
- if (actcopybuf.first==NULL || actcopybuf.last==NULL) {
- error("No data in buffer to paste");
- return;
- }
-
- /* get data */
- data= get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* from selected channels */
- for (ale= act_data.first; ale; ale= ale->next) {
- Ipo *ipo_src=NULL, *ipo_dst=ale->key_data;
- bActionChannel *achan;
- IpoCurve *ico, *icu;
- BezTriple *bezt;
- int i;
- float offset= 0.0f;
- short offsetInit= 1;
-
- /* find matching ipo-block */
- for (achan= actcopybuf.first; achan; achan= achan->next) {
- /* try to match data */
- if (ale->ownertype == ACTTYPE_ACHAN) {
- bActionChannel *achant= ale->owner;
-
- /* check if we have a corresponding action channel */
- if (strcmp(achan->name, achant->name)==0) {
- /* check if this is a constraint channel */
- if (ale->type == ACTTYPE_CONCHAN) {
- bConstraintChannel *conchant= ale->data;
- bConstraintChannel *conchan;
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (strcmp(conchan->name, conchant->name)==0) {
- ipo_src= conchan->ipo;
- break;
- }
- }
- if (ipo_src) break;
- }
- else {
- ipo_src= achan->ipo;
- break;
- }
- }
- }
- else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
- /* check if this action channel is "#ACP_ShapeKey" */
- if (strcmp(achan->name, "#ACP_ShapeKey")==0) {
- ipo_src= achan->ipo;
- break;
- }
- }
- }
-
- /* loop over curves, pasting keyframes */
- for (icu= ipo_dst->curve.first; icu; icu= icu->next) {
- for (ico= ipo_src->curve.first; ico; ico= ico->next) {
- /* only paste if compatable blocktype + adrcode */
- if ((ico->blocktype==icu->blocktype) && (ico->adrcode==icu->adrcode)) {
- /* just start pasting, with the the first keyframe on the current frame, and so on */
- for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
- /* initialise offset (if not already done) */
- if (offsetInit) {
- offset= CFRA - bezt->vec[1][0];
- offsetInit= 0;
- }
-
- /* temporarily apply offset to src beztriple while copying */
- bezt->vec[0][0] += offset;
- bezt->vec[1][0] += offset;
- bezt->vec[2][0] += offset;
-
- /* insert the keyframe */
- insert_bezt_icu(icu, bezt);
-
- /* un-apply offset from src beztriple after copying */
- bezt->vec[0][0] -= offset;
- bezt->vec[1][0] -= offset;
- bezt->vec[2][0] -= offset;
- }
-
- /* recalculate channel's handles? */
- calchandles_ipocurve(icu);
-
- /* done for this channel */
- break;
- }
- }
- }
- }
-
- /* free temp memory */
- BLI_freelistN(&act_data);
-
- /* undo and redraw stuff */
- allqueue(REDRAWVIEW3D, 0);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
- BIF_undo_push("Paste Action Keyframes");
-}
-
-/* **************************************************** */
-/* VARIOUS SETTINGS */
-
-/* This function combines several features related to setting
- * various ipo extrapolation/interpolation
- */
-void action_set_ipo_flags (short mode, short event)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* determine which set of processing we are doing */
- switch (mode) {
- case SET_EXTEND_POPUP:
- {
- /* present popup menu for ipo extrapolation type */
- event
- = pupmenu("Channel Extending Type %t|"
- "Constant %x11|"
- "Extrapolation %x12|"
- "Cyclic %x13|"
- "Cyclic extrapolation %x14");
- if (event < 1) return;
- }
- break;
- case SET_IPO_POPUP:
- {
- /* present popup menu for ipo interpolation type */
- event
- = pupmenu("Channel Ipo Type %t|"
- "Constant %x1|"
- "Linear %x2|"
- "Bezier %x3");
- if (event < 1) return;
- }
- break;
-
- case SET_IPO_MENU: /* called from menus */
- case SET_EXTEND_MENU:
- break;
-
- default: /* weird, unhandled case */
- return;
- }
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through setting flags */
- for (ale= act_data.first; ale; ale= ale->next) {
- Ipo *ipo= (Ipo *)ale->key_data;
-
- /* depending on the mode */
- switch (mode) {
- case SET_EXTEND_POPUP: /* extrapolation */
- case SET_EXTEND_MENU:
- {
- switch (event) {
- case SET_EXTEND_CONSTANT:
- setexprap_ipoloop(ipo, IPO_HORIZ);
- break;
- case SET_EXTEND_EXTRAPOLATION:
- setexprap_ipoloop(ipo, IPO_DIR);
- break;
- case SET_EXTEND_CYCLIC:
- setexprap_ipoloop(ipo, IPO_CYCL);
- break;
- case SET_EXTEND_CYCLICEXTRAPOLATION:
- setexprap_ipoloop(ipo, IPO_CYCLX);
- break;
- }
- }
- break;
- case SET_IPO_POPUP: /* interpolation */
- case SET_IPO_MENU:
- {
- setipotype_ipo(ipo, event);
- }
- break;
- }
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
-
- if (datatype == ACTCONT_ACTION)
- remake_action_ipos(data);
-
- BIF_undo_push("Set Ipo Type");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* this function sets the handles on keyframes */
-void sethandles_action_keys (int code)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
- int filter;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop through setting flags */
- for (ale= act_data.first; ale; ale= ale->next) {
- sethandles_ipo_keys((Ipo *)ale->key_data, code);
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
- if (datatype == ACTCONT_ACTION)
- remake_action_ipos(data);
-
- BIF_undo_push("Set Handle Type");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* ----------------------------------------- */
-
-/* this gets called when nkey is pressed (no Transform Properties panel yet) */
-static void numbuts_action ()
-{
- void *data;
- short datatype;
-
- void *act_channel;
- short chantype;
-
- bActionChannel *achan= NULL;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
- KeyBlock *kb= NULL;
-
- short mval[2];
-
- int but=0;
- char str[64];
- short expand, protect, mute;
- float slidermin, slidermax;
-
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* figure out what is under cursor */
- getmouseco_areawin(mval);
- if (mval[0] < NAMEWIDTH)
- return;
- act_channel= get_nearest_act_channel(mval, &chantype);
-
- /* create items for clever-numbut */
- if (chantype == ACTTYPE_ACHAN) {
- /* Action Channel */
- achan= (bActionChannel *)act_channel;
-
- strcpy(str, achan->name);
- protect= (achan->flag & ACHAN_PROTECTED);
- expand = (achan->flag & ACHAN_EXPANDED);
- mute = (achan->ipo)? (achan->ipo->muteipo): 0;
-
- add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
- add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
- add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_CONCHAN) {
- /* Constraint Channel */
- conchan= (bConstraintChannel *)act_channel;
-
- strcpy(str, conchan->name);
- protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
- mute = (conchan->ipo)? (conchan->ipo->muteipo): 0;
-
- add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
- add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_ICU) {
- /* IPO Curve */
- icu= (IpoCurve *)act_channel;
-
- if (G.saction->pin)
- sprintf(str, getname_ipocurve(icu, NULL));
- else
- sprintf(str, getname_ipocurve(icu, OBACT));
-
- if (IS_EQ(icu->slide_max, icu->slide_min)) {
- if (IS_EQ(icu->ymax, icu->ymin)) {
- icu->slide_min= -100.0;
- icu->slide_max= 100.0;
- }
- else {
- icu->slide_min= icu->ymin;
- icu->slide_max= icu->ymax;
- }
- }
- slidermin= icu->slide_min;
- slidermax= icu->slide_max;
-
- //protect= (icu->flag & IPO_PROTECT);
- mute = (icu->flag & IPO_MUTE);
-
- add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
- add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
- //add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_SHAPEKEY) {
- /* Shape Key */
- kb= (KeyBlock *)act_channel;
-
- if (kb->name[0] == '\0') {
- Key *key= (Key *)data;
- int keynum= BLI_findindex(&key->block, kb);
-
- sprintf(str, "Key %d", keynum);
- }
- else
- strcpy(str, kb->name);
-
- if (kb->slidermin >= kb->slidermax) {
- kb->slidermin = 0.0;
- kb->slidermax = 1.0;
- }
-
- add_numbut(but++, TEX, "KB: ", 0, 24, str,
- "Does this really need a tool tip?");
- add_numbut(but++, NUM|FLO, "Slider Min:",
- -10000, kb->slidermax, &kb->slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:",
- kb->slidermin, 10000, &kb->slidermax, 0);
- }
- else {
- /* nothing under-cursor */
- return;
- }
-
- /* draw clever-numbut */
- if (do_clever_numbuts(str, but, REDRAW)) {
- /* restore settings based on type */
- if (icu) {
- icu->slide_min= slidermin;
- icu->slide_max= slidermax;
-
- //if (protect) icu->flag |= IPO_PROTECT;
- //else icu->flag &= ~IPO_PROTECT;
- if (mute) icu->flag |= IPO_MUTE;
- else icu->flag &= ~IPO_MUTE;
- }
- else if (conchan) {
- strcpy(conchan->name, str);
-
- if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
- else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
-
- if (conchan->ipo)
- conchan->ipo->muteipo = mute;
- }
- else if (achan) {
- strcpy(achan->name, str);
-
- if (expand) achan->flag |= ACHAN_EXPANDED;
- else achan->flag &= ~ACHAN_EXPANDED;
-
- if (protect) achan->flag |= ACHAN_PROTECTED;
- else achan->flag &= ~ACHAN_PROTECTED;
-
- if (achan->ipo)
- achan->ipo->muteipo = mute;
- }
-
- allqueue(REDRAWACTION, 0);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
-}
-
-
-
-/* **************************************************** */
-/* CHANNEL SELECTION */
-
-static void hilight_channel(bAction *act, bActionChannel *achan, short select)
-{
- bActionChannel *curchan;
-
- if (!act)
- return;
-
- for (curchan=act->chanbase.first; curchan; curchan=curchan->next) {
- if (curchan==achan && select)
- curchan->flag |= ACHAN_HILIGHTED;
- else
- curchan->flag &= ~ACHAN_HILIGHTED;
- }
-}
-
-/* messy call... */
-static void select_poseelement_by_name(char *name, int select)
-{
- /* Syncs selection of channels with selection of object elements in posemode */
- Object *ob= OBACT;
- bPoseChannel *pchan;
-
- if (!ob || ob->type!=OB_ARMATURE)
- return;
-
- if(select==2) {
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
- pchan->bone->flag &= ~(BONE_ACTIVE);
- }
-
- pchan= get_pose_channel(ob->pose, name);
- if(pchan) {
- if(select)
- pchan->bone->flag |= (BONE_SELECTED);
- else
- pchan->bone->flag &= ~(BONE_SELECTED);
- if(select==2)
- pchan->bone->flag |= (BONE_ACTIVE);
- }
-}
-
-/* apparently within active object context */
-/* called extern, like on bone selection */
-void select_actionchannel_by_name (bAction *act, char *name, int select)
-{
- bActionChannel *achan;
-
- if (!act)
- return;
-
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (!strcmp(achan->name, name)) {
- if (select) {
- achan->flag |= ACHAN_SELECTED;
- hilight_channel(act, achan, 1);
- }
- else {
- achan->flag &= ~ACHAN_SELECTED;
- hilight_channel(act, achan, 0);
- }
- return;
- }
- }
-}
-
-/* select_mode = SELECT_REPLACE
- * = SELECT_ADD
- * = SELECT_SUBTRACT
- * = SELECT_INVERT
- */
-
-/* exported for outliner (ton) */
-/* apparently within active object context */
-int select_channel(bAction *act, bActionChannel *achan, int selectmode)
-{
- /* Select the channel based on the selection mode */
- int flag;
-
- switch (selectmode) {
- case SELECT_ADD:
- achan->flag |= ACHAN_SELECTED;
- break;
- case SELECT_SUBTRACT:
- achan->flag &= ~ACHAN_SELECTED;
- break;
- case SELECT_INVERT:
- achan->flag ^= ACHAN_SELECTED;
- break;
- }
- flag = (achan->flag & ACHAN_SELECTED) ? 1 : 0;
-
- hilight_channel(act, achan, flag);
- select_poseelement_by_name(achan->name, flag);
-
- return flag;
-}
-
-static int select_constraint_channel(bAction *act,
- bConstraintChannel *conchan,
- int selectmode)
-{
- /* Select the constraint channel based on the selection mode */
- int flag;
-
- switch (selectmode) {
- case SELECT_ADD:
- conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
- break;
- case SELECT_SUBTRACT:
- conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
- break;
- case SELECT_INVERT:
- conchan->flag ^= CONSTRAINT_CHANNEL_SELECT;
- break;
- }
- flag = (conchan->flag & CONSTRAINT_CHANNEL_SELECT) ? 1 : 0;
-
- return flag;
-}
-
-int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
-{
- /* Select the channel based on the selection mode */
- int flag;
-
- switch (selectmode) {
- case SELECT_ADD:
- icu->flag |= IPO_SELECT;
- break;
- case SELECT_SUBTRACT:
- icu->flag &= ~IPO_SELECT;
- break;
- case SELECT_INVERT:
- icu->flag ^= IPO_SELECT;
- break;
- }
- flag = (icu->flag & IPO_SELECT) ? 1 : 0;
- return flag;
-}
-
-/* ----------------------------------------- */
-
-/* deselects action channels in given action */
-void deselect_actionchannels (bAction *act, short test)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter, sel=1;
-
- /* filter data */
- filter= ACTFILTER_VISIBLE;
- actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale= act_data.first; ale; ale= ale->next) {
- if (sel == 0)
- break;
-
- switch (ale->type) {
- case ACTTYPE_ACHAN:
- if (ale->flag & ACHAN_SELECTED)
- sel= 0;
- break;
- case ACTTYPE_CONCHAN:
- if (ale->flag & CONSTRAINT_CHANNEL_SELECT)
- sel=0;
- break;
- case ACTTYPE_ICU:
- if (ale->flag & IPO_SELECT)
- sel=0;
- break;
- }
- }
- }
- else
- sel= 0;
-
- /* Now set the flags */
- for (ale= act_data.first; ale; ale= ale->next) {
- switch (ale->type) {
- case ACTTYPE_ACHAN:
- {
- bActionChannel *achan= (bActionChannel *)ale->data;
-
- if (sel)
- achan->flag |= ACHAN_SELECTED;
- else
- achan->flag &= ~ACHAN_SELECTED;
- select_poseelement_by_name(achan->name, sel);
- }
- break;
- case ACTTYPE_CONCHAN:
- {
- bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
-
- if (sel)
- conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
- else
- conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
- }
- break;
- case ACTTYPE_ICU:
- {
- IpoCurve *icu= (IpoCurve *)ale->data;
-
- if (sel)
- icu->flag |= IPO_SELECT;
- else
- icu->flag &= ~IPO_SELECT;
- }
- break;
- }
- }
-
- /* Cleanup */
- BLI_freelistN(&act_data);
-}
-
-/* deselects channels in the action editor */
-void deselect_action_channels (short test)
-{
- void *data;
- short datatype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* based on type */
- if (datatype == ACTCONT_ACTION)
- deselect_actionchannels(data, test);
- // should shapekey channels be allowed to do this?
-}
-
-/* deselects keyframes in the action editor */
-void deselect_action_keys (short test, short sel)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale= act_data.first; ale; ale= ale->next) {
- if (is_ipo_key_selected(ale->key_data)) {
- sel= 0;
- break;
- }
- }
- }
-
- /* Now set the flags */
- for (ale= act_data.first; ale; ale= ale->next) {
- set_ipo_key_selection(ale->key_data, sel);
- }
-
- /* Cleanup */
- BLI_freelistN(&act_data);
-}
-
-/* selects all keyframes in the action editor - per channel or time
- * mode = 0: all in channel; mode = 1: all in frame
- */
-void selectall_action_keys (short mval[], short mode, short select_mode)
-{
- void *data;
- short datatype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- if (select_mode == SELECT_REPLACE) {
- deselect_action_keys(0, 0);
- select_mode = SELECT_ADD;
- }
-
- /* depending on mode */
- switch (mode) {
- case 0: /* all in channel*/
- {
- void *act_channel;
- short chantype;
-
- /* get channel, and act according to type */
- act_channel= get_nearest_act_channel(mval, &chantype);
- switch (chantype) {
- case ACTTYPE_ACHAN:
- {
- bActionChannel *achan= (bActionChannel *)act_channel;
- select_ipo_bezier_keys(achan->ipo, select_mode);
- }
- break;
- case ACTTYPE_CONCHAN:
- {
- bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
- select_ipo_bezier_keys(conchan->ipo, select_mode);
- }
- break;
- case ACTTYPE_ICU:
- {
- IpoCurve *icu= (IpoCurve *)act_channel;
- select_icu_bezier_keys(icu, select_mode);
- }
- break;
- }
- }
- break;
- case 1: /* all in frame */
- {
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- rcti rect;
- rctf rectf;
-
- /* use bounding box to find kframe */
- rect.xmin = rect.xmax = mval[0];
- rect.ymin = rect.ymax = mval[1];
-
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- rectf.xmax= rectf.xmin;
- rectf.ymax= rectf.ymin;
-
- rectf.xmin = rectf.xmin - 0.5;
- rectf.xmax = rectf.xmax + 0.5;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* Now set the flags */
- for (ale= act_data.first; ale; ale= ale->next)
- borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, select_mode);
-
- /* Cleanup */
- BLI_freelistN(&act_data);
- }
- break;
- }
-
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
-}
-
-void markers_selectkeys_between (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
- float min, max;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* get extreme markers */
- get_minmax_markers(1, &min, &max);
- if (min==max) return;
- min -= 0.5f;
- max += 0.5f;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* select keys in-between */
- for (ale= act_data.first; ale; ale= ale->next) {
- if(NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
- borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
- }
- else {
- borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
- }
- }
-
- /* Cleanup */
- BLI_freelistN(&act_data);
-}
-
-void selectkeys_leftright (short leftright, short select_mode)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
- float min, max;
-
- if (select_mode==SELECT_REPLACE) {
- select_mode=SELECT_ADD;
- deselect_action_keys(0, 0);
- }
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- if (leftright==1) {
- min = -MAXFRAMEF;
- max = (float)CFRA+0.1f;
- }
- else {
- min = (float)CFRA-0.1f;
- max = MAXFRAMEF;
- }
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* select keys to the right */
- for (ale= act_data.first; ale; ale= ale->next) {
- if(NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
- borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
- }
- else {
- borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
- }
- }
-
- /* Cleanup */
- BLI_freelistN(&act_data);
-
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
-
-}
-
-
-/* ----------------------------------------- */
-
-/* This function makes a list of the selected keyframes
- * in the ipo curves it has been passed
- */
-static void make_sel_cfra_list(Ipo *ipo, ListBase *elems)
-{
- IpoCurve *icu;
-
- if (ipo == NULL) return;
-
- for(icu= ipo->curve.first; icu; icu= icu->next) {
- BezTriple *bezt;
- int a= 0;
-
- for (bezt=icu->bezt; a<icu->totvert; a++, bezt++) {
- if (bezt && BEZSELECTED(bezt))
- add_to_cfra_elem(elems, bezt);
- }
- }
-}
-
-/* This function selects all key frames in the same column(s) as a already selected key(s)
- * or marker(s), or all the keyframes on a particular frame (triggered by a RMB on x-scrollbar)
- */
-void column_select_action_keys(int mode)
-{
- ListBase elems= {NULL, NULL};
- CfraElem *ce;
- IpoCurve *icu;
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* build list of columns */
- switch (mode) {
- case 1: /* list of selected keys */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- for (ale= act_data.first; ale; ale= ale->next)
- make_sel_cfra_list(ale->key_data, &elems);
-
- BLI_freelistN(&act_data);
- break;
- case 2: /* list of selected markers */
- make_marker_cfra_list(&elems, 1);
-
- /* apply scaled action correction if needed */
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- for (ce= elems.first; ce; ce= ce->next)
- ce->cfra= get_action_frame(OBACT, ce->cfra);
- }
- break;
- }
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_ONLYICU);
- actdata_filter(&act_data, filter, data, datatype);
-
- for (ale= act_data.first; ale; ale= ale->next) {
- for (ce= elems.first; ce; ce= ce->next) {
- for (icu= ale->key_data; icu; icu= icu->next) {
- BezTriple *bezt;
- int verts = 0;
-
- for (bezt=icu->bezt; verts<icu->totvert; bezt++, verts++) {
- if (bezt) {
- if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) )
- bezt->f2 |= 1;
- }
- }
- }
- }
- }
-
- BLI_freelistN(&act_data);
- BLI_freelistN(&elems);
-}
-
-/* some quick defines for borderselect modes */
-#define ACTEDIT_BORDERSEL_ALL 0
-#define ACTEDIT_BORDERSEL_FRA 1
-#define ACTEDIT_BORDERSEL_CHA 2
-
-/* borderselect: for keyframes only */
-void borderselect_action (void)
-{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- int filter;
- void *data;
- short datatype;
-
- rcti rect;
- rctf rectf;
- int val, selectmode, mode;
- int (*select_function)(BezTriple *);
- short mval[2];
- float ymin, ymax;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* what should be selected (based on the starting location of cursor) */
- getmouseco_areawin(mval);
- if (IN_2D_VERT_SCROLL(mval))
- mode = ACTEDIT_BORDERSEL_CHA;
- else if (IN_2D_HORIZ_SCROLL(mval))
- mode = ACTEDIT_BORDERSEL_FRA;
- else
- mode = ACTEDIT_BORDERSEL_ALL;
-
- /* draw and handle the borderselect stuff (ui) and get the select rect */
- if ( (val = get_border(&rect, 3)) ) {
- if (val == LEFTMOUSE) {
- selectmode = SELECT_ADD;
- select_function = select_bezier_add;
- }
- else {
- selectmode = SELECT_SUBTRACT;
- select_function = select_bezier_subtract;
- }
-
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- /* if action is mapped in NLA, it returns a correction */
- if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
- rectf.xmin= get_action_frame(OBACT, rectf.xmin);
- rectf.xmax= get_action_frame(OBACT, rectf.xmax);
- }
-
- ymax = CHANNELHEIGHT/2;
-
- /* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
- actdata_filter(&act_data, filter, data, datatype);
-
- /* loop over data, doing border select */
- for (ale= act_data.first; ale; ale= ale->next) {
- ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
-
- /* what gets selected depends on the mode (based on initial position of cursor) */
- switch (mode) {
- case ACTEDIT_BORDERSEL_FRA: /* all in frame(s) */
- if (ale->key_data) {
- if (ale->datatype == ALE_IPO)
- borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
- else if (ale->datatype == ALE_ICU)
- borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_function);
- }
- break;
- case ACTEDIT_BORDERSEL_CHA: /* all in channel(s) */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- if (ale->key_data) {
- if (ale->datatype == ALE_IPO)
- select_ipo_bezier_keys(ale->key_data, selectmode);
- else if (ale->datatype == ALE_ICU)
- select_icu_bezier_keys(ale->key_data, selectmode);
- }
- }
- break;
- default: /* any keyframe inside region defined by region */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- if (ale->key_data) {
- if (ale->datatype == ALE_IPO)
- borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
- else if (ale->datatype == ALE_ICU)
- borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_function);
- }
- }
- }
-
- ymax=ymin;
- }
-
- /* cleanup */
- BLI_freelistN(&act_data);
-
- BIF_undo_push("Border Select Action");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- }
-}
-
-/* **************************************************** */
-/* MOUSE-HANDLING */
-
-/* right-hand side - mouse click */
-static void mouse_action (int selectmode)
-{
- void *data;
- short datatype;
-
- bAction *act= NULL;
- bActionChannel *achan= NULL;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
- TimeMarker *marker;
-
- void *act_channel;
- short sel, act_type;
- float selx;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
- if (datatype == ACTCONT_ACTION) act= (bAction *)data;
-
- act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
- marker=find_nearest_marker(1);
-
- if (act_channel) {
- switch (act_type) {
- case ACTTYPE_ICU:
- icu= (IpoCurve *)act_channel;
- break;
- case ACTTYPE_CONCHAN:
- conchan= (bConstraintChannel *)act_channel;
- break;
- case ACTTYPE_ACHAN:
- achan= (bActionChannel *)act_channel;
- break;
- default:
- return;
- }
-
- if (selectmode == SELECT_REPLACE) {
- selectmode = SELECT_ADD;
-
- deselect_action_keys(0, 0);
-
- if (datatype == ACTCONT_ACTION) {
- deselect_action_channels(0);
-
- achan->flag |= ACHAN_SELECTED;
- hilight_channel(act, achan, 1);
- select_poseelement_by_name(achan->name, 2); /* 2 is activate */
- }
- }
-
- if (icu)
- select_icu_key(icu, selx, selectmode);
- else if (conchan)
- select_ipo_key(conchan->ipo, selx, selectmode);
- else
- select_ipo_key(achan->ipo, selx, selectmode);
-
- std_rmouse_transform(transform_action_keys);
-
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWBUTSALL, 0);
- }
- else if (marker) {
- /* not channel, so maybe marker */
- if (selectmode == SELECT_REPLACE) {
- deselect_markers(0, 0);
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_INVERT) {
- if (marker->flag & SELECT)
- marker->flag &= ~SELECT;
- else
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_ADD)
- marker->flag |= SELECT;
- else if (selectmode == SELECT_SUBTRACT)
- marker->flag &= ~SELECT;
-
- std_rmouse_transform(transform_markers);
-
- allqueue(REDRAWMARKER, 0);
- }
-}
-
-/* lefthand side - mouse-click */
-static void mouse_actionchannels (short mval[])
-{
- bAction *act= G.saction->action;
- void *data, *act_channel;
- short datatype, chantype;
-
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) return;
-
- /* get channel to work on */
- act_channel= get_nearest_act_channel(mval, &chantype);
-
- /* action to take depends on what channel we've got */
- switch (chantype) {
- case ACTTYPE_ACHAN:
- {
- bActionChannel *achan= (bActionChannel *)act_channel;
-
- if (mval[0] >= (NAMEWIDTH-16)) {
- /* toggle protect */
- achan->flag ^= ACHAN_PROTECTED;
- }
- else if ((mval[0] >= (NAMEWIDTH-32)) && (achan->ipo)) {
- /* toggle mute */
- achan->ipo->muteipo = (achan->ipo->muteipo)? 0: 1;
- }
- else if (mval[0] <= 17) {
- /* toggle expand */
- achan->flag ^= ACHAN_EXPANDED;
- }
- else {
- /* select/deselect achan */
- if (G.qual & LR_SHIFTKEY) {
- select_channel(act, achan, SELECT_INVERT);
- }
- else {
- deselect_actionchannels(act, 0);
- select_channel(act, achan, SELECT_ADD);
- }
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 2);
- }
- }
- break;
- case ACTTYPE_FILLIPO:
- {
- bActionChannel *achan= (bActionChannel *)act_channel;
-
- achan->flag ^= ACHAN_SHOWIPO;
-
- if ((mval[0] > 24) && (achan->flag & ACHAN_SHOWIPO)) {
- /* select+make active achan */
- deselect_actionchannels(act, 0);
- select_channel(act, achan, SELECT_ADD);
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 2);
- }
- }
- break;
- case ACTTYPE_FILLCON:
- {
- bActionChannel *achan= (bActionChannel *)act_channel;
-
- achan->flag ^= ACHAN_SHOWCONS;
-
- if ((mval[0] > 24) && (achan->flag & ACHAN_SHOWCONS)) {
- /* select+make active achan */
- deselect_actionchannels(act, 0);
- select_channel(act, achan, SELECT_ADD);
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 2);
- }
- }
- break;
- case ACTTYPE_ICU:
- {
- IpoCurve *icu= (IpoCurve *)act_channel;
-
-#if 0 /* disabled until all ipo tools support this -------> */
- if (mval[0] >= (NAMEWIDTH-16)) {
- /* toggle protection */
- icu->flag ^= IPO_PROTECT;
- }
-#endif /* <------- end of disabled code */
- if (mval[0] >= (NAMEWIDTH-16)) {
- /* toggle mute */
- icu->flag ^= IPO_MUTE;
- }
- else {
- /* select/deselect */
- select_icu_channel(act, icu, SELECT_INVERT);
- }
- }
- break;
- case ACTTYPE_CONCHAN:
- {
- bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
-
- if (mval[0] >= (NAMEWIDTH-16)) {
- /* toggle protection */
- conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
- }
- else if ((mval[0] >= (NAMEWIDTH-32)) && (conchan->ipo)) {
- /* toggle mute */
- conchan->ipo->muteipo = (conchan->ipo->muteipo)? 0: 1;
- }
- else {
- /* select/deselect */
- select_constraint_channel(act, conchan, SELECT_INVERT);
- }
- }
- break;
- default:
- return;
- }
-
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWBUTSALL, 0);
-}
-
-/* **************************************************** */
-/* ACTION CHANNEL RE-ORDERING */
-
-void top_sel_action ()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.first; achan; achan= achan->next){
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* make it first element */
- BLI_insertlinkbefore(&act->chanbase, act->chanbase.first, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Top Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void up_sel_action ()
-{
- bAction *act;
- bActionChannel *achan, *prev;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- prev = achan->prev;
- if (prev) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* push it up */
- BLI_insertlinkbefore(&act->chanbase, prev, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Up Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void down_sel_action ()
-{
- bAction *act;
- bActionChannel *achan, *next;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- next = achan->next;
- if (next) next = next->next;
- if (next) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* move it down */
- BLI_insertlinkbefore(&act->chanbase, next, achan);
- achan->flag |= ACHAN_MOVED;
- }
- else {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
- }
- }
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Down Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void bottom_sel_action ()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
- }
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Bottom Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* **************************************************** */
-/* EVENT HANDLING */
-
-void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
-{
- extern void do_actionbuts(unsigned short event); // drawaction.c
- SpaceAction *saction;
- void *data;
- short datatype;
- float dx, dy;
- int doredraw= 0;
- int cfra;
- short mval[2];
- unsigned short event= evt->event;
- short val= evt->val;
- short mousebut = L_MOUSE;
-
- if (curarea->win==0) return;
-
- saction= curarea->spacedata.first;
- if (!saction)
- return;
-
- data= get_action_context(&datatype);
-
- if (val) {
- if ( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
-
- /* swap mouse buttons based on user preference */
- if (U.flag & USER_LMOUSESELECT) {
- if (event == LEFTMOUSE) {
- event = RIGHTMOUSE;
- mousebut = L_MOUSE;
- } else if (event == RIGHTMOUSE) {
- event = LEFTMOUSE;
- mousebut = R_MOUSE;
- }
- }
-
- getmouseco_areawin(mval);
-
- switch(event) {
- case UI_BUT_EVENT:
- do_actionbuts(val); // window itself
- break;
-
- case HOMEKEY:
- do_action_buttons(B_ACTHOME); // header
- break;
-
- case AKEY:
- if (mval[0]<NAMEWIDTH) {
- deselect_action_channels (1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (mval[0]>ACTWIDTH) {
- if (G.qual == LR_CTRLKEY) {
- deselect_markers (1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- else {
- deselect_action_keys (1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- }
- break;
-
- case BKEY:
- if (G.qual & LR_CTRLKEY) {
- borderselect_markers();
- }
- else {
- if (mval[0]>ACTWIDTH)
- borderselect_action();
- }
- break;
-
- case CKEY:
- /* scroll the window so the current
- * frame is in the center.
- */
- center_currframe();
- break;
-
- case DKEY:
- if (mval[0]>ACTWIDTH) {
- if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
- duplicate_marker();
- else if (G.qual == LR_SHIFTKEY)
- duplicate_action_keys();
- }
- break;
-
- case EKEY:
- if (mval[0] >= ACTWIDTH)
- transform_action_keys('e', 0);
- break;
-
- case GKEY:
- if (G.qual & LR_CTRLKEY) {
- transform_markers('g', 0);
- }
- else {
- if (mval[0]>=ACTWIDTH)
- transform_action_keys('g', 0);
- }
- break;
-
- case HKEY:
- if (G.qual & LR_SHIFTKEY) {
- if (okee("Set Keys to Auto Handle"))
- sethandles_action_keys(HD_AUTO);
- }
- else {
- if (okee("Toggle Keys Aligned Handle"))
- sethandles_action_keys(HD_ALIGN);
- }
- break;
-
- case KKEY:
- if (G.qual & LR_CTRLKEY) {
- markers_selectkeys_between();
- }
- else {
- val= (G.qual & LR_SHIFTKEY) ? 2 : 1;
- column_select_action_keys(val);
- }
-
- allqueue(REDRAWMARKER, 0);
- break;
-
- case MKEY:
- if (G.qual & LR_SHIFTKEY) {
- /* mirror keyframes */
- if (data) {
- if (G.saction->flag & SACTION_DRAWTIME)
- val = pupmenu("Mirror Keys Over%t|Current Time%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
- else
- val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
-
- mirror_action_keys(val);
- }
- }
- else {
- /* marker operations */
- if (G.qual == 0)
- add_marker(CFRA);
- else if (G.qual == LR_CTRLKEY)
- rename_marker();
- else
- break;
- allqueue(REDRAWMARKER, 0);
- }
- break;
-
- case NKEY:
- if(G.qual==0) {
- numbuts_action();
-
- /* no panel (yet). current numbuts are not easy to put in panel... */
- //add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
- //scrarea_queue_winredraw(curarea);
- }
- break;
-
- case OKEY:
- clean_action();
- break;
-
- case PKEY:
- if (G.qual & LR_CTRLKEY) /* set preview range */
- anim_previewrange_set();
- else if (G.qual & LR_ALTKEY) /* clear preview range */
- anim_previewrange_clear();
-
- allqueue(REDRAWMARKER, 0);
- allqueue(REDRAWBUTSALL, 0);
- break;
-
- case SKEY:
- if (mval[0]>=ACTWIDTH) {
- if (G.qual == (LR_SHIFTKEY|LR_CTRLKEY)) {
- if (data) {
- snap_cfra_action();
- }
- }
- else if (G.qual & LR_SHIFTKEY) {
- if (data) {
- if (G.saction->flag & SACTION_DRAWTIME)
- val = pupmenu("Snap Keys To%t|Nearest Second%x4|Current Time%x2|Nearest Marker %x3");
- else
- val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
-
- snap_action_keys(val);
- }
- }
- else {
- transform_action_keys('s', 0);
- }
- }
- break;
-
- case TKEY:
- if (G.qual & LR_SHIFTKEY)
- action_set_ipo_flags(SET_IPO_POPUP, 0);
- else if (G.qual & LR_CTRLKEY) {
- val= pupmenu("Time value%t|Frames %x1|Seconds%x2");
-
- if (val > 0) {
- if (val == 2) saction->flag |= SACTION_DRAWTIME;
- else saction->flag &= ~SACTION_DRAWTIME;
-
- doredraw= 1;
- }
- }
- else
- transform_action_keys ('t', 0);
- break;
-
- case VKEY:
- if (okee("Set Keys to Vector Handle"))
- sethandles_action_keys(HD_VECT);
- break;
-
- case PAGEUPKEY:
- if (datatype == ACTCONT_ACTION) {
- if(G.qual & LR_SHIFTKEY)
- top_sel_action();
- else if (G.qual & LR_CTRLKEY)
- up_sel_action();
- else
- nextprev_marker(1);
- }
- else if (datatype == ACTCONT_SHAPEKEY) {
- /* only jump to markers possible (key channels can't be moved yet) */
- nextprev_marker(1);
- }
- break;
- case PAGEDOWNKEY:
- if (datatype == ACTCONT_ACTION) {
- if(G.qual & LR_SHIFTKEY)
- bottom_sel_action();
- else if (G.qual & LR_CTRLKEY)
- down_sel_action();
- else
- nextprev_marker(-1);
- }
- else if (datatype == ACTCONT_SHAPEKEY) {
- /* only jump to markers possible (key channels can't be moved yet) */
- nextprev_marker(-1);
- }
- break;
-
- case DELKEY:
- case XKEY:
- if (okee("Erase selected")) {
- if (mval[0]<NAMEWIDTH)
- delete_action_channels();
- else
- delete_action_keys();
-
- if (mval[0] >= NAMEWIDTH)
- remove_marker();
-
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- break;
-
- /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
- * based on user preference USER_LMOUSESELECT
- */
- case LEFTMOUSE:
- if (view2dmove(LEFTMOUSE)) /* only checks for sliders */
- break;
- else if ((G.v2d->mask.xmin==0) || (mval[0]>ACTWIDTH)) {
- /* moving time-marker / current frame */
- do {
- getmouseco_areawin(mval);
- areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
-
- cfra= (int)dx;
- if (cfra < 1) cfra= 1;
-
- if (cfra != CFRA) {
- CFRA= cfra;
- update_for_newframe();
- force_draw_all(0);
- }
- else PIL_sleep_ms(30);
-
- } while(get_mbut() & mousebut);
- break;
- }
- /* passed on as selection */
- case RIGHTMOUSE:
- /* Clicking in the channel area */
- if ((G.v2d->mask.xmin) && (mval[0]<NAMEWIDTH)) {
- if (datatype == ACTCONT_ACTION) {
- /* mouse is over action channels */
- if (G.qual & LR_CTRLKEY)
- numbuts_action();
- else
- mouse_actionchannels(mval);
- }
- else numbuts_action();
- }
- else {
- short select_mode= (G.qual & LR_SHIFTKEY)? SELECT_INVERT: SELECT_REPLACE;
-
- /* Clicking in the vertical scrollbar selects
- * all of the keys for that channel at that height
- */
- if (IN_2D_VERT_SCROLL(mval))
- selectall_action_keys(mval, 0, select_mode);
-
- /* Clicking in the horizontal scrollbar selects
- * all of the keys within 0.5 of the nearest integer
- * frame
- */
- else if (IN_2D_HORIZ_SCROLL(mval))
- selectall_action_keys(mval, 1, select_mode);
-
- /* Clicking in the main area of the action window
- * selects keys and markers
- */
- else if (G.qual & LR_ALTKEY) {
- areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
-
- /* sends a 1 for left and 0 for right */
- selectkeys_leftright((dx < (float)CFRA), select_mode);
- }
- else
- mouse_action(select_mode);
- }
- break;
- case PADPLUSKEY:
- view2d_zoom(G.v2d, 0.1154, sa->winx, sa->winy);
- test_view2d(G.v2d, sa->winx, sa->winy);
- view2d_do_locks(curarea, V2D_LOCK_COPY);
-
- doredraw= 1;
- break;
- case PADMINUS:
- view2d_zoom(G.v2d, -0.15, sa->winx, sa->winy);
- test_view2d(G.v2d, sa->winx, sa->winy);
- view2d_do_locks(curarea, V2D_LOCK_COPY);
-
- doredraw= 1;
- break;
- case MIDDLEMOUSE:
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- view2dmove(event); /* in drawipo.c */
- break;
- }
- }
-
- if(doredraw) addqueue(curarea->win, REDRAW, 1);
-
-}
-
-/* **************************************************** */