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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/animation/anim_filter.c14
-rw-r--r--source/blender/editors/animation/keyframes_edit.c191
-rw-r--r--source/blender/editors/include/ED_anim_api.h15
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h41
-rw-r--r--source/blender/editors/space_action/action_draw.c39
-rw-r--r--source/blender/editors/space_action/action_intern.h21
-rw-r--r--source/blender/editors/space_action/action_ops.c13
-rw-r--r--source/blender/editors/space_action/action_select.c771
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_ipo/space_ipo.c2
10 files changed, 764 insertions, 347 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index d21340782e6..6283f2dd0c6 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -210,9 +210,10 @@ static short ipoedit_get_context (const bContext *C, bAnimContext *ac, SpaceIpo
*/
short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
{
- ScrArea *sa= CTX_wm_area(C); // XXX it is assumed that this will always be valid
+ ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
Scene *scene= CTX_data_scene(C);
+ short ok= 0;
/* clear old context info */
if (ac == NULL) return 0;
@@ -231,20 +232,23 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
case SPACE_ACTION:
{
SpaceAction *saction= (SpaceAction *)CTX_wm_space_data(C);
- return actedit_get_context(C, ac, saction);
+ ok= actedit_get_context(C, ac, saction);
}
break;
case SPACE_IPO:
{
SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
- return ipoedit_get_context(C, ac, sipo);
+ ok= ipoedit_get_context(C, ac, sipo);
}
break;
}
- /* nothing appropriate */
- return 0;
+ /* check if there's any valid data */
+ if (ok && ac->data)
+ return 1;
+ else
+ return 0;
}
/* ************************************************************ */
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 278e216535b..a3a04901533 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <float.h>
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -60,6 +61,10 @@
* appropriate bezier-modify function to set. These functions (ANIM_editkeyframes_*) will need
* to be called before getting any channels.
*
+ * A set of 'validation' callbacks are provided for checking if a BezTriple should be operated on.
+ * These should only be used when using a 'general' BezTriple editor (i.e. selection setters which
+ * don't check existing selection status).
+ *
* - Joshua Leung, Dec 2008
*/
@@ -74,18 +79,34 @@
/* This function is used to loop over BezTriples in the given IpoCurve, applying a given
* operation on them, and optionally applies an IPO-curve validate function afterwards.
*/
-short icu_keys_bezier_loop(Scene *scene, IpoCurve *icu, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+short icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
{
BezTriple *bezt;
int b;
/* if function to apply to bezier curves is set, then loop through executing it on beztriples */
if (bezt_cb) {
- for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
- /* Exit with return-code '1' if function returns positive
- * This is useful if finding if some BezTriple satisfies a condition.
- */
- if (bezt_cb(scene, bezt)) return 1;
+ /* if there's a validation func, include that check in the loop
+ * (this is should be more efficient than checking for it in every loop)
+ */
+ if (bezt_ok) {
+ for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
+ /* Only operate on this BezTriple if it fullfills the criteria of the validation func */
+ if (bezt_ok(bed, bezt)) {
+ /* Exit with return-code '1' if function returns positive
+ * This is useful if finding if some BezTriple satisfies a condition.
+ */
+ if (bezt_cb(bed, bezt)) return 1;
+ }
+ }
+ }
+ else {
+ for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
+ /* Exit with return-code '1' if function returns positive
+ * This is useful if finding if some BezTriple satisfies a condition.
+ */
+ if (bezt_cb(bed, bezt)) return 1;
+ }
}
}
@@ -98,7 +119,7 @@ short icu_keys_bezier_loop(Scene *scene, IpoCurve *icu, BeztEditFunc bezt_cb, Ic
}
/* This function is used to loop over the IPO curves (and subsequently the keyframes in them) */
-short ipo_keys_bezier_loop(Scene *scene, Ipo *ipo, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+short ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
{
IpoCurve *icu;
@@ -108,54 +129,98 @@ short ipo_keys_bezier_loop(Scene *scene, Ipo *ipo, BeztEditFunc bezt_cb, IcuEdit
/* Loop through each curve in the Ipo */
for (icu= ipo->curve.first; icu; icu=icu->next) {
- if (icu_keys_bezier_loop(scene, icu, bezt_cb, icu_cb))
+ if (icu_keys_bezier_loop(bed, icu, bezt_ok, bezt_cb, icu_cb))
return 1;
}
return 0;
}
-/* This function is used to loop over the channels in an Action Group to modify the IPO blocks within them */
-short actgroup_keys_bezier_loop(Scene *scene, bActionGroup *agrp, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+/* -------------------------------- Further Abstracted ----------------------------- */
+
+/* This function is used to apply operation to all keyframes, regardless of the type */
+short animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
{
-
+ return 0;
}
-/* -------------------------------- Further Abstracted ----------------------------- */
+/* ************************************************************************** */
+/* BezTriple Validation Callbacks */
-/* this function is called to apply the same operation to all types of channels */
-short animchannel_keys_bezier_loop(Scene *scene, bAnimListElem *ale, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+static short ok_bezier_frame(BeztEditData *bed, BezTriple *bezt)
{
+ /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
+ return IS_EQ(bezt->vec[1][0], bed->f1);
+}
+static short ok_bezier_framerange(BeztEditData *bed, BezTriple *bezt)
+{
+ /* frame range is stored in float properties */
+ return ((bezt->vec[1][0] > bed->f1) && (bezt->vec[1][0] < bed->f2));
}
+static short ok_bezier_selected(BeztEditData *bed, BezTriple *bezt)
+{
+ /* this macro checks all beztriple handles for selection... */
+ return BEZSELECTED(bezt);
+}
+
+static short ok_bezier_value(BeztEditData *bed, BezTriple *bezt)
+{
+ /* value is stored in f1 property
+ * - this float accuracy check may need to be dropped?
+ * - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
+ */
+ return IS_EQ(bezt->vec[1][1], bed->f1);
+}
+
+
+BeztEditFunc ANIM_editkeyframes_ok(short mode)
+{
+ /* eEditKeyframes_Validate */
+ switch (mode) {
+ case BEZT_OK_FRAME: /* only if bezt falls on the right frame (float) */
+ return ok_bezier_frame;
+ case BEZT_OK_FRAMERANGE: /* only if bezt falls within the specified frame range (floats) */
+ return ok_bezier_framerange;
+ case BEZT_OK_SELECTED: /* only if bezt is selected */
+ return ok_bezier_selected;
+ case BEZT_OK_VALUE: /* only if bezt value matches (float) */
+ return ok_bezier_value;
+ default: /* nothing was ok */
+ return NULL;
+ }
+}
/* ******************************************* */
/* Transform */
-static short snap_bezier_nearest(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearest(BeztEditData *bed, BezTriple *bezt)
{
if (bezt->f2 & SELECT)
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
return 0;
}
-static short snap_bezier_nearestsec(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearestsec(BeztEditData *bed, BezTriple *bezt)
{
- float secf = FPS;
+ const Scene *scene= bed->scene;
+ const float secf = FPS;
+
if (bezt->f2 & SELECT)
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]/secf + 0.5f) * secf);
return 0;
}
-static short snap_bezier_cframe(Scene *scene, BezTriple *bezt)
+static short snap_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
{
+ const Scene *scene= bed->scene;
if (bezt->f2 & SELECT)
bezt->vec[1][0]= (float)CFRA;
return 0;
}
-static short snap_bezier_nearmarker(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearmarker(BeztEditData *bed, BezTriple *bezt)
{
//if (bezt->f2 & SELECT)
// bezt->vec[1][0]= (float)find_nearest_marker_time(bezt->vec[1][0]); // XXX missing function!
@@ -163,8 +228,9 @@ static short snap_bezier_nearmarker(Scene *scene, BezTriple *bezt)
}
// calchandles_ipocurve
-BeztEditFunc ANIM_editkeys_snap(short type)
+BeztEditFunc ANIM_editkeyframes_snap(short type)
{
+ /* eEditKeyframes_Snap */
switch (type) {
case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
return snap_bezier_nearest;
@@ -181,8 +247,9 @@ BeztEditFunc ANIM_editkeys_snap(short type)
/* --------- */
-static short mirror_bezier_cframe(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
{
+ const Scene *scene= bed->scene;
float diff;
if (bezt->f2 & SELECT) {
@@ -193,7 +260,7 @@ static short mirror_bezier_cframe(Scene *scene, BezTriple *bezt)
return 0;
}
-static short mirror_bezier_yaxis(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_yaxis(BeztEditData *bed, BezTriple *bezt)
{
float diff;
@@ -205,7 +272,7 @@ static short mirror_bezier_yaxis(Scene *scene, BezTriple *bezt)
return 0;
}
-static short mirror_bezier_xaxis(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_xaxis(BeztEditData *bed, BezTriple *bezt)
{
float diff;
@@ -217,10 +284,11 @@ static short mirror_bezier_xaxis(Scene *scene, BezTriple *bezt)
return 0;
}
-static short mirror_bezier_marker(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
{
static TimeMarker *marker;
static short initialised = 0;
+ const Scene *scene= bed->scene;
/* In order for this mirror function to work without
* any extra arguments being added, we use the case
@@ -288,11 +356,13 @@ BeztEditFunc ANIM_editkeyframes_mirror(short type)
* for (ipo...) snap_cfra_ipo_keys(scene, ipo, 0); // sum up keyframe times
* snap_cfra_ipo_keys(scene, NULL, 1); // set current frame after taking average
*/
-void snap_cfra_ipo_keys(Scene *scene, Ipo *ipo, short mode)
+// XXX this thing needs to be refactored!
+void snap_cfra_ipo_keys(BeztEditData *bed, Ipo *ipo, short mode)
{
static int cfra;
static int tot;
+ Scene *scene= bed->scene;
IpoCurve *icu;
BezTriple *bezt;
int a;
@@ -330,7 +400,7 @@ void snap_cfra_ipo_keys(Scene *scene, Ipo *ipo, short mode)
/* Settings */
/* Sets the selected bezier handles to type 'auto' */
-static short set_bezier_auto(Scene *scene, BezTriple *bezt)
+static short set_bezier_auto(BeztEditData *bed, BezTriple *bezt)
{
/* is a handle selected? If so set it to type auto */
if((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
@@ -349,7 +419,7 @@ static short set_bezier_auto(Scene *scene, BezTriple *bezt)
}
/* Sets the selected bezier handles to type 'vector' */
-static short set_bezier_vector(Scene *scene, BezTriple *bezt)
+static short set_bezier_vector(BeztEditData *bed, BezTriple *bezt)
{
/* is a handle selected? If so set it to type vector */
if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
@@ -368,7 +438,7 @@ static short set_bezier_vector(Scene *scene, BezTriple *bezt)
}
#if 0 // xxx currently not used (only used by old code as a check)
-static short bezier_isfree(Scene *scene, BezTriple *bezt)
+static short bezier_isfree(BeztEditData *bed, BezTriple *bezt)
{
/* queries whether the handle should be set
* to type 'free' or 'align'
@@ -378,7 +448,7 @@ static short bezier_isfree(Scene *scene, BezTriple *bezt)
return 0;
}
-static short set_bezier_align(Scene *scene, BezTriple *bezt)
+static short set_bezier_align(BeztEditData *bed, BezTriple *bezt)
{
/* Sets selected bezier handles to type 'align' */
if (bezt->f1 & SELECT) bezt->h1= HD_ALIGN;
@@ -387,7 +457,7 @@ static short set_bezier_align(Scene *scene, BezTriple *bezt)
}
#endif // xxx currently not used (only used by old code as a check, but can't replicate that now)
-static short set_bezier_free(Scene *scene, BezTriple *bezt)
+static short set_bezier_free(BeztEditData *bed, BezTriple *bezt)
{
/* Sets selected bezier handles to type 'free' */
if (bezt->f1 & SELECT) bezt->h1= HD_FREE;
@@ -452,21 +522,21 @@ void set_ipocurve_mixed(IpoCurve *icu)
calchandles_ipocurve(icu);
}
-static short set_bezt_constant(Scene *scene, BezTriple *bezt)
+static short set_bezt_constant(BeztEditData *bed, BezTriple *bezt)
{
if (bezt->f2 & SELECT)
bezt->ipo= IPO_CONST;
return 0;
}
-static short set_bezt_linear(Scene *scene, BezTriple *bezt)
+static short set_bezt_linear(BeztEditData *bed, BezTriple *bezt)
{
if (bezt->f2 & SELECT)
bezt->ipo= IPO_LIN;
return 0;
}
-static short set_bezt_bezier(Scene *scene, BezTriple *bezt)
+static short set_bezt_bezier(BeztEditData *bed, BezTriple *bezt)
{
if (bezt->f2 & SELECT)
bezt->ipo= IPO_BEZ;
@@ -520,21 +590,21 @@ void setexprap_ipoloop(Ipo *ipo, int code)
/* ******************************************* */
/* Selection */
-static short select_bezier_add(Scene *scene, BezTriple *bezt)
+static short select_bezier_add(BeztEditData *bed, BezTriple *bezt)
{
/* Select the bezier triple */
BEZ_SEL(bezt);
return 0;
}
-static short select_bezier_subtract(Scene *scene, BezTriple *bezt)
+static short select_bezier_subtract(BeztEditData *bed, BezTriple *bezt)
{
/* Deselect the bezier triple */
BEZ_DESEL(bezt);
return 0;
}
-static short select_bezier_invert(Scene *scene, BezTriple *bezt)
+static short select_bezier_invert(BeztEditData *bed, BezTriple *bezt)
{
/* Invert the selection for the bezier triple */
bezt->f2 ^= SELECT;
@@ -684,48 +754,7 @@ void borderselect_ipo_key(Ipo *ipo, float xmin, float xmax, short selectmode)
}
}
-
-#if 0
-void select_ipo_bezier_keys(Ipo *ipo, int selectmode)
-{
- /* Select all of the beziers in all
- * of the Ipo curves belonging to the
- * Ipo, using the selection mode.
- */
- switch (selectmode) {
- case SELECT_ADD:
- ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
- break;
- case SELECT_SUBTRACT:
- ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
- break;
- case SELECT_INVERT:
- ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
- break;
- }
-}
-
-void select_icu_bezier_keys(IpoCurve *icu, int selectmode)
-{
- /* Select all of the beziers in all
- * of the Ipo curves belonging to the
- * Ipo, using the selection mode.
- */
- switch (selectmode) {
- case SELECT_ADD:
- icu_keys_bezier_loop(icu, select_bezier_add, NULL);
- break;
- case SELECT_SUBTRACT:
- icu_keys_bezier_loop(icu, select_bezier_subtract, NULL);
- break;
- case SELECT_INVERT:
- icu_keys_bezier_loop(icu, select_bezier_invert, NULL);
- break;
- }
-}
-#endif
-
-void select_icu_key(Scene *scene, IpoCurve *icu, float selx, short selectmode)
+void select_icu_key(BeztEditData *bed, IpoCurve *icu, float selx, short selectmode)
{
/* Selects all bezier triples in the Ipocurve
* at time selx, using the selection mode.
@@ -762,12 +791,12 @@ void select_icu_key(Scene *scene, IpoCurve *icu, float selx, short selectmode)
*/
for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
if (bezt->vec[1][0] == selx) {
- select_cb(scene, bezt);
+ select_cb(bed, bezt);
}
}
}
-void select_ipo_key(Scene *scene, Ipo *ipo, float selx, short selectmode)
+void select_ipo_key(BeztEditData *bed, Ipo *ipo, float selx, short selectmode)
{
/* Selects all bezier triples in each Ipocurve of the
* Ipo at time selx, using the selection mode.
@@ -796,7 +825,7 @@ void select_ipo_key(Scene *scene, Ipo *ipo, float selx, short selectmode)
for (icu=ipo->curve.first; icu; icu=icu->next) {
for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
if (bezt->vec[1][0] == selx) {
- select_cb(scene, bezt);
+ select_cb(bed, bezt);
}
}
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index d8407477970..adc2f3a8c4c 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -218,14 +218,13 @@ typedef enum eAnimFilter_Flags {
/* ---------------- API -------------------- */
-/* Obtain list of filtered Animation channels to operate on */
-int ANIM_animdata_filter(struct ListBase *anim_data, int filter_mode, void *data, short datatype);
-
-/* Obtain current anim-data context from Blender Context info */
-/** Example usage (example to be removed...):
- // get editor data
- if ((ANIM_animdata_get_context(C, &ac) == 0) || (ac.data == NULL))
- return;
+/* Obtain list of filtered Animation channels to operate on.
+ * Returns the number of channels in the list
+ */
+int ANIM_animdata_filter(ListBase *anim_data, int filter_mode, void *data, short datatype);
+
+/* Obtain current anim-data context from Blender Context info.
+ * Returns whether the operation was successful.
*/
short ANIM_animdata_get_context(const struct bContext *C, bAnimContext *ac);
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 1015de2e9e4..56a4cb6089c 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -47,6 +47,16 @@ struct Scene;
/* --------- Tool Flags ------------ */
+/* bezt validation */
+typedef enum eEditKeyframes_Validate {
+ BEZT_OK_FRAME = 1,
+ BEZT_OK_FRAMERANGE,
+ BEZT_OK_SELECTED,
+ BEZT_OK_VALUE,
+} eEditKeyframes_Validate;
+
+/* ------------ */
+
/* select tools */
typedef enum eEditKeyframes_Select {
SELECT_REPLACE = (1<<0),
@@ -71,32 +81,47 @@ typedef enum eEditKeyframes_Snap {
/* ************************************************ */
/* Editing API */
+/* --- Generic Properties for Bezier Edit Tools ----- */
+
+// XXX maybe a union would be more compact?
+typedef struct BeztEditData {
+ ListBase list; /* temp list for storing custom list of data to check */
+ struct Scene *scene; /* pointer to current scene - many tools need access to cfra/etc. */
+ void *data; /* pointer to custom data - not that useful? */
+ float f1, f2; /* storage of times/values as 'decimals' */
+ int i1, i2; /* storage of times/values as 'whole' numbers */
+} BeztEditData;
+
/* ------- Function Pointer Typedefs --------------- */
/* callback function that refreshes the IPO curve after use */
typedef void (*IcuEditFunc)(struct IpoCurve *icu);
-typedef short (*BeztEditFunc)(struct Scene *scene, struct BezTriple *bezt);
+ /* callback function that operates on the given BezTriple */
+typedef short (*BeztEditFunc)(BeztEditData *bed, struct BezTriple *bezt);
/* ------------- Looping API ------------------- */
-short icu_keys_bezier_loop(struct Scene *scene, struct IpoCurve *icu, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
-short ipo_keys_bezier_loop(struct Scene *scene, struct Ipo *ipo, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
+short icu_keys_bezier_loop(BeztEditData *bed, struct IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
+short ipo_keys_bezier_loop(BeztEditData *bed, struct Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
/* ------------ BezTriple Callback Getters --------------- */
+/* accessories */
+BeztEditFunc ANIM_editkeyframes_ok(short mode);
+
+/* edit */
BeztEditFunc ANIM_editkeyframes_snap(short mode);
BeztEditFunc ANIM_editkeyframes_mirror(short mode);
BeztEditFunc ANIM_editkeyframes_select(short mode);
BeztEditFunc ANIM_editkeyframes_handles(short mode);
BeztEditFunc ANIM_editkeyframes_ipo(short mode);
-/* ------------ Helper Funcs -------------- */
-// XXX will these be needed to set globals for some funcs?
-
/* ************************************************ */
-void select_ipo_key(struct Scene *scene, struct Ipo *ipo, float selx, short selectmode);
-void select_icu_key(struct Scene *scene, struct IpoCurve *icu, float selx, short selectmode);
+// XXX all of these funcs will be depreceated!
+
+void select_ipo_key(BeztEditData *bed, struct Ipo *ipo, float selx, short selectmode);
+void select_icu_key(BeztEditData *bed, struct IpoCurve *icu, float selx, short selectmode);
short is_ipo_key_selected(struct Ipo *ipo);
void set_ipo_key_selection(struct Ipo *ipo, short sel);
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 7a99b151148..0b63cad4712 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -404,10 +404,25 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
int filter;
View2D *v2d= &ar->v2d;
float x= 0.0f, y= 0.0f;
+ int items, height;
/* build list of channels to draw */
filter= (ANIMFILTER_FORDRAWING|ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS);
- ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+ items= ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* Update max-extent of channels here (taking into account scrollers):
+ * - this is done to allow the channel list to be scrollable, but must be done here
+ * to avoid regenerating the list again and/or also because channels list is drawn first
+ * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * start of list offset, and the second is as a correction for the scrollers.
+ */
+ height= ((items*ACHANNEL_STEP) + (ACHANNEL_HEIGHT*2));
+ if (height > (v2d->mask.ymax - v2d->mask.ymin)) {
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
+ */
+ v2d->tot.ymin= -height;
+ }
/* loop through channels, and set up drawing depending on their type */
y= (float)(-ACHANNEL_HEIGHT);
@@ -728,6 +743,11 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
mute = ICON_MUTE_IPO_ON;
else
mute = ICON_MUTE_IPO_OFF;
+
+ if (icu->flag & IPO_PROTECT)
+ protect = ICON_UNLOCKED;
+ else
+ protect = ICON_LOCKED;
sel = SEL_ICU(icu);
if (saction->pin)
@@ -1076,6 +1096,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
rcti scr_rct;
int act_start, act_end, dummy;
+ int height, items;
float y, sta, end;
char col1[3], col2[3];
@@ -1117,7 +1138,21 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* build list of channels to draw */
filter= (ANIMFILTER_FORDRAWING|ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS);
- ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+ items= ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* Update max-extent of channels here (taking into account scrollers):
+ * - this is done to allow the channel list to be scrollable, but must be done here
+ * to avoid regenerating the list again and/or also because channels list is drawn first
+ * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * start of list offset, and the second is as a correction for the scrollers.
+ */
+ height= ((items*ACHANNEL_STEP) + (ACHANNEL_HEIGHT*2));
+ if (height > (v2d->mask.ymax - v2d->mask.ymin)) {
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
+ */
+ v2d->tot.ymin= -height;
+ }
/* first backdrop strips */
y= (float)(-ACHANNEL_HEIGHT);
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 788e5df2d13..51c6c3c7a1d 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -37,18 +37,39 @@ struct wmOperatorType;
/* internal exports only */
+/* ***************************************** */
/* action_draw.c */
void draw_channel_names(struct bAnimContext *ac, struct SpaceAction *saction, struct ARegion *ar);
void draw_channel_strips(struct bAnimContext *ac, struct SpaceAction *saction, struct ARegion *ar);
+/* ***************************************** */
/* action_header.c */
void action_header_buttons(const struct bContext *C, struct ARegion *ar);
+/* ***************************************** */
/* action_select.c */
void ED_ACT_OT_keyframes_deselectall(struct wmOperatorType *ot);
void ED_ACT_OT_keyframes_borderselect(struct wmOperatorType *ot);
+void ED_ACT_OT_keyframes_columnselect(struct wmOperatorType *ot);
void ED_ACT_OT_keyframes_clickselect(struct wmOperatorType *ot);
+/* defines for left-right select tool */
+enum {
+ ACTKEYS_LRSEL_TEST = -1,
+ ACTKEYS_LRSEL_NONE,
+ ACTKEYS_LRSEL_LEFT,
+ ACTKEYS_LRSEL_RIGHT,
+} eActKeys_LeftRightSelect_Mode;
+
+/* defines for column-select mode */
+enum {
+ ACTKEYS_COLUMNSEL_KEYS = 0,
+ ACTKEYS_COLUMNSEL_CFRA,
+ ACTKEYS_COLUMNSEL_MARKERS_COLUMN,
+ ACTKEYS_COLUMNSEL_MARKERS_BETWEEN,
+} eActKeys_ColumnSelect_Mode;
+
+/* ***************************************** */
/* action_ops.c */
void action_operatortypes(void);
void action_keymap(struct wmWindowManager *wm);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 6d6bee90171..ceaa8117de7 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -65,16 +65,20 @@ void action_operatortypes(void)
WM_operatortype_append(ED_ACT_OT_keyframes_clickselect);
WM_operatortype_append(ED_ACT_OT_keyframes_deselectall);
WM_operatortype_append(ED_ACT_OT_keyframes_borderselect);
+ WM_operatortype_append(ED_ACT_OT_keyframes_columnselect);
}
/* ************************** registration - keymaps **********************************/
static void action_keymap_keyframes (ListBase *keymap)
{
+ /* action_select.c - selection tools */
/* click-select */
WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "column_select", 1);
RNA_boolean_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "left_right", 1);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "left_right", ACTKEYS_LRSEL_TEST);
+
/* deselect all */
WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_deselectall", AKEY, KM_PRESS, 0, 0);
@@ -82,6 +86,13 @@ static void action_keymap_keyframes (ListBase *keymap)
/* borderselect */
WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_borderselect", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_borderselect", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
+
+ /* column select */
+ RNA_enum_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_CFRA);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ED_ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN);
}
/* --------------- */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 100024fc0d1..cd454388a57 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -83,6 +83,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "action_intern.h"
+
/* ************************************************************************** */
/* GENERAL STUFF */
@@ -384,7 +386,7 @@ static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
bAnimContext ac;
/* get editor data */
- if ((ANIM_animdata_get_context(C, &ac) == 0) || (ac.data == NULL))
+ if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
/* 'standard' behaviour - check if selected, then apply relevant selection */
@@ -414,23 +416,34 @@ void ED_ACT_OT_keyframes_deselectall (wmOperatorType *ot)
}
/* ******************** Border Select Operator **************************** */
-/* This operator works in one of three ways:
- * 1) borderselect over keys (BKEY) - mouse over main area when initialised; will select keys in region
- * 2) borderselect over horizontal scroller - mouse over horizontal scroller when initialised; will select keys in frame range
- * 3) borderselect over vertical scroller - mouse over vertical scroller when initialised; will select keys in row range
+/* This operator currently works in one of three ways:
+ * -> BKEY - 1) all keyframes within region are selected (ACTKEYS_BORDERSEL_ALLKEYS)
+ * -> ALT-BKEY - depending on which axis of the region was larger...
+ * -> 2) x-axis, so select all frames within frame range (ACTKEYS_BORDERSEL_FRAMERANGE)
+ * -> 3) y-axis, so select all frames within channels that region included (ACTKEYS_BORDERSEL_CHANNELS)
*/
-static void borderselect_action (bAnimContext *ac, rcti rect, short in_scroller, short selectmode)
+/* defines for borderselect mode */
+enum {
+ ACTKEYS_BORDERSEL_ALLKEYS = 0,
+ ACTKEYS_BORDERSEL_FRAMERANGE,
+ ACTKEYS_BORDERSEL_CHANNELS,
+} eActKeys_BorderSelect_Mode;
+
+
+static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short selectmode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
+ BeztEditData bed;
+ BeztEditFunc ok_cb, select_cb;
View2D *v2d= &ac->ar->v2d;
- BeztEditFunc select_cb;
rctf rectf;
- float ymin=0, ymax=ACHANNEL_HEIGHT;
+ float ymin=0, ymax=(float)(-ACHANNEL_HEIGHT);
+ /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
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);
@@ -438,29 +451,47 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short in_scroller,
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
- /* get selection editing func */
+ /* get beztriple editing/validation funcs */
select_cb= ANIM_editkeyframes_select(selectmode);
+ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS))
+ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ else
+ ok_cb= NULL;
+
+ /* init editing data */
+ memset(&bed, 0, sizeof(BeztEditData));
+
/* loop over data, doing border select */
for (ale= anim_data.first; ale; ale= ale->next) {
Object *nob= ANIM_nla_mapping_get(ac, ale);
+ /* get new vertical minimum extent of channel */
ymin= ymax - ACHANNEL_STEP;
- /* if action is mapped in NLA, it returns a correction */
- if (nob) {
- rectf.xmin= get_action_frame(nob, rectf.xmin);
- rectf.xmax= get_action_frame(nob, rectf.xmax);
+ /* set horizontal range (if applicable) */
+ if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
+ /* if channel is mapped in NLA, apply correction */
+ if (nob) {
+ bed.f1= get_action_frame(nob, rectf.xmin);
+ bed.f2= get_action_frame(nob, rectf.xmax);
+ }
+ else {
+ bed.f1= rectf.xmin;
+ bed.f2= rectf.xmax;
+ }
}
- /* what gets selected depends on the mode (based on initial position of cursor) */
- switch (in_scroller) {
- case 'h': /* all in frame(s) (option 3) */
+ /* perform vertical suitability check (if applicable) */
+ if ( (mode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
+ !((ymax < rectf.ymin) || (ymin > rectf.ymax)) )
+ {
+ /* loop over data selecting */
if (ale->key_data) {
if (ale->datatype == ALE_IPO)
- borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
+ ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
else if (ale->datatype == ALE_ICU)
- borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_cb);
+ icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
}
else if (ale->type == ANIMTYPE_GROUP) {
bActionGroup *agrp= ale->data;
@@ -468,74 +499,18 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short in_scroller,
bConstraintChannel *conchan;
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
+ ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL);
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
}
}
//else if (ale->type == ANIMTYPE_GPLAYER) {
// borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
//}
- break;
- case 'v': /* all in channel(s) (option 2) */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- if (ale->key_data) {
- if (ale->datatype == ALE_IPO)
- ipo_keys_bezier_loop(ac->scene, ale->key_data, select_cb, NULL);
- else if (ale->datatype == ALE_ICU)
- icu_keys_bezier_loop(ac->scene, ale->key_data, select_cb, NULL);
- }
- else if (ale->type == ANIMTYPE_GROUP) {
- bActionGroup *agrp= ale->data;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- ipo_keys_bezier_loop(ac->scene, achan->ipo, select_cb, NULL);
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- ipo_keys_bezier_loop(ac->scene, conchan->ipo, select_cb, NULL);
- }
- }
- //else if (ale->type == ANIMTYPE_GPLAYER) {
- // select_gpencil_frames(ale->data, selectmode);
- //}
- }
- break;
- default: /* any keyframe inside region defined by region (option 1) */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- if (ale->key_data) {
- if (ale->datatype == ALE_IPO)
- borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
- else if (ale->datatype == ALE_ICU)
- borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_cb);
- }
- else if (ale->type == ANIMTYPE_GROUP) {
- // fixme: need a nicer way of dealing with summaries!
- bActionGroup *agrp= ale->data;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
- }
- }
- //else if (ale->type == ANIMTYPE_GPLAYER) {
- //// borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
- //}
- }
- }
-
- /* if action is mapped in NLA, unapply correction */
- if (nob) {
- rectf.xmin= get_action_frame_inv(nob, rectf.xmin);
- rectf.xmax= get_action_frame_inv(nob, rectf.xmax);
}
+ /* set minimum extent to be the maximum of the next channel */
ymax=ymin;
}
@@ -549,11 +524,11 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
rcti rect;
- short in_scroller, selectmode;
+ short mode=0, selectmode=0;
int event;
/* get editor data */
- if ((ANIM_animdata_get_context(C, &ac) == 0) || (ac.data == NULL))
+ if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
/* get settings from operator */
@@ -561,37 +536,33 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
rect.ymin= RNA_int_get(op->ptr, "ymin");
rect.xmax= RNA_int_get(op->ptr, "xmax");
rect.ymax= RNA_int_get(op->ptr, "ymax");
-
- in_scroller= RNA_int_get(op->ptr, "in_scroller");
-
+
event= RNA_int_get(op->ptr, "event_type");
if (event == LEFTMOUSE) // FIXME... hardcoded
selectmode = SELECT_ADD;
else
selectmode = SELECT_SUBTRACT;
-
- borderselect_action(&ac, rect, in_scroller, selectmode);
- return OPERATOR_FINISHED;
-}
-
-static int actkeys_borderselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- bAnimContext ac;
- ARegion *ar;
+ /* selection 'mode' depends on whether borderselect region only matters on one axis */
+ if (RNA_boolean_get(op->ptr, "axis_range")) {
+ /* 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 favoured 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...
+ */
+ if ((rect.xmax - rect.xmin) >= (rect.ymax - rect.ymin))
+ mode= ACTKEYS_BORDERSEL_FRAMERANGE;
+ else
+ mode= ACTKEYS_BORDERSEL_CHANNELS;
+ }
+ else
+ mode= ACTKEYS_BORDERSEL_ALLKEYS;
- /* get editor data */
- if ((ANIM_animdata_get_context(C, &ac) == 0) || (ac.data == NULL))
- return OPERATOR_CANCELLED;
- ar= ac.ar;
-
- /* check if mouse is in a scroller */
- // XXX move this to keymap level thing (boundbox checking)?
- RNA_enum_set(op->ptr, "in_scroller", UI_view2d_mouse_in_scrollers(C, &ar->v2d, event->x, event->y));
+ /* apply borderselect action */
+ borderselect_action(&ac, rect, mode, selectmode);
- /* now init borderselect operator to handle borderselect as per normal */
- return WM_border_select_invoke(C, op, event);
-}
+ return OPERATOR_FINISHED;
+}
void ED_ACT_OT_keyframes_borderselect(wmOperatorType *ot)
{
@@ -600,34 +571,270 @@ void ED_ACT_OT_keyframes_borderselect(wmOperatorType *ot)
ot->idname= "ED_ACT_OT_keyframes_borderselect";
/* api callbacks */
- ot->invoke= actkeys_borderselect_invoke;//WM_border_select_invoke;
+ ot->invoke= WM_border_select_invoke;
ot->exec= actkeys_borderselect_exec;
ot->modal= WM_border_select_modal;
ot->poll= ED_operator_areaactive;
/* rna */
- RNA_def_property(ot->srna, "in_scroller", PROP_INT, PROP_NONE); // as enum instead?
RNA_def_property(ot->srna, "event_type", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmax", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymax", PROP_INT, PROP_NONE);
+
+ RNA_def_property(ot->srna, "axis_range", PROP_BOOLEAN, PROP_NONE);
}
/* ******************** Column Select Operator **************************** */
+/* This operator works in one of four ways:
+ * - 1) select all keyframes in the same frame as a selected one (KKEY)
+ * - 2) select all keyframes in the same frame as the current frame marker (CTRL-KKEY)
+ * - 3) select all keyframes in the same frame as a selected markers (SHIFT-KKEY)
+ * - 4) select all keyframes that occur between selected markers (ALT-KKEY)
+ */
+
+/* defines for column-select mode */
+EnumPropertyItem prop_column_select_types[] = {
+ {ACTKEYS_COLUMNSEL_KEYS, "KEYS", "On Selected Keyframes", ""},
+ {ACTKEYS_COLUMNSEL_CFRA, "CFRA", "On Current Frame", ""},
+ {ACTKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", "On Selected Markers", ""},
+ {ACTKEYS_COLUMNSEL_MARKERS_BETWEEN, "MARKERS_BETWEEN", "Between Min/Max Selected Markers", ""},
+ {0, NULL, NULL, NULL}
+};
+
+/* ------------------- */
+
+/* Selects all visible keyframes between the specified markers */
+static void markers_selectkeys_between (bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ BeztEditFunc select_cb;
+ BeztEditData bed;
+ float min, max;
+
+ /* get extreme markers */
+ //get_minmax_markers(1, &min, &max); // FIXME... add back markers api!
+ min= ac->scene->r.sfra; // xxx temp code
+ max= ac->scene->r.efra; // xxx temp code
+
+ if (min==max) return;
+ min -= 0.5f;
+ max += 0.5f;
+
+ /* get editing funcs + data */
+ select_cb= ANIM_editkeyframes_select(SELECT_ADD);
+ memset(&bed, 0, sizeof(BeztEditData));
+ bed.f1= min;
+ bed.f2= max;
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_IPOKEYS);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* select keys in-between */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ Object *nob= ANIM_nla_mapping_get(ac, ale);
+
+ if (nob) {
+ ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1);
+ ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL);
+ ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1);
+ }
+ else {
+ ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL);
+ }
+ }
+
+ /* Cleanup */
+ BLI_freelistN(&anim_data);
+}
+
+
+/* helper callback for columnselect_action_keys() -> populate list CfraElems with frame numbers from selected beztriples */
+// TODO: if some other code somewhere needs this, it'll be time to port this over to keyframes_edit.c!!!
+static short bezt_to_cfraelem(BeztEditData *bed, BezTriple *bezt)
+{
+ /* only if selected */
+ if (bezt->f2 & SELECT) {
+ CfraElem *ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&bed->list, ce);
+
+ ce->cfra= bezt->vec[1][0];
+ }
+
+ return 0;
+}
+
+/* Selects all visible keyframes in the same frames as the specified elements */
+static void columnselect_action_keys (bAnimContext *ac, short mode)
+{
+ ListBase anim_data= {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ Scene *scene= ac->scene;
+ CfraElem *ce;
+ BeztEditFunc select_cb, ok_cb;
+ BeztEditData bed;
+
+ /* initialise keyframe editing data */
+ memset(&bed, 0, sizeof(BeztEditData));
+
+ /* build list of columns */
+ switch (mode) {
+ case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */
+ if (ac->datatype == ANIMCONT_GPENCIL) {
+ filter= (ANIMFILTER_VISIBLE);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ //for (ale= anim_data.first; ale; ale= ale->next)
+ // gplayer_make_cfra_list(ale->data, &elems, 1);
+ }
+ else {
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_IPOKEYS);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ for (ale= anim_data.first; ale; ale= ale->next)
+ ipo_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ }
+ BLI_freelistN(&anim_data);
+ break;
+
+ case ACTKEYS_COLUMNSEL_CFRA: /* current frame */
+ /* make a single CfraElem for storing this */
+ ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&bed.list, ce);
+
+ ce->cfra= (float)CFRA;
+ break;
+
+ case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
+ // FIXME: markers api needs to be improved for this first!
+ //make_marker_cfra_list(&elems, 1);
+ return; // XXX currently, this does nothing!
+ break;
+
+ default: /* invalid option */
+ return;
+ }
+
+ /* set up BezTriple edit callbacks */
+ select_cb= ANIM_editkeyframes_select(SELECT_ADD);
+ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ if (ac->datatype == ANIMCONT_GPENCIL)
+ filter= (ANIMFILTER_VISIBLE);
+ else
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ONLYICU);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ Object *nob= ANIM_nla_mapping_get(ac, ale);
+
+ /* loop over cfraelems (stored in the BeztEditData->list)
+ * - we need to do this here, as we can apply fewer NLA-mapping conversions
+ */
+ for (ce= bed.list.first; ce; ce= ce->next) {
+ /* set frame for validation callback to refer to */
+ if (nob)
+ bed.f1= get_action_frame(nob, ce->cfra);
+ else
+ bed.f1= ce->cfra;
+
+ /* select elements with frame number matching cfraelem */
+ icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
+
+#if 0 // XXX reenable when Grease Pencil stuff is back
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+ bGPDframe *gpf;
+
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+ if (ecfra == gpf->framenum)
+ gpf->flag |= GP_FRAME_SELECT;
+ }
+ }
+ //else...
+#endif // XXX reenable when Grease Pencil stuff is back
+ }
+ }
+
+ /* free elements */
+ BLI_freelistN(&bed.list);
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_columnselect_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ short mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* action to take depends on the mode */
+ mode= RNA_enum_get(op->ptr, "mode");
+
+ if (mode == ACTKEYS_COLUMNSEL_MARKERS_BETWEEN)
+ markers_selectkeys_between(&ac);
+ else
+ columnselect_action_keys(&ac, mode);
+
+ /* 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 ED_ACT_OT_keyframes_columnselect (wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name= "Select All";
+ ot->idname= "ED_ACT_OT_keyframes_columnselect";
+
+ /* api callbacks */
+ ot->exec= actkeys_columnselect_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* props */
+ prop= RNA_def_property(ot->srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_column_select_types);
+}
/* ******************** Mouse-Click Select Operator *********************** */
-/* This operator works in one of four ways:
- * - main area
- * -> 1) without alt-key - selects keyframe that was under mouse position
- * -> 2) with alt-key - only those keyframes on same side of current frame
- * - 3) horizontal scroller (*) - select all keyframes in frame (err... maybe integrate this with column select only)?
- * - 4) vertical scroller (*) - select all keyframes in channel
+/* This operator works in one of three ways:
+ * - 1) keyframe under mouse - no special modifiers
+ * - 2) all keyframes on the same side of current frame indicator as mouse - ALT modifier
+ * - 3) column select all keyframes in frame under mouse - CTRL modifier
*
- * (*) - these are not obviously presented in UI. We need to find a new way to showcase them.
+ * In addition to these basic options, the SHIFT modifier can be used to toggle the
+ * selection mode between replacing the selection (without) and inverting the selection (with).
*/
+/* defines for left-right select tool */
+EnumPropertyItem prop_leftright_select_types[] = {
+ {ACTKEYS_LRSEL_TEST, "CHECK", "Check if Select Left or Right", ""},
+ {ACTKEYS_LRSEL_NONE, "OFF", "Don't select", ""},
+ {ACTKEYS_LRSEL_LEFT, "LEFT", "Before current frame", ""},
+ {ACTKEYS_LRSEL_RIGHT, "RIGHT", "After current frame", ""},
+ {0, NULL, NULL, NULL}
+};
+
+/* ------------------- */
+
/* option 1) select keyframe directly under mouse */
static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode)
{
@@ -642,6 +849,8 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode)
bGPdata *gpd = NULL;
bGPDlayer *gpl = NULL;
+ BeztEditData bed;
+ BeztEditFunc select_cb, ok_cb;
void *anim_channel;
short sel, chan_type = 0;
float selx = 0.0f, selxa;
@@ -653,127 +862,143 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode)
ads= (bDopeSheet *)ac->data;
else if (ac->datatype == ANIMCONT_GPENCIL)
gpd= (bGPdata *)ac->data;
-
+
+ /* get channel and selection info */
anim_channel= get_nearest_action_key(ac, mval, &selx, &sel, &chan_type, &achan);
- if (anim_channel) {
- /* must have been a channel */
- switch (chan_type) {
- case ANIMTYPE_ICU:
- icu= (IpoCurve *)anim_channel;
- break;
- case ANIMTYPE_CONCHAN:
- conchan= (bConstraintChannel *)anim_channel;
- break;
- case ANIMTYPE_ACHAN:
- achan= (bActionChannel *)anim_channel;
- break;
- case ANIMTYPE_GROUP:
- agrp= (bActionGroup *)anim_channel;
- break;
- case ANIMTYPE_DSMAT:
- ipo= ((Material *)anim_channel)->ipo;
- break;
- case ANIMTYPE_DSLAM:
- ipo= ((Lamp *)anim_channel)->ipo;
- break;
- case ANIMTYPE_DSCAM:
- ipo= ((Camera *)anim_channel)->ipo;
- break;
- case ANIMTYPE_DSCUR:
- ipo= ((Curve *)anim_channel)->ipo;
- break;
- case ANIMTYPE_DSSKEY:
- ipo= ((Key *)anim_channel)->ipo;
- break;
- case ANIMTYPE_FILLACTD:
- act= (bAction *)anim_channel;
- break;
- case ANIMTYPE_FILLIPOD:
- ipo= ((Object *)anim_channel)->ipo;
- break;
- case ANIMTYPE_OBJECT:
- ob= ((Base *)anim_channel)->object;
- break;
- case ANIMTYPE_GPLAYER:
- gpl= (bGPDlayer *)anim_channel;
- break;
- default:
- return;
- }
+ if (anim_channel == NULL)
+ return;
+
+ switch (chan_type) {
+ case ANIMTYPE_ICU:
+ icu= (IpoCurve *)anim_channel;
+ break;
+ case ANIMTYPE_CONCHAN:
+ conchan= (bConstraintChannel *)anim_channel;
+ break;
+ case ANIMTYPE_ACHAN:
+ achan= (bActionChannel *)anim_channel;
+ break;
+ case ANIMTYPE_GROUP:
+ agrp= (bActionGroup *)anim_channel;
+ break;
+ case ANIMTYPE_DSMAT:
+ ipo= ((Material *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_DSLAM:
+ ipo= ((Lamp *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_DSCAM:
+ ipo= ((Camera *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_DSCUR:
+ ipo= ((Curve *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_DSSKEY:
+ ipo= ((Key *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_FILLACTD:
+ act= (bAction *)anim_channel;
+ break;
+ case ANIMTYPE_FILLIPOD:
+ ipo= ((Object *)anim_channel)->ipo;
+ break;
+ case ANIMTYPE_OBJECT:
+ ob= ((Base *)anim_channel)->object;
+ break;
+ case ANIMTYPE_GPLAYER:
+ gpl= (bGPDlayer *)anim_channel;
+ break;
+ default:
+ return;
+ }
+
+ /* for replacing selection, firstly need to clear existing selection */
+ if (selectmode == SELECT_REPLACE) {
+ selectmode = SELECT_ADD;
- if (selectmode == SELECT_REPLACE) {
- selectmode = SELECT_ADD;
-
- deselect_action_keys(ac, 0, 0);
+ deselect_action_keys(ac, 0, 0);
+
+ if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET)) {
+ //deselect_action_channels(0);
- if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET)) {
- //deselect_action_channels(0);
-
- /* Highlight either an Action-Channel or Action-Group */
- if (achan) {
- achan->flag |= ACHAN_SELECTED;
- //hilight_channel(act, achan, 1);
- //select_poseelement_by_name(achan->name, 2); /* 2 is activate */
- }
- else if (agrp) {
- agrp->flag |= AGRP_SELECTED;
- //set_active_actiongroup(act, agrp, 1);
- }
+ /* Highlight either an Action-Channel or Action-Group */
+ if (achan) {
+ achan->flag |= ACHAN_SELECTED;
+ //hilight_channel(act, achan, 1);
+ //select_poseelement_by_name(achan->name, 2); /* 2 is activate */
}
- else if (ac->datatype == ANIMCONT_GPENCIL) {
- //deselect_action_channels(0);
-
- /* Highlight gpencil layer */
- gpl->flag |= GP_LAYER_SELECT;
- //gpencil_layer_setactive(gpd, gpl);
+ else if (agrp) {
+ agrp->flag |= AGRP_SELECTED;
+ //set_active_actiongroup(act, agrp, 1);
}
}
-
- if (icu)
- select_icu_key(ac->scene, icu, selx, selectmode);
- else if (ipo)
- select_ipo_key(ac->scene, ipo, selx, selectmode);
- else if (conchan)
- select_ipo_key(ac->scene, conchan->ipo, selx, selectmode);
- else if (achan)
- select_ipo_key(ac->scene, achan->ipo, selx, selectmode);
- else if (agrp) {
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- select_ipo_key(ac->scene, achan->ipo, selx, selectmode);
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- select_ipo_key(ac->scene, conchan->ipo, selx, selectmode);
- }
+ else if (ac->datatype == ANIMCONT_GPENCIL) {
+ //deselect_action_channels(0);
+
+ /* Highlight gpencil layer */
+ gpl->flag |= GP_LAYER_SELECT;
+ //gpencil_layer_setactive(gpd, gpl);
}
- else if (act) {
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- select_ipo_key(ac->scene, achan->ipo, selx, selectmode);
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- select_ipo_key(ac->scene, conchan->ipo, selx, selectmode);
- }
+ }
+
+ /* get functions for selecting keyframes */
+ select_cb= ANIM_editkeyframes_select(selectmode);
+ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+ memset(&bed, 0, sizeof(BeztEditData));
+ bed.f1= selx;
+
+ /* apply selection to keyframes */
+ if (icu)
+ icu_keys_bezier_loop(&bed, icu, ok_cb, select_cb, NULL);
+ else if (ipo)
+ ipo_keys_bezier_loop(&bed, ipo, ok_cb, select_cb, NULL);
+ else if (conchan)
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
+ else if (achan)
+ ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL);
+ else if (agrp) {
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
+ }
+ }
+ else if (act) {
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
+ }
+ }
+ else if (ob) {
+ if (ob->ipo) {
+ bed.f1= selx;
+ ipo_keys_bezier_loop(&bed, ob->ipo, ok_cb, select_cb, NULL);
}
- else if (ob) {
- if (ob->ipo)
- select_ipo_key(ac->scene, ob->ipo, selx, selectmode);
+
+ if (ob->action) {
+ selxa= get_action_frame(ob, selx);
+ bed.f1= selxa;
- if (ob->action) {
- selxa= get_action_frame(ob, selx);
+ for (achan= ob->action->chanbase.first; achan; achan= achan->next) {
+ ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL);
- for (achan= ob->action->chanbase.first; achan; achan= achan->next) {
- select_ipo_key(ac->scene, achan->ipo, selxa, selectmode);
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- select_ipo_key(ac->scene, conchan->ipo, selxa, selectmode);
- }
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
}
+ }
+
+ if (ob->constraintChannels.first) {
+ bed.f1= selx;
for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next)
- select_ipo_key(ac->scene, conchan->ipo, selx, selectmode);
+ ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL);
}
- //else if (gpl)
- // select_gpencil_frame(gpl, (int)selx, selectmode);
}
+ //else if (gpl)
+ // select_gpencil_frame(gpl, (int)selx, selectmode);
}
/* Option 2) Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */
@@ -790,7 +1015,7 @@ static void selectkeys_leftright (bAnimContext *ac, short leftright, short selec
deselect_action_keys(ac, 0, 0);
}
- if (leftright == 1) {
+ if (leftright == ACTKEYS_LRSEL_LEFT) {
min = -MAXFRAMEF;
max = (float)(CFRA + 0.1f);
}
@@ -824,50 +1049,116 @@ static void selectkeys_leftright (bAnimContext *ac, short leftright, short selec
/* Cleanup */
BLI_freelistN(&anim_data);
}
+
+/* Option 3) Selects all visible keyframes in the same frame as the mouse click */
+static void mouse_columnselect_action_keys (bAnimContext *ac, float selx)
+{
+ ListBase anim_data= {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ BeztEditFunc select_cb, ok_cb;
+ BeztEditData bed;
+
+ /* initialise keyframe editing data */
+ memset(&bed, 0, sizeof(BeztEditData));
+
+ /* set up BezTriple edit callbacks */
+ select_cb= ANIM_editkeyframes_select(SELECT_ADD);
+ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ if (ac->datatype == ANIMCONT_GPENCIL)
+ filter= (ANIMFILTER_VISIBLE);
+ else
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ONLYICU);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ Object *nob= ANIM_nla_mapping_get(ac, ale);
+
+ /* set frame for validation callback to refer to */
+ if (nob)
+ bed.f1= get_action_frame(nob, selx);
+ else
+ bed.f1= selx;
+
+ /* select elements with frame number matching cfraelem */
+ icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
+
+#if 0 // XXX reenable when Grease Pencil stuff is back
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+ bGPDframe *gpf;
+
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+ if (ecfra == gpf->framenum)
+ gpf->flag |= GP_FRAME_SELECT;
+ }
+ }
+ //else...
+#endif // XXX reenable when Grease Pencil stuff is back
+ }
+
+ /* free elements */
+ BLI_freelistN(&bed.list);
+ BLI_freelistN(&anim_data);
+}
/* ------------------- */
+/* handle clicking */
static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
bAnimContext ac;
Scene *scene;
ARegion *ar;
- short in_scroller, selectmode;
+ View2D *v2d;
+ short selectmode;
int mval[2];
/* get editor data */
- if ((ANIM_animdata_get_context(C, &ac) == 0) || (ac.data == NULL))
+ 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);
- /* check where in view mouse is */
- in_scroller = UI_view2d_mouse_in_scrollers(C, &ar->v2d, event->x, event->y);
-
/* select mode is either replace (deselect all, then add) or add/extend */
+ // XXX this is currently only available for normal select only
if (RNA_boolean_get(op->ptr, "extend_select"))
- selectmode= SELECT_ADD;
+ selectmode= SELECT_INVERT;
else
selectmode= SELECT_REPLACE;
- /* check which scroller mouse is in, and figure out how to handle this */
- if (in_scroller == 'h') {
- /* horizontal - column select in current frame */
- // FIXME.... todo
- }
- else if (in_scroller == 'v') {
- /* vertical - row select in current channel */
- // FIXME...
- }
- else if (RNA_boolean_get(op->ptr, "left_right")) {
+ /* figure out action to take */
+ if (RNA_enum_get(op->ptr, "left_right")) {
/* select all keys on same side of current frame as mouse */
- selectkeys_leftright(&ac, (mval[0] < CFRA), selectmode);
+ float x;
+
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, NULL);
+ if (x < CFRA)
+ RNA_int_set(op->ptr, "left_right", ACTKEYS_LRSEL_LEFT);
+ else
+ RNA_int_set(op->ptr, "left_right", ACTKEYS_LRSEL_RIGHT);
+
+ selectkeys_leftright(&ac, RNA_enum_get(op->ptr, "left_right"), selectmode);
+ }
+ else if (RNA_boolean_get(op->ptr, "column_select")) {
+ /* select all the keyframes that occur on the same frame as where the mouse clicked */
+ float x;
+
+ /* figure out where (the frame) the mouse clicked, and set all keyframes in that frame */
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, NULL);
+ mouse_columnselect_action_keys(&ac, x);
}
else {
/* select keyframe under mouse */
@@ -883,17 +1174,21 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even
void ED_ACT_OT_keyframes_clickselect (wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Mouse Select Keys";
ot->idname= "ED_ACT_OT_keyframes_clickselect";
/* api callbacks */
ot->invoke= actkeys_clickselect_invoke;
- //ot->poll= ED_operator_areaactive;
+ ot->poll= ED_operator_areaactive;
/* id-props */
- RNA_def_property(ot->srna, "left_right", PROP_BOOLEAN, PROP_NONE); // ALTKEY
- RNA_def_property(ot->srna, "extend_select", PROP_BOOLEAN, PROP_NONE); // SHIFTKEY
+ prop= RNA_def_property(ot->srna, "left_right", PROP_ENUM, PROP_NONE); // ALTKEY
+ //RNA_def_property_enum_items(prop, prop_actkeys_clickselect_items);
+ prop= RNA_def_property(ot->srna, "extend_select", PROP_BOOLEAN, PROP_NONE); // SHIFTKEY
+ prop= RNA_def_property(ot->srna, "column_select", PROP_BOOLEAN, PROP_NONE); // CTRLKEY
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 7c56af53397..fec2e28fa0e 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -188,7 +188,7 @@ static void action_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_grid_free(grid);
/* data */
- if ((ANIM_animdata_get_context(C, &ac)) && (ac.data)) {
+ if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_strips(&ac, saction, ar);
}
@@ -243,7 +243,7 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar)
UI_view2d_view_ortho(C, v2d);
/* data */
- if ((ANIM_animdata_get_context(C, &ac)) && (ac.data)) {
+ if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_names(&ac, saction, ar);
}
diff --git a/source/blender/editors/space_ipo/space_ipo.c b/source/blender/editors/space_ipo/space_ipo.c
index 99b0ebcf03c..00e446c65a9 100644
--- a/source/blender/editors/space_ipo/space_ipo.c
+++ b/source/blender/editors/space_ipo/space_ipo.c
@@ -88,8 +88,6 @@ static SpaceLink *ipo_new(const bContext *C)
ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
- /* XXX view2d init for channels */
-
/* main area */
ar= MEM_callocN(sizeof(ARegion), "main area for ipo");