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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editaction.c')
-rw-r--r--source/blender/src/editaction.c504
1 files changed, 409 insertions, 95 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index f93a1526e3c..3251cb33b53 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -52,6 +52,7 @@
#include "DNA_mesh_types.h"
#include "DNA_nla_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_gpencil_types.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -90,6 +91,7 @@
#include "BDR_drawaction.h"
#include "BDR_editobject.h"
+#include "BDR_gpencil.h"
#include "mydevice.h"
#include "blendef.h"
@@ -296,6 +298,16 @@ bActListElem *make_new_actlistelem (void *data, short datatype, void *owner, sho
ale->datatype= ALE_IPO;
}
break;
+ case ACTTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl= (bGPDlayer *)data;
+
+ ale->flag= gpl->flag;
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_GPFRAME;
+ }
+ break;
}
}
@@ -505,6 +517,29 @@ static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mo
}
}
+static void actdata_filter_gpencil (ListBase *act_data, bGPdata *gpd, int filter_mode)
+{
+ bActListElem *ale;
+ bGPDlayer *gpl;
+
+ /* check if filtering types are appropriate */
+ if ( !(filter_mode & (ACTFILTER_IPOKEYS|ACTFILTER_ONLYICU|ACTFILTER_ACTGROUPED)) )
+ {
+ /* loop over layers as the conditions are acceptable */
+ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+ /* only if selected */
+ if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) {
+ /* only if editable */
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
+ /* add to list */
+ ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, NULL, ACTTYPE_NONE);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+ }
+}
+
/* This function filters the active data source to leave only the desired
* data types. 'Public' api call.
* *act_data: is a pointer to a ListBase, to which the filtered action data
@@ -525,6 +560,9 @@ void actdata_filter (ListBase *act_data, int filter_mode, void *data, short data
case ACTCONT_SHAPEKEY:
actdata_filter_shapekey(act_data, data, filter_mode);
break;
+ case ACTCONT_GPENCIL:
+ actdata_filter_gpencil(act_data, data, filter_mode);
+ break;
}
/* remove any weedy entries */
@@ -743,6 +781,10 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b
bActionGroup *agrp= (bActionGroup *)ale->data;
agroup_to_keylist(agrp, &act_keys, NULL, NULL);
}
+ else if (ale->type == ACTTYPE_GPLAYER) {
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+ gpl_to_keylist(gpl, &act_keys, NULL, NULL);
+ }
/* loop through keyframes, finding one that was clicked on */
for (ak= act_keys.first; ak; ak= ak->next) {
@@ -766,6 +808,10 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b
data = ale->key_data;
*ret_type= ACTTYPE_ICU;
}
+ else if (datatype == ACTCONT_GPENCIL) {
+ data = ale->data;
+ *ret_type= ACTTYPE_GPLAYER;
+ }
/* cleanup tempolary lists */
BLI_freelistN(&act_keys);
@@ -795,17 +841,43 @@ void *get_action_context (short *datatype)
act = (G.saction)? G.saction->action: NULL;
key = get_action_mesh_key();
- if (act) {
- *datatype= ACTCONT_ACTION;
- return act;
- }
- else if (key) {
- *datatype= ACTCONT_SHAPEKEY;
- return key;
+ /* check mode selector */
+ if (G.saction) {
+ switch (G.saction->mode) {
+ case SACTCONT_ACTION:
+ *datatype= ACTCONT_ACTION;
+ return act;
+
+ case SACTCONT_SHAPEKEY:
+ *datatype= ACTCONT_SHAPEKEY;
+ return key;
+
+ case SACTCONT_GPENCIL:
+ *datatype= ACTCONT_GPENCIL;
+ if (G.saction->pin)
+ return G.saction->gpd;
+ else
+ return gpencil_data_getetime(G.curscreen);
+
+ default: /* includes SACTCONT_DOPESHEET for now */
+ *datatype= ACTCONT_NONE;
+ return NULL;
+ }
}
else {
- *datatype= ACTCONT_NONE;
- return NULL;
+ /* resort to guessing based on what is available */
+ if (act) {
+ *datatype= ACTCONT_ACTION;
+ return act;
+ }
+ else if (key) {
+ *datatype= ACTCONT_SHAPEKEY;
+ return key;
+ }
+ else {
+ *datatype= ACTCONT_NONE;
+ return NULL;
+ }
}
}
@@ -1114,6 +1186,38 @@ void action_groups_ungroup (void)
allqueue(REDRAWACTION, 0);
}
+/* Copy colors from a specified theme's color set to an Action/Bone Group */
+void actionbone_group_copycolors (bActionGroup *grp, short init_new)
+{
+ /* error checking */
+ if (grp == NULL)
+ return;
+
+ /* only do color copying if using a custom color */
+ if (grp->customCol) {
+ if (grp->customCol > 0) {
+ /* copy theme colors on-to group's custom color in case user tries to edit color */
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+
+ memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
+ }
+ else if (init_new) {
+ /* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */
+ if (grp->cs.solid[0] == 0) {
+ /* define for setting colors in theme below */
+ #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+
+ SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
+ SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
+ SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
+
+ #undef SETCOL
+ }
+ }
+ }
+}
+
/* This function is used when inserting keyframes for pose-channels. It assigns the
* action-channel with the nominated name to a group with the same name as that of
* the pose-channel with the nominated name.
@@ -1160,34 +1264,9 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
/* copy name */
sprintf(grp->name, agrp->name);
- /* deal with group-color copying */
- if (agrp->customCol) {
- if (agrp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(agrp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (agrp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- else {
- /* just copy color set specified */
- memcpy(&grp->cs, &agrp->cs, sizeof(ThemeWireColor));
- }
- }
- }
- grp->customCol= agrp->customCol;
+ /* deal with group-color copying (grp is destination, agrp is source) */
+ memcpy(grp, agrp, sizeof(bActionGroup));
+ actionbone_group_copycolors(grp, 1);
BLI_addtail(&act->groups, grp);
}
@@ -1300,12 +1379,18 @@ void duplicate_action_keys (void)
if (data == NULL) return;
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* loop through filtered data and duplicate selected keys */
for (ale= act_data.first; ale; ale= ale->next) {
- duplicate_ipo_keys((Ipo *)ale->key_data);
+ if (ale->type == ACTTYPE_GPLAYER)
+ duplicate_gplayer_frames(ale->data);
+ else
+ duplicate_ipo_keys((Ipo *)ale->key_data);
}
/* free filtered list */
@@ -1391,7 +1476,10 @@ void snap_action_keys(short mode)
}
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* snap to frame */
@@ -1401,6 +1489,8 @@ void snap_action_keys(short mode)
snap_ipo_keys(ale->key_data, mode);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
+ else if (ale->type == ACTTYPE_GPLAYER)
+ snap_gplayer_frames(ale->data, mode);
else
snap_ipo_keys(ale->key_data, mode);
}
@@ -1414,6 +1504,7 @@ void snap_action_keys(short mode)
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
/* this function is responsible for snapping keyframes to frame-times */
@@ -1449,7 +1540,10 @@ void mirror_action_keys(short mode)
}
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* mirror */
@@ -1459,6 +1553,8 @@ void mirror_action_keys(short mode)
mirror_ipo_keys(ale->key_data, mode);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
+ else if (ale->type == ACTTYPE_GPLAYER)
+ mirror_gplayer_frames(ale->data, mode);
else
mirror_ipo_keys(ale->key_data, mode);
}
@@ -1543,6 +1639,10 @@ void insertkey_action(void)
}
}
}
+ else {
+ /* this tool is not supported in this mode */
+ return;
+ }
BIF_undo_push("Insert Key");
allspace(REMAKEIPO, 0);
@@ -1566,12 +1666,18 @@ void delete_action_keys (void)
if (data == NULL) return;
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* loop through filtered data and delete selected keys */
for (ale= act_data.first; ale; ale= ale->next) {
- delete_ipo_keys((Ipo *)ale->key_data);
+ if (ale->type == ACTTYPE_GPLAYER)
+ delete_gplayer_frames((bGPDlayer *)ale->data);
+ else
+ delete_ipo_keys((Ipo *)ale->key_data);
}
/* free filtered list */
@@ -1692,6 +1798,7 @@ void clean_action (void)
0.0000001f, 1.0, 0.001, 0.1,
"Clean Threshold");
if (!ok) return;
+ if (datatype == ACTCONT_GPENCIL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_SEL | ACTFILTER_ONLYICU);
@@ -1730,6 +1837,7 @@ void sample_action_keys (void)
/* sanity checks */
data= get_action_context(&datatype);
if (data == NULL) return;
+ if (datatype == ACTCONT_GPENCIL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
@@ -2089,6 +2197,7 @@ void action_set_ipo_flags (short mode, short event)
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
+ if (datatype == ACTCONT_GPENCIL) return;
/* determine which set of processing we are doing */
switch (mode) {
@@ -2187,6 +2296,7 @@ void sethandles_action_keys (int code)
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
+ if (datatype == ACTCONT_GPENCIL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
@@ -2225,11 +2335,12 @@ static void numbuts_action ()
bConstraintChannel *conchan= NULL;
IpoCurve *icu= NULL;
KeyBlock *kb= NULL;
+ bGPDlayer *gpl= NULL;
short mval[2];
int but=0;
- char str[64];
+ char str[128];
short expand, protect, mute;
float slidermin, slidermax;
@@ -2338,6 +2449,18 @@ static void numbuts_action ()
add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Group is Expanded");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Group is Protected");
}
+ else if (chantype == ACTTYPE_GPLAYER) {
+ /* Grease-Pencil Layer */
+ gpl= (bGPDlayer *)act_channel;
+
+ strcpy(str, gpl->info);
+ protect= (gpl->flag & GP_LAYER_LOCKED);
+ mute = (gpl->flag & GP_LAYER_HIDE);
+
+ add_numbut(but++, TEX, "GP-Layer: ", 0, 128, str, "Name of Grease Pencil Layer");
+ add_numbut(but++, TOG|SHO, "Hide", 0, 24, &mute, "Grease Pencil Layer is Visible");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Grease Pencil Layer is Protected");
+ }
else {
/* nothing under-cursor */
return;
@@ -2386,6 +2509,16 @@ static void numbuts_action ()
if (protect) agrp->flag |= AGRP_PROTECTED;
else agrp->flag &= ~AGRP_PROTECTED;
}
+ else if (gpl) {
+ strcpy(gpl->info, str);
+ BLI_uniquename(&( ((bGPdata *)data)->layers ), gpl, "GP_Layer", offsetof(bGPDlayer, info), 128);
+
+ if (mute) gpl->flag |= GP_LAYER_HIDE;
+ else gpl->flag &= ~GP_LAYER_HIDE;;
+
+ if (protect) gpl->flag |= GP_LAYER_LOCKED;
+ else gpl->flag &= ~GP_LAYER_LOCKED;
+ }
allqueue(REDRAWACTION, 0);
allspace(REMAKEIPO, 0);
@@ -2517,6 +2650,31 @@ void setflag_action_channels (short mode)
}
}
break;
+ case ACTTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+
+ /* 'protect' and 'mute' */
+ if (val == 2) {
+ /* mute */
+ if (mode == 2)
+ gpl->flag &= ~GP_LAYER_HIDE;
+ else if (mode == 1)
+ gpl->flag |= GP_LAYER_HIDE;
+ else
+ gpl->flag ^= GP_LAYER_HIDE;
+ }
+ else if (val == 1) {
+ /* protected */
+ if (mode == 2)
+ gpl->flag &= ~GP_LAYER_LOCKED;
+ else if (mode == 1)
+ gpl->flag |= GP_LAYER_LOCKED;
+ else
+ gpl->flag ^= GP_LAYER_LOCKED;
+ }
+ }
+ break;
}
}
BLI_freelistN(&act_data);
@@ -2557,7 +2715,7 @@ static void select_action_group (bAction *act, bActionGroup *agrp, int selectmod
set_active_actiongroup(act, agrp, select);
}
-static void hilight_channel(bAction *act, bActionChannel *achan, short select)
+static void hilight_channel (bAction *act, bActionChannel *achan, short select)
{
bActionChannel *curchan;
@@ -2630,7 +2788,7 @@ void select_actionchannel_by_name (bAction *act, char *name, int select)
/* exported for outliner (ton) */
/* apparently within active object context */
-int select_channel(bAction *act, bActionChannel *achan, int selectmode)
+int select_channel (bAction *act, bActionChannel *achan, int selectmode)
{
/* Select the channel based on the selection mode */
int flag;
@@ -2654,9 +2812,9 @@ int select_channel(bAction *act, bActionChannel *achan, int selectmode)
return flag;
}
-static int select_constraint_channel(bAction *act,
- bConstraintChannel *conchan,
- int selectmode)
+static int select_constraint_channel (bAction *act,
+ bConstraintChannel *conchan,
+ int selectmode)
{
/* Select the constraint channel based on the selection mode */
int flag;
@@ -2677,7 +2835,7 @@ static int select_constraint_channel(bAction *act,
return flag;
}
-int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
+int select_icu_channel (bAction *act, IpoCurve *icu, int selectmode)
{
/* Select the channel based on the selection mode */
int flag;
@@ -2697,6 +2855,51 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
return flag;
}
+int select_gplayer_channel (bGPdata *gpd, bGPDlayer *gpl, int selectmode)
+{
+ /* Select the channel based on the selection mode */
+ int flag;
+
+ switch (selectmode) {
+ case SELECT_ADD:
+ gpl->flag |= GP_LAYER_SELECT;
+ break;
+ case SELECT_SUBTRACT:
+ gpl->flag &= ~GP_LAYER_SELECT;
+ break;
+ case SELECT_INVERT:
+ gpl->flag ^= GP_LAYER_SELECT;
+ break;
+ }
+ flag = (gpl->flag & GP_LAYER_SELECT) ? 1 : 0;
+
+ gpencil_layer_setactive(gpd, gpl);
+
+ return flag;
+}
+
+
+/* select only the active action-group's action channels */
+void select_action_group_channels (bAction *act, bActionGroup *agrp)
+{
+ bActionChannel *achan;
+
+ /* error checking */
+ if (ELEM(NULL, act, agrp))
+ return;
+
+ /* deselect all other channels */
+ deselect_actionchannels(act, 0);
+
+ /* only select channels in group */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_channel(act, achan, SELECT_ADD);
+
+ /* messy... set active bone */
+ select_poseelement_by_name(achan->name, 1);
+ }
+}
+
/* ----------------------------------------- */
/* De-selects or inverts the selection of Channels in a given Action
@@ -2819,6 +3022,8 @@ void deselect_action_channels (short mode)
/* based on type */
if (datatype == ACTCONT_ACTION)
deselect_actionchannels(data, mode);
+ else if (datatype == ACTCONT_GPENCIL)
+ deselect_gpencil_layers(data, mode);
// should shapekey channels be allowed to do this?
}
@@ -2834,24 +3039,40 @@ void deselect_action_keys (short test, short sel)
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
-
+
+ /* determine type-based settings */
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* See if we should be selecting or deselecting */
if (test) {
for (ale= act_data.first; ale; ale= ale->next) {
- if (is_ipo_key_selected(ale->key_data)) {
- sel= 0;
- break;
+ if (ale->type == ACTTYPE_GPLAYER) {
+ if (is_gplayer_frame_selected(ale->data)) {
+ sel= 0;
+ break;
+ }
+ }
+ else {
+ if (is_ipo_key_selected(ale->key_data)) {
+ sel= 0;
+ break;
+ }
}
}
}
/* Now set the flags */
for (ale= act_data.first; ale; ale= ale->next) {
- set_ipo_key_selection(ale->key_data, sel);
+ if (ale->type == ACTTYPE_GPLAYER)
+ set_gplayer_frame_selection(ale->data, sel);
+ else
+ set_ipo_key_selection(ale->key_data, sel);
}
/* Cleanup */
@@ -2917,6 +3138,12 @@ void selectall_action_keys (short mval[], short mode, short select_mode)
select_icu_bezier_keys(icu, select_mode);
}
break;
+ case ACTTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl= (bGPDlayer *)act_channel;
+ select_gpencil_frames(gpl, select_mode);
+ }
+ break;
}
}
break;
@@ -2942,12 +3169,16 @@ void selectall_action_keys (short mval[], short mode, short select_mode)
rectf.xmax = rectf.xmax + 0.5;
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* Now set the flags */
- for (ale= act_data.first; ale; ale= ale->next)
+ for (ale= act_data.first; ale; ale= ale->next) {
borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, select_mode);
+ }
/* Cleanup */
BLI_freelistN(&act_data);
@@ -3029,19 +3260,23 @@ void selectkeys_leftright (short leftright, short select_mode)
}
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* select keys on the side where most data occurs */
for (ale= act_data.first; ale; ale= ale->next) {
- if(NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
- else {
+ else if (ale->type == ACTTYPE_GPLAYER)
+ borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD);
+ else
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
- }
}
/* Cleanup */
@@ -3079,7 +3314,10 @@ void nextprev_action_keyframe (short dir)
return;
/* get list of keyframes that can be used (in global-time) */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
for (ale= act_data.first; ale; ale= ale->next) {
@@ -3088,6 +3326,8 @@ void nextprev_action_keyframe (short dir)
make_cfra_list(ale->key_data, &elems);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
+ else if (ale->type == ACTTYPE_GPLAYER)
+ gplayer_make_cfra_list(ale->key_data, &elems, 0);
else
make_cfra_list(ale->key_data, &elems);
}
@@ -3170,11 +3410,20 @@ void column_select_action_keys (int mode)
/* build list of columns */
switch (mode) {
case 1: /* list of selected keys */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
- actdata_filter(&act_data, filter, data, datatype);
-
- for (ale= act_data.first; ale; ale= ale->next)
- make_sel_cfra_list(ale->key_data, &elems);
+ if (datatype == ACTCONT_GPENCIL) {
+ filter= (ACTFILTER_VISIBLE);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next)
+ gplayer_make_cfra_list(ale->data, &elems, 1);
+ }
+ else {
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next)
+ make_sel_cfra_list(ale->key_data, &elems);
+ }
BLI_freelistN(&act_data);
break;
@@ -3202,19 +3451,34 @@ void column_select_action_keys (int mode)
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- filter= (ACTFILTER_VISIBLE | ACTFILTER_ONLYICU);
+ if (datatype == ACTCONT_GPENCIL)
+ filter= (ACTFILTER_VISIBLE);
+ else
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_ONLYICU);
actdata_filter(&act_data, filter, data, datatype);
for (ale= act_data.first; ale; ale= ale->next) {
for (ce= elems.first; ce; ce= ce->next) {
- for (icu= ale->key_data; icu; icu= icu->next) {
- BezTriple *bezt;
- int verts = 0;
+ /* select elements with frame number matching cfraelem */
+ if (ale->type == ACTTYPE_GPLAYER) {
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+ bGPDframe *gpf;
- for (bezt=icu->bezt; verts<icu->totvert; bezt++, verts++) {
- if (bezt) {
- if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) )
- bezt->f2 |= 1;
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+ if ( (int)ce->cfra == gpf->framenum )
+ gpf->flag |= GP_FRAME_SELECT;
+ }
+ }
+ else {
+ for (icu= ale->key_data; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int verts = 0;
+
+ for (bezt=icu->bezt; verts<icu->totvert; bezt++, verts++) {
+ if (bezt) {
+ if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) )
+ bezt->f2 |= 1;
+ }
}
}
}
@@ -3243,7 +3507,7 @@ void borderselect_actionchannels (void)
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
- if (datatype != ACTCONT_ACTION) return;
+ if (ELEM(datatype, ACTCONT_ACTION, ACTCONT_GPENCIL)==0) return;
/* draw and handle the borderselect stuff (ui) and get the select rect */
if ( (val = get_border(&rect, 3)) ) {
@@ -3315,6 +3579,16 @@ void borderselect_actionchannels (void)
icu->flag &= ~IPO_SELECT;
}
break;
+ case ACTTYPE_GPLAYER: /* grease-pencil layer */
+ {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ if (selectmode == SELECT_ADD)
+ gpl->flag |= GP_LAYER_SELECT;
+ else
+ gpl->flag &= ~GP_LAYER_SELECT;
+ }
+ break;
}
/* select action-channel 'owner' */
@@ -3431,6 +3705,9 @@ void borderselect_action (void)
borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
}
}
+ else if (ale->type == ACTTYPE_GPLAYER) {
+ borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ }
break;
case ACTEDIT_BORDERSEL_CHA: /* all in channel(s) */
if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
@@ -3452,6 +3729,9 @@ void borderselect_action (void)
select_ipo_bezier_keys(conchan->ipo, selectmode);
}
}
+ else if (ale->type == ACTTYPE_GPLAYER) {
+ select_gpencil_frames(ale->data, selectmode);
+ }
}
break;
default: /* any keyframe inside region defined by region */
@@ -3474,6 +3754,9 @@ void borderselect_action (void)
borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
}
}
+ else if (ale->type == ACTTYPE_GPLAYER) {
+ borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
+ }
}
}
@@ -3504,6 +3787,8 @@ static void mouse_action (int selectmode)
bActionChannel *achan= NULL;
bConstraintChannel *conchan= NULL;
IpoCurve *icu= NULL;
+ bGPdata *gpd = NULL;
+ bGPDlayer *gpl = NULL;
TimeMarker *marker, *pmarker;
void *act_channel;
@@ -3514,6 +3799,7 @@ static void mouse_action (int selectmode)
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype == ACTCONT_ACTION) act= (bAction *)data;
+ if (datatype == ACTCONT_GPENCIL) gpd= (bGPdata *)data;
act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
marker= find_nearest_marker(SCE_MARKERS, 1);
@@ -3586,6 +3872,9 @@ static void mouse_action (int selectmode)
case ACTTYPE_GROUP:
agrp= (bActionGroup *)act_channel;
break;
+ case ACTTYPE_GPLAYER:
+ gpl= (bGPDlayer *)act_channel;
+ break;
default:
return;
}
@@ -3609,6 +3898,13 @@ static void mouse_action (int selectmode)
set_active_actiongroup(act, agrp, 1);
}
}
+ else if (datatype == ACTCONT_GPENCIL) {
+ deselect_action_channels(0);
+
+ /* Highlight gpencil layer */
+ gpl->flag |= GP_LAYER_SELECT;
+ gpencil_layer_setactive(gpd, gpl);
+ }
}
if (icu)
@@ -3625,6 +3921,8 @@ static void mouse_action (int selectmode)
select_ipo_key(conchan->ipo, selx, selectmode);
}
}
+ else if (gpl)
+ select_gpencil_frame(gpl, selx, selectmode);
std_rmouse_transform(transform_action_keys);
@@ -3641,6 +3939,7 @@ static void mouse_action (int selectmode)
static void mouse_actionchannels (short mval[])
{
bAction *act= G.saction->action;
+ bGPdata *gpd= G.saction->gpd;
void *data, *act_channel;
short datatype, chantype;
@@ -3672,17 +3971,8 @@ static void mouse_actionchannels (short mval[])
select_action_group(act, agrp, SELECT_INVERT);
}
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
- bActionChannel *achan;
-
/* select all in group (and deselect everthing else) */
- deselect_actionchannels(act, 0);
-
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- select_channel(act, achan, SELECT_ADD);
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 1);
- }
+ select_action_group_channels(act, agrp);
select_action_group(act, agrp, SELECT_ADD);
}
else {
@@ -3796,6 +4086,24 @@ static void mouse_actionchannels (short mval[])
}
}
break;
+ case ACTTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl= (bGPDlayer *)act_channel;
+
+ if (mval[0] >= (NAMEWIDTH-16)) {
+ /* toggle lock */
+ gpl->flag ^= GP_LAYER_LOCKED;
+ }
+ else if (mval[0] >= (NAMEWIDTH-32)) {
+ /* toggle hide */
+ gpl->flag ^= GP_LAYER_HIDE;
+ }
+ else {
+ /* select/deselect */
+ select_gplayer_channel(gpd, gpl, SELECT_INVERT);
+ }
+ }
+ break;
default:
return;
}
@@ -4462,7 +4770,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case RIGHTMOUSE:
/* Clicking in the channel area */
if ((G.v2d->mask.xmin) && (mval[0] < NAMEWIDTH)) {
- if (datatype == ACTCONT_ACTION) {
+ if (ELEM(datatype, ACTCONT_ACTION, ACTCONT_GPENCIL)) {
/* mouse is over action channels */
if (G.qual == LR_CTRLKEY)
numbuts_action();
@@ -4682,11 +4990,13 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case NKEY:
if (G.qual==0) {
- numbuts_action();
-
- /* no panel (yet). current numbuts are not easy to put in panel... */
- //add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
- //scrarea_queue_winredraw(curarea);
+ /* panel will not always show useful info! */
+ if (mval[0] > ACTWIDTH) {
+ add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
+ scrarea_queue_winredraw(curarea);
+ }
+ else
+ numbuts_action();
}
break;
@@ -4810,8 +5120,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DELKEY:
case XKEY:
if (okee("Erase selected")) {
- if (mval[0] < NAMEWIDTH)
- delete_action_channels();
+ if (mval[0] < NAMEWIDTH) {
+ if (datatype == ACTCONT_ACTION)
+ delete_action_channels();
+ else if (datatype == ACTCONT_GPENCIL)
+ delete_gpencil_layers();
+ }
else
delete_action_keys();