diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index e2fa67e3873..f7ad69a046c 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -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() diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 3b1a5dbfc8a..1432dc151d0 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -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 diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 216e3b19672..bb4a7783c82 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -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; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index eb697aad17c..2199259a322 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 1814b253def..574eb5b2570 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -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); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 4543876ffe5..82f76efacaa 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -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); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index c2fbc611bc3..0bc91907d6e 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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 */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index db1899ab31b..4e2b3c46aa4 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -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 { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 47bad8f31e5..bc2e1b7e1f3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -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); }