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"
|
|
|
|
#include "DNA_action_types.h"
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "DNA_camera_types.h"
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "DNA_ipo_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"
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
/* -------------------------- Internal Tools -------------------------------- */
|
|
|
|
|
2009-01-01 08:08:55 +00:00
|
|
|
|
|
|
|
|
2009-01-01 00:18:23 +00:00
|
|
|
/* -------------------------- Exposed API ----------------------------------- */
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|
2009-01-01 08:08:55 +00:00
|
|
|
/* OPERATORS */
|
|
|
|
|
|
|
|
/* ********************** Select All Operator *********************** */
|
|
|
|
|
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 */
|
|
|
|
filter= (ANIMFILTER_FORDRAWING | ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
|
|
|
|
filter= ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* get channel from index */
|
|
|
|
ale= BLI_findlink(&anim_data, channel_index);
|
|
|
|
if (ale == NULL) {
|
|
|
|
/* channel not found */
|
|
|
|
printf("Error: animation channel not found in mouse_anim_channels() \n");
|
2009-01-01 08:08:55 +00:00
|
|
|
// XXX remove me..
|
2009-01-01 00:18:23 +00:00
|
|
|
printf("\t channel index = %d, channels = %d\n", channel_index, filter);
|
|
|
|
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* action to take depends on what channel we've got */
|
|
|
|
switch (ale->type) {
|
|
|
|
case ANIMTYPE_OBJECT:
|
|
|
|
{
|
|
|
|
bDopeSheet *ads= (bDopeSheet *)ac->data;
|
|
|
|
Scene *sce= (Scene *)ads->source;
|
|
|
|
Base *base= (Base *)ale->data;
|
|
|
|
Object *ob= base->object;
|
|
|
|
|
|
|
|
if (x < 16) {
|
|
|
|
/* toggle expand */
|
|
|
|
ob->nlaflag ^= OB_ADS_COLLAPSED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* set selection status */
|
|
|
|
// FIXME: this needs to use the new stuff...
|
2009-01-01 08:08:55 +00:00
|
|
|
if (selectmode == SELECT_INVERT) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* swap select */
|
|
|
|
base->flag ^= SELECT;
|
|
|
|
ob->flag= base->flag;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Base *b;
|
|
|
|
|
|
|
|
/* deleselect all */
|
|
|
|
for (b= sce->base.first; b; b= b->next) {
|
|
|
|
b->flag &= ~SELECT;
|
|
|
|
b->object->flag= b->flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* select object now */
|
|
|
|
base->flag |= SELECT;
|
|
|
|
ob->flag |= SELECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
//set_active_base(base); /* editview.c */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLIPOD:
|
|
|
|
{
|
|
|
|
Object *ob= (Object *)ale->data;
|
|
|
|
ob->nlaflag ^= OB_ADS_SHOWIPO;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLACTD:
|
|
|
|
{
|
|
|
|
bAction *act= (bAction *)ale->data;
|
|
|
|
act->flag ^= ACTC_EXPANDED;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLCOND:
|
|
|
|
{
|
|
|
|
Object *ob= (Object *)ale->data;
|
|
|
|
ob->nlaflag ^= OB_ADS_SHOWCONS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLMATD:
|
|
|
|
{
|
|
|
|
Object *ob= (Object *)ale->data;
|
|
|
|
ob->nlaflag ^= OB_ADS_SHOWMATS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ANIMTYPE_DSMAT:
|
|
|
|
{
|
|
|
|
Material *ma= (Material *)ale->data;
|
|
|
|
ma->flag ^= MA_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSLAM:
|
|
|
|
{
|
|
|
|
Lamp *la= (Lamp *)ale->data;
|
|
|
|
la->flag ^= LA_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSCAM:
|
|
|
|
{
|
|
|
|
Camera *ca= (Camera *)ale->data;
|
|
|
|
ca->flag ^= CAM_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSCUR:
|
|
|
|
{
|
|
|
|
Curve *cu= (Curve *)ale->data;
|
|
|
|
cu->flag ^= CU_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_DSSKEY:
|
|
|
|
{
|
|
|
|
Key *key= (Key *)ale->data;
|
|
|
|
key->flag ^= KEYBLOCK_DS_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ANIMTYPE_GROUP:
|
|
|
|
{
|
|
|
|
bActionGroup *agrp= (bActionGroup *)ale->data;
|
|
|
|
short offset= (ac->datatype == ANIMCONT_DOPESHEET)? 21 : 0;
|
|
|
|
|
|
|
|
if ((x < (offset+17)) && (agrp->channels.first)) {
|
|
|
|
/* toggle expand */
|
|
|
|
agrp->flag ^= AGRP_EXPANDED;
|
|
|
|
}
|
2009-01-01 01:47:36 +00:00
|
|
|
else if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* toggle protection/locking */
|
|
|
|
agrp->flag ^= AGRP_PROTECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect group */
|
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
/* inverse selection status of group */
|
|
|
|
//select_action_group(act, agrp, SELECT_INVERT);
|
|
|
|
}
|
|
|
|
else if (/*G.qual == (LR_CTRLKEY|LR_SHIFTKEY)*/0) {
|
|
|
|
// FIXME: need a special case for this!
|
|
|
|
/* select all in group (and deselect everthing else) */
|
|
|
|
//select_action_group_channels(act, agrp);
|
|
|
|
//select_action_group(act, agrp, SELECT_ADD);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select group by itself */
|
|
|
|
//deselect_actionchannels(act, ANIMCONT_ACTION, 0);
|
|
|
|
//select_action_group(act, agrp, SELECT_ADD);
|
|
|
|
}
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
// XXX
|
|
|
|
agrp->flag ^= AGRP_SELECTED;
|
2009-01-01 00:18:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_ACHAN:
|
|
|
|
{
|
|
|
|
bActionChannel *achan= (bActionChannel *)ale->data;
|
|
|
|
short offset= (ac->datatype == ANIMCONT_DOPESHEET)? 21 : 0;
|
|
|
|
|
2009-01-01 01:47:36 +00:00
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* toggle protect */
|
|
|
|
achan->flag ^= ACHAN_PROTECTED;
|
|
|
|
}
|
2009-01-01 01:47:36 +00:00
|
|
|
else if ((x >= (ACHANNEL_NAMEWIDTH-2*ACHANNEL_BUTTON_WIDTH)) && (achan->ipo)) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* toggle mute */
|
|
|
|
achan->ipo->muteipo = (achan->ipo->muteipo)? 0: 1;
|
|
|
|
}
|
|
|
|
else if (x <= (offset+17)) {
|
|
|
|
/* toggle expand */
|
|
|
|
achan->flag ^= ACHAN_EXPANDED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect achan */
|
|
|
|
if (selectmode == SELECT_INVERT) {
|
|
|
|
//select_channel(act, achan, SELECT_INVERT);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//deselect_actionchannels(act, ACTCONT_ACTION, 0);
|
|
|
|
//select_channel(act, achan, SELECT_ADD);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* messy... set active bone */
|
|
|
|
//select_poseelement_by_name(achan->name, 2);
|
|
|
|
|
|
|
|
// XXX for now only
|
|
|
|
achan->flag ^= ACHAN_SELECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLIPO:
|
|
|
|
{
|
|
|
|
bActionChannel *achan= (bActionChannel *)ale->data;
|
|
|
|
|
|
|
|
achan->flag ^= ACHAN_SHOWIPO;
|
|
|
|
|
|
|
|
if ((x > 24) && (achan->flag & ACHAN_SHOWIPO)) {
|
|
|
|
/* select+make active achan */
|
|
|
|
//deselect_actionchannels(act, ACTCONT_ACTION, 0);
|
|
|
|
//select_channel(act, achan, SELECT_ADD);
|
|
|
|
|
|
|
|
/* messy... set active bone */
|
|
|
|
//select_poseelement_by_name(achan->name, 2);
|
|
|
|
|
|
|
|
// XXX for now only
|
|
|
|
achan->flag ^= ACHAN_SELECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_FILLCON:
|
|
|
|
{
|
|
|
|
bActionChannel *achan= (bActionChannel *)ale->data;
|
|
|
|
|
|
|
|
achan->flag ^= ACHAN_SHOWCONS;
|
|
|
|
|
|
|
|
if ((x > 24) && (achan->flag & ACHAN_SHOWCONS)) {
|
|
|
|
/* select+make active achan */
|
|
|
|
//deselect_actionchannels(act, ACTCONT_ACTION, 0);
|
|
|
|
//select_channel(act, achan, SELECT_ADD);
|
|
|
|
|
|
|
|
/* messy... set active bone */
|
|
|
|
//select_poseelement_by_name(achan->name, 2);
|
|
|
|
|
|
|
|
// XXX for now only
|
|
|
|
achan->flag ^= ACHAN_SELECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_ICU:
|
|
|
|
{
|
|
|
|
IpoCurve *icu= (IpoCurve *)ale->data;
|
|
|
|
|
2009-01-01 01:47:36 +00:00
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* toggle protection */
|
|
|
|
icu->flag ^= IPO_PROTECT;
|
|
|
|
}
|
2009-01-01 01:47:36 +00:00
|
|
|
else if (x >= (ACHANNEL_NAMEWIDTH-2*ACHANNEL_BUTTON_WIDTH)) {
|
2009-01-01 00:18:23 +00:00
|
|
|
/* toggle mute */
|
|
|
|
icu->flag ^= IPO_MUTE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect */
|
|
|
|
//select_icu_channel(act, icu, SELECT_INVERT);
|
|
|
|
|
|
|
|
// XXX for now only
|
|
|
|
icu->flag ^= IPO_SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_CONCHAN:
|
|
|
|
{
|
|
|
|
bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
|
|
|
|
|
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-16)) {
|
|
|
|
/* toggle protection */
|
|
|
|
conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
|
|
|
|
}
|
|
|
|
else if ((x >= (ACHANNEL_NAMEWIDTH-32)) && (conchan->ipo)) {
|
|
|
|
/* toggle mute */
|
|
|
|
conchan->ipo->muteipo = (conchan->ipo->muteipo)? 0: 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select/deselect */
|
|
|
|
//select_constraint_channel(act, conchan, SELECT_INVERT);
|
|
|
|
|
|
|
|
// XXX for now only
|
|
|
|
conchan->flag ^= CONSTRAINT_CHANNEL_SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GPDATABLOCK:
|
|
|
|
{
|
|
|
|
bGPdata *gpd= (bGPdata *)ale->data;
|
|
|
|
|
|
|
|
/* toggle expand */
|
|
|
|
gpd->flag ^= GP_DATA_EXPAND;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ANIMTYPE_GPLAYER:
|
|
|
|
{
|
|
|
|
#if 0 // XXX future of this is unclear
|
|
|
|
bGPdata *gpd= (bGPdata *)ale->owner;
|
|
|
|
bGPDlayer *gpl= (bGPDlayer *)ale->data;
|
|
|
|
|
|
|
|
if (x >= (ACHANNEL_NAMEWIDTH-16)) {
|
|
|
|
/* toggle lock */
|
|
|
|
gpl->flag ^= GP_LAYER_LOCKED;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
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 */
|
|
|
|
if (RNA_boolean_get(op->ptr, "extend_select"))
|
|
|
|
selectmode= SELECT_INVERT;
|
|
|
|
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);
|
|
|
|
UI_view2d_listview_get_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index);
|
|
|
|
|
|
|
|
/* handle mouse-click in the relevant channel then */
|
|
|
|
mouse_anim_channels(&ac, x, channel_index, selectmode);
|
|
|
|
|
|
|
|
/* set notifier tha things have changed */
|
|
|
|
ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ANIM_OT_channels_mouseclick (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Mouse Click on Channels";
|
|
|
|
ot->idname= "ANIM_OT_channels_mouseclick";
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= animchannels_mouseclick_invoke;
|
|
|
|
ot->poll= ED_operator_areaactive;
|
|
|
|
|
|
|
|
/* id-props */
|
|
|
|
RNA_def_property(ot->srna, "extend_select", PROP_BOOLEAN, PROP_NONE); // SHIFTKEY
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
/* Operator Registration */
|
|
|
|
|
|
|
|
void ED_operatortypes_animchannels(void)
|
|
|
|
{
|
|
|
|
WM_operatortype_append(ANIM_OT_channels_mouseclick);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ED_keymap_animchannels(wmWindowManager *wm)
|
|
|
|
{
|
|
|
|
ListBase *keymap = WM_keymap_listbase(wm, "Animation_Channels", 0, 0);
|
|
|
|
|
|
|
|
/* click-select */
|
|
|
|
// XXX for now, only leftmouse....
|
|
|
|
WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, 0, 0);
|
|
|
|
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|