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:
authorJoshua Leung <aligorith@gmail.com>2011-01-11 01:10:28 +0300
committerJoshua Leung <aligorith@gmail.com>2011-01-11 01:10:28 +0300
commitcf25b10eb5bb61662ce0db6b3ef54a3e3e73a328 (patch)
tree0d7ffcdd0735d1788bfb3e679b6f7489605c1aab /source/blender/editors/animation
parentd841a206314922eec0a0fed0b87e3078b68487c9 (diff)
Todo #22395: Restoring Grease Pencil Editing Mode in DopeSheet Editor
This commit restores some basic functionality for retiming Grease Pencil sketches. Some of the functionality that existed before still hasn't been restored (namely snap/mirror tools as well as copy+paste), though it should be possible to use this for basic retiming and sketch-frame management again. - There's still a lot of work required to get this up to the standard of the rest of the animation editor code, as some of this code was originally just hacked in based on the old-style code. - Work is already required to not have to directly access the main db global to get the list of Grease Pencil datablocks to show, but that can come along with pending cleanups of the filtering code.
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c259
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c50
-rw-r--r--source/blender/editors/animation/anim_filter.c44
-rw-r--r--source/blender/editors/animation/keyframes_draw.c70
4 files changed, 246 insertions, 177 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 298fd9102ec..66f574a4b70 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -49,6 +49,7 @@
#include "DNA_meta_types.h"
#include "DNA_node_types.h"
#include "DNA_world_types.h"
+#include "DNA_gpencil_types.h"
#include "RNA_access.h"
@@ -2404,126 +2405,157 @@ static bAnimChannelType ACF_SHAPEKEY=
acf_shapekey_setting_ptr /* pointer for setting */
};
-/* Grease Pencil entries ------------------------------------------- */
-// XXX ... this is currently not restored yet
+/* GPencil Datablock ------------------------------------------- */
-#if 0
-static void dummy_olddraw_gpencil ()
+/* get backdrop color for gpencil datablock widget */
+static void acf_gpd_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float *color)
{
- /* determine what needs to be drawn */
- switch (ale->type) {
- case ANIMTYPE_GPDATABLOCK: /* gpencil datablock */
- {
- bGPdata *gpd = (bGPdata *)ale->data;
- ScrArea *sa = (ScrArea *)ale->owner; // XXX depreceated...
-
- indent = 0;
- group= 3;
+ /* highlight only for datablock channels */
+ //if (ale->flag & AGRP_ACTIVE)
+ // UI_GetThemeColorShade3fv(TH_GROUP_ACTIVE, 10, color);
+ //else
+ UI_GetThemeColorShade3fv(TH_GROUP, 20, color);
+}
+
+// TODO: just get this from RNA?
+static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
+{
+ return ICON_GREASEPENCIL;
+}
+
+/* check if some setting exists for this channel */
+static short acf_gpd_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting)
+{
+ switch (setting) {
+ /* only select and expand supported */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return 1;
- /* only show expand if there are any channels */
- if (gpd->layers.first) {
- if (gpd->flag & GP_DATA_EXPAND)
- expand = ICON_TRIA_DOWN;
- else
- expand = ICON_TRIA_RIGHT;
- }
+ default:
+ return 0;
+ }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_gpd_setting_flag(bAnimContext *ac, int setting, short *neg)
+{
+ /* clear extra return data first */
+ *neg= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return AGRP_SELECTED;
- switch (sa->spacetype) {
- case SPACE_VIEW3D:
- {
- /* this shouldn't cause any overflow... */
- //sprintf(name, "View3D:%s", view3d_get_name(sa->spacedata.first)); // XXX missing func..
- strcpy(name, "View3D");
- special= ICON_VIEW3D;
- }
- break;
- case SPACE_NODE:
- {
- SpaceNode *snode= sa->spacedata.first;
- char treetype[12];
-
- if (snode->treetype == 1)
- strcpy(treetype, "Composite");
- else
- strcpy(treetype, "Material");
- sprintf(name, "Nodes:%s", treetype);
-
- special= ICON_NODETREE;
- }
- break;
- case SPACE_SEQ:
- {
- SpaceSeq *sseq= sa->spacedata.first;
- char imgpreview[10];
-
- switch (sseq->mainb) {
- case 1: sprintf(imgpreview, "Image..."); break;
- case 2: sprintf(imgpreview, "Luma..."); break;
- case 3: sprintf(imgpreview, "Chroma..."); break;
- case 4: sprintf(imgpreview, "Histogram"); break;
-
- default: sprintf(imgpreview, "Sequence"); break;
- }
- sprintf(name, "Sequencer:%s", imgpreview);
-
- special= ICON_SEQUENCE;
- }
- break;
- case SPACE_IMAGE:
- {
- SpaceImage *sima= sa->spacedata.first;
-
- if (sima->image)
- sprintf(name, "Image:%s", sima->image->id.name+2);
- else
- strcpy(name, "Image:<None>");
-
- special= ICON_IMAGE_COL;
- }
- break;
-
- default:
- {
- sprintf(name, "<Unknown GP-Data Source>");
- special= -1;
- }
- break;
- }
- }
- break;
- case ANIMTYPE_GPLAYER: /* gpencil layer */
- {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GP_DATA_EXPAND;
+ }
+
+ /* this shouldn't happen */
+ return 0;
+}
+
+/* get pointer to the setting */
+static void *acf_gpd_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+{
+ bGPdata *gpd= (bGPdata *)ale->data;
+
+ /* all flags are just in gpd->flag for now... */
+ GET_ACF_FLAG_PTR(gpd->flag);
+}
+
+/* gpencil datablock type define */
+static bAnimChannelType ACF_GPD =
+{
+ "GPencil Datablock", /* type name */
+
+ acf_gpd_color, /* backdrop color */
+ acf_group_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_gpd_icon, /* icon */
+
+ acf_gpd_setting_valid, /* has setting */
+ acf_gpd_setting_flag, /* flag for setting */
+ acf_gpd_setting_ptr /* pointer for setting */
+};
+
+/* GPencil Layer ------------------------------------------- */
+
+/* name for grase pencil layer entries */
+static void acf_gpl_name(bAnimListElem *ale, char *name)
+{
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ if (gpl && name)
+ sprintf(name, gpl->info);
+}
+
+/* check if some setting exists for this channel */
+static short acf_gpl_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+ switch (setting) {
+ /* unsupported */
+ case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
+ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
+ return 0;
+
+ /* always available */
+ default:
+ return 1;
+ }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
+{
+ /* clear extra return data first */
+ *neg= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return GP_LAYER_SELECT;
- indent = 0;
- special = -1;
- expand = -1;
- group = 1;
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ return GP_LAYER_HIDE;
- if (EDITABLE_GPL(gpl))
- protect = ICON_UNLOCKED;
- else
- protect = ICON_LOCKED;
-
- if (gpl->flag & GP_LAYER_HIDE)
- mute = ICON_MUTE_IPO_ON;
- else
- mute = ICON_MUTE_IPO_OFF;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ //*neg= 1; - if we change this to edtiability
+ return GP_LAYER_LOCKED;
- sel = SEL_GPL(gpl);
- BLI_snprintf(name, 32, gpl->info);
- }
- break;
- }
-
- if (group == 3) {
- /* only for gp-data channels */
- UI_ThemeColorShade(TH_GROUP, 20);
- uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
- gl_round_box(GL_POLYGON, x+offset, yminc, (float)ACHANNEL_NAMEWIDTH, ymaxc, 8);
+ default: /* unsupported */
+ return 0;
}
}
-#endif
+
+/* get pointer to the setting */
+static void *acf_gpl_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type)
+{
+ bGPDlayer *gpl= (bGPDlayer *)ale->data;
+
+ /* all flags are just in agrp->flag for now... */
+ GET_ACF_FLAG_PTR(gpl->flag);
+}
+
+/* grease pencil layer type define */
+static bAnimChannelType ACF_GPL =
+{
+ "GPencil Layer", /* type name */
+
+ acf_generic_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_gpl_name, /* name */
+ NULL, /* icon */
+
+ acf_gpl_setting_valid, /* has setting */
+ acf_gpl_setting_flag, /* flag for setting */
+ acf_gpl_setting_ptr /* pointer for setting */
+};
/* *********************************************** */
/* Type Registration and General Access */
@@ -2574,9 +2606,8 @@ void ANIM_init_channel_typeinfo_data (void)
animchannelTypeInfo[type++]= &ACF_SHAPEKEY; /* ShapeKey */
- // XXX not restored yet
- animchannelTypeInfo[type++]= NULL; /* Grease Pencil Datablock */
- animchannelTypeInfo[type++]= NULL; /* Grease Pencil Layer */
+ animchannelTypeInfo[type++]= &ACF_GPD; /* Grease Pencil Datablock */
+ animchannelTypeInfo[type++]= &ACF_GPL; /* Grease Pencil Layer */
// TODO: these types still need to be implemented!!!
// probably need a few extra flags for these special cases...
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 319f80404b4..6701729f34f 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -245,6 +245,11 @@ void ANIM_deselect_anim_channels (bAnimContext *ac, void *data, short datatype,
sel= ACHANNEL_SETFLAG_CLEAR;
}
break;
+
+ case ANIMTYPE_GPLAYER:
+ if (ale->flag & GP_LAYER_SELECT)
+ sel= ACHANNEL_SETFLAG_CLEAR;
+ break;
}
}
}
@@ -332,6 +337,14 @@ void ANIM_deselect_anim_channels (bAnimContext *ac, void *data, short datatype,
}
}
break;
+
+ case ANIMTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
+ }
+ break;
}
}
@@ -1000,10 +1013,10 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
rearrange_driver_channels(&ac, adt, mode);
break;
-#if 0
case ANIMCONT_GPENCIL: /* Grease Pencil channels */
+ // FIXME: this case probably needs to get moved out of here or treated specially...
+ printf("grease pencil not supported for moving yet\n");
break;
-#endif
case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
@@ -2047,7 +2060,9 @@ static int mouse_anim_channels (bAnimContext *ac, float UNUSED(x), int channel_i
{
bGPdata *gpd= (bGPdata *)ale->data;
- /* toggle expand */
+ /* toggle expand
+ * - although the triangle widget already allows this, the whole channel can also be used for this purpose
+ */
gpd->flag ^= GP_DATA_EXPAND;
notifierFlags |= (ND_ANIMCHAN|NA_EDITED);
@@ -2055,29 +2070,20 @@ static int mouse_anim_channels (bAnimContext *ac, float UNUSED(x), int channel_i
break;
case ANIMTYPE_GPLAYER:
{
-#if 0 // XXX future of this is unclear
- bGPdata *gpd= (bGPdata *)ale->owner; // xxx depreceated
bGPDlayer *gpl= (bGPDlayer *)ale->data;
- if (x >= (ACHANNEL_NAMEWIDTH-16)) {
- /* toggle lock */
- gpl->flag ^= GP_LAYER_LOCKED;
- }
- else if (x >= (ACHANNEL_NAMEWIDTH-32)) {
- /* toggle hide */
- gpl->flag ^= GP_LAYER_HIDE;
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* invert selection status of this layer only */
+ gpl->flag ^= GP_LAYER_SELECT;
}
- else {
- /* select/deselect */
- //if (G.qual & LR_SHIFTKEY) {
- //select_gplayer_channel(gpd, gpl, SELECT_INVERT);
- //}
- //else {
- //deselect_gpencil_layers(data, 0);
- //select_gplayer_channel(gpd, gpl, SELECT_INVERT);
- //}
+ else {
+ /* select layer by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ gpl->flag |= GP_LAYER_SELECT;
}
-#endif // XXX future of this is unclear
+
+ notifierFlags |= (ND_ANIMCHAN|NA_EDITED);
}
break;
default:
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index c61adcd6518..1d54a7e5195 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -79,6 +79,7 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_sequencer.h"
@@ -145,9 +146,11 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
return 1;
case SACTCONT_GPENCIL: /* Grease Pencil */ // XXX review how this mode is handled...
- ac->datatype=ANIMCONT_GPENCIL;
- //ac->data= CTX_wm_screen(C); // FIXME: add that dopesheet type thing here!
- ac->data= NULL; // !!!
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source= (ID *)ac->scene;
+
+ ac->datatype= ANIMCONT_GPENCIL;
+ ac->data= &saction->ads;
ac->mode= saction->mode;
return 1;
@@ -1181,38 +1184,28 @@ static int animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key
return items;
}
-#if 0
-// FIXME: switch this to use the bDopeSheet...
-static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter_mode)
+/* Grab all Grase Pencil datablocks in file */
+// TODO: should this be amalgamated with the dopesheet filtering code?
+static int animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int filter_mode)
{
bAnimListElem *ale;
- ScrArea *sa, *curarea;
bGPdata *gpd;
bGPDlayer *gpl;
int items = 0;
/* check if filtering types are appropriate */
+ if (!(filter_mode & (ANIMFILTER_ACTGROUPED|ANIMFILTER_CURVESONLY)))
{
- /* special hack for fullscreen area (which must be this one then):
- * - we use the curarea->full as screen to get spaces from, since the
- * old (pre-fullscreen) screen was stored there...
- * - this is needed as all data would otherwise disappear
- */
- // XXX need to get new alternative for curarea
- if ((curarea->full) && (curarea->spacetype==SPACE_ACTION))
- sc= curarea->full;
-
- /* loop over spaces in current screen, finding gpd blocks (could be slow!) */
- for (sa= sc->areabase.first; sa; sa= sa->next) {
- /* try to get gp data */
- // XXX need to put back grease pencil api...
- gpd= gpencil_data_get_active(sa);
- if (gpd == NULL) continue;
+ /* for now, grab grease pencil datablocks directly from main*/
+ for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
+ /* only show if gpd is used by something... */
+ if (ID_REAL_USERS(gpd) < 1)
+ continue;
/* add gpd as channel too (if for drawing, and it has layers) */
if ((filter_mode & ANIMFILTER_CHANNELS) && (gpd->layers.first)) {
/* add to list */
- ale= make_new_animlistelem(gpd, ANIMTYPE_GPDATABLOCK, sa, ANIMTYPE_SPECIALDATA);
+ ale= make_new_animlistelem(gpd, ANIMTYPE_GPDATABLOCK, NULL, ANIMTYPE_NONE, NULL);
if (ale) {
BLI_addtail(anim_data, ale);
items++;
@@ -1228,7 +1221,7 @@ static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter
/* only if editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
/* add to list */
- ale= make_new_animlistelem(gpl, ANIMTYPE_GPLAYER, gpd, ANIMTYPE_GPDATABLOCK);
+ ale= make_new_animlistelem(gpl, ANIMTYPE_GPLAYER, gpd, ANIMTYPE_GPDATABLOCK, (ID*)gpd);
if (ale) {
BLI_addtail(anim_data, ale);
items++;
@@ -1243,7 +1236,6 @@ static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter
/* return the number of items added to the list */
return items;
}
-#endif
/* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */
static int animdata_filter_dopesheet_texs (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
@@ -2591,7 +2583,7 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
case ANIMCONT_GPENCIL:
{
- //items= animdata_filter_gpencil(anim_data, data, filter_mode);
+ items= animdata_filter_gpencil(anim_data, data, filter_mode);
}
break;
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 5e7e071954c..12c4baaaa87 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -137,6 +137,49 @@ static void nupdate_ak_bezt (void *node, void *data)
ak->key_type= BEZT_KEYTYPE_KEYFRAME;
}
+/* ......... */
+
+/* Comparator callback used for ActKeyColumns and GPencil frame */
+static short compare_ak_gpframe (void *node, void *data)
+{
+ ActKeyColumn *ak= (ActKeyColumn *)node;
+ bGPDframe *gpf= (bGPDframe *)data;
+
+ if (gpf->framenum < ak->cfra)
+ return -1;
+ else if (gpf->framenum > ak->cfra)
+ return 1;
+ else
+ return 0;
+}
+
+/* New node callback used for building ActKeyColumns from GPencil frames */
+static DLRBT_Node *nalloc_ak_gpframe (void *data)
+{
+ ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ bGPDframe *gpf= (bGPDframe *)data;
+
+ /* store settings based on state of BezTriple */
+ ak->cfra= gpf->framenum;
+ ak->sel= (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
+
+ /* set 'modified', since this is used to identify long keyframes */
+ ak->modified = 1;
+
+ return (DLRBT_Node *)ak;
+}
+
+/* Node updater callback used for building ActKeyColumns from GPencil frames */
+static void nupdate_ak_gpframe (void *node, void *data)
+{
+ ActKeyColumn *ak= (ActKeyColumn *)node;
+ bGPDframe *gpf= (bGPDframe *)data;
+
+ /* set selection status and 'touched' status */
+ if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
+ ak->modified += 1;
+}
+
/* --------------- */
/* Add the given BezTriple to the given 'list' of Keyframes */
@@ -148,6 +191,15 @@ static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt)
BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
}
+/* Add the given GPencil Frame to the given 'list' of Keyframes */
+static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
+{
+ if ELEM(NULL, keys, gpf)
+ return;
+ else
+ BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
+}
+
/* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
/* maximum size of default buffer for BezTriple columns */
@@ -917,23 +969,11 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
{
bGPDframe *gpf;
- ActKeyColumn *ak;
if (gpl && keys) {
- /* loop over frames, converting directly to 'keyframes' (should be in order too) */
- for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
- BLI_addtail((ListBase *)keys, ak);
-
- ak->cfra= (float)gpf->framenum;
- ak->modified = 1;
- ak->key_type= 0;
-
- if (gpf->flag & GP_FRAME_SELECT)
- ak->sel = SELECT;
- else
- ak->sel = 0;
- }
+ /* although the frames should already be in an ordered list, they are not suitable for displaying yet */
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next)
+ add_gpframe_to_keycolumns_list(keys, gpf);
}
}