2009-01-01 00:18:23 +00:00
|
|
|
/**
|
|
|
|
* $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
|
|
|
|
*
|
|
|
|
* ***** 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) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* 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"
|
2009-01-20 11:07:42 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2009-01-01 00:18:23 +00:00
|
|
|
#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_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_userdef_types.h"
|
|
|
|
#include "DNA_gpencil_types.h"
|
|
|
|
#include "DNA_windowmanager_types.h"
|
2009-02-13 06:33:07 +00:00
|
|
|
#include "DNA_world_types.h"
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
|
|
#include "BKE_action.h"
|
|
|
|
#include "BKE_depsgraph.h"
|
|
|
|
#include "BKE_ipo.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_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 "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|
2009-01-01 08:08:55 +00:00
|
|
|
/* CHANNELS API */
|
2009-01-01 00:18:23 +00:00
|
|
|
|
2009-01-02 00:56:48 +00:00
|
|
|
/* -------------------------- Internal Macros ------------------------------- */
|
2009-01-01 00:18:23 +00:00
|
|
|
|
2009-01-02 00:56:48 +00:00
|
|
|
/* set/clear/toggle macro
|
|
|
|
* - channel - channel with a 'flag' member that we're setting
|
|
|
|
* - smode - 0=clear, 1=set, 2=toggle
|
|
|
|
* - sflag - bitflag to set
|
|
|
|
*/
|
|
|
|
#define ACHANNEL_SET_FLAG(channel, smode, sflag) \
|
|
|
|
{ \
|
|
|
|
if (smode == ACHANNEL_SETFLAG_TOGGLE) (channel)->flag ^= (sflag); \
|
|
|
|
else if (smode == ACHANNEL_SETFLAG_ADD) (channel)->flag |= (sflag); \
|
|
|
|
else (channel)->flag &= ~(sflag); \
|
|
|
|
}
|
2009-04-09 07:26:49 +00:00
|
|
|
|
|
|
|
/* set/clear/toggle macro, where the flag is negative
|
|
|
|
* - channel - channel with a 'flag' member that we're setting
|
|
|
|
* - smode - 0=clear, 1=set, 2=toggle
|
|
|
|
* - sflag - bitflag to set
|
|
|
|
*/
|
|
|
|
#define ACHANNEL_SET_FLAG_NEG(channel, smode, sflag) \
|
|
|
|
{ \
|
|
|
|
if (smode == ACHANNEL_SETFLAG_TOGGLE) (channel)->flag ^= (sflag); \
|
|
|
|
else if (smode == ACHANNEL_SETFLAG_ADD) (channel)->flag &= ~(sflag); \
|
|
|
|
else (channel)->flag |= (sflag); \
|
|
|
|
}
|
2009-01-01 08:08:55 +00:00
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* -------------------------- Exposed API ----------------------------------- */
|
2009-01-01 08:08:55 +00:00
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* Set the given animation-channel as the active one for the active context */
|
|
|
|
void ANIM_set_active_channel (void *data, short datatype, int filter, void *channel_data, short channel_type)
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
2009-02-22 04:13:29 +00:00
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
2009-01-05 00:38:17 +00:00
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* try to build list of filtered items */
|
|
|
|
// XXX we don't need/supply animcontext for now, since in this case, there's nothing really essential there that isn't already covered
|
|
|
|
ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
|
|
|
|
if (anim_data.first == NULL)
|
2009-01-05 00:38:17 +00:00
|
|
|
return;
|
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* only clear the 'active' flag for the channels of the same type */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
/* skip if types don't match */
|
|
|
|
if (channel_type != ale->type)
|
2009-04-11 00:29:21 +00:00
|
|
|
continue;
|
2009-01-05 00:38:17 +00:00
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* flag to set depends on type */
|
|
|
|
switch (ale->type) {
|
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
|
|
|
|
2009-04-11 00:29:21 +00:00
|
|
|
ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
|
2009-02-22 04:13:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FCURVE:
|
|
|
|
{
|
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
|
|
|
|
2009-04-11 00:29:21 +00:00
|
|
|
ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set active flag */
|
|
|
|
if (channel_data) {
|
|
|
|
switch (channel_type) {
|
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)channel_data;
|
|
|
|
agrp->flag |= AGRP_ACTIVE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FCURVE:
|
|
|
|
{
|
|
|
|
FCurve *fcu= (FCurve *)channel_data;
|
|
|
|
fcu->flag |= FCURVE_ACTIVE;
|
2009-02-22 04:13:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
2009-02-22 04:13:29 +00:00
|
|
|
|
|
|
|
/* clean up */
|
|
|
|
BLI_freelistN(&anim_data);
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 00:56:48 +00:00
|
|
|
/* Deselect all animation channels
|
|
|
|
* - data: pointer to datatype, as contained in bAnimContext
|
2009-01-05 00:38:17 +00:00
|
|
|
* - datatype: the type of data that 'data' represents (eAnimCont_Types)
|
2009-01-02 00:56:48 +00:00
|
|
|
* - test: check if deselecting instead of selecting
|
|
|
|
* - sel: eAnimChannels_SetFlag;
|
|
|
|
*/
|
|
|
|
void ANIM_deselect_anim_channels (void *data, short datatype, short test, short sel)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
filter= ANIMFILTER_VISIBLE;
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
|
2009-01-02 00:56:48 +00:00
|
|
|
|
|
|
|
/* See if we should be selecting or deselecting */
|
|
|
|
if (test) {
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
if (sel == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (ale->type) {
|
2009-02-13 06:33:07 +00:00
|
|
|
case ANIMTYPE_SCENE:
|
|
|
|
if (ale->flag & SCE_DS_SELECTED)
|
|
|
|
sel= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
break;
|
2009-01-02 00:56:48 +00:00
|
|
|
case ANIMTYPE_OBJECT:
|
|
|
|
if (ale->flag & SELECT)
|
|
|
|
sel= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLACTD:
|
2009-01-20 11:07:42 +00:00
|
|
|
if (ale->flag & ACT_SELECTED)
|
2009-01-02 00:56:48 +00:00
|
|
|
sel= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
if (ale->flag & AGRP_SELECTED)
|
|
|
|
sel= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
break;
|
2009-01-20 11:07:42 +00:00
|
|
|
case ANIMTYPE_FCURVE:
|
|
|
|
if (ale->flag & FCURVE_SELECTED)
|
2009-01-02 00:56:48 +00:00
|
|
|
sel= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now set the flags */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
switch (ale->type) {
|
2009-02-13 06:33:07 +00:00
|
|
|
case ANIMTYPE_SCENE:
|
|
|
|
{
|
|
|
|
Scene *scene= (Scene *)ale->data;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
|
|
|
|
}
|
|
|
|
break;
|
2009-01-02 00:56:48 +00:00
|
|
|
case ANIMTYPE_OBJECT:
|
|
|
|
{
|
|
|
|
Base *base= (Base *)ale->data;
|
|
|
|
Object *ob= base->object;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(base, sel, SELECT);
|
|
|
|
ACHANNEL_SET_FLAG(ob, sel, SELECT);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLACTD:
|
|
|
|
{
|
|
|
|
bAction *act= (bAction *)ale->data;
|
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
ACHANNEL_SET_FLAG(act, sel, ACT_SELECTED);
|
2009-01-02 00:56:48 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
|
|
|
|
agrp->flag &= ~AGRP_ACTIVE;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-20 11:07:42 +00:00
|
|
|
case ANIMTYPE_FCURVE:
|
2009-01-02 00:56:48 +00:00
|
|
|
{
|
2009-01-20 11:07:42 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
2009-01-02 00:56:48 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
|
|
|
|
fcu->flag &= ~FCURVE_ACTIVE;
|
2009-01-02 00:56:48 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
2009-01-01 00:18:23 +00:00
|
|
|
/* ************************************************************************** */
|
2009-01-01 08:08:55 +00:00
|
|
|
/* OPERATORS */
|
|
|
|
|
2009-01-05 00:38:17 +00:00
|
|
|
/* ****************** Rearrange Channels Operator ******************* */
|
2009-01-05 09:54:39 +00:00
|
|
|
/* This operator only works for Action Editor mode for now, as having it elsewhere makes things difficult */
|
2009-01-05 00:38:17 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
#if 0 // XXX old animation system - needs to be updated for new system...
|
|
|
|
|
2009-01-05 09:54:39 +00:00
|
|
|
/* constants for channel rearranging */
|
|
|
|
/* WARNING: don't change exising ones without modifying rearrange func accordingly */
|
|
|
|
enum {
|
|
|
|
REARRANGE_ACTCHAN_TOP= -2,
|
|
|
|
REARRANGE_ACTCHAN_UP= -1,
|
|
|
|
REARRANGE_ACTCHAN_DOWN= 1,
|
|
|
|
REARRANGE_ACTCHAN_BOTTOM= 2
|
|
|
|
};
|
|
|
|
|
|
|
|
/* make sure all action-channels belong to a group (and clear action's list) */
|
|
|
|
static void split_groups_action_temp (bAction *act, bActionGroup *tgrp)
|
|
|
|
{
|
|
|
|
bActionChannel *achan;
|
|
|
|
bActionGroup *agrp;
|
|
|
|
|
|
|
|
/* Separate action-channels into lists per group */
|
|
|
|
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
|
|
|
|
if (agrp->channels.first) {
|
|
|
|
achan= agrp->channels.last;
|
|
|
|
act->chanbase.first= achan->next;
|
|
|
|
|
|
|
|
achan= agrp->channels.first;
|
|
|
|
achan->prev= NULL;
|
|
|
|
|
|
|
|
achan= agrp->channels.last;
|
|
|
|
achan->next= NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialise memory for temp-group */
|
|
|
|
memset(tgrp, 0, sizeof(bActionGroup));
|
|
|
|
tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP);
|
|
|
|
strcpy(tgrp->name, "#TempGroup");
|
|
|
|
|
|
|
|
/* Move any action-channels not already moved, to the temp group */
|
|
|
|
if (act->chanbase.first) {
|
|
|
|
/* start of list */
|
|
|
|
achan= act->chanbase.first;
|
|
|
|
achan->prev= NULL;
|
|
|
|
tgrp->channels.first= achan;
|
|
|
|
act->chanbase.first= NULL;
|
|
|
|
|
|
|
|
/* end of list */
|
|
|
|
achan= act->chanbase.last;
|
|
|
|
achan->next= NULL;
|
|
|
|
tgrp->channels.last= achan;
|
|
|
|
act->chanbase.last= NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add temp-group to list */
|
|
|
|
BLI_addtail(&act->groups, tgrp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* link lists of channels that groups have */
|
|
|
|
static void join_groups_action_temp (bAction *act)
|
|
|
|
{
|
|
|
|
bActionGroup *agrp;
|
|
|
|
bActionChannel *achan;
|
|
|
|
|
|
|
|
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
|
|
|
|
ListBase tempGroup;
|
|
|
|
|
|
|
|
/* add list of channels to action's channels */
|
|
|
|
tempGroup= agrp->channels;
|
|
|
|
addlisttolist(&act->chanbase, &agrp->channels);
|
|
|
|
agrp->channels= tempGroup;
|
|
|
|
|
|
|
|
/* clear moved flag */
|
|
|
|
agrp->flag &= ~AGRP_MOVED;
|
|
|
|
|
|
|
|
/* if temp-group... remove from list (but don't free as it's on the stack!) */
|
|
|
|
if (agrp->flag & AGRP_TEMP) {
|
|
|
|
BLI_remlink(&act->groups, agrp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear "moved" flag from all achans */
|
|
|
|
for (achan= act->chanbase.first; achan; achan= achan->next)
|
|
|
|
achan->flag &= ~ACHAN_MOVED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static short rearrange_actchannel_is_ok (Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (type == ANIMTYPE_GROUP) {
|
|
|
|
bActionGroup *agrp= (bActionGroup *)channel;
|
|
|
|
|
|
|
|
if (SEL_AGRP(agrp) && !(agrp->flag & AGRP_MOVED))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (type == ANIMTYPE_ACHAN) {
|
|
|
|
bActionChannel *achan= (bActionChannel *)channel;
|
|
|
|
|
|
|
|
if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static short rearrange_actchannel_after_ok (Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (type == ANIMTYPE_GROUP) {
|
|
|
|
bActionGroup *agrp= (bActionGroup *)channel;
|
|
|
|
|
|
|
|
if (agrp->flag & AGRP_TEMP)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static short rearrange_actchannel_top (ListBase *list, Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (rearrange_actchannel_is_ok(channel, type)) {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* make it first element */
|
|
|
|
BLI_insertlinkbefore(list, list->first, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static short rearrange_actchannel_up (ListBase *list, Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (rearrange_actchannel_is_ok(channel, type)) {
|
|
|
|
Link *prev= channel->prev;
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* push it up */
|
|
|
|
BLI_insertlinkbefore(list, prev, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static short rearrange_actchannel_down (ListBase *list, Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (rearrange_actchannel_is_ok(channel, type)) {
|
|
|
|
Link *next = (channel->next) ? channel->next->next : NULL;
|
|
|
|
|
|
|
|
if (next) {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* move it down */
|
|
|
|
BLI_insertlinkbefore(list, next, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (rearrange_actchannel_after_ok(list->last, type)) {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* add at end */
|
|
|
|
BLI_addtail(list, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* add just before end */
|
|
|
|
BLI_insertlinkbefore(list, list->last, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short type)
|
|
|
|
{
|
|
|
|
if (rearrange_actchannel_is_ok(channel, type)) {
|
|
|
|
if (rearrange_actchannel_after_ok(list->last, type)) {
|
|
|
|
/* take it out off the chain keep data */
|
|
|
|
BLI_remlink(list, channel);
|
|
|
|
|
|
|
|
/* add at end */
|
|
|
|
BLI_addtail(list, channel);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Change the order of action-channels
|
|
|
|
* mode: REARRANGE_ACTCHAN_*
|
|
|
|
*/
|
|
|
|
static void rearrange_action_channels (bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
bAction *act;
|
|
|
|
bActionChannel *achan, *chan;
|
|
|
|
bActionGroup *agrp, *grp;
|
|
|
|
bActionGroup tgrp;
|
|
|
|
|
|
|
|
short (*rearrange_func)(ListBase *, Link *, short);
|
|
|
|
short do_channels = 1;
|
|
|
|
|
|
|
|
/* Get the active action, exit if none are selected */
|
|
|
|
act= (bAction *)ac->data;
|
|
|
|
|
|
|
|
/* exit if invalid mode */
|
|
|
|
switch (mode) {
|
|
|
|
case REARRANGE_ACTCHAN_TOP:
|
|
|
|
rearrange_func= rearrange_actchannel_top;
|
|
|
|
break;
|
|
|
|
case REARRANGE_ACTCHAN_UP:
|
|
|
|
rearrange_func= rearrange_actchannel_up;
|
|
|
|
break;
|
|
|
|
case REARRANGE_ACTCHAN_DOWN:
|
|
|
|
rearrange_func= rearrange_actchannel_down;
|
|
|
|
break;
|
|
|
|
case REARRANGE_ACTCHAN_BOTTOM:
|
|
|
|
rearrange_func= rearrange_actchannel_bottom;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make sure we're only operating with groups */
|
|
|
|
split_groups_action_temp(act, &tgrp);
|
|
|
|
|
|
|
|
/* rearrange groups first (and then, only consider channels if the groups weren't moved) */
|
|
|
|
#define GET_FIRST(list) ((mode > 0) ? (list.first) : (list.last))
|
|
|
|
#define GET_NEXT(item) ((mode > 0) ? (item->next) : (item->prev))
|
|
|
|
|
|
|
|
for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
|
|
|
|
/* Get next group to consider */
|
|
|
|
grp= GET_NEXT(agrp);
|
|
|
|
|
|
|
|
/* try to do group first */
|
|
|
|
if (rearrange_func(&act->groups, (Link *)agrp, ANIMTYPE_GROUP)) {
|
|
|
|
do_channels= 0;
|
|
|
|
agrp->flag |= AGRP_MOVED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (do_channels) {
|
|
|
|
for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
|
|
|
|
/* Get next group to consider */
|
|
|
|
grp= GET_NEXT(agrp);
|
|
|
|
|
|
|
|
/* only consider action-channels if they're visible (group expanded) */
|
|
|
|
if (EXPANDED_AGRP(agrp)) {
|
|
|
|
for (achan= GET_FIRST(agrp->channels); achan; achan= chan) {
|
|
|
|
/* Get next channel to consider */
|
|
|
|
chan= GET_NEXT(achan);
|
|
|
|
|
|
|
|
/* Try to do channel */
|
|
|
|
if (rearrange_func(&agrp->channels, (Link *)achan, ANIMTYPE_ACHAN))
|
|
|
|
achan->flag |= ACHAN_MOVED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef GET_FIRST
|
|
|
|
#undef GET_NEXT
|
|
|
|
|
|
|
|
/* assemble lists into one list (and clear moved tags) */
|
|
|
|
join_groups_action_temp(act);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data - only for Action Editor (for now) */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype != ANIMCONT_ACTION)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get mode, then rearrange channels */
|
2009-01-16 23:53:11 +00:00
|
|
|
mode= RNA_enum_get(op->ptr, "direction");
|
2009-01-05 09:54:39 +00:00
|
|
|
rearrange_action_channels(&ac, mode);
|
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ANIM_OT_channels_move_up (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Move Channel(s) Up";
|
|
|
|
ot->idname= "ANIM_OT_channels_move_up";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_rearrange_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-05 09:54:39 +00:00
|
|
|
|
|
|
|
/* props */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_UP, "Direction", "");
|
2009-01-05 09:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_move_down (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Move Channel(s) Down";
|
|
|
|
ot->idname= "ANIM_OT_channels_move_down";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_rearrange_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-05 09:54:39 +00:00
|
|
|
|
|
|
|
/* props */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_DOWN, "Direction", "");
|
2009-01-05 09:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_move_top (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Move Channel(s) to Top";
|
|
|
|
ot->idname= "ANIM_OT_channels_move_to_top";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_rearrange_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-05 09:54:39 +00:00
|
|
|
|
|
|
|
/* props */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_TOP, "Direction", "");
|
2009-01-05 09:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_move_bottom (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Move Channel(s) to Bottom";
|
|
|
|
ot->idname= "ANIM_OT_channels_move_to_bottom";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_rearrange_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-05 09:54:39 +00:00
|
|
|
|
|
|
|
/* props */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "direction", NULL /* XXX add enum for this */, REARRANGE_ACTCHAN_BOTTOM, "Direction", "");
|
2009-01-05 09:54:39 +00:00
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
#endif // XXX old animation system - needs to be updated for new system...
|
2009-01-05 00:38:17 +00:00
|
|
|
|
2009-02-10 11:37:14 +00:00
|
|
|
|
|
|
|
/* ******************** Toggle Channel Visibility Operator *********************** */
|
|
|
|
|
|
|
|
static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
short vis= ACHANNEL_SETFLAG_ADD;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
|
|
|
|
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
|
|
|
|
|
|
|
/* See if we should be making showing all selected or hiding */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
if (vis == ACHANNEL_SETFLAG_CLEAR)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (ale->flag & FCURVE_VISIBLE)
|
|
|
|
vis= ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now set the flags */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
|
|
|
ACHANNEL_SET_FLAG(fcu, vis, FCURVE_VISIBLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_visibility_toggle (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Toggle Visibility";
|
|
|
|
ot->idname= "ANIM_OT_channels_visibility_toggle";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_visibility_toggle_exec;
|
|
|
|
ot->poll= ED_operator_ipo_active;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
|
|
|
|
2009-01-02 11:06:27 +00:00
|
|
|
/* ********************** Set Flags Operator *********************** */
|
|
|
|
|
|
|
|
enum {
|
|
|
|
// ACHANNEL_SETTING_SELECT = 0,
|
|
|
|
ACHANNEL_SETTING_PROTECT = 1,
|
|
|
|
ACHANNEL_SETTING_MUTE,
|
2009-02-10 11:37:14 +00:00
|
|
|
ACHANNEL_SETTING_VISIBLE,
|
2009-04-08 12:35:38 +00:00
|
|
|
ACHANNEL_SETTING_EXPAND,
|
2009-01-02 11:06:27 +00:00
|
|
|
} eAnimChannel_Settings;
|
|
|
|
|
|
|
|
/* defines for setting animation-channel flags */
|
|
|
|
EnumPropertyItem prop_animchannel_setflag_types[] = {
|
|
|
|
{ACHANNEL_SETFLAG_CLEAR, "DISABLE", "Disable", ""},
|
|
|
|
{ACHANNEL_SETFLAG_ADD, "ENABLE", "Enable", ""},
|
|
|
|
{ACHANNEL_SETFLAG_TOGGLE, "TOGGLE", "Toggle", ""},
|
|
|
|
{0, NULL, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
/* defines for set animation-channel settings */
|
|
|
|
EnumPropertyItem prop_animchannel_settings_types[] = {
|
|
|
|
{ACHANNEL_SETTING_PROTECT, "PROTECT", "Protect", ""},
|
|
|
|
{ACHANNEL_SETTING_MUTE, "MUTE", "Mute", ""},
|
|
|
|
{0, NULL, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
2009-04-09 07:26:49 +00:00
|
|
|
/* macro to be used in setflag_anim_channels */
|
|
|
|
#define ASUBCHANNEL_SEL_OK(ale) ( (onlysel == 0) || \
|
|
|
|
((ale->id) && (GS(ale->id->name)==ID_OB) && (((Object *)ale->id)->flag & SELECT)) )
|
|
|
|
|
2009-01-02 11:06:27 +00:00
|
|
|
/* Set/clear a particular flag (setting) for all selected + visible channels
|
|
|
|
* setting: the setting to modify
|
|
|
|
* mode: eAnimChannels_SetFlag
|
2009-04-08 12:35:38 +00:00
|
|
|
* onlysel: only selected channels get the flag set
|
2009-01-02 11:06:27 +00:00
|
|
|
*/
|
2009-04-08 12:35:38 +00:00
|
|
|
static void setflag_anim_channels (bAnimContext *ac, short setting, short mode, short onlysel)
|
2009-01-02 11:06:27 +00:00
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
2009-04-08 12:35:38 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
|
|
|
|
if (onlysel) filter |= ANIMFILTER_SEL;
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* affect selected channels */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
switch (ale->type) {
|
2009-04-08 12:35:38 +00:00
|
|
|
case ANIMTYPE_OBJECT:
|
|
|
|
{
|
|
|
|
Base *base= (Base *)ale->data;
|
|
|
|
Object *ob= base->object;
|
|
|
|
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
// XXX - settings should really be moved out of ob->nlaflag
|
|
|
|
if (mode == ACHANNEL_SETFLAG_TOGGLE) ob->nlaflag ^= OB_ADS_COLLAPSED;
|
|
|
|
else if (mode == ACHANNEL_SETFLAG_ADD) ob->nlaflag &= ~OB_ADS_COLLAPSED;
|
|
|
|
else ob->nlaflag |= OB_ADS_COLLAPSED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2009-04-09 07:26:49 +00:00
|
|
|
|
|
|
|
case ANIMTYPE_FILLACTD:
|
|
|
|
{
|
|
|
|
bAction *act= (bAction *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG_NEG(act, mode, ACT_COLLAPSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLDRIVERS:
|
|
|
|
{
|
|
|
|
AnimData *adt= (AnimData *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG_NEG(adt, mode, ADT_DRIVERS_COLLAPSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLMATD:
|
|
|
|
{
|
|
|
|
Object *ob= (Object *)ale->data;
|
|
|
|
|
|
|
|
// XXX - settings should really be moved out of ob->nlaflag
|
|
|
|
if ((onlysel == 0) || (ob->flag & SELECT)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
if (mode == ACHANNEL_SETFLAG_TOGGLE) ob->nlaflag ^= OB_ADS_SHOWMATS;
|
|
|
|
else if (mode == ACHANNEL_SETFLAG_ADD) ob->nlaflag |= OB_ADS_SHOWMATS;
|
|
|
|
else ob->nlaflag &= ~OB_ADS_SHOWMATS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ANIMTYPE_DSMAT:
|
|
|
|
{
|
|
|
|
Material *ma= (Material *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(ma, mode, MA_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSLAM:
|
|
|
|
{
|
|
|
|
Lamp *la= (Lamp *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(la, mode, LA_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSCAM:
|
|
|
|
{
|
|
|
|
Camera *ca= (Camera *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(ca, mode, CAM_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSCUR:
|
|
|
|
{
|
|
|
|
Curve *cu= (Curve *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(cu, mode, CU_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSSKEY:
|
|
|
|
{
|
|
|
|
Key *key= (Key *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(key, mode, KEYBLOCK_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSWOR:
|
|
|
|
{
|
|
|
|
World *wo= (World *)ale->data;
|
|
|
|
|
|
|
|
if (ASUBCHANNEL_SEL_OK(ale)) {
|
|
|
|
if (setting == ACHANNEL_SETTING_EXPAND) {
|
|
|
|
ACHANNEL_SET_FLAG(wo, mode, WO_DS_EXPAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-01-02 11:06:27 +00:00
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
switch (setting) {
|
|
|
|
case ACHANNEL_SETTING_PROTECT:
|
|
|
|
ACHANNEL_SET_FLAG(agrp, mode, AGRP_PROTECTED);
|
|
|
|
break;
|
|
|
|
case ACHANNEL_SETTING_EXPAND:
|
|
|
|
ACHANNEL_SET_FLAG(agrp, mode, AGRP_EXPANDED);
|
|
|
|
break;
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2009-01-20 11:07:42 +00:00
|
|
|
case ANIMTYPE_FCURVE:
|
2009-01-02 11:06:27 +00:00
|
|
|
{
|
2009-01-20 11:07:42 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
2009-01-02 11:06:27 +00:00
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
switch (setting) {
|
|
|
|
case ACHANNEL_SETTING_MUTE:
|
|
|
|
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_MUTED);
|
|
|
|
break;
|
|
|
|
case ACHANNEL_SETTING_PROTECT:
|
|
|
|
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_PROTECTED);
|
|
|
|
break;
|
|
|
|
case ACHANNEL_SETTING_VISIBLE:
|
|
|
|
ACHANNEL_SET_FLAG(fcu, mode, FCURVE_VISIBLE);
|
|
|
|
break;
|
2009-02-10 11:37:14 +00:00
|
|
|
}
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GPLAYER:
|
|
|
|
{
|
|
|
|
bGPDlayer *gpl= (bGPDlayer *)ale->data;
|
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
switch (setting) {
|
|
|
|
case ACHANNEL_SETTING_MUTE:
|
|
|
|
ACHANNEL_SET_FLAG(gpl, mode, GP_LAYER_HIDE);
|
|
|
|
break;
|
|
|
|
case ACHANNEL_SETTING_PROTECT:
|
|
|
|
ACHANNEL_SET_FLAG(gpl, mode, GP_LAYER_LOCKED);
|
|
|
|
break;
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int animchannels_setflag_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode, setting;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
|
|
|
|
mode= RNA_enum_get(op->ptr, "mode");
|
|
|
|
setting= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* modify setting */
|
2009-04-08 12:35:38 +00:00
|
|
|
setflag_anim_channels(&ac, setting, mode, 1);
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
2009-01-05 09:54:39 +00:00
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
|
2009-01-02 11:06:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Enable Channel Setting";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_setting_enable";
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= animchannels_setflag_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* props */
|
|
|
|
/* flag-setting mode */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
/* setting to set */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
|
2009-01-02 11:06:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Disable Channel Setting";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_setting_disable";
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= animchannels_setflag_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* props */
|
|
|
|
/* flag-setting mode */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
/* setting to set */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
|
2009-01-02 11:06:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Toggle Channel Setting";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_setting_toggle";
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= animchannels_setflag_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* props */
|
|
|
|
/* flag-setting mode */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
/* setting to set */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
2009-01-02 11:06:27 +00:00
|
|
|
}
|
|
|
|
|
2009-02-22 05:55:37 +00:00
|
|
|
// XXX currently, this is a separate operator, but perhaps we could in future specify in keymaps whether to call invoke or exec?
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_editable_toggle (wmOperatorType *ot)
|
2009-02-22 05:55:37 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Toggle Channel Editability";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_editable_toggle";
|
2009-02-22 05:55:37 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_setflag_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* props */
|
|
|
|
/* flag-setting mode */
|
|
|
|
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
|
|
|
|
/* setting to set */
|
|
|
|
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
|
|
|
|
}
|
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
/* ********************** Expand Channels Operator *********************** */
|
|
|
|
|
|
|
|
static int animchannels_expand_exec (bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short onlysel= 1;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* only affect selected channels? */
|
|
|
|
if (RNA_boolean_get(op->ptr, "all"))
|
|
|
|
onlysel= 0;
|
|
|
|
|
|
|
|
/* modify setting */
|
|
|
|
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel);
|
|
|
|
|
|
|
|
/* set notifier that things have changed */
|
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_expand (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Expand Channels";
|
|
|
|
ot->idname= "ANIM_OT_channels_expand";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_expand_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* props */
|
|
|
|
RNA_def_boolean(ot->srna, "all", 0, "All", "Expand all channels (not just selected ones)");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ********************** Collapse Channels Operator *********************** */
|
|
|
|
|
|
|
|
static int animchannels_collapse_exec (bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short onlysel= 1;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* only affect selected channels? */
|
|
|
|
if (RNA_boolean_get(op->ptr, "all"))
|
|
|
|
onlysel= 0;
|
|
|
|
|
|
|
|
/* modify setting */
|
|
|
|
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel);
|
|
|
|
|
|
|
|
/* set notifier that things have changed */
|
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_collapse (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Collapse Channels";
|
|
|
|
ot->idname= "ANIM_OT_channels_collapse";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_collapse_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* props */
|
|
|
|
RNA_def_boolean(ot->srna, "all", 0, "All", "Collapse all channels (not just selected ones)");
|
|
|
|
}
|
|
|
|
|
2009-01-01 08:08:55 +00:00
|
|
|
/* ********************** Select All Operator *********************** */
|
|
|
|
|
2009-01-02 00:56:48 +00:00
|
|
|
static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* 'standard' behaviour - check if selected, then apply relevant selection */
|
|
|
|
if (RNA_boolean_get(op->ptr, "invert"))
|
|
|
|
ANIM_deselect_anim_channels(ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_TOGGLE);
|
|
|
|
else
|
|
|
|
ANIM_deselect_anim_channels(ac.data, ac.datatype, 1, ACHANNEL_SETFLAG_ADD);
|
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
2009-01-05 09:54:39 +00:00
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
2009-01-02 00:56:48 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_select_all_toggle (wmOperatorType *ot)
|
2009-01-02 00:56:48 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select All";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_select_all_toggle";
|
2009-01-02 00:56:48 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= animchannels_deselectall_exec;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-02 00:56:48 +00:00
|
|
|
|
|
|
|
/* props */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
|
2009-01-02 00:56:48 +00:00
|
|
|
}
|
2009-01-01 00:18:23 +00:00
|
|
|
|
2009-01-02 01:28:05 +00:00
|
|
|
/* ******************** Borderselect Operator *********************** */
|
|
|
|
|
|
|
|
static void borderselect_anim_channels (bAnimContext *ac, rcti *rect, short selectmode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
View2D *v2d= &ac->ar->v2d;
|
|
|
|
rctf rectf;
|
|
|
|
float ymin=0, ymax=(float)(-ACHANNEL_HEIGHT);
|
|
|
|
|
|
|
|
/* convert border-region to view coordinates */
|
|
|
|
UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin+2, &rectf.xmin, &rectf.ymin);
|
|
|
|
UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax-2, &rectf.xmax, &rectf.ymax);
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2009-01-02 01:28:05 +00:00
|
|
|
|
|
|
|
/* loop over data, doing border select */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
ymin= ymax - ACHANNEL_STEP;
|
|
|
|
|
|
|
|
/* if channel is within border-select region, alter it */
|
|
|
|
if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
|
|
|
|
/* only the following types can be selected */
|
|
|
|
switch (ale->type) {
|
|
|
|
case ANIMTYPE_OBJECT: /* object */
|
|
|
|
{
|
|
|
|
Base *base= (Base *)ale->data;
|
|
|
|
Object *ob= base->object;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(base, selectmode, SELECT);
|
|
|
|
ACHANNEL_SET_FLAG(ob, selectmode, SELECT);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GROUP: /* action group */
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(agrp, selectmode, AGRP_SELECTED);
|
2009-01-05 00:38:17 +00:00
|
|
|
agrp->flag &= ~AGRP_ACTIVE;
|
2009-01-02 01:28:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-01-20 11:07:42 +00:00
|
|
|
case ANIMTYPE_FCURVE: /* F-Curve channel */
|
2009-01-02 01:28:05 +00:00
|
|
|
{
|
2009-01-20 11:07:42 +00:00
|
|
|
FCurve *fcu = (FCurve *)ale->data;
|
2009-01-02 01:28:05 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
ACHANNEL_SET_FLAG(fcu, selectmode, FCURVE_SELECTED);
|
2009-01-02 01:28:05 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GPLAYER: /* grease-pencil layer */
|
|
|
|
{
|
|
|
|
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
|
|
|
|
|
|
|
ACHANNEL_SET_FLAG(gpl, selectmode, GP_LAYER_SELECT);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set minimum extent to be the maximum of the next channel */
|
|
|
|
ymax= ymin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
rcti rect;
|
|
|
|
short selectmode=0;
|
|
|
|
int event;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* get settings from operator */
|
|
|
|
rect.xmin= RNA_int_get(op->ptr, "xmin");
|
|
|
|
rect.ymin= RNA_int_get(op->ptr, "ymin");
|
|
|
|
rect.xmax= RNA_int_get(op->ptr, "xmax");
|
|
|
|
rect.ymax= RNA_int_get(op->ptr, "ymax");
|
|
|
|
|
|
|
|
event= RNA_int_get(op->ptr, "event_type");
|
|
|
|
if (event == LEFTMOUSE) // FIXME... hardcoded
|
|
|
|
selectmode = ACHANNEL_SETFLAG_ADD;
|
|
|
|
else
|
|
|
|
selectmode = ACHANNEL_SETFLAG_CLEAR;
|
|
|
|
|
|
|
|
/* apply borderselect animation channels */
|
|
|
|
borderselect_anim_channels(&ac, &rect, selectmode);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void ANIM_OT_channels_select_border(wmOperatorType *ot)
|
2009-01-02 01:28:05 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Border Select";
|
2009-03-29 02:15:13 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_select_border";
|
2009-01-02 01:28:05 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_border_select_invoke;
|
|
|
|
ot->exec= animchannels_borderselect_exec;
|
|
|
|
ot->modal= WM_border_select_modal;
|
|
|
|
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-02 01:28:05 +00:00
|
|
|
|
|
|
|
/* rna */
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
|
|
|
|
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
|
2009-01-02 01:28:05 +00:00
|
|
|
}
|
|
|
|
|
2009-01-01 00:18:23 +00:00
|
|
|
/* ******************** Mouse-Click Operator *********************** */
|
|
|
|
/* Depending on the channel that was clicked on, the mouse click will activate whichever
|
|
|
|
* part of the channel is relevant.
|
|
|
|
*
|
|
|
|
* NOTE: eventually, this should probably be phased out when many of these things are replaced with buttons
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, short selectmode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* get the channel that was clicked on */
|
|
|
|
/* filter channels */
|
2009-01-20 11:07:42 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
|
2009-01-26 04:13:38 +00:00
|
|
|
filter= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
/* get channel from index */
|
|
|
|
ale= BLI_findlink(&anim_data, channel_index);
|
|
|
|
if (ale == NULL) {
|
|
|
|
/* channel not found */
|
2009-01-05 00:38:17 +00:00
|
|
|
printf("Error: animation channel (index = %d) not found in mouse_anim_channels() \n", channel_index);
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-01-05 00:38:17 +00:00
|
|
|
/* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
|
|
|
|
// TODO: should this feature be extended to work with other channel types too?
|
|
|
|
if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
|
|
|
|
/* normal channels should not behave normally in this case */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-01-01 00:18:23 +00:00
|
|
|
/* action to take depends on what channel we've got */
|
|
|
|
switch (ale->type) {
|
2009-02-13 06:33:07 +00:00
|
|
|
case ANIMTYPE_SCENE:
|
|
|
|
{
|
|
|
|
Scene *sce= (Scene *)ale->data;
|
|
|
|
|
|
|
|
if (x < 16) {
|
|
|
|
/* toggle expand */
|
|
|
|
sce->flag ^= SCE_DS_COLLAPSED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* set selection status */
|
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
/* swap select */
|
|
|
|
sce->flag ^= SCE_DS_SELECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sce->flag |= SCE_DS_SELECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_OBJECT:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
bDopeSheet *ads= (bDopeSheet *)ac->data;
|
|
|
|
Scene *sce= (Scene *)ads->source;
|
|
|
|
Base *base= (Base *)ale->data;
|
|
|
|
Object *ob= base->object;
|
|
|
|
|
|
|
|
if (x < 16) {
|
|
|
|
/* toggle expand */
|
2009-01-20 11:07:42 +00:00
|
|
|
ob->nlaflag ^= OB_ADS_COLLAPSED; // XXX
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* set selection status */
|
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
/* swap select */
|
|
|
|
base->flag ^= SELECT;
|
|
|
|
ob->flag= base->flag;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-01-05 00:38:17 +00:00
|
|
|
Base *b;
|
|
|
|
|
|
|
|
/* deleselect all */
|
|
|
|
for (b= sce->base.first; b; b= b->next) {
|
|
|
|
b->flag &= ~SELECT;
|
|
|
|
b->object->flag= b->flag;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
|
2009-01-05 00:38:17 +00:00
|
|
|
/* select object now */
|
|
|
|
base->flag |= SELECT;
|
|
|
|
ob->flag |= SELECT;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
|
|
|
|
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
|
|
|
|
//set_active_base(base);
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_FILLACTD:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
bAction *act= (bAction *)ale->data;
|
2009-01-28 00:50:56 +00:00
|
|
|
act->flag ^= ACT_COLLAPSED;
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-01-30 08:10:31 +00:00
|
|
|
case ANIMTYPE_FILLDRIVERS:
|
|
|
|
{
|
|
|
|
AnimData *adt= (AnimData* )ale->data;
|
|
|
|
adt->flag ^= ADT_DRIVERS_COLLAPSED;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_FILLMATD:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Object *ob= (Object *)ale->data;
|
2009-01-20 11:07:42 +00:00
|
|
|
ob->nlaflag ^= OB_ADS_SHOWMATS; // XXX
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
case ANIMTYPE_DSMAT:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Material *ma= (Material *)ale->data;
|
|
|
|
ma->flag ^= MA_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_DSLAM:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Lamp *la= (Lamp *)ale->data;
|
|
|
|
la->flag ^= LA_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_DSCAM:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Camera *ca= (Camera *)ale->data;
|
|
|
|
ca->flag ^= CAM_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_DSCUR:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Curve *cu= (Curve *)ale->data;
|
|
|
|
cu->flag ^= CU_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_DSSKEY:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
Key *key= (Key *)ale->data;
|
|
|
|
key->flag ^= KEYBLOCK_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-02-13 06:33:07 +00:00
|
|
|
case ANIMTYPE_DSWOR:
|
|
|
|
{
|
|
|
|
World *wo= (World *)ale->data;
|
|
|
|
wo->flag ^= WO_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
case ANIMTYPE_GROUP:
|
2009-01-05 00:38:17 +00:00
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
2009-02-10 23:08:53 +00:00
|
|
|
short offset= (ELEM3(ac->datatype, ANIMCONT_DOPESHEET, ANIMCONT_FCURVES, ANIMCONT_DRIVERS))? 18 : 0;
|
2009-01-05 00:38:17 +00:00
|
|
|
|
|
|
|
if ((x < (offset+17)) && (agrp->channels.first)) {
|
|
|
|
/* toggle expand */
|
|
|
|
agrp->flag ^= AGRP_EXPANDED;
|
|
|
|
}
|
|
|
|
else if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
|
|
|
/* toggle protection/locking */
|
|
|
|
agrp->flag ^= AGRP_PROTECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect group */
|
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
/* inverse selection status of this group only */
|
|
|
|
agrp->flag ^= AGRP_SELECTED;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
else if (selectmode == -1) {
|
|
|
|
/* select all in group (and deselect everthing else) */
|
2009-02-22 04:13:29 +00:00
|
|
|
FCurve *fcu;
|
2009-01-01 01:47:36 +00:00
|
|
|
|
2009-01-05 00:38:17 +00:00
|
|
|
/* deselect all other channels */
|
|
|
|
ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
|
|
|
|
|
|
|
|
/* only select channels in group and group itself */
|
2009-02-22 04:13:29 +00:00
|
|
|
for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next)
|
|
|
|
fcu->flag |= FCURVE_SELECTED;
|
2009-01-05 00:38:17 +00:00
|
|
|
agrp->flag |= AGRP_SELECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select group by itself */
|
|
|
|
ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
|
|
|
|
agrp->flag |= AGRP_SELECTED;
|
|
|
|
}
|
|
|
|
|
2009-02-22 04:13:29 +00:00
|
|
|
/* if group is selected now, make group the 'active' one in the visible list */
|
2009-02-22 05:34:47 +00:00
|
|
|
if (agrp->flag & AGRP_SELECTED)
|
2009-02-22 04:13:29 +00:00
|
|
|
ANIM_set_active_channel(ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-05 00:38:17 +00:00
|
|
|
}
|
2009-01-01 00:18:23 +00:00
|
|
|
break;
|
2009-01-20 11:07:42 +00:00
|
|
|
case ANIMTYPE_FCURVE:
|
|
|
|
{
|
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
2009-02-22 09:30:18 +00:00
|
|
|
short offset;
|
|
|
|
|
|
|
|
if (ac->datatype != ANIMCONT_ACTION) {
|
|
|
|
/* for now, special case for materials */
|
|
|
|
if (ale->ownertype == ANIMTYPE_DSMAT)
|
|
|
|
offset= 21;
|
|
|
|
else
|
|
|
|
offset= 18;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
offset = 0;
|
2009-01-20 11:07:42 +00:00
|
|
|
|
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
|
|
|
/* toggle protection */
|
|
|
|
fcu->flag ^= FCURVE_PROTECTED;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-20 11:07:42 +00:00
|
|
|
else if (x >= (ACHANNEL_NAMEWIDTH-2*ACHANNEL_BUTTON_WIDTH)) {
|
|
|
|
/* toggle mute */
|
|
|
|
fcu->flag ^= FCURVE_MUTED;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-02-10 11:37:14 +00:00
|
|
|
else if ((x < (offset+17)) && (ac->spacetype==SPACE_IPO)) {
|
|
|
|
/* toggle visibility */
|
|
|
|
fcu->flag ^= FCURVE_VISIBLE;
|
|
|
|
}
|
2009-01-20 11:07:42 +00:00
|
|
|
else {
|
|
|
|
/* select/deselect */
|
2009-02-22 05:34:47 +00:00
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
/* inverse selection status of this F-Curve only */
|
|
|
|
fcu->flag ^= FCURVE_SELECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select F-Curve by itself */
|
|
|
|
ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
|
|
|
|
fcu->flag |= FCURVE_SELECTED;
|
|
|
|
}
|
2009-01-30 08:10:31 +00:00
|
|
|
|
2009-02-22 05:34:47 +00:00
|
|
|
/* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
|
2009-01-30 08:10:31 +00:00
|
|
|
if (fcu->flag & FCURVE_SELECTED)
|
2009-02-22 05:34:47 +00:00
|
|
|
ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-20 11:07:42 +00:00
|
|
|
}
|
2009-01-01 00:18:23 +00:00
|
|
|
break;
|
|
|
|
case ANIMTYPE_GPDATABLOCK:
|
2009-01-20 11:07:42 +00:00
|
|
|
{
|
|
|
|
bGPdata *gpd= (bGPdata *)ale->data;
|
|
|
|
|
|
|
|
/* toggle expand */
|
|
|
|
gpd->flag ^= GP_DATA_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_GPLAYER:
|
2009-01-20 11:07:42 +00:00
|
|
|
{
|
2009-01-01 00:18:23 +00:00
|
|
|
#if 0 // XXX future of this is unclear
|
2009-01-20 11:07:42 +00:00
|
|
|
bGPdata *gpd= (bGPdata *)ale->owner;
|
|
|
|
bGPDlayer *gpl= (bGPDlayer *)ale->data;
|
|
|
|
|
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-16)) {
|
|
|
|
/* toggle lock */
|
|
|
|
gpl->flag ^= GP_LAYER_LOCKED;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
2009-01-20 11:07:42 +00:00
|
|
|
else if (x >= (ACHANNEL_NAMEWIDTH-32)) {
|
|
|
|
/* toggle hide */
|
|
|
|
gpl->flag ^= GP_LAYER_HIDE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect */
|
|
|
|
//if (G.qual & LR_SHIFTKEY) {
|
|
|
|
//select_gplayer_channel(gpd, gpl, SELECT_INVERT);
|
|
|
|
//}
|
|
|
|
//else {
|
|
|
|
//deselect_gpencil_layers(data, 0);
|
|
|
|
//select_gplayer_channel(gpd, gpl, SELECT_INVERT);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
#endif // XXX future of this is unclear
|
|
|
|
}
|
|
|
|
break;
|
2009-01-01 00:18:23 +00:00
|
|
|
case ANIMTYPE_SHAPEKEY:
|
|
|
|
/* TODO: shapekey channels cannot be selected atm... */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Error: Invalid channel type in mouse_anim_channels() \n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free channels */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
/* handle clicking */
|
|
|
|
static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
Scene *scene;
|
|
|
|
ARegion *ar;
|
|
|
|
View2D *v2d;
|
|
|
|
int mval[2], channel_index;
|
|
|
|
short selectmode;
|
|
|
|
float x, y;
|
|
|
|
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* get useful pointers from animation context data */
|
|
|
|
scene= ac.scene;
|
|
|
|
ar= ac.ar;
|
|
|
|
v2d= &ar->v2d;
|
|
|
|
|
|
|
|
/* get mouse coordinates (in region coordinates) */
|
|
|
|
mval[0]= (event->x - ar->winrct.xmin);
|
|
|
|
mval[1]= (event->y - ar->winrct.ymin);
|
|
|
|
|
|
|
|
/* select mode is either replace (deselect all, then add) or add/extend */
|
2009-03-29 02:15:13 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "extend"))
|
2009-01-01 00:18:23 +00:00
|
|
|
selectmode= SELECT_INVERT;
|
2009-03-29 02:15:13 +00:00
|
|
|
else if (RNA_boolean_get(op->ptr, "children_only"))
|
2009-01-05 00:38:17 +00:00
|
|
|
selectmode= -1; /* this is a bit of a special case for ActionGroups only... should it be removed or extended to all instead? */
|
2009-01-01 00:18:23 +00:00
|
|
|
else
|
|
|
|
selectmode= SELECT_REPLACE;
|
|
|
|
|
|
|
|
/* figure out which channel user clicked in
|
|
|
|
* Note: although channels technically start at y= ACHANNEL_FIRST, we need to adjust by half a channel's height
|
|
|
|
* so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
|
|
|
|
* ACHANNEL_HEIGHT_HALF.
|
|
|
|
*/
|
|
|
|
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
|
2009-01-02 00:56:48 +00:00
|
|
|
UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index);
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
/* handle mouse-click in the relevant channel then */
|
|
|
|
mouse_anim_channels(&ac, x, channel_index, selectmode);
|
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
2009-01-05 09:54:39 +00:00
|
|
|
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
void ANIM_OT_channels_click (wmOperatorType *ot)
|
2009-01-01 00:18:23 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Mouse Click on Channels";
|
2009-04-08 12:35:38 +00:00
|
|
|
ot->idname= "ANIM_OT_channels_click";
|
2009-01-01 00:18:23 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= animchannels_mouseclick_invoke;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
2009-01-01 00:18:23 +00:00
|
|
|
/* id-props */
|
2009-03-29 02:15:13 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
|
|
|
|
RNA_def_boolean(ot->srna, "children_only", 0, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
/* Operator Registration */
|
|
|
|
|
|
|
|
void ED_operatortypes_animchannels(void)
|
|
|
|
{
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_select_all_toggle);
|
|
|
|
WM_operatortype_append(ANIM_OT_channels_select_border);
|
2009-04-08 12:35:38 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_click);
|
2009-01-02 11:06:27 +00:00
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_setting_enable);
|
|
|
|
WM_operatortype_append(ANIM_OT_channels_setting_disable);
|
|
|
|
WM_operatortype_append(ANIM_OT_channels_setting_toggle);
|
2009-01-05 09:54:39 +00:00
|
|
|
|
2009-02-22 05:55:37 +00:00
|
|
|
// XXX does this need to be a separate operator?
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_editable_toggle);
|
2009-02-22 05:55:37 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
// XXX these need to be updated for new system... todo...
|
|
|
|
//WM_operatortype_append(ANIM_OT_channels_move_up);
|
|
|
|
//WM_operatortype_append(ANIM_OT_channels_move_down);
|
|
|
|
//WM_operatortype_append(ANIM_OT_channels_move_top);
|
|
|
|
//WM_operatortype_append(ANIM_OT_channels_move_bottom);
|
2009-02-10 11:37:14 +00:00
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_expand);
|
|
|
|
WM_operatortype_append(ANIM_OT_channels_collapse);
|
|
|
|
|
2009-02-10 11:37:14 +00:00
|
|
|
WM_operatortype_append(ANIM_OT_channels_visibility_toggle);
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ED_keymap_animchannels(wmWindowManager *wm)
|
|
|
|
{
|
|
|
|
ListBase *keymap = WM_keymap_listbase(wm, "Animation_Channels", 0, 0);
|
|
|
|
|
2009-01-02 01:28:05 +00:00
|
|
|
/* selection */
|
|
|
|
/* click-select */
|
2009-01-01 00:18:23 +00:00
|
|
|
// XXX for now, only leftmouse....
|
2009-04-08 12:35:38 +00:00
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0);
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "children_only", 1);
|
2009-01-02 00:56:48 +00:00
|
|
|
|
2009-01-02 01:28:05 +00:00
|
|
|
/* deselect all */
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
|
2009-01-02 01:28:05 +00:00
|
|
|
|
|
|
|
/* borderselect */
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
|
2009-01-02 11:06:27 +00:00
|
|
|
|
|
|
|
/* settings */
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_disable", WKEY, KM_PRESS, KM_ALT, 0);
|
2009-01-05 09:54:39 +00:00
|
|
|
|
2009-02-22 05:55:37 +00:00
|
|
|
/* settings - specialised hotkeys */
|
2009-03-29 02:15:13 +00:00
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
|
2009-02-22 05:55:37 +00:00
|
|
|
|
2009-04-08 12:35:38 +00:00
|
|
|
/* expand/collapse */
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, 0, 0);
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0);
|
|
|
|
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1);
|
|
|
|
|
2009-01-05 09:54:39 +00:00
|
|
|
/* rearranging - actions only */
|
2009-01-20 11:07:42 +00:00
|
|
|
//WM_keymap_add_item(keymap, "ANIM_OT_channels_move_up", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0);
|
|
|
|
//WM_keymap_add_item(keymap, "ANIM_OT_channels_move_down", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0);
|
|
|
|
//WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_top", PAGEUPKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
|
|
|
|
//WM_keymap_add_item(keymap, "ANIM_OT_channels_move_to_bottom", PAGEDOWNKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
|
2009-02-10 11:37:14 +00:00
|
|
|
|
|
|
|
/* Graph Editor only */
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_toggle", VKEY, KM_PRESS, 0, 0);
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|