From 4f0dc8abbf4e25345370c691fb591ecc23976c5d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 8 May 2009 12:51:36 +0000 Subject: [PATCH] 2.5 - Restored Various Tools using Markers * Added back a few Marker-API tools * Restored column select tools using markers (some of these aren't working right yet though). --- .../blender/editors/animation/anim_filter.c | 7 +- .../blender/editors/animation/anim_markers.c | 161 +++++++++++++++--- .../editors/animation/keyframes_edit.c | 20 ++- source/blender/editors/include/ED_anim_api.h | 1 + .../editors/include/ED_keyframes_edit.h | 1 + source/blender/editors/include/ED_markers.h | 20 ++- .../editors/space_action/action_edit.c | 1 + .../editors/space_action/action_select.c | 27 +-- .../blender/editors/space_graph/graph_edit.c | 6 +- .../editors/space_graph/graph_select.c | 25 +-- 10 files changed, 190 insertions(+), 79 deletions(-) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 93bdadc27d3..b177a19a07f 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -291,7 +291,12 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac) /* get useful default context settings from context */ ac->scene= scene; - ac->obact= (scene && scene->basact)? scene->basact->object : NULL; + if (scene) { + ac->markers.first= scene->markers.first; + ac->markers.last= scene->markers.last; + + ac->obact= (scene->basact)? scene->basact->object : NULL; + } ac->sa= sa; ac->ar= ar; ac->spacetype= (sa) ? sa->spacetype : 0; diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 97904dcdddf..3848eef3608 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -46,6 +46,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_fcurve.h" #include "BKE_utildefines.h" #include "WM_api.h" @@ -83,6 +84,140 @@ static ListBase *context_get_markers(const bContext *C) return &CTX_data_scene(C)->markers; } +/* Get the marker that is closest to this point */ +TimeMarker *ED_markers_find_nearest_marker (ListBase *markers, float x) +{ + TimeMarker *marker, *nearest=NULL; + float dist, min_dist= 1000000; + + if (markers) { + for (marker= markers->first; marker; marker= marker->next) { + dist = ABS((float)marker->frame - x); + + if (dist < min_dist) { + min_dist= dist; + nearest= marker; + } + } + } + + return nearest; +} + +/* Return the time of the marker that occurs on a frame closest to the given time */ +int ED_markers_find_nearest_marker_time (ListBase *markers, float x) +{ + TimeMarker *nearest= ED_markers_find_nearest_marker(markers, x); + return (nearest) ? (nearest->frame) : (int)floor(x + 0.5f); +} + + +void ED_markers_get_minmax (ListBase *markers, short sel, float *first, float *last) +{ + TimeMarker *marker; + float min, max; + int selcount = 0; + + /* sanity check */ + if (markers == NULL) { + *first = 0.0f; + *last = 0.0f; + return; + } + + if (markers->first && markers->last) { + TimeMarker *first= markers->first; + TimeMarker *last= markers->last; + + min= first->frame; + max= last->frame; + } + else { + *first = 0.0f; + *last = 0.0f; + return; + } + + /* count how many markers are usable - see later */ + if (sel) { + for (marker= markers->first; marker; marker= marker->next) { + if (marker->flag & SELECT) + selcount++; + } + } + else + selcount= BLI_countlist(markers); + + /* if only selected are to be considered, only consider the selected ones + * (optimisation for not searching list) + */ + if (selcount > 1) { + for (marker= markers->first; marker; marker= marker->next) { + if (sel) { + if (marker->flag & SELECT) { + if (marker->frame < min) + min= (float)marker->frame; + else if (marker->frame > max) + max= (float)marker->frame; + } + } + else { + if (marker->frame < min) + min= marker->frame; + else if (marker->frame > max) + max= marker->frame; + } + } + } + + /* set the min/max values */ + *first= min; + *last= max; +} + +/* Adds a marker to list of cfra elems */ +void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel) +{ + CfraElem *ce, *cen; + + /* should this one only be considered if it is selected? */ + if ((only_sel) && ((marker->flag & SELECT)==0)) + return; + + /* insertion sort - try to find a previous cfra elem */ + for (ce= lb->first; ce; ce= ce->next) { + if (ce->cfra == marker->frame) { + /* do because of double keys */ + if (marker->flag & SELECT) + ce->sel= marker->flag; + return; + } + else if (ce->cfra > marker->frame) break; + } + + cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); + if (ce) BLI_insertlinkbefore(lb, ce, cen); + else BLI_addtail(lb, cen); + + cen->cfra= marker->frame; + cen->sel= marker->flag; +} + +/* This function makes a list of all the markers. The only_sel + * argument is used to specify whether only the selected markers + * are added. + */ +void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel) +{ + TimeMarker *marker; + + if (markers == NULL) + return; + + for (marker= markers->first; marker; marker= marker->next) + add_marker_to_cfra_elem(lb, marker, only_sel); +} + /* ************* Marker Drawing ************ */ /* function to draw markers */ @@ -185,8 +320,6 @@ void draw_markers_time(const bContext *C, int flag) } } - - /* ************************** add markers *************************** */ /* add TimeMarker at curent frame */ @@ -598,24 +731,6 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned } } -int find_nearest_marker_time (ListBase *markers, float dx) -{ - TimeMarker *marker, *nearest= NULL; - float dist, min_dist= 1000000; - - for (marker= markers->first; marker; marker= marker->next) { - dist = ABS((float)marker->frame - dx); - if (dist < min_dist) { - min_dist= dist; - nearest= marker; - } - } - - if (nearest) return nearest->frame; - else return (int)floor(dx); /* hrmf? */ -} - - static int ed_marker_select(bContext *C, wmEvent *evt, int extend) { ListBase *markers= context_get_markers(C); @@ -631,7 +746,7 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend) UI_view2d_region_to_view(v2d, x, y, &viewx, NULL); - cfra= find_nearest_marker_time(markers, viewx); + cfra= ED_markers_find_nearest_marker_time(markers, viewx); if (extend) select_timeline_marker_frame(markers, cfra, 1); @@ -834,9 +949,9 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *op) } } - if(changed) { + if (changed) WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); - } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 1aadeb7969f..8243629b4a6 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -382,6 +382,20 @@ short bezt_calc_average(BeztEditData *bed, BezTriple *bezt) return 0; } +/* helper callback for columnselect__keys() -> populate list CfraElems with frame numbers from selected beztriples */ +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; +} + /* ******************************************* */ /* Transform */ @@ -412,15 +426,15 @@ static short snap_bezier_cframe(BeztEditData *bed, 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! + if (bezt->f2 & SELECT) + bezt->vec[1][0]= (float)ED_markers_find_nearest_marker_time(&bed->list, bezt->vec[1][0]); return 0; } static short snap_bezier_horizontal(BeztEditData *bed, BezTriple *bezt) { if (bezt->f2 & SELECT) { - bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; + bezt->vec[0][1]= bezt->vec[2][1]= (float)floor(bezt->vec[1][1] + 0.5f); if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN; if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN; } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 0210e3d6a85..e0f322b79ff 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -64,6 +64,7 @@ typedef struct bAnimContext { struct Scene *scene; /* active scene */ struct Object *obact; /* active object */ + ListBase markers; /* active set of markers */ } bAnimContext; /* Main Data container types */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 44d4e26fea5..77e95dc77de 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -137,6 +137,7 @@ BeztEditFunc ANIM_editkeyframes_ipo(short mode); /* ----------- BezTriple Callback (Assorted Utilities) ---------- */ short bezt_calc_average(BeztEditData *bed, struct BezTriple *bezt); +short bezt_to_cfraelem(BeztEditData *bed, struct BezTriple *bezt); /* ************************************************ */ /* Destructive Editing API (keyframes_general.c) */ diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h index 0e9a82083a6..048bbbd7463 100644 --- a/source/blender/editors/include/ED_markers.h +++ b/source/blender/editors/include/ED_markers.h @@ -28,6 +28,11 @@ #ifndef ED_MARKERS_H #define ED_MARKERS_H +struct wmWindowManager; +struct bContext; +struct TimeMarker; + +/* Drawing API ------------------------------ */ /* flags for drawing markers */ enum { @@ -35,11 +40,18 @@ enum { DRAW_MARKERS_LOCAL = (1<<1) }; -struct wmWindowManager; -struct bContext; - void draw_markers_time(const struct bContext *C, int flag); -int find_nearest_marker_time(ListBase *markers, float dx); + +/* Backend API ----------------------------- */ + +struct TimeMarker *ED_markers_find_nearest_marker(ListBase *markers, float x); +int ED_markers_find_nearest_marker_time(ListBase *markers, float x); + +void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *last); + +void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short sel); + +/* Operators ------------------------------ */ /* called in screen_ops.c:ED_operatortypes_screen() */ void ED_marker_operatortypes(void); diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index a486e9067ae..99360450367 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1118,6 +1118,7 @@ static void snap_action_keys(bAnimContext *ac, short mode) memset(&bed, 0, sizeof(BeztEditData)); bed.scene= ac->scene; + bed.list= ac->scene->markers; /* for marker-snapping option */ /* snap keyframes */ for (ale= anim_data.first; ale; ale= ale->next) { diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index ced80647fec..bb3f16dd506 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -74,6 +74,7 @@ #include "ED_keyframing.h" #include "ED_keyframes_draw.h" #include "ED_keyframes_edit.h" +#include "ED_markers.h" #include "ED_screen.h" #include "ED_space_api.h" @@ -394,11 +395,8 @@ static void markers_selectkeys_between (bAnimContext *ac) float min, max; /* get extreme markers */ - //get_minmax_markers(1, &min, &max); // FIXME... add back markers api! - min= (float)ac->scene->r.sfra; // xxx temp code - max= (float)ac->scene->r.efra; // xxx temp code + ED_markers_get_minmax(&ac->markers, 1, &min, &max); - if (min==max) return; min -= 0.5f; max += 0.5f; @@ -431,21 +429,6 @@ static void markers_selectkeys_between (bAnimContext *ac) } -/* 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) { @@ -490,9 +473,7 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) 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! + ED_markers_make_cfra_list(&ac->markers, &bed.list, 1); break; default: /* invalid option */ @@ -509,7 +490,7 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) if (ac->datatype == ANIMCONT_GPENCIL) filter= (ANIMFILTER_VISIBLE); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale= anim_data.first; ale; ale= ale->next) { diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 4c7d855009a..40d66725847 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1388,7 +1388,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode) BeztEditFunc edit_cb; /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* get beztriple editing callbacks */ @@ -1396,6 +1396,7 @@ static void snap_graph_keys(bAnimContext *ac, short mode) memset(&bed, 0, sizeof(BeztEditData)); bed.scene= ac->scene; + bed.list= ac->markers; /* for marker-snapping option */ /* snap keyframes */ for (ale= anim_data.first; ale; ale= ale->next) { @@ -1486,11 +1487,10 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) /* for 'first selected marker' mode, need to find first selected marker first! */ // XXX should this be made into a helper func in the API? if (mode == GRAPHKEYS_MIRROR_MARKER) { - Scene *scene= ac->scene; TimeMarker *marker= NULL; /* find first selected marker */ - for (marker= scene->markers.first; marker; marker=marker->next) { + for (marker= ac->markers.first; marker; marker=marker->next) { if (marker->flag & SELECT) { break; } diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 4b6e55d2a03..a2ecb3a3fad 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -73,6 +73,7 @@ #include "ED_keyframing.h" #include "ED_keyframes_draw.h" #include "ED_keyframes_edit.h" +#include "ED_markers.h" #include "ED_screen.h" #include "ED_space_api.h" @@ -358,11 +359,8 @@ static void markers_selectkeys_between (bAnimContext *ac) float min, max; /* get extreme markers */ - //get_minmax_markers(1, &min, &max); // FIXME... add back markers api! - min= (float)ac->scene->r.sfra; // xxx temp code - max= (float)ac->scene->r.efra; // xxx temp code + ED_markers_get_minmax(&ac->markers, 1, &min, &max); - if (min==max) return; min -= 0.5f; max += 0.5f; @@ -395,21 +393,6 @@ static void markers_selectkeys_between (bAnimContext *ac) } -/* helper callback for columnselect_graph_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_graph_keys (bAnimContext *ac, short mode) { @@ -446,9 +429,7 @@ static void columnselect_graph_keys (bAnimContext *ac, short mode) break; case GRAPHKEYS_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! + ED_markers_make_cfra_list(&ac->markers, &bed.list, 1); break; default: /* invalid option */