diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2011-01-16 02:09:52 +0300 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2011-01-16 02:09:52 +0300 |
commit | c7a122aa27662a2fb528663ddd3dd652cdda2010 (patch) | |
tree | a014a8601c20ccd4d48dd82e9b0f88245b4beddd /source/blender/editors/animation | |
parent | bc1e26e4965877533902aa5d0e51537deeb319c4 (diff) | |
parent | 86bbab7de53b07ad9a45b11dbff6bd5c0ee40c14 (diff) |
Merged changes in the trunk up to revision 34335.
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 286 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 50 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 47 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_markers.c | 111 | ||||
-rw-r--r-- | source/blender/editors/animation/drivers.c | 99 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 70 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 2 |
7 files changed, 418 insertions, 247 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index cc1e8bd9eb8..14babe7ce00 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -50,6 +50,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" @@ -80,6 +81,8 @@ /* size of indent steps */ #define INDENT_STEP_SIZE 7 +#define ANIM_CHAN_NAME_SIZE 256 + /* macros used for type defines */ /* get the pointer used for some flag */ #define GET_ACF_FLAG_PTR(ptr) \ @@ -304,7 +307,7 @@ static void acf_generic_idblock_name(bAnimListElem *ale, char *name) /* just copy the name... */ if (id && name) - strcpy(name, id->name+2); + BLI_strncpy(name, id->name+2, ANIM_CHAN_NAME_SIZE); } /* Settings ------------------------------------------- */ @@ -413,7 +416,7 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name) { if (name) - strcpy(name, "DopeSheet Summary"); + BLI_strncpy(name, "DopeSheet Summary", ANIM_CHAN_NAME_SIZE); } // TODO: this is really a temp icon I think @@ -629,7 +632,7 @@ static void acf_object_name(bAnimListElem *ale, char *name) /* just copy the name... */ if (ob && name) - strcpy(name, ob->id.name+2); + BLI_strncpy(name, ob->id.name+2, ANIM_CHAN_NAME_SIZE); } /* check if some setting exists for this channel */ @@ -766,7 +769,7 @@ static void acf_group_name(bAnimListElem *ale, char *name) /* just copy the name... */ if (agrp && name) - strcpy(name, agrp->name); + BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE); } /* check if some setting exists for this channel */ @@ -1026,7 +1029,7 @@ static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale)) static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name) { - strcpy(name, "Drivers"); + BLI_strncpy(name, "Drivers", ANIM_CHAN_NAME_SIZE); } /* check if some setting exists for this channel */ @@ -1104,7 +1107,7 @@ static int acf_fillmatd_icon(bAnimListElem *UNUSED(ale)) static void acf_fillmatd_name(bAnimListElem *UNUSED(ale), char *name) { - strcpy(name, "Materials"); + BLI_strncpy(name, "Materials", ANIM_CHAN_NAME_SIZE); } /* get the appropriate flag(s) for the setting when it is valid */ @@ -1150,7 +1153,7 @@ static int acf_fillpartd_icon(bAnimListElem *UNUSED(ale)) static void acf_fillpartd_name(bAnimListElem *UNUSED(ale), char *name) { - strcpy(name, "Particles"); + BLI_strncpy(name, "Particles", ANIM_CHAN_NAME_SIZE); } /* get the appropriate flag(s) for the setting when it is valid */ @@ -1218,7 +1221,7 @@ static int acf_filltexd_icon(bAnimListElem *UNUSED(ale)) static void acf_filltexd_name(bAnimListElem *UNUSED(ale), char *name) { - strcpy(name, "Textures"); + BLI_strncpy(name, "Textures", ANIM_CHAN_NAME_SIZE); } /* get pointer to the setting (category only) */ @@ -2402,9 +2405,9 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name) if (kb && name) { /* if the KeyBlock had a name, use it, otherwise use the index */ if (kb->name[0]) - strcpy(name, kb->name); + BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE); else - sprintf(name, "Key %d", ale->index); + BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, "Key %d", ale->index); } } @@ -2481,126 +2484,154 @@ 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 *UNUSED(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; + /* these are ID-blocks, but not exactly standalone... */ + UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 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 *UNUSED(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 *UNUSED(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) + BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE); +} + +/* check if some setting exists for this channel */ +static short acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(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 */ @@ -2652,9 +2683,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... @@ -2693,14 +2723,14 @@ void ANIM_channel_debug_print_info (bAnimListElem *ale, short indent_level) /* print info */ if (acf) { - char name[256]; /* hopefully this will be enough! */ + char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */ /* get UI name */ if (acf->name) acf->name(ale, name); else - sprintf(name, "<No name>"); - + BLI_strncpy(name, "<No name>", sizeof(name)); + /* print type name + ui name */ printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name); } @@ -2932,7 +2962,7 @@ void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float /* step 5) draw name ............................................... */ if (acf->name) { - char name[256]; /* hopefully this will be enough! */ + char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */ /* set text color */ if (selected) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index f4e3602343f..65444f20c31 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -246,6 +246,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; } } } @@ -334,6 +339,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; } } @@ -1002,10 +1015,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... @@ -2050,7 +2063,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); @@ -2058,29 +2073,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 91af5534eaa..04f81dd62f2 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -80,12 +80,14 @@ #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" #include "BKE_utildefines.h" #include "ED_anim_api.h" +#include "ED_markers.h" /* ************************************************************ */ /* Blender Context <-> Animation Context mapping */ @@ -146,9 +148,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; @@ -304,7 +308,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac) /* get useful default context settings from context */ ac->scene= scene; if (scene) { - ac->markers= &scene->markers; + ac->markers= ED_context_get_markers(C); ac->obact= (scene->basact)? scene->basact->object : NULL; } ac->sa= sa; @@ -1195,38 +1199,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++; @@ -1242,7 +1236,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++; @@ -1257,7 +1251,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) @@ -2721,7 +2714,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/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 80b026ddd6e..e1a3d8d2fa0 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -57,6 +57,7 @@ #include "UI_view2d.h" #include "UI_resources.h" +#include "ED_anim_api.h" #include "ED_markers.h" #include "ED_screen.h" #include "ED_util.h" @@ -66,21 +67,44 @@ /* ************* Marker API **************** */ -static ListBase *context_get_markers(const bContext *C) +/* helper function for getting the list of markers to work on */ +static ListBase *context_get_markers(Scene *scene, ScrArea *sa) { - -#if 0 - /* XXX get them from pose */ - if ((slink->spacetype == SPACE_ACTION) && (saction->flag & SACTION_POSEMARKERS_MOVE)) { - if (saction->action) - markers= &saction->action->markers; - else - markers= NULL; + /* local marker sets... */ + if (sa) { + if (sa->spacetype == SPACE_ACTION) { + SpaceAction *saction = (SpaceAction *)sa->spacedata.first; + + /* local markers can only be shown when there's only a single active action to grab them from + * - flag only takes effect when there's an action, otherwise it can get too confusing? + */ + if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) + { + if (saction->flag & SACTION_POSEMARKERS_SHOW) + return &saction->action->markers; + } + } } - else -#endif - return &CTX_data_scene(C)->markers; + /* default to using the scene's markers */ + return &scene->markers; +} + +/* ............. */ + +/* public API for getting markers from context */ +ListBase *ED_context_get_markers(const bContext *C) +{ + return context_get_markers(CTX_data_scene(C), CTX_wm_area(C)); +} + +/* public API for getting markers from "animation" context */ +ListBase *ED_animcontext_get_markers(const bAnimContext *ac) +{ + if (ac) + return context_get_markers(ac->scene, ac->sa); + else + return NULL; } /* --------------------------------- */ @@ -336,7 +360,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) /* Draw Scene-Markers in time window */ void draw_markers_time(const bContext *C, int flag) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); View2D *v2d= UI_view2d_fromcontext(C); TimeMarker *marker; @@ -363,14 +387,14 @@ void draw_markers_time(const bContext *C, int flag) */ /* maximum y-axis value (in region screen-space) that marker events should still be accepted for */ -#define ANIMEDIT_MARKER_YAXIS_MAX 30 +#define ANIMEDIT_MARKER_YAXIS_MAX 40 /* ------------------------ */ /* special poll() which checks if there are selected markers first */ static int ed_markers_poll_selected_markers(bContext *C) { - ListBase *markers = context_get_markers(C); + ListBase *markers = ED_context_get_markers(C); /* first things first: markers can only exist in timeline views */ if (ED_operator_animview_active(C) == 0) @@ -439,7 +463,7 @@ static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, wmEvent *evt) /* add TimeMarker at curent frame */ static int ed_marker_add(bContext *C, wmOperator *UNUSED(op)) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker; int frame= CTX_data_scene(C)->r.cfra; @@ -453,7 +477,7 @@ static int ed_marker_add(bContext *C, wmOperator *UNUSED(op)) } /* deselect all */ - for(marker= markers->first; marker; marker= marker->next) + for (marker= markers->first; marker; marker= marker->next) marker->flag &= ~SELECT; marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker"); @@ -522,7 +546,7 @@ typedef struct MarkerMove { /* return 0 if not OK */ static int ed_marker_move_init(bContext *C, wmOperator *op) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); MarkerMove *mm; TimeMarker *marker; int totmark=0; @@ -643,7 +667,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: - if(WM_modal_tweak_exit(evt, mm->event_type)) { + if (WM_modal_tweak_exit(evt, mm->event_type)) { ed_marker_move_exit(C, op); WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); @@ -652,9 +676,9 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) break; case MOUSEMOVE: - if(hasNumInput(&mm->num)) + if (hasNumInput(&mm->num)) break; - + dx= v2d->mask.xmax-v2d->mask.xmin; dx= (v2d->cur.xmax-v2d->cur.xmin)/dx; @@ -668,7 +692,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0); else - apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID); + apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/); offs= (int)fac; RNA_int_set(op->ptr, "frames", offs); @@ -729,22 +753,22 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) } } - if(evt->val==KM_PRESS) { + if (evt->val==KM_PRESS) { float vec[3]; char str_tx[256]; - + if (handleNumInput(&mm->num, evt)) { applyNumInput(&mm->num, vec); outputNumInput(&mm->num, str_tx); - + RNA_int_set(op->ptr, "frames", vec[0]); ed_marker_move_apply(op); // ed_marker_header_update(C, op, str, (int)vec[0]); // strcat(str, str_tx); sprintf(str, "Marker offset %s", str_tx); ED_area_headerprint(CTX_wm_area(C), str); - + WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); } @@ -806,7 +830,7 @@ callbacks: /* duplicate selected TimeMarkers */ static void ed_marker_duplicate_apply(bContext *C) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker, *newmarker; if (markers == NULL) @@ -901,7 +925,7 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); View2D *v2d= UI_view2d_fromcontext(C); float viewx; int x, y, cfra; @@ -1022,7 +1046,7 @@ callbacks: static int ed_marker_border_select_exec(bContext *C, wmOperator *op) { View2D *v2d= UI_view2d_fromcontext(C); - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker; float xminf, xmaxf, yminf, ymaxf; int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); @@ -1087,7 +1111,7 @@ static void MARKER_OT_select_border(wmOperatorType *ot) static int ed_marker_select_all_exec(bContext *C, wmOperator *op) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker; int action = RNA_enum_get(op->ptr, "action"); @@ -1142,7 +1166,7 @@ static void MARKER_OT_select_all(wmOperatorType *ot) /* remove selected TimeMarkers */ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op)) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker, *nmarker; short changed= 0; @@ -1193,7 +1217,7 @@ static void MARKER_OT_delete(wmOperatorType *ot) /* rename first selected TimeMarker */ static int ed_marker_rename_exec(bContext *C, wmOperator *op) { - TimeMarker *marker= ED_markers_get_first_selected(context_get_markers(C)); + TimeMarker *marker= ED_markers_get_first_selected(ED_context_get_markers(C)); if(marker) { RNA_string_get(op->ptr, "name", marker->name); @@ -1211,7 +1235,7 @@ static int ed_marker_rename_exec(bContext *C, wmOperator *op) static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) { /* must initialise the marker name first if there is a marker selected */ - TimeMarker *marker = ED_markers_get_first_selected(context_get_markers(C)); + TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C)); if (marker) RNA_string_set(op->ptr, "name", marker->name); @@ -1243,7 +1267,7 @@ static void MARKER_OT_rename(wmOperatorType *ot) static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op) { - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); TimeMarker *marker, *marker_new; @@ -1297,27 +1321,20 @@ static void MARKER_OT_make_links_scene(wmOperatorType *ot) #ifdef DURIAN_CAMERA_SWITCH /* ******************************* camera bind marker ***************** */ -/* remove selected TimeMarkers */ static int ed_marker_camera_bind_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - ListBase *markers= context_get_markers(C); + ListBase *markers= ED_context_get_markers(C); TimeMarker *marker; - short changed= 0; - if(markers == NULL) + marker= ED_markers_get_first_selected(markers); + if(marker == NULL) return OPERATOR_CANCELLED; - for(marker= markers->first; marker; marker= marker->next) { - if(marker->flag & SELECT) { - marker->camera= scene->camera; - } - } + marker->camera= scene->camera; - if (changed) { - WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); - WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); - } + WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index c6c333755b0..8d74e7b1b59 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -27,6 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <stdio.h> #include <string.h> #include "MEM_guardedalloc.h" @@ -35,12 +36,19 @@ #include "BLI_utildefines.h" #include "DNA_anim_types.h" +#include "DNA_object_types.h" +#include "DNA_material_types.h" +#include "DNA_texture_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_animsys.h" #include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_context.h" #include "BKE_report.h" +#include "BKE_material.h" +#include "BKE_texture.h" #include "ED_keyframing.h" @@ -386,6 +394,83 @@ short ANIM_paste_driver (ReportList *reports, ID *id, const char rna_path[], int /* ************************************************** */ /* UI-Button Interface */ +/* Temporary wrapper for driver operators for buttons to make it easier to create + * such drivers by rerouting all paths through the active object instead so that + * they will get picked up by the dependency system. + * + * < C: context pointer - for getting active data + * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping. + * < prop: RNA definition of property to add for + * + * > returns: MEM_alloc'd string representing the path to the property from the given PointerRNA + */ +static char *get_driver_path_hack (bContext *C, PointerRNA *ptr, PropertyRNA *prop) +{ + ID *id = (ID *)ptr->id.data; + ScrArea *sa = CTX_wm_area(C); + + /* get standard path which may be extended */ + char *basepath = RNA_path_from_ID_to_property(ptr, prop); + char *path = basepath; /* in case no remapping is needed */ + + /* Remapping will only be performed in the Properties Editor, as only this + * restricts the subspace of options to the 'active' data (a manageable state) + */ + // TODO: watch out for pinned context? + if ((sa) && (sa->spacetype == SPACE_BUTS)) { + Object *ob = CTX_data_active_object(C); + + if (ob && id) { + /* only id-types which can be remapped to go through objects should be considered */ + switch (GS(id->name)) { + case ID_MA: /* materials */ + { + Material *ma = give_current_material(ob, ob->actcol); + + /* assumes: material will only be shown if it is active objects's active material it's ok */ + if ((ID*)ma == id) { + /* create new path */ + // TODO: use RNA path functions to construct instead? + path = BLI_sprintfN("material_slots[\"%s\"].material.%s", + ma->id.name+2, basepath); + + /* free old one */ + MEM_freeN(basepath); + } + } + break; + + case ID_TE: /* textures */ + { + Material *ma = give_current_material(ob, ob->actcol); + Tex *tex = give_current_material_texture(ma); + + /* assumes: texture will only be shown if it is active material's active texture it's ok */ + if ((ID*)tex == id) { + /* create new path */ + // TODO: use RNA path functions to construct step by step instead? + path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s", + ma->id.name+2, tex->id.name+2, basepath); + + /* free old one */ + MEM_freeN(basepath); + } + } + break; + } + + /* fix RNA pointer, as we've now changed the ID root by changing the paths */ + if (basepath != path) { + /* rebase provided pointer so that it starts from object... */ + RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr); + } + } + } + + /* the path should now have been corrected for use */ + return path; +} + /* Add Driver Button Operator ------------------------ */ static int add_driver_button_exec (bContext *C, wmOperator *op) @@ -397,12 +482,12 @@ static int add_driver_button_exec (bContext *C, wmOperator *op) /* try to create driver using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); - + if (all) index= -1; - + if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path= RNA_path_from_ID_to_property(&ptr, prop); + char *path= get_driver_path_hack(C, &ptr, prop); short flags = CREATEDRIVER_WITH_DEFAULT_DVAR; if (path) { @@ -456,9 +541,9 @@ static int remove_driver_button_exec (bContext *C, wmOperator *op) if (all) index= -1; - + if (ptr.id.data && ptr.data && prop) { - char *path= RNA_path_from_ID_to_property(&ptr, prop); + char *path= get_driver_path_hack(C, &ptr, prop); success= ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0); MEM_freeN(path); @@ -507,7 +592,7 @@ static int copy_driver_button_exec (bContext *C, wmOperator *op) uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path= RNA_path_from_ID_to_property(&ptr, prop); + char *path= get_driver_path_hack(C, &ptr, prop); if (path) { /* only copy the driver for the button that this was involved for */ @@ -551,7 +636,7 @@ static int paste_driver_button_exec (bContext *C, wmOperator *op) uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { - char *path= RNA_path_from_ID_to_property(&ptr, prop); + char *path= get_driver_path_hack(C, &ptr, prop); if (path) { /* only copy the driver for the button that this was involved for */ diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 93808233288..543153464ea 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -138,6 +138,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 */ @@ -149,6 +192,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 */ @@ -935,23 +987,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); } } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 726c898e843..888ab9769d8 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -231,7 +231,7 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag) dst->vec[0][1] += dy; dst->vec[1][1] += dy; dst->vec[2][1] += dy; - + dst->f1= bezt->f1; dst->f2= bezt->f2; dst->f3= bezt->f3; |