2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-05-31 11:14:50 +00:00
|
|
|
* 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
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2009-05-31 11:14:50 +00:00
|
|
|
*
|
|
|
|
|
* 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-05-31 11:14:50 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup spnla
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
#include <stdio.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <string.h>
|
2009-05-31 11:14:50 +00:00
|
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
|
|
|
|
|
|
#include "BKE_context.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_nla.h"
|
2009-05-31 11:14:50 +00:00
|
|
|
#include "BKE_screen.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_anim_api.h"
|
|
|
|
|
#include "ED_keyframes_edit.h"
|
|
|
|
|
#include "ED_screen.h"
|
2018-08-14 10:28:41 +10:00
|
|
|
#include "ED_select_utils.h"
|
2009-05-31 11:14:50 +00:00
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
2019-05-07 15:09:14 +02:00
|
|
|
#include "UI_interface.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "UI_view2d.h"
|
2009-05-31 11:14:50 +00:00
|
|
|
|
2012-05-08 18:05:57 +00:00
|
|
|
#include "nla_intern.h" /* own include */
|
2009-05-31 11:14:50 +00:00
|
|
|
|
|
|
|
|
/* ******************** Utilities ***************************************** */
|
|
|
|
|
|
|
|
|
|
/* Convert SELECT_* flags to ACHANNEL_SETFLAG_* flags */
|
2012-05-08 18:05:57 +00:00
|
|
|
static short selmodes_to_flagmodes(short sel)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
|
|
|
|
/* convert selection modes to selection modes */
|
|
|
|
|
switch (sel) {
|
|
|
|
|
case SELECT_SUBTRACT:
|
|
|
|
|
return ACHANNEL_SETFLAG_CLEAR;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
case SELECT_INVERT:
|
2010-05-21 13:01:18 +00:00
|
|
|
return ACHANNEL_SETFLAG_INVERT;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
case SELECT_ADD:
|
|
|
|
|
default:
|
|
|
|
|
return ACHANNEL_SETFLAG_ADD;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ******************** Deselect All Operator ***************************** */
|
|
|
|
|
/* This operator works in one of three ways:
|
2018-11-14 12:53:15 +11:00
|
|
|
* 1) (de)select all (AKEY) - test if select all or deselect all
|
|
|
|
|
* 2) invert all (CTRL-IKEY) - invert selection of all keyframes
|
|
|
|
|
* 3) (de)select all - no testing is done; only for use internal tools as normal function...
|
2009-05-31 11:14:50 +00:00
|
|
|
*/
|
|
|
|
|
|
2011-02-17 22:34:41 +00:00
|
|
|
enum {
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
DESELECT_STRIPS_NOTEST = 0,
|
|
|
|
|
DESELECT_STRIPS_TEST,
|
|
|
|
|
DESELECT_STRIPS_CLEARACTIVE,
|
2011-02-17 22:34:41 +00:00
|
|
|
} /*eDeselectNlaStrips*/;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* Deselects strips in the NLA Editor
|
2018-11-14 12:53:15 +11:00
|
|
|
* - This is called by the deselect all operator, as well as other ones!
|
2009-05-31 11:14:50 +00:00
|
|
|
*
|
2018-11-14 12:53:15 +11:00
|
|
|
* - test: check if select or deselect all (1) or clear all active (2)
|
|
|
|
|
* - sel: how to select keyframes
|
|
|
|
|
* 0 = deselect
|
|
|
|
|
* 1 = select
|
|
|
|
|
* 2 = invert
|
2009-05-31 11:14:50 +00:00
|
|
|
*/
|
2012-05-08 18:05:57 +00:00
|
|
|
static void deselect_nla_strips(bAnimContext *ac, short test, short sel)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
|
bAnimListElem *ale;
|
|
|
|
|
int filter;
|
|
|
|
|
short smode;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-09 12:28:10 +00:00
|
|
|
/* determine type-based settings */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
/* FIXME: double check whether ANIMFILTER_LIST_VISIBLE is needed! */
|
2012-05-08 18:05:57 +00:00
|
|
|
filter = (ANIMFILTER_DATA_VISIBLE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* filter data */
|
|
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* See if we should be selecting or deselecting */
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
if (test == DESELECT_STRIPS_TEST) {
|
2012-05-08 18:05:57 +00:00
|
|
|
for (ale = anim_data.first; ale; ale = ale->next) {
|
|
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
2009-05-31 11:14:50 +00:00
|
|
|
NlaStrip *strip;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* if any strip is selected, break out, since we should now be deselecting */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (strip = nlt->strips.first; strip; strip = strip->next) {
|
2009-05-31 11:14:50 +00:00
|
|
|
if (strip->flag & NLASTRIP_FLAG_SELECT) {
|
2012-05-08 18:05:57 +00:00
|
|
|
sel = SELECT_SUBTRACT;
|
2009-05-31 11:14:50 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (sel == SELECT_SUBTRACT) {
|
2009-05-31 11:14:50 +00:00
|
|
|
break;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* convert selection modes to selection modes */
|
2012-05-08 18:05:57 +00:00
|
|
|
smode = selmodes_to_flagmodes(sel);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* Now set the flags */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (ale = anim_data.first; ale; ale = ale->next) {
|
|
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
2009-05-31 11:14:50 +00:00
|
|
|
NlaStrip *strip;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* apply same selection to all strips */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (strip = nlt->strips.first; strip; strip = strip->next) {
|
2009-05-31 11:14:50 +00:00
|
|
|
/* set selection */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (test != DESELECT_STRIPS_CLEARACTIVE) {
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
ACHANNEL_SET_FLAG(strip, smode, NLASTRIP_FLAG_SELECT);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* clear active flag */
|
2019-04-22 00:18:34 +10:00
|
|
|
/* TODO: for clear active,
|
|
|
|
|
* do we want to limit this to only doing this on a certain set of tracks though? */
|
2009-05-31 11:14:50 +00:00
|
|
|
strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* Cleanup */
|
2014-05-19 00:24:45 +10:00
|
|
|
ANIM_animdata_freelist(&anim_data);
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
|
|
static int nlaedit_deselectall_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* get editor data */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
2009-05-31 11:14:50 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-01 12:20:18 +00:00
|
|
|
/* 'standard' behavior - check if selected, then apply relevant selection */
|
2018-07-03 15:44:56 +02:00
|
|
|
const int action = RNA_enum_get(op->ptr, "action");
|
|
|
|
|
switch (action) {
|
|
|
|
|
case SEL_TOGGLE:
|
|
|
|
|
deselect_nla_strips(&ac, DESELECT_STRIPS_TEST, SELECT_ADD);
|
|
|
|
|
break;
|
|
|
|
|
case SEL_SELECT:
|
|
|
|
|
deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_ADD);
|
|
|
|
|
break;
|
|
|
|
|
case SEL_DESELECT:
|
|
|
|
|
deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_SUBTRACT);
|
|
|
|
|
break;
|
|
|
|
|
case SEL_INVERT:
|
|
|
|
|
deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_INVERT);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* set notifier that things have changed */
|
2012-05-08 18:05:57 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2018-07-03 15:44:56 +02:00
|
|
|
void NLA_OT_select_all(wmOperatorType *ot)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "(De)select All";
|
2018-07-03 15:44:56 +02:00
|
|
|
ot->idname = "NLA_OT_select_all";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Select or deselect all NLA-Strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = nlaedit_deselectall_exec;
|
|
|
|
|
ot->poll = nlaop_poll_tweakmode_off;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* flags */
|
2012-05-08 18:05:57 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2018-07-03 15:44:56 +02:00
|
|
|
/* properties */
|
|
|
|
|
WM_operator_properties_select_all(ot);
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* ******************** Box Select Operator **************************** */
|
2019-04-22 00:18:34 +10:00
|
|
|
/**
|
|
|
|
|
* This operator currently works in one of three ways:
|
|
|
|
|
* - BKEY - 1: all strips within region are selected #NLAEDIT_BOX_ALLSTRIPS.
|
|
|
|
|
* - ALT-BKEY - depending on which axis of the region was larger.
|
|
|
|
|
* - 2: x-axis, so select all frames within frame range #NLAEDIT_BOXSEL_FRAMERANGE.
|
|
|
|
|
* - 3: y-axis, so select all frames within channels that region included
|
|
|
|
|
* #NLAEDIT_BOXSEL_CHANNELS.
|
2009-06-10 04:43:18 +00:00
|
|
|
*/
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* defines for box_select mode */
|
2011-02-27 08:31:10 +00:00
|
|
|
enum {
|
2018-10-05 10:27:04 +10:00
|
|
|
NLA_BOXSEL_ALLSTRIPS = 0,
|
|
|
|
|
NLA_BOXSEL_FRAMERANGE,
|
|
|
|
|
NLA_BOXSEL_CHANNELS,
|
|
|
|
|
} /* eNLAEDIT_BoxSelect_Mode */;
|
2009-06-10 04:43:18 +00:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
static void box_select_nla_strips(bAnimContext *ac, rcti rect, short mode, short selectmode)
|
2009-06-10 04:43:18 +00:00
|
|
|
{
|
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
|
bAnimListElem *ale;
|
|
|
|
|
int filter;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-06 01:34:10 +00:00
|
|
|
SpaceNla *snla = (SpaceNla *)ac->sl;
|
2020-03-06 16:56:42 +01:00
|
|
|
View2D *v2d = &ac->region->v2d;
|
2009-06-10 04:43:18 +00:00
|
|
|
rctf rectf;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* convert border-region to view coordinates */
|
2012-05-08 18:05:57 +00:00
|
|
|
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);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* filter data */
|
2012-05-08 18:05:57 +00:00
|
|
|
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
|
2009-06-10 04:43:18 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* convert selection modes to selection modes */
|
2012-05-08 18:05:57 +00:00
|
|
|
selectmode = selmodes_to_flagmodes(selectmode);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* loop over data, doing box select */
|
2019-06-04 14:50:43 +02:00
|
|
|
float ymax = NLACHANNEL_FIRST_TOP(ac);
|
|
|
|
|
for (ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
|
|
|
|
|
float ymin = ymax - NLACHANNEL_HEIGHT(snla);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* perform vertical suitability check (if applicable) */
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((mode == NLA_BOXSEL_FRAMERANGE) || !((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
|
2009-06-10 04:43:18 +00:00
|
|
|
/* loop over data selecting (only if NLA-Track) */
|
|
|
|
|
if (ale->type == ANIMTYPE_NLATRACK) {
|
2012-05-08 18:05:57 +00:00
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
2009-06-10 04:43:18 +00:00
|
|
|
NlaStrip *strip;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* only select strips if they fall within the required ranges (if applicable) */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (strip = nlt->strips.first; strip; strip = strip->next) {
|
2018-10-05 10:27:04 +10:00
|
|
|
if ((mode == NLA_BOXSEL_CHANNELS) ||
|
2012-09-09 00:00:21 +00:00
|
|
|
BKE_nlastrip_within_bounds(strip, rectf.xmin, rectf.xmax)) {
|
2009-06-10 04:43:18 +00:00
|
|
|
/* set selection */
|
|
|
|
|
ACHANNEL_SET_FLAG(strip, selectmode, NLASTRIP_FLAG_SELECT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* clear active flag */
|
|
|
|
|
strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-06-10 04:43:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* cleanup */
|
2014-05-19 00:24:45 +10:00
|
|
|
ANIM_animdata_freelist(&anim_data);
|
2009-06-10 04:43:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
2019-06-04 16:20:30 +02:00
|
|
|
static void nlaedit_strip_at_region_position(
|
|
|
|
|
bAnimContext *ac, float region_x, float region_y, bAnimListElem **r_ale, NlaStrip **r_strip)
|
|
|
|
|
{
|
|
|
|
|
*r_ale = NULL;
|
|
|
|
|
*r_strip = NULL;
|
|
|
|
|
|
|
|
|
|
SpaceNla *snla = (SpaceNla *)ac->sl;
|
2020-03-06 16:56:42 +01:00
|
|
|
View2D *v2d = &ac->region->v2d;
|
2019-06-04 16:20:30 +02:00
|
|
|
|
|
|
|
|
float view_x, view_y;
|
|
|
|
|
int channel_index;
|
|
|
|
|
UI_view2d_region_to_view(v2d, region_x, region_y, &view_x, &view_y);
|
|
|
|
|
UI_view2d_listview_view_to_cell(
|
|
|
|
|
0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(ac), view_x, view_y, NULL, &channel_index);
|
|
|
|
|
|
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
|
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
|
|
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
|
|
/* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
|
|
|
|
|
* (that is the size of keyframe icons, so user should be expecting similar tolerances)
|
|
|
|
|
*/
|
|
|
|
|
float xmin = UI_view2d_region_to_view_x(v2d, region_x - 7);
|
|
|
|
|
float xmax = UI_view2d_region_to_view_x(v2d, region_x + 7);
|
|
|
|
|
|
|
|
|
|
bAnimListElem *ale = BLI_findlink(&anim_data, channel_index);
|
|
|
|
|
if (ale != NULL) {
|
|
|
|
|
if (ale->type == ANIMTYPE_NLATRACK) {
|
|
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
|
|
|
|
|
2020-04-03 19:15:01 +02:00
|
|
|
LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
|
2019-06-04 16:20:30 +02:00
|
|
|
if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) {
|
|
|
|
|
*r_ale = ale;
|
|
|
|
|
*r_strip = strip;
|
|
|
|
|
|
|
|
|
|
BLI_remlink(&anim_data, ale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ANIM_animdata_freelist(&anim_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool nlaedit_mouse_is_over_strip(bAnimContext *ac, const int mval[2])
|
|
|
|
|
{
|
|
|
|
|
bAnimListElem *ale;
|
|
|
|
|
NlaStrip *strip;
|
|
|
|
|
nlaedit_strip_at_region_position(ac, mval[0], mval[1], &ale, &strip);
|
|
|
|
|
|
|
|
|
|
if (ale != NULL) {
|
|
|
|
|
BLI_assert(strip != NULL);
|
|
|
|
|
MEM_freeN(ale);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int nlaedit_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool tweak = RNA_boolean_get(op->ptr, "tweak");
|
|
|
|
|
if (tweak && nlaedit_mouse_is_over_strip(&ac, event->mval)) {
|
|
|
|
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
|
|
|
|
}
|
|
|
|
|
return WM_gesture_box_invoke(C, op, event);
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
static int nlaedit_box_select_exec(bContext *C, wmOperator *op)
|
2009-06-10 04:43:18 +00:00
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
|
|
|
|
rcti rect;
|
2019-03-07 20:33:57 +11:00
|
|
|
short mode = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* get editor data */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
2009-06-10 04:43:18 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-07 20:33:57 +11:00
|
|
|
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
|
|
|
|
|
const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
|
|
|
|
|
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
2011-11-16 19:22:14 +00:00
|
|
|
deselect_nla_strips(&ac, DESELECT_STRIPS_TEST, SELECT_SUBTRACT);
|
2017-10-16 21:58:51 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* get settings from operator */
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border_to_rcti(op, &rect);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* selection 'mode' depends on whether box_select region only matters on one axis */
|
2009-06-10 04:43:18 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "axis_range")) {
|
2019-04-22 00:18:34 +10:00
|
|
|
/* mode depends on which axis of the range is larger to determine which axis to use.
|
|
|
|
|
* - Checking this in region-space is fine,
|
|
|
|
|
* as it's fundamentally still going to be a different rect size.
|
|
|
|
|
* - The frame-range select option is favored over the channel one (x over y),
|
|
|
|
|
* as frame-range one is often.
|
|
|
|
|
* Used for tweaking timing when "blocking", while channels is not that useful.
|
2009-06-10 04:43:18 +00:00
|
|
|
*/
|
2019-04-22 09:19:45 +10:00
|
|
|
if (BLI_rcti_size_x(&rect) >= BLI_rcti_size_y(&rect)) {
|
2018-10-05 10:27:04 +10:00
|
|
|
mode = NLA_BOXSEL_FRAMERANGE;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2018-10-05 10:27:04 +10:00
|
|
|
mode = NLA_BOXSEL_CHANNELS;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2009-06-10 04:43:18 +00:00
|
|
|
}
|
2019-04-22 09:19:45 +10:00
|
|
|
else {
|
2018-10-05 10:27:04 +10:00
|
|
|
mode = NLA_BOXSEL_ALLSTRIPS;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* apply box_select action */
|
|
|
|
|
box_select_nla_strips(&ac, rect, mode, selectmode);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that things have changed */
|
2012-05-08 18:05:57 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2018-06-04 09:31:30 +02:00
|
|
|
}
|
2009-06-10 04:43:18 +00:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
void NLA_OT_select_box(wmOperatorType *ot)
|
2009-06-10 04:43:18 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->name = "Box Select";
|
|
|
|
|
ot->idname = "NLA_OT_select_box";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Use box selection to grab NLA-Strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* api callbacks */
|
2019-06-04 16:20:30 +02:00
|
|
|
ot->invoke = nlaedit_box_select_invoke;
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->exec = nlaedit_box_select_exec;
|
|
|
|
|
ot->modal = WM_gesture_box_modal;
|
|
|
|
|
ot->cancel = WM_gesture_box_cancel;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = nlaop_poll_tweakmode_off;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-06-10 04:43:18 +00:00
|
|
|
/* flags */
|
2012-05-08 18:05:57 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-03-07 20:33:57 +11:00
|
|
|
/* properties */
|
2009-06-10 04:43:18 +00:00
|
|
|
RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
|
2019-03-07 20:33:57 +11:00
|
|
|
|
2019-06-04 16:20:30 +02:00
|
|
|
PropertyRNA *prop = RNA_def_boolean(
|
|
|
|
|
ot->srna, "tweak", 0, "Tweak", "Operator has been activated using a tweak event");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
|
2019-03-07 20:33:57 +11:00
|
|
|
WM_operator_properties_gesture_box(ot);
|
|
|
|
|
WM_operator_properties_select_operation_simple(ot);
|
2009-06-10 04:43:18 +00:00
|
|
|
}
|
|
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* ******************** Select Left/Right Operator ************************* */
|
|
|
|
|
/* Select keyframes left/right of the current frame indicator */
|
2009-05-31 11:14:50 +00:00
|
|
|
|
|
|
|
|
/* defines for left-right select tool */
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem prop_nlaedit_leftright_select_types[] = {
|
2009-06-20 03:58:25 +00:00
|
|
|
{NLAEDIT_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
|
2020-12-24 11:07:32 -06:00
|
|
|
{NLAEDIT_LRSEL_LEFT, "LEFT", 0, "Before Current Frame", ""},
|
|
|
|
|
{NLAEDIT_LRSEL_RIGHT, "RIGHT", 0, "After Current Frame", ""},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
2009-05-31 11:14:50 +00:00
|
|
|
};
|
|
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* ------------------- */
|
2009-05-31 11:14:50 +00:00
|
|
|
|
2012-05-08 18:05:57 +00:00
|
|
|
static void nlaedit_select_leftright(bContext *C,
|
|
|
|
|
bAnimContext *ac,
|
|
|
|
|
short leftright,
|
|
|
|
|
short select_mode)
|
2011-02-14 03:04:59 +00:00
|
|
|
{
|
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
|
bAnimListElem *ale;
|
|
|
|
|
int filter;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-08 18:05:57 +00:00
|
|
|
Scene *scene = ac->scene;
|
2011-02-14 03:04:59 +00:00
|
|
|
float xmin, xmax;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* if currently in tweakmode, exit tweakmode first */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (scene->flag & SCE_NLA_EDIT_ON) {
|
2011-02-14 03:04:59 +00:00
|
|
|
WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* if select mode is replace, deselect all keyframes (and channels) first */
|
2012-05-08 18:05:57 +00:00
|
|
|
if (select_mode == SELECT_REPLACE) {
|
|
|
|
|
select_mode = SELECT_ADD;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-11-12 05:00:24 +00:00
|
|
|
/* - deselect all other keyframes, so that just the newly selected remain
|
|
|
|
|
* - channels aren't deselected, since we don't re-select any as a consequence
|
|
|
|
|
*/
|
2011-02-14 03:04:59 +00:00
|
|
|
deselect_nla_strips(ac, 0, SELECT_SUBTRACT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* get range, and get the right flag-setting mode */
|
|
|
|
|
if (leftright == NLAEDIT_LRSEL_LEFT) {
|
|
|
|
|
xmin = MINAFRAMEF;
|
|
|
|
|
xmax = (float)(CFRA + 0.1f);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2011-02-14 03:04:59 +00:00
|
|
|
else {
|
|
|
|
|
xmin = (float)(CFRA - 0.1f);
|
|
|
|
|
xmax = MAXFRAMEF;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-08 18:05:57 +00:00
|
|
|
select_mode = selmodes_to_flagmodes(select_mode);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* filter data */
|
2012-05-08 18:05:57 +00:00
|
|
|
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
|
2011-02-14 03:04:59 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* select strips on the side where most data occurs */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (ale = anim_data.first; ale; ale = ale->next) {
|
|
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
2011-02-14 03:04:59 +00:00
|
|
|
NlaStrip *strip;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* check each strip to see if it is appropriate */
|
2012-05-08 18:05:57 +00:00
|
|
|
for (strip = nlt->strips.first; strip; strip = strip->next) {
|
2011-02-14 03:04:59 +00:00
|
|
|
if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) {
|
|
|
|
|
ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* Cleanup */
|
2014-05-19 00:24:45 +10:00
|
|
|
ANIM_animdata_freelist(&anim_data);
|
2011-02-14 03:04:59 +00:00
|
|
|
}
|
2009-05-31 11:14:50 +00:00
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
2012-05-08 18:05:57 +00:00
|
|
|
static int nlaedit_select_leftright_exec(bContext *C, wmOperator *op)
|
2011-02-14 03:04:59 +00:00
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
|
|
|
|
short leftright = RNA_enum_get(op->ptr, "mode");
|
|
|
|
|
short selectmode;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* get editor data */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
2011-02-14 03:04:59 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* select mode is either replace (deselect all, then add) or add/extend */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (RNA_boolean_get(op->ptr, "extend")) {
|
2012-05-08 18:05:57 +00:00
|
|
|
selectmode = SELECT_INVERT;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-05-08 18:05:57 +00:00
|
|
|
selectmode = SELECT_REPLACE;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* if "test" mode is set, we don't have any info to set this with */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (leftright == NLAEDIT_LRSEL_TEST) {
|
2011-02-14 03:04:59 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* do the selecting now */
|
|
|
|
|
nlaedit_select_leftright(C, &ac, leftright, selectmode);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* set notifier that keyframe selection (and channels too) have changed */
|
2018-01-25 10:10:21 -02:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2011-02-14 03:04:59 +00:00
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
|
|
|
|
short leftright = RNA_enum_get(op->ptr, "mode");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* get editor data */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
2011-02-14 03:04:59 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* handle mode-based testing */
|
|
|
|
|
if (leftright == NLAEDIT_LRSEL_TEST) {
|
2012-05-08 18:05:57 +00:00
|
|
|
Scene *scene = ac.scene;
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = ac.region;
|
|
|
|
|
View2D *v2d = ®ion->v2d;
|
2011-02-14 03:04:59 +00:00
|
|
|
float x;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* determine which side of the current frame mouse is on */
|
2014-04-21 16:47:16 +10:00
|
|
|
x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
|
2019-04-22 09:19:45 +10:00
|
|
|
if (x < CFRA) {
|
2014-07-06 20:54:08 +10:00
|
|
|
RNA_enum_set(op->ptr, "mode", NLAEDIT_LRSEL_LEFT);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2014-07-06 20:54:08 +10:00
|
|
|
RNA_enum_set(op->ptr, "mode", NLAEDIT_LRSEL_RIGHT);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-02-14 03:04:59 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* perform selection */
|
|
|
|
|
return nlaedit_select_leftright_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void NLA_OT_select_leftright(wmOperatorType *ot)
|
2011-02-14 03:04:59 +00:00
|
|
|
{
|
2012-08-08 14:02:18 +00:00
|
|
|
PropertyRNA *prop;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Select Left/Right";
|
|
|
|
|
ot->idname = "NLA_OT_select_leftright";
|
|
|
|
|
ot->description = "Select strips to the left or the right of the current frame";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = nlaedit_select_leftright_invoke;
|
|
|
|
|
ot->exec = nlaedit_select_leftright_exec;
|
|
|
|
|
ot->poll = ED_operator_nla_active;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* flags */
|
2012-05-08 18:05:57 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-08-08 14:02:18 +00:00
|
|
|
/* properties */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->prop = RNA_def_enum(
|
|
|
|
|
ot->srna, "mode", prop_nlaedit_leftright_select_types, NLAEDIT_LRSEL_TEST, "Mode", "");
|
2012-08-08 14:02:18 +00:00
|
|
|
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-08-08 14:02:18 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2011-02-14 03:04:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ******************** Mouse-Click Select Operator *********************** */
|
|
|
|
|
|
|
|
|
|
/* select strip directly under mouse */
|
2019-10-07 20:32:23 +02:00
|
|
|
static int mouse_nla_strips(bContext *C,
|
|
|
|
|
bAnimContext *ac,
|
|
|
|
|
const int mval[2],
|
|
|
|
|
short select_mode,
|
|
|
|
|
const bool deselect_all,
|
|
|
|
|
bool wait_to_deselect_others)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
2012-05-08 18:05:57 +00:00
|
|
|
Scene *scene = ac->scene;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-04 16:20:30 +02:00
|
|
|
bAnimListElem *ale = NULL;
|
|
|
|
|
NlaStrip *strip = NULL;
|
2019-10-07 20:32:23 +02:00
|
|
|
int ret_value = OPERATOR_FINISHED;
|
|
|
|
|
|
2019-06-04 16:20:30 +02:00
|
|
|
nlaedit_strip_at_region_position(ac, mval[0], mval[1], &ale, &strip);
|
2019-04-30 17:05:34 +02:00
|
|
|
|
2009-06-21 02:03:50 +00:00
|
|
|
/* if currently in tweakmode, exit tweakmode before changing selection states
|
|
|
|
|
* now that we've found our target...
|
|
|
|
|
*/
|
2019-04-22 09:19:45 +10:00
|
|
|
if (scene->flag & SCE_NLA_EDIT_ON) {
|
2009-06-28 03:13:01 +00:00
|
|
|
WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-07 20:32:23 +02:00
|
|
|
if (select_mode != SELECT_REPLACE) {
|
|
|
|
|
wait_to_deselect_others = false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-30 17:20:21 +02:00
|
|
|
/* For replacing selection, if we have something to select, we have to clear existing selection.
|
|
|
|
|
* The same goes if we found nothing to select, and deselect_all is true
|
|
|
|
|
* (deselect on nothing behavior). */
|
|
|
|
|
if ((strip != NULL && select_mode == SELECT_REPLACE) || (strip == NULL && deselect_all)) {
|
2009-05-31 11:14:50 +00:00
|
|
|
/* reset selection mode for next steps */
|
|
|
|
|
select_mode = SELECT_ADD;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-07 20:32:23 +02:00
|
|
|
if (strip && wait_to_deselect_others && (strip->flag & DESELECT_STRIPS_CLEARACTIVE)) {
|
|
|
|
|
ret_value = OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* deselect all strips */
|
|
|
|
|
deselect_nla_strips(ac, 0, SELECT_SUBTRACT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-07 20:32:23 +02:00
|
|
|
/* deselect all other channels first */
|
Cleanup: Animation, simplify channel selection code
Split up `ANIM_deselect_anim_channels()` into
`ANIM_anim_channels_select_set()` and
`ANIM_anim_channels_select_toggle()`.
`ANIM_anim_channels_select_set()` is equivalent to the old
`ANIM_deselect_anim_channels(..., false, ACHANNEL_SETFLAG_xxx)`.
`ANIM_anim_channels_select_toggle()` is equivalent to the old
`ANIM_deselect_anim_channels(..., true, ACHANNEL_SETFLAG_ADD)`.
`ANIM_deselect_anim_channels(..., true, ACHANNEL_SETFLAG_CLEAR)` was
also called once. The `true` parameter suggested the "toggle" behaviour
was intended, but the `ACHANNEL_SETFLAG_CLEAR` argument prevented any
toggling. This is now replaced with `ANIM_anim_channels_select_set(ac,
ACHANNEL_SETFLAG_CLEAR)` to make this explicit.
No functional changes, just a cleanup in order to better understand how
the selection works.
2020-10-13 14:43:19 +02:00
|
|
|
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
|
2019-10-07 20:32:23 +02:00
|
|
|
}
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* only select strip if we clicked on a valid channel and hit something */
|
2019-04-30 17:20:21 +02:00
|
|
|
if (ale != NULL) {
|
2009-05-31 11:14:50 +00:00
|
|
|
/* select the strip accordingly (if a matching one was found) */
|
2019-04-30 17:20:21 +02:00
|
|
|
if (strip != NULL) {
|
2012-05-08 18:05:57 +00:00
|
|
|
select_mode = selmodes_to_flagmodes(select_mode);
|
2009-05-31 11:14:50 +00:00
|
|
|
ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
/* if we selected it, we can make it active too
|
2018-11-14 12:53:15 +11:00
|
|
|
* - we always need to clear the active strip flag though...
|
|
|
|
|
* - as well as selecting its track...
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
*/
|
|
|
|
|
deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-09 16:17:04 +12:00
|
|
|
if (strip->flag & NLASTRIP_FLAG_SELECT) {
|
NLA SoC: More Drawing Tweaks
* Following user feedback, I've increased the separation between normal NLA-tracks and the 'action lines' to try and differentiate them more. This hopefully this will be sufficient, otherwise, I'm going to have to abandon the use of nice, generic channel-identification code for lists of channels...
* Improved drawing of 'active' strips.
- Now, the active strip (when NOT being 'tweaked') will be simply drawn as a yellow strip + a white border.
- The active strip (when BEING 'tweaked') will now be greenish + a white border. The colour here may be tweakable, but we'll see...
* Strip extrapolation modes (hold, etc.) are now visualised as rects with alpha and the same colour as the strip they belong to.
* Selecting strips now makes them 'active' (and deactivates the others). Only one strip can be active at a time. Still need to figure out precisely how this will work with multiple AnimData blocks + NLA-'tweaking'.
* Fixed view-matrix bug introduced in last commit for text drawing. For now, we'll just reset the view matrix after doing that, since it's not too acceptable to move these calls to the end yet, as they should get overlapped by some other editor features (such as the Current Frame indicator)
2009-06-03 11:22:49 +00:00
|
|
|
strip->flag |= NLASTRIP_FLAG_ACTIVE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-09 16:17:04 +12:00
|
|
|
/* Highlight NLA-Track */
|
|
|
|
|
if (ale->type == ANIMTYPE_NLATRACK) {
|
|
|
|
|
NlaTrack *nlt = (NlaTrack *)ale->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-05-09 16:17:04 +12:00
|
|
|
nlt->flag |= NLATRACK_SELECTED;
|
2019-06-04 16:20:30 +02:00
|
|
|
int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
|
|
|
|
|
ANIMFILTER_LIST_CHANNELS;
|
2014-05-09 16:17:04 +12:00
|
|
|
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* free this channel */
|
|
|
|
|
MEM_freeN(ale);
|
|
|
|
|
}
|
2019-10-07 20:32:23 +02:00
|
|
|
|
|
|
|
|
return ret_value;
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
|
|
/* handle clicking */
|
2019-10-07 20:32:23 +02:00
|
|
|
static int nlaedit_clickselect_exec(bContext *C, wmOperator *op)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
|
|
|
|
bAnimContext ac;
|
2019-10-07 20:32:23 +02:00
|
|
|
int ret_value;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* get editor data */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
2009-05-31 11:14:50 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* select mode is either replace (deselect all, then add) or add/extend */
|
2019-04-30 17:20:21 +02:00
|
|
|
const short selectmode = RNA_boolean_get(op->ptr, "extend") ? SELECT_INVERT : SELECT_REPLACE;
|
|
|
|
|
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
|
2019-10-07 20:32:23 +02:00
|
|
|
const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
|
|
|
|
|
int mval[2];
|
|
|
|
|
mval[0] = RNA_int_get(op->ptr, "mouse_x");
|
|
|
|
|
mval[1] = RNA_int_get(op->ptr, "mouse_y");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-14 03:04:59 +00:00
|
|
|
/* select strips based upon mouse position */
|
2019-10-07 20:32:23 +02:00
|
|
|
ret_value = mouse_nla_strips(C, &ac, mval, selectmode, deselect_all, wait_to_deselect_others);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* set notifier that things have changed */
|
2012-05-08 18:05:57 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* for tweak grab to work */
|
2019-10-07 20:32:23 +02:00
|
|
|
return ret_value | OPERATOR_PASS_THROUGH;
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void NLA_OT_click_select(wmOperatorType *ot)
|
2009-05-31 11:14:50 +00:00
|
|
|
{
|
2012-08-08 14:02:18 +00:00
|
|
|
PropertyRNA *prop;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* identifiers */
|
2018-06-27 17:07:02 +02:00
|
|
|
ot->name = "Select";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "NLA_OT_click_select";
|
|
|
|
|
ot->description = "Handle clicks to select NLA Strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-10-07 20:32:23 +02:00
|
|
|
/* callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_nla_active;
|
2019-10-07 20:32:23 +02:00
|
|
|
ot->exec = nlaedit_clickselect_exec;
|
|
|
|
|
ot->invoke = WM_generic_select_invoke;
|
|
|
|
|
ot->modal = WM_generic_select_modal;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-05-31 11:14:50 +00:00
|
|
|
/* flags */
|
2013-03-16 05:48:46 +00:00
|
|
|
ot->flag = OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-08-08 14:02:18 +00:00
|
|
|
/* properties */
|
2019-10-07 20:32:23 +02:00
|
|
|
WM_operator_properties_generic_select(ot);
|
2012-08-08 14:02:18 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); /* SHIFTKEY */
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2019-04-30 17:20:21 +02:00
|
|
|
|
|
|
|
|
prop = RNA_def_boolean(ot->srna,
|
|
|
|
|
"deselect_all",
|
|
|
|
|
false,
|
|
|
|
|
"Deselect On Nothing",
|
|
|
|
|
"Deselect all when nothing under the cursor");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2009-05-31 11:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* *********************************************** */
|