Clip editor: sort order for dopesheet channels
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 3 May 2012 19:28:41 +0000 (19:28 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 3 May 2012 19:28:41 +0000 (19:28 +0000)
Supported sorting by name, longest tracked segment and total tracked frames.

Internally tracks are stored in Tracking datablock, but sort order is
a clip editor space property and sorting happens on clip editor draw.
If there's no dopesheet opened with different sort orders it's not
a problem due to re-sorting wouldn't happen.

Also fixed draw issue of tracked segments introduced in previous commit.

release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/space_clip/clip_dopesheet_draw.c
source/blender/editors/space_clip/space_clip.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_space.c

index e2fa67e387353255a83fd4c1a9fba2049c851cea..f7ad69a046c5dca7bb896ced0574a85d33fd779b 100644 (file)
@@ -84,6 +84,11 @@ class CLIP_HT_header(Header):
                 layout.label(text="Average solve error: %.4f" %
                     (r.average_error))
 
+            if sc.view == 'DOPESHEET':
+                layout.label(text="Sort by:")
+                layout.prop(sc, "dopesheet_sort_order", text="")
+                layout.prop(sc, "invert_dopesheet_sort", text="Invert")
+
         layout.template_running_jobs()
 
 
index 3b1a5dbfc8a36a62357a8cba4b188850dc310659..1432dc151d095360d745d852f58931f7b3abe507 100644 (file)
@@ -166,6 +166,7 @@ void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
 
 /* Dopesheet */
 void BKE_tracking_update_dopesheet(struct MovieTracking *tracking);
+void BKE_tracking_dopesheet_sort(struct MovieTracking *tracking, int sort_order, int inverse);
 
 #define TRACK_SELECTED(track)                          ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)
 
@@ -197,4 +198,9 @@ void BKE_tracking_update_dopesheet(struct MovieTracking *tracking);
 
 #define TRACK_AREA_ALL         (TRACK_AREA_POINT|TRACK_AREA_PAT|TRACK_AREA_SEARCH)
 
+#define TRACK_SORT_NONE                -1
+#define TRACK_SORT_NAME                0
+#define TRACK_SORT_LONGEST     1
+#define TRACK_SORT_TOTAL       2
+
 #endif
index 216e3b19672c0129bc3c2a57de28dbe0051a24b8..bb4a7783c82bdc5d2dadd51b27f0b264a92ab55e 100644 (file)
@@ -3072,6 +3072,52 @@ static int channels_alpha_sort(void *a, void *b)
                return 0;
 }
 
+static int channels_total_track_sort(void *a, void *b)
+{
+       MovieTrackingDopesheetChannel *channel_a = a;
+       MovieTrackingDopesheetChannel *channel_b = b;
+
+       if (channel_a->total_frames > channel_b->total_frames)
+               return 1;
+       else
+               return 0;
+}
+
+static int channels_longest_segment_sort(void *a, void *b)
+{
+       MovieTrackingDopesheetChannel *channel_a = a;
+       MovieTrackingDopesheetChannel *channel_b = b;
+
+       if (channel_a->max_segment > channel_b->max_segment)
+               return 1;
+       else
+               return 0;
+}
+
+static int channels_alpha_inverse_sort(void *a, void *b)
+{
+       if (channels_alpha_sort(a, b))
+               return 0;
+       else
+               return 1;
+}
+
+static int channels_total_track_inverse_sort(void *a, void *b)
+{
+       if (channels_total_track_sort(a, b))
+               return 0;
+       else
+               return 1;
+}
+
+static int channels_longest_segment_inverse_sort(void *a, void *b)
+{
+       if (channels_longest_segment_sort(a, b))
+               return 0;
+       else
+               return 1;
+}
+
 static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
 {
        MovieTrackingTrack *track = channel->track;
@@ -3173,5 +3219,40 @@ void BKE_tracking_update_dopesheet(MovieTracking *tracking)
                }
        }
 
-       BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
+       dopesheet->sort_order = TRACK_SORT_NONE;
+       dopesheet->sort_inverse = -1;
+}
+
+void BKE_tracking_dopesheet_sort(MovieTracking *tracking, int sort_order, int inverse)
+{
+       MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+
+       if (dopesheet->sort_order == sort_order && dopesheet->sort_inverse == inverse)
+               return;
+
+       if (inverse) {
+               if (sort_order == TRACK_SORT_NAME) {
+                       BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort);
+               }
+               else if (sort_order == TRACK_SORT_LONGEST) {
+                       BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort);
+               }
+               else if (sort_order == TRACK_SORT_TOTAL) {
+                       BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort);
+               }
+       }
+       else {
+               if (sort_order == TRACK_SORT_NAME) {
+                       BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
+               }
+               else if (sort_order == TRACK_SORT_LONGEST) {
+                       BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort);
+               }
+               else if (sort_order == TRACK_SORT_TOTAL) {
+                       BLI_sortlist(&dopesheet->channels, channels_total_track_sort);
+               }
+       }
+
+       dopesheet->sort_order = sort_order;
+       dopesheet->sort_inverse = inverse;
 }
index eb697aad17ceb3aba1d4cf5af4ed159470098d2d..2199259a3224335cc6d06c10bd89a02ddf324ec3 100644 (file)
@@ -2686,7 +2686,7 @@ static void write_movieDopesheet(WriteData *wd, MovieTrackingDopesheet *dopeshee
        channel = dopesheet->channels.first;
        while (channel) {
                writestruct(wd, DATA, "MovieTrackingDopesheetChannel", 1, channel);
-               writedata(wd, DATA, 2 * channel->tot_segment, channel->segments);
+               writedata(wd, DATA, 2 * channel->tot_segment * sizeof(int), channel->segments);
 
                channel = channel->next;
        }
index 1814b253def18b7a7e55067ff1c6908b1ab4c422..574eb5b25709dabe785c4560c2074c73467602d6 100644 (file)
@@ -203,6 +203,11 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
                                        int start_frame = channel->segments[2 * i];
                                        int end_frame = channel->segments[2 * i + 1];
 
+                                       if (sel)
+                                               glColor4fv(selected_strip);
+                                       else
+                                               glColor4fv(strip);
+
                                        if (start_frame != end_frame) {
                                                glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF,
                                                                end_frame, (float) y + STRIP_HEIGHT_HALF);
index 4543876ffe50f9edd866df2379d343777b3c1aae..82f76efacaacc6bb21f3481b3832562b9fe90a34 100644 (file)
@@ -1129,11 +1129,14 @@ static void dopesheet_area_draw(const bContext *C, ARegion *ar)
 {
        Scene *scene = CTX_data_scene(C);
        SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
        View2D *v2d = &ar->v2d;
        View2DGrid *grid;
        View2DScrollers *scrollers;
        short unit = 0;
 
+       BKE_tracking_dopesheet_sort(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE);
+
        /* clear and setup matrix */
        UI_ThemeClearColor(TH_BACK);
        glClear(GL_COLOR_BUFFER_BIT);
@@ -1186,9 +1189,13 @@ static void clip_channels_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void clip_channels_area_draw(const bContext *C, ARegion *ar)
 {
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
        View2D *v2d = &ar->v2d;
        View2DScrollers *scrollers;
 
+       BKE_tracking_dopesheet_sort(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE);
+
        /* clear and setup matrix */
        UI_ThemeClearColor(TH_BACK);
        glClear(GL_COLOR_BUFFER_BIT);
index c2fbc611bc314cad2951d30c05d3fb812417d629..0bc91907d6e9baef7fbecd2648d8eb8d574ab4c5 100644 (file)
@@ -523,6 +523,12 @@ typedef struct SpaceClip {
        int postproc_flag, pad2;
 
        void *draw_context;
+
+       /* dopesheet */
+       short dope_sort;                /* sort order in dopesheet view */
+       short dope_flag;                /* dopsheet view flags */
+
+       int pad3;
 } SpaceClip;
 
 /* view3d  Now in DNA_view3d_types.h */
@@ -916,8 +922,13 @@ enum {
 #define SC_VIEW_GRAPH          1
 #define SC_VIEW_DOPESHEET      2
 
-/* SpaceClip->runtime_flag */
-#define SC_GRAPH_BOTTOM                (1<<0)
+/* SpaceClip->dope_sort */
+#define SC_DOPE_SORT_NAME              0
+#define SC_DOPE_SORT_LONGEST           1
+#define SC_DOPE_SORT_TOTAL             2
+
+/* SpaceClip->dope_flag */
+#define SC_DOPE_SORT_INVERSE           1
 
 /* space types, moved from DNA_screen_types.h */
 /* Do NOT change order, append on end. types are hardcoded needed */
index db1899ab31bfde554b532da813cb2e2dc66cd7ad..4e2b3c46aa4a91ec48065518ad52f0c4780e225f 100644 (file)
@@ -206,7 +206,10 @@ typedef struct MovieTrackingDopesheetChannel {
 
 typedef struct MovieTrackingDopesheet {
        ListBase channels;
-       int tot_channel, pad;
+       int tot_channel;
+
+       short sort_order;                       /* order in which tracks are stored */
+       short sort_inverse;                     /* order of tracks is inverted */
 } MovieTrackingDopesheet;
 
 typedef struct MovieTracking {
index 47bad8f31e544f62a0ca0d196646a08a76de61d7..bc2e1b7e1f3987061a58ead8f3599b94c2bf624d 100644 (file)
@@ -2934,6 +2934,12 @@ static void rna_def_space_clip(BlenderRNA *brna)
                {SC_VIEW_DOPESHEET, "DOPESHEET", ICON_ACTION, "Dopesheet", "Dopesheet view for tracking data"},
                {0, NULL, 0, NULL, NULL}};
 
+       static EnumPropertyItem dope_sort_items[] = {
+               {SC_DOPE_SORT_NAME, "NAME", 0, "Name", "Sort channels by their names"},
+               {SC_DOPE_SORT_LONGEST, "LONGEST", 0, "Longest", "Sort channels by longest tracked segment"},
+               {SC_DOPE_SORT_TOTAL, "TOTAL", 0, "Total", "Sort channels by overall amount of tracked segments"},
+               {0, NULL, 0, NULL, NULL}};
+
        srna = RNA_def_struct(brna, "SpaceClipEditor", "Space");
        RNA_def_struct_sdna(srna, "SpaceClip");
        RNA_def_struct_ui_text(srna, "Space Clip Editor", "Clip editor space data");
@@ -3112,6 +3118,21 @@ static void rna_def_space_clip(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_SECONDS);
        RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+       /* ** dopesheet ** */
+
+       /* dopesheet sort */
+       prop = RNA_def_property(srna, "dopesheet_sort_order", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "dope_sort");
+       RNA_def_property_enum_items(prop, dope_sort_items);
+       RNA_def_property_ui_text(prop, "Dopesheet Sort Field", "Field used to sort channels in dopesheet view");
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+       /* invert_dopesheet_sort */
+       prop = RNA_def_property(srna, "invert_dopesheet_sort", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "dope_flag", SC_DOPE_SORT_INVERSE);
+       RNA_def_property_ui_text(prop, "Invert Dopesheet Sort", "Invert sort order of dopesheet channels");
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
 }