2.5 - Restored Various Tools using Markers
authorJoshua Leung <aligorith@gmail.com>
Fri, 8 May 2009 12:51:36 +0000 (12:51 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 8 May 2009 12:51:36 +0000 (12:51 +0000)
* Added back a few Marker-API tools
* Restored column select tools using markers (some of these aren't working right yet though).

source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_keyframes_edit.h
source/blender/editors/include/ED_markers.h
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_select.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_graph/graph_select.c

index 93bdadc27d388186f083650960548dbe15e23598..b177a19a07f56741300014901ae5b58d5935664a 100644 (file)
@@ -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;
index 97904dcdddfceba8f031f6b1d9addecfc09bb180..3848eef360842bb6aba7f620b15f84f6146d9534 100644 (file)
@@ -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;
 }
 
index 1aadeb7969f6152a81eff9c17770ccdaea89c1b1..8243629b4a6c9917a2a309ac2725268f4ada3745 100644 (file)
@@ -382,6 +382,20 @@ short bezt_calc_average(BeztEditData *bed, BezTriple *bezt)
        return 0;
 }
 
+/* helper callback for columnselect_<animeditor>_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;
        }
index 0210e3d6a85de33c82dbfea237f1c698a823a926..e0f322b79ff0481b6d00e29a3890596d42bc6d56 100644 (file)
@@ -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 */
index 44d4e26fea57c5154eb423fe57bcb0302873b5e4..77e95dc77de788af2f924eb2b518d6e2231a36c6 100644 (file)
@@ -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) */
index 0e9a82083a68b7376b0624abf73dc89ab0ec3e74..048bbbd746371a8f6162114dcda4050b4961195f 100644 (file)
 #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); 
index a486e9067aec6392c80be2d5c019e470e6ef78ba..99360450367398657642de752d53b0a8a968e9a2 100644 (file)
@@ -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) {
index ced80647fecb80fbb2cddba343b12ff10e7409ed..bb3f16dd506ca3e9374f1b1cb1b0a75a9f21d5b0 100644 (file)
@@ -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) {
index 4c7d855009af2e948febe56738ce153c99e7d13f..40d66725847b2dd44526b2ce3d8b6b57150c0b77 100644 (file)
@@ -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;
                        }
index 4b6e55d2a03c77fe95198c05e3698f962b51b50c..a2ecb3a3fadc13488dd809da8da5fd15c2895541 100644 (file)
@@ -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 */