Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-04-30 20:19:20 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-04-30 20:19:20 +0400
commitf111131ca68359e928056eff09a03d0eee8c681a (patch)
tree866483646a4fca238c0d1f4e22ff1bcb1ed0d6d2 /source/blender/editors/space_clip
parent323aedb81e8f606cfb1357053891e989ff393099 (diff)
Camera tracking: initial commit of dopesheet view for clip editor
- Displays dopesheet information for selected tracks, and currently does not support any kind of editing. - Changed regions to use the whole main region for such views as curves and dopesheet. This allows to have own panels with tools/properties in this area. - Active clip is getting synchronized between different clip editor editors in the same screen, so updating of curve/dopesheet views happens automatically when one changes current clip in one of this editors. - Panels in toolbox and properties panels are now separated to rely on current view mode, but some operators and poll functions still need to be updated. - Added new screen called "Movie Tracking" where layout is configured to display timeline, main clip window, curves and dopesheet.
Diffstat (limited to 'source/blender/editors/space_clip')
-rw-r--r--source/blender/editors/space_clip/CMakeLists.txt14
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c6
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c377
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c139
-rw-r--r--source/blender/editors/space_clip/clip_editor.c35
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c14
-rw-r--r--source/blender/editors/space_clip/clip_intern.h21
-rw-r--r--source/blender/editors/space_clip/clip_ops.c3
-rw-r--r--source/blender/editors/space_clip/space_clip.c277
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c17
10 files changed, 854 insertions, 49 deletions
diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt
index 30d2fe57c10..ec5e81e4b2c 100644
--- a/source/blender/editors/space_clip/CMakeLists.txt
+++ b/source/blender/editors/space_clip/CMakeLists.txt
@@ -40,15 +40,17 @@ set(INC_SYS
)
set(SRC
- space_clip.c
+ clip_buttons.c
+ clip_dopesheet_draw.c
+ clip_dopesheet_ops.c
clip_draw.c
- clip_toolbar.c
- clip_ops.c
- clip_graph_ops.c
- clip_graph_draw.c
clip_editor.c
- clip_buttons.c
+ clip_graph_draw.c
+ clip_graph_ops.c
+ clip_ops.c
+ clip_toolbar.c
clip_utils.c
+ space_clip.c
tracking_ops.c
clip_intern.h
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 82178e47ae5..df6d713d82d 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -63,9 +63,11 @@
/* Panels */
-static int clip_grease_pencil_panel_poll(const bContext *UNUSED(C), PanelType *UNUSED(pt))
+static int clip_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return TRUE;
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ return sc->view == SC_VIEW_CLIP;
}
void ED_clip_buttons_register(ARegionType *art)
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
new file mode 100644
index 00000000000..d1733cf322b
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -0,0 +1,377 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_graph_draw.c
+ * \ingroup spclip
+ */
+
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "BLF_api.h"
+
+#include "RNA_access.h"
+
+#include "clip_intern.h" // own include
+
+static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3])
+{
+ if (track->flag & TRACK_CUSTOMCOLOR) {
+ float bg[3];
+ UI_GetThemeColor3fv(TH_HEADER, bg);
+
+ interp_v3_v3v3(color, track->color, bg, 0.5);
+ }
+ else {
+ if (default_color)
+ copy_v3_v3(color, default_color);
+ else
+ UI_GetThemeColor3fv(TH_HEADER, color);
+ }
+}
+
+static void draw_keyframe_shape(float x, float y, float xscale, float yscale, short sel, float alpha)
+{
+ /* coordinates for diamond shape */
+ static const float _unit_diamond_shape[4][2] = {
+ {0.0f, 1.0f}, /* top vert */
+ {1.0f, 0.0f}, /* mid-right */
+ {0.0f, -1.0f}, /* bottom vert */
+ {-1.0f, 0.0f} /* mid-left */
+ };
+ static GLuint displist1 = 0;
+ static GLuint displist2 = 0;
+ int hsize = STRIP_HEIGHT_HALF;
+
+ /* initialize 2 display lists for diamond shape - one empty, one filled */
+ if (displist1 == 0) {
+ displist1 = glGenLists(1);
+ glNewList(displist1, GL_COMPILE);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(_unit_diamond_shape[0]);
+ glVertex2fv(_unit_diamond_shape[1]);
+ glVertex2fv(_unit_diamond_shape[2]);
+ glVertex2fv(_unit_diamond_shape[3]);
+ glEnd();
+ glEndList();
+ }
+ if (displist2 == 0) {
+ displist2 = glGenLists(1);
+ glNewList(displist2, GL_COMPILE);
+
+ glBegin(GL_QUADS);
+ glVertex2fv(_unit_diamond_shape[0]);
+ glVertex2fv(_unit_diamond_shape[1]);
+ glVertex2fv(_unit_diamond_shape[2]);
+ glVertex2fv(_unit_diamond_shape[3]);
+ glEnd();
+ glEndList();
+ }
+
+ glPushMatrix();
+
+ /* adjust view transform before starting */
+ glTranslatef(x, y, 0.0f);
+ glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f);
+
+ /* anti-aliased lines for more consistent appearance */
+ glEnable(GL_LINE_SMOOTH);
+
+ if (sel)
+ UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255*(1.0f-alpha));
+ else
+ glColor4f(0.91f, 0.91f, 0.91f, alpha);
+
+ glCallList(displist2);
+
+ /* exterior - black frame */
+ glColor4f(0.0f, 0.0f, 0.0f, alpha);
+ glCallList(displist1);
+
+ glDisable(GL_LINE_SMOOTH);
+
+ /* restore view transform */
+ glPopMatrix();
+}
+
+void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
+{
+ MovieClip *clip = ED_space_clip(sc);
+ View2D *v2d = &ar->v2d;
+
+ /* frame range */
+ clip_draw_sfra_efra(v2d, scene);
+
+ if (clip) {
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingDopesheetChannel *channel;
+ float y, xscale, yscale;
+ float strip[4], selected_strip[4];
+
+ y = (float) CHANNEL_FIRST;
+
+ UI_view2d_getscale(v2d, &xscale, &yscale);
+
+ /* setup colors for regular and selected strips */
+ UI_GetThemeColor3fv(TH_STRIP, strip);
+ UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip);
+
+ strip[3] = 0.5f;
+ selected_strip[3] = 1.0f;
+
+ glEnable(GL_BLEND);
+
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
+ float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
+ {
+ MovieTrackingTrack *track = channel->track;
+ float alpha;
+ int i, sel = track->flag & TRACK_DOPE_SEL;
+
+ /* selection background */
+ if (sel) {
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
+ float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f};
+
+ track_channel_color(track, default_color, color);
+ glColor4fv(color);
+
+ glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
+ v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
+ }
+
+ alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;
+
+ /* tracked segments */
+ i = 0;
+ while (i < track->markersnr) {
+ MovieTrackingMarker *marker = &track->markers[i];
+
+ if ((marker->flag & MARKER_DISABLED) == 0) {
+ MovieTrackingMarker *start_marker = marker;
+ int prev_fra = marker->framenr, len = 0;
+
+ i++;
+ while (i < track->markersnr) {
+ marker = &track->markers[i];
+
+ if (marker->framenr != prev_fra + 1)
+ break;
+ if (marker->flag & MARKER_DISABLED)
+ break;
+
+ prev_fra = marker->framenr;
+ len++;
+ i++;
+ }
+
+ if (sel)
+ glColor4fv(selected_strip);
+ else
+ glColor4fv(strip);
+
+ if (len) {
+ glRectf(start_marker->framenr, (float) y - STRIP_HEIGHT_HALF,
+ start_marker->framenr + len, (float) y + STRIP_HEIGHT_HALF);
+ draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha);
+ draw_keyframe_shape(start_marker->framenr + len, y, xscale, yscale, sel, alpha);
+ }
+ else {
+ draw_keyframe_shape(start_marker->framenr, y, xscale, yscale, sel, alpha);
+ }
+ }
+
+ i++;
+ }
+
+ /* keyframes */
+ i = 0;
+ while (i < track->markersnr) {
+ MovieTrackingMarker *marker = &track->markers[i];
+
+ if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0)
+ draw_keyframe_shape(marker->framenr, y, xscale, yscale, sel, alpha);
+
+ i++;
+ }
+ }
+
+ /* adjust y-position for next one */
+ y -= CHANNEL_STEP;
+ }
+
+ glDisable(GL_BLEND);
+ }
+
+ /* current frame */
+ clip_draw_cfra(sc, ar, scene);
+}
+
+void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ View2D *v2d = &ar->v2d;
+ MovieClip *clip = ED_space_clip(sc);
+ MovieTracking *tracking;
+ MovieTrackingDopesheet *dopesheet;
+ MovieTrackingDopesheetChannel *channel;
+ uiStyle *style = UI_GetStyle();
+ uiBlock *block;
+ int fontid = style->widget.uifont_id;
+ int height;
+ float y;
+
+ if (!clip)
+ return;
+
+ tracking = &clip->tracking;
+ dopesheet = &tracking->dopesheet;
+ height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT * 2);
+
+ if (height > (v2d->mask.ymax - v2d->mask.ymin)) {
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
+ */
+ v2d->tot.ymin = (float)(-height);
+ }
+
+ /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
+ UI_view2d_sync(NULL, sa, v2d, V2D_LOCK_COPY);
+
+ /* loop through channels, and set up drawing depending on their type
+ * first pass: just the standard GL-drawing for backdrop + text
+ */
+ y = (float) CHANNEL_FIRST;
+
+ BLF_size(fontid, 11.0f, U.dpi);
+
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ float yminc = (float) (y - CHANNEL_HEIGHT_HALF);
+ float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF);
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
+ {
+ MovieTrackingTrack *track = channel->track;
+ float font_height, color[3];
+ int sel = track->flag & TRACK_DOPE_SEL;
+
+ track_channel_color(track, NULL, color);
+ glColor3fv(color);
+
+ glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF,
+ v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF);
+
+ if (sel)
+ UI_ThemeColor(TH_TEXT_HI);
+ else
+ UI_ThemeColor(TH_TEXT);
+
+ font_height = BLF_height(fontid, track->name);
+ BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD,
+ y - font_height / 2.0f, 0.0f);
+ BLF_draw(fontid, track->name, strlen(track->name));
+ }
+
+ /* adjust y-position for next one */
+ y -= CHANNEL_STEP;
+ }
+
+ /* second pass: widgets */
+ block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ y = (float) CHANNEL_FIRST;
+
+ glEnable(GL_BLEND);
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
+ float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax))
+ {
+ MovieTrackingTrack *track = channel->track;
+ uiBut *but;
+ PointerRNA ptr;
+ int icon;
+
+ RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr);
+
+ if (track->flag & TRACK_LOCKED)
+ icon = ICON_LOCKED;
+ else
+ icon = ICON_UNLOCKED;
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but = uiDefIconButR(block, ICONTOG, 1, icon,
+ v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD, y - UI_UNIT_Y / 2.0f,
+ UI_UNIT_X, UI_UNIT_Y, &ptr, "lock", 0, 0, 0, 0, 0, NULL);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+
+ /* adjust y-position for next one */
+ y -= CHANNEL_STEP;
+ }
+ glDisable(GL_BLEND);
+
+ uiEndBlock(C, block);
+ uiDrawBlock(C, block);
+}
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
new file mode 100644
index 00000000000..9b9190e3e05
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -0,0 +1,139 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_graph_ops.c
+ * \ingroup spclip
+ */
+
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+#include "BKE_depsgraph.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+/********************** select channel operator *********************/
+
+static int dopesheet_select_channel_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip)
+ return sc->view == SC_VIEW_DOPESHEET;
+
+ return FALSE;
+}
+
+static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingDopesheetChannel *channel;
+ float location[2];
+ int extend = RNA_boolean_get(op->ptr, "extend");
+ int current_channel_index = 0, channel_index;
+
+ RNA_float_get_array(op->ptr, "location", location);
+ channel_index = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP;
+
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ MovieTrackingTrack *track = channel->track;
+
+ if (current_channel_index == channel_index) {
+ if (extend)
+ track->flag ^= TRACK_DOPE_SEL;
+ else
+ track->flag |= TRACK_DOPE_SEL;
+ }
+ else if (!extend)
+ track->flag &= ~TRACK_DOPE_SEL;
+
+ current_channel_index++;
+ }
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ float location[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
+ RNA_float_set_array(op->ptr, "location", location);
+
+ return dopesheet_select_channel_exec(C, op);
+}
+
+void CLIP_OT_dopesheet_select_channel(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Channel";
+ ot->description = "Select movie tracking channel";
+ ot->idname = "CLIP_OT_dopesheet_select_channel";
+
+ /* api callbacks */
+ ot->invoke = dopesheet_select_channel_invoke;
+ ot->exec = dopesheet_select_channel_exec;
+ ot->poll = dopesheet_select_channel_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
+ "Location", "Mouse location to select channel", -100.0f, 100.0f);
+ RNA_def_boolean(ot->srna, "extend", 0,
+ "Extend", "Extend selection rather than clearing the existing selection");
+}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index cd50366f854..443cb8f7ef4 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -118,13 +118,38 @@ int ED_space_clip_tracking_frame_poll(bContext *C)
/* ******** editing functions ******** */
-void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip)
+void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip)
{
+ MovieClip *old_clip;
+
+ if (!screen && C)
+ screen = CTX_wm_screen(C);
+
+ old_clip = sc->clip;
sc->clip = clip;
if (sc->clip && sc->clip->id.us==0)
sc->clip->id.us = 1;
+ if (screen) {
+ ScrArea *area;
+ SpaceLink *sl;
+
+ for (area = screen->areabase.first; area; area = area->next) {
+ for (sl = area->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *cur_sc = (SpaceClip *) sl;
+
+ if (cur_sc != sc) {
+ if (cur_sc->clip == old_clip || cur_sc->clip == NULL) {
+ cur_sc->clip = clip;
+ }
+ }
+ }
+ }
+ }
+ }
+
if (C)
WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip);
}
@@ -516,3 +541,11 @@ int ED_space_clip_show_trackedit(SpaceClip *sc)
return FALSE;
}
+
+void ED_space_clip_update_dopesheet(SpaceClip *sc)
+{
+ MovieClip *clip = sc->clip;
+ MovieTracking *tracking = &clip->tracking;
+
+ BKE_tracking_update_dopesheet(tracking);
+}
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index 7916a96f98c..03557a0b264 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -64,9 +64,13 @@
static int ED_space_clip_graph_poll(bContext *C)
{
if (ED_space_clip_tracking_poll(C)) {
- ARegion *ar = CTX_wm_region(C);
+ SpaceClip *sc = CTX_wm_space_clip(C);
- return ar->regiontype == RGN_TYPE_PREVIEW;
+ if (sc->view == SC_VIEW_GRAPH) {
+ ARegion *ar = CTX_wm_region(C);
+
+ return ar->regiontype == RGN_TYPE_PREVIEW;
+ }
}
return FALSE;
@@ -225,16 +229,10 @@ static int mouse_select_curve(bContext *C, float co[2], int extend)
}
}
else if (act_track != userdata.track) {
- MovieTrackingMarker *marker;
SelectUserData selectdata = {SEL_DESELECT};
tracking->act_track = userdata.track;
- /* make active track be centered to screen */
- marker = BKE_tracking_get_marker(userdata.track, sc->user.framenr);
-
- clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]);
-
/* deselect all knots on newly selected curve */
clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb);
}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 0b63ae5b12f..f32cb1651a1 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -42,11 +42,32 @@ struct ScrArea;
struct SpaceClip;
struct wmOperatorType;
+/* channel heights */
+#define CHANNEL_FIRST -UI_UNIT_Y
+#define CHANNEL_HEIGHT UI_UNIT_Y
+#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f)
+#define CHANNEL_SKIP 2
+#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP)
+
+#define CHANNEL_PAD 4
+
+/* extra padding for lengths (to go under scrollers) */
+#define EXTRA_SCROLL_PAD 100.0f
+
+#define STRIP_HEIGHT_HALF 5
+
/* internal exports only */
/* clip_buttons.c */
void ED_clip_buttons_register(struct ARegionType *art);
+/* clip_dopesheet_draw.c */
+void clip_draw_dopesheet_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene);
+void clip_draw_dopesheet_channels(const struct bContext *C, struct ARegion *ar);
+
+/* clip_dopesheet_ops.c */
+void CLIP_OT_dopesheet_select_channel(struct wmOperatorType *ot);
+
/* clip_draw.c */
void clip_draw_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene);
void clip_draw_grease_pencil(struct bContext *C, int onlyv2d);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index c7033b0db99..2bfc7a1dec8 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -147,6 +147,7 @@ static int open_cancel(bContext *UNUSED(C), wmOperator *op)
static int open_exec(bContext *C, wmOperator *op)
{
SpaceClip *sc = CTX_wm_space_clip(C);
+ bScreen *screen = CTX_wm_screen(C);
PropertyPointerRNA *pprop;
PointerRNA idptr;
MovieClip *clip = NULL;
@@ -184,7 +185,7 @@ static int open_exec(bContext *C, wmOperator *op)
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
else if (sc) {
- ED_space_clip_set(C, sc, clip);
+ ED_space_clip_set(C, screen, sc, clip);
}
WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index f64d2ba90cb..271ad84fec6 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -72,28 +72,76 @@
static void init_preview_region(const bContext *C, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceClip *sc = CTX_wm_space_clip(C);
ar->regiontype = RGN_TYPE_PREVIEW;
ar->alignment = RGN_ALIGN_TOP;
ar->flag |= RGN_FLAG_HIDDEN;
- ar->v2d.tot.xmin = 0.0f;
- ar->v2d.tot.ymin = -10.0f;
- ar->v2d.tot.xmax = (float)scene->r.efra;
- ar->v2d.tot.ymax = 10.0f;
+ if (sc->view == SC_VIEW_DOPESHEET) {
+ ar->v2d.tot.xmin = -10.0f;
+ ar->v2d.tot.ymin = (float)(-sa->winy)/3.0f;
+ ar->v2d.tot.xmax = (float)(sa->winx);
+ ar->v2d.tot.ymax = 0.0f;
+
+ ar->v2d.cur = ar->v2d.tot;
+
+ ar->v2d.min[0] = 0.0f;
+ ar->v2d.min[1] = 0.0f;
- ar->v2d.cur = ar->v2d.tot;
+ ar->v2d.max[0] = MAXFRAMEF;
+ ar->v2d.max[1] = FLT_MAX;
- ar->v2d.min[0] = FLT_MIN;
- ar->v2d.min[1] = FLT_MIN;
+ ar->v2d.minzoom = 0.01f;
+ ar->v2d.maxzoom = 50;
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
+ ar->v2d.keepofs = V2D_KEEPOFS_Y;
+ ar->v2d.align = V2D_ALIGN_NO_POS_Y;
+ ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+ }
+ else {
+ ar->v2d.tot.xmin = 0.0f;
+ ar->v2d.tot.ymin = -10.0f;
+ ar->v2d.tot.xmax = (float)scene->r.efra;
+ ar->v2d.tot.ymax = 10.0f;
- ar->v2d.max[0] = MAXFRAMEF;
- ar->v2d.max[1] = FLT_MAX;
+ ar->v2d.cur = ar->v2d.tot;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.min[0] = FLT_MIN;
+ ar->v2d.min[1] = FLT_MIN;
- ar->v2d.keeptot = 0;
+ ar->v2d.max[0] = MAXFRAMEF;
+ ar->v2d.max[1] = FLT_MAX;
+
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
+
+ ar->v2d.minzoom = 0.0f;
+ ar->v2d.maxzoom = 0.0f;
+ ar->v2d.keepzoom = 0;
+ ar->v2d.keepofs = 0;
+ ar->v2d.align = 0;
+ ar->v2d.flag = 0;
+
+ ar->v2d.keeptot = 0;
+ }
+}
+
+static void reinit_preview_region(const bContext *C, ARegion *ar)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc->view == SC_VIEW_DOPESHEET) {
+ if ((ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0)
+ init_preview_region(C, ar);
+ }
+ else {
+ if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL)
+ init_preview_region(C, ar);
+ }
}
static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *sa)
@@ -119,6 +167,33 @@ static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *sa)
return arnew;
}
+static ARegion *ED_clip_has_channels_region(ScrArea *sa)
+{
+ ARegion *ar, *arnew;
+
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
+ if (ar)
+ return ar;
+
+ /* add subdiv level; after header */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
+
+ /* is error! */
+ if (ar == NULL)
+ return NULL;
+
+ arnew = MEM_callocN(sizeof(ARegion), "clip channels region");
+
+ BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_CHANNELS;
+ arnew->alignment = RGN_ALIGN_LEFT;
+
+ arnew->v2d.scroll = V2D_SCROLL_BOTTOM;
+ arnew->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+
+ return arnew;
+}
+
static void clip_scopes_tag_refresh(ScrArea *sa)
{
SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
@@ -190,6 +265,16 @@ static SpaceLink *clip_new(const bContext *C)
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
+ /* channels view */
+ ar = MEM_callocN(sizeof(ARegion), "channels for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype = RGN_TYPE_CHANNELS;
+ ar->alignment = RGN_ALIGN_LEFT;
+
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+ ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+
/* preview view */
ar = MEM_callocN(sizeof(ARegion), "preview for clip");
@@ -214,6 +299,8 @@ static void clip_free(SpaceLink *sl)
if (sc->scopes.track_preview)
IMB_freeImBuf(sc->scopes.track_preview);
+
+ ED_space_clip_free_texture_buffer(sc);
}
/* spacetype; init callback */
@@ -229,6 +316,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
scn->scopes.track_preview = NULL;
scn->scopes.ok = FALSE;
+ scn->draw_context = NULL;
return (SpaceLink *)scn;
}
@@ -391,6 +479,10 @@ static void clip_operatortypes(void)
WM_operatortype_append(CLIP_OT_graph_center_current_frame);
WM_operatortype_append(CLIP_OT_graph_disable_markers);
+
+ /* ** clip_dopesheet_ops.c ** */
+
+ WM_operatortype_append(CLIP_OT_dopesheet_select_channel);
}
static void clip_keymap(struct wmKeyConfig *keyconf)
@@ -609,6 +701,13 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "action", 2); /* toggle */
transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
+
+ /* ******** Hotkeys avalaible for channels region only ******** */
+
+ keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
+
+ kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
}
const char *clip_context_dir[]= {"edit_movieclip", NULL};
@@ -643,8 +742,9 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
ARegion *ar_tool_props = BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS);
ARegion *ar_preview = ED_clip_has_preview_region(C, sa);
ARegion *ar_properties = ED_clip_has_properties_region(sa);
+ ARegion *ar_channels = ED_clip_has_channels_region(sa);
int main_visible = FALSE, preview_visible = FALSE, tools_visible = FALSE;
- int tool_props_visible = FALSE, properties_visible = FALSE;
+ int tool_props_visible = FALSE, properties_visible = FALSE, channels_visible = FALSE;
int view_changed = FALSE;
switch (sc->view) {
@@ -654,13 +754,27 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
tools_visible = TRUE;
tool_props_visible = TRUE;
properties_visible = TRUE;
+ channels_visible = FALSE;
break;
case SC_VIEW_GRAPH:
- main_visible = TRUE;
+ main_visible = FALSE;
preview_visible = TRUE;
- tools_visible = TRUE;
- tool_props_visible = TRUE;
- properties_visible = TRUE;
+ tools_visible = FALSE;
+ tool_props_visible = FALSE;
+ properties_visible = FALSE;
+ channels_visible = FALSE;
+
+ reinit_preview_region(C, ar_preview);
+ break;
+ case SC_VIEW_DOPESHEET:
+ main_visible = FALSE;
+ preview_visible = TRUE;
+ tools_visible = FALSE;
+ tool_props_visible = FALSE;
+ properties_visible = FALSE;
+ channels_visible = TRUE;
+
+ reinit_preview_region(C, ar_preview);
break;
}
@@ -768,23 +882,12 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
ar_preview->v2d.cur = ar_preview->v2d.tot;
view_changed = TRUE;
}
- if (ar_preview && !ELEM(ar_preview->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
- if (sc->runtime_flag & SC_GRAPH_BOTTOM)
- ar_preview->alignment = RGN_ALIGN_BOTTOM;
- else
- ar_preview->alignment = RGN_ALIGN_TOP;
-
+ if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
+ ar_preview->alignment = RGN_ALIGN_NONE;
view_changed = TRUE;
}
}
else {
- /* store graph region align */
- if (ar_preview) {
- if (ar_preview->alignment == RGN_ALIGN_TOP)
- sc->runtime_flag &= ~SC_GRAPH_BOTTOM;
- else if (ar_preview->alignment == RGN_ALIGN_BOTTOM)
- sc->runtime_flag |= SC_GRAPH_BOTTOM;
- }
if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
ar_preview->flag |= RGN_FLAG_HIDDEN;
ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
@@ -797,6 +900,30 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
}
}
+ if (channels_visible) {
+ if (ar_channels && (ar_channels->flag & RGN_FLAG_HIDDEN)) {
+ ar_channels->flag &= ~RGN_FLAG_HIDDEN;
+ ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ view_changed = TRUE;
+ }
+ if (ar_channels && ar_channels->alignment != RGN_ALIGN_LEFT) {
+ ar_channels->alignment = RGN_ALIGN_LEFT;
+ view_changed = TRUE;
+ }
+ }
+ else {
+ if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) {
+ ar_channels->flag |= RGN_FLAG_HIDDEN;
+ ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
+ view_changed = TRUE;
+ }
+ if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) {
+ ar_channels->alignment = RGN_ALIGN_NONE;
+ view_changed = TRUE;
+ }
+ }
+
if (view_changed) {
ED_area_initialize(wm, window, sa);
ED_area_tag_redraw(sa);
@@ -976,15 +1103,92 @@ static void graph_area_draw(const bContext *C, ARegion *ar)
UI_view2d_scrollers_free(scrollers);
}
+static void dopesheet_area_draw(const bContext *C, ARegion *ar)
+{
+ Scene *scene = CTX_data_scene(C);
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ View2D *v2d = &ar->v2d;
+ View2DGrid *grid;
+ View2DScrollers *scrollers;
+ short unit = 0;
+
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* time grid */
+ unit = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
+ grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
+ UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+ UI_view2d_grid_free(grid);
+
+ /* data... */
+ clip_draw_dopesheet_main(sc, ar, scene);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
+}
+
static void clip_preview_area_draw(const bContext *C, ARegion *ar)
{
- graph_area_draw(C, ar);
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc->view == SC_VIEW_GRAPH)
+ graph_area_draw(C, ar);
+ else if (sc->view == SC_VIEW_DOPESHEET)
+ dopesheet_area_draw(C, ar);
}
static void clip_preview_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
{
}
+/****************** channels region ******************/
+
+static void clip_channels_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+}
+
+static void clip_channels_area_draw(const bContext *C, ARegion *ar)
+{
+ View2D *v2d = &ar->v2d;
+ View2DScrollers *scrollers;
+
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* data... */
+ clip_draw_dopesheet_channels(C, ar);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
+}
+
+static void clip_channels_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+{
+}
+
/****************** header region ******************/
/* add handlers, stuff you only do once or on area/region changes */
@@ -1162,4 +1366,15 @@ void ED_spacetype_clip(void)
BLI_addhead(&st->regiontypes, art);
BKE_spacetype_register(st);
+
+ /* channels */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype clip channels region");
+ art->regionid = RGN_TYPE_CHANNELS;
+ art->prefsizex = UI_COMPACT_PANEL_WIDTH;
+ art->keymapflag = ED_KEYMAP_FRAMES|ED_KEYMAP_UI;
+ art->listener = clip_channels_area_listener;
+ art->init = clip_channels_area_init;
+ art->draw = clip_channels_area_draw;
+
+ BLI_addhead(&st->regiontypes, art);
}
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index b3bb7464761..2c9b61ed1ef 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -95,6 +95,8 @@ static void add_marker(SpaceClip *sc, float x, float y)
BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0);
clip->tracking.act_track = track;
+
+ ED_space_clip_update_dopesheet(sc);
}
static int add_marker_exec(bContext *C, wmOperator *op)
@@ -174,6 +176,8 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
/* nothing selected now, unlock view so it can be scrolled nice again */
sc->flag &= ~SC_LOCK_SELECTION;
+ ED_space_clip_update_dopesheet(sc);
+
return OPERATOR_FINISHED;
}
@@ -225,6 +229,8 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
sc->flag &= ~SC_LOCK_SELECTION;
}
+ ED_space_clip_update_dopesheet(sc);
+
return OPERATOR_FINISHED;
}
@@ -790,6 +796,7 @@ static int mouse_select(bContext *C, float co[2], int extend)
}
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+ ED_space_clip_update_dopesheet(sc);
return OPERATOR_FINISHED;
}
@@ -901,6 +908,8 @@ static int border_select_exec(bContext *C, wmOperator *op)
}
if (change) {
+ ED_space_clip_update_dopesheet(sc);
+
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
return OPERATOR_FINISHED;
@@ -985,6 +994,8 @@ static int circle_select_exec(bContext *C, wmOperator *op)
}
if (change) {
+ ED_space_clip_update_dopesheet(sc);
+
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
return OPERATOR_FINISHED;
@@ -1081,6 +1092,8 @@ static int select_all_exec(bContext *C, wmOperator *op)
if (!has_selection)
sc->flag &= ~SC_LOCK_SELECTION;
+ ED_space_clip_update_dopesheet(sc);
+
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
return OPERATOR_FINISHED;
@@ -1161,6 +1174,8 @@ static int select_groped_exec(bContext *C, wmOperator *op)
track = track->next;
}
+ ED_space_clip_update_dopesheet(sc);
+
WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
return OPERATOR_FINISHED;
@@ -2730,6 +2745,8 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
sc->flag &= ~SC_LOCK_SELECTION;
}
+ BKE_tracking_update_dopesheet(tracking);
+
WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL);
return OPERATOR_FINISHED;