void clip_draw_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) { View2D *v2d = &ar->v2d; float xscale, yscale; float vec[2]; /* Draw a light green line to indicate current frame */ vec[0] = (float)(sc->user.framenr * scene->r.framelen); UI_ThemeColor(TH_CFRAME); glLineWidth(2.0); glBegin(GL_LINE_STRIP); vec[1] = v2d->cur.ymin; glVertex2fv(vec); vec[1] = v2d->cur.ymax; glVertex2fv(vec); glEnd(); glLineWidth(1.0); UI_view2d_view_orthoSpecial(ar, v2d, 1); /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); clip_draw_curfra_label(sc->user.framenr, (float)sc->user.framenr * xscale, 18); /* restore view transform */ glScalef(xscale, 1.0, 1.0); }
/* helper func - draw keyframe vertices only for an F-Curve */ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu) { FPoint *first, *last; float hsize, xscale, yscale; /* get view settings */ hsize = UI_GetThemeValuef(TH_VERTEX_SIZE); UI_view2d_getscale(&ar->v2d, &xscale, &yscale); /* set vertex color */ if (fcu->flag & (FCURVE_ACTIVE | FCURVE_SELECTED)) UI_ThemeColor(TH_TEXT_HI); else UI_ThemeColor(TH_TEXT); /* get verts */ first = fcu->fpt; last = (first) ? (first + (fcu->totvert - 1)) : (NULL); /* draw */ if (first && last) { /* anti-aliased lines for more consistent appearance */ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize); draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize); glDisable(GL_BLEND); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH); } }
static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking); int width, height; struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata; BKE_movieclip_get_size(clip, &sc->user, &width, &height); if(!width || !height) return; /* non-selected knot handles */ userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); userdata.sel= 0; userdata.act_track= act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel= 1; clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); }
void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *scaley) { if (sa && sa->spacedata.first) { switch (sa->spacetype) { case SPACE_CLIP: { SpaceClip *sc = sa->spacedata.first; float aspx, aspy; UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_clip_get_aspect(sc, &aspx, &aspy); *scalex *= aspx; *scaley *= aspy; break; } case SPACE_SEQ: { *scalex = *scaley = 1.0f; /* MASKTODO? */ break; } case SPACE_IMAGE: { SpaceImage *sima = sa->spacedata.first; float aspx, aspy; UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_image_get_aspect(sima, &aspx, &aspy); *scalex *= aspx; *scaley *= aspy; break; } default: /* possible other spaces from which mask editing is available */ BLI_assert(0); *scalex = *scaley = 1.0f; break; } } else { BLI_assert(0); *scalex = *scaley = 1.0f; } }
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ static void draw_fcurve_vertices_handles(FCurve *fcu, SpaceIpo *sipo, View2D *v2d, short sel, short sel_handle_only, float units_scale) { BezTriple *bezt = fcu->bezt; BezTriple *prevbezt = NULL; float hsize, xscale, yscale; int i; /* get view settings */ hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize; UI_view2d_getscale(v2d, &xscale, &yscale); /* Compensate OGL scale sued for unit mapping, so circle will be circle, not ellipse */ yscale *= units_scale; /* set handle color */ if (sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); else UI_ThemeColor(TH_HANDLE_VERTEX); /* anti-aliased lines for more consistent appearance */ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); for (i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) { /* Draw the editmode handles for a bezier curve (others don't have handles) * if their selection status matches the selection status we're drawing for * - first handle only if previous beztriple was bezier-mode * - second handle only if current beztriple is bezier-mode * * Also, need to take into account whether the keyframe was selected * if a Graph Editor option to only show handles of selected keys is on. */ if (!sel_handle_only || BEZSELECTED(bezt)) { if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { if ((bezt->f1 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax)*/ draw_fcurve_handle_control(bezt->vec[0][0], bezt->vec[0][1], xscale, yscale, hsize); } if (bezt->ipo == BEZT_IPO_BEZ) { if ((bezt->f3 & SELECT) == sel) /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax)*/ draw_fcurve_handle_control(bezt->vec[2][0], bezt->vec[2][1], xscale, yscale, hsize); } } } if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); }
/* draw the keyframes in the specified Action */ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, View2D *v2d, float y, float ymin, float ymax) { DLRBT_Tree keys; ActKeyColumn *ak; float xscale, f1, f2; float color[4]; /* get a list of the keyframes with NLA-scaling applied */ BLI_dlrbTree_init(&keys); action_to_keylist(adt, act, &keys, NULL); BLI_dlrbTree_linkedlist_sync(&keys); if (ELEM(NULL, act, keys.first)) return; /* draw a darkened region behind the strips * - get and reset the background color, this time without the alpha to stand out better * (amplified alpha is used instead) */ nla_action_get_color(adt, act, color); color[3] *= 2.5f; glColor4fv(color); /* - draw a rect from the first to the last frame (no extra overlaps for now) * that is slightly stumpier than the track background (hardcoded 2-units here) */ f1 = ((ActKeyColumn *)keys.first)->cfra; f2 = ((ActKeyColumn *)keys.last)->cfra; glRectf(f1, ymin + 2, f2, ymax - 2); /* get View2D scaling factor */ UI_view2d_getscale(v2d, &xscale, NULL); /* for now, color is hardcoded to be black */ glColor3f(0.0f, 0.0f, 0.0f); /* just draw each keyframe as a simple dot (regardless of the selection status) * - size is 3.0f which is smaller than the editable keyframes, so that there is a distinction */ for (ak = keys.first; ak; ak = ak->next) draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f); /* free icons */ BLI_dlrbTree_free(&keys); }
static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); int width, height; TrackMotionCurveUserData userdata; BKE_movieclip_get_size(clip, &sc->user, &width, &height); if (!width || !height) return; /* non-selected knot handles */ userdata.hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); userdata.sel = false; userdata.act_track = act_track; UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); /* draw graph lines */ glEnable(GL_BLEND); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); glDisable(GL_BLEND); /* selected knot handles on top of curves */ userdata.sel = TRUE; clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, &userdata, tracking_segment_knot_cb, NULL, NULL); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time) { float xscale, yscale, x, y; char numstr[32] = " t"; /* t is the character to start replacing from */ short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); /* get timecode string * - padding on str-buf passed so that it doesn't sit on the frame indicator * - power = 0, gives 'standard' behavior for time * but power = 1 is required for frames (to get integer frames) */ if (time) ANIM_timecode_string_from_frame(&numstr[4], scene, 0, time, FRA2TIME(cfra)); else ANIM_timecode_string_from_frame(&numstr[4], scene, 1, time, cfra); slen = (short)UI_GetStringWidth(numstr) - 1; /* get starting coordinates for drawing */ x = cfra * xscale; y = 0.9f * U.widget_unit; /* draw green box around/behind text */ UI_ThemeColorShade(TH_CFRAME, 0); glRectf(x, y, x + slen, y + 0.75f * U.widget_unit); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); }
/* function to draw markers */ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) { float xpos, ypixels, xscale, yscale; int icon_id = 0; xpos = marker->frame; /* no time correction for framelen! space is drawn with old values */ ypixels = BLI_rcti_size_y(&v2d->mask); UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* vertical line - dotted */ #ifdef DURIAN_CAMERA_SWITCH if ((marker->camera) || (flag & DRAW_MARKERS_LINES)) #else if (flag & DRAW_MARKERS_LINES) #endif { setlinestyle(3); if (marker->flag & SELECT) glColor4ub(255, 255, 255, 96); else glColor4ub(0, 0, 0, 96); glBegin(GL_LINES); glVertex2f((xpos * xscale) + 0.5f, 12.0f); glVertex2f((xpos * xscale) + 0.5f, (v2d->cur.ymax + 12.0f) * yscale); glEnd(); setlinestyle(0); } /* 5 px to offset icon to align properly, space / pixels corrects for zoom */ if (flag & DRAW_MARKERS_LOCAL) { icon_id = (marker->flag & ACTIVE) ? ICON_PMARKER_ACT : (marker->flag & SELECT) ? ICON_PMARKER_SEL : ICON_PMARKER; } else { icon_id = (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER; } UI_icon_draw(xpos * xscale - 0.45f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id); glDisable(GL_BLEND); /* and the marker name too, shifted slightly to the top-right */ if (marker->name && marker->name[0]) { float x, y; /* minimal y coordinate which wouldn't be occluded by scroll */ int min_y = 17.0f * UI_DPI_FAC; if (marker->flag & SELECT) { UI_ThemeColor(TH_TEXT_HI); x = xpos * xscale + 4.0f * UI_DPI_FAC; y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; y = max_ii(y, min_y); } else { UI_ThemeColor(TH_TEXT); if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) { x = xpos * xscale + 8.0f * UI_DPI_FAC; y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; y = max_ii(y, min_y); } else { x = xpos * xscale + 8.0f * UI_DPI_FAC; y = 17.0f * UI_DPI_FAC; } } #ifdef DURIAN_CAMERA_SWITCH if (marker->camera && (marker->camera->restrictflag & OB_RESTRICT_RENDER)) { float col[4]; glGetFloatv(GL_CURRENT_COLOR, col); col[3] = 0.4; glColor4fv(col); } #endif UI_DrawString(x, y, marker->name); } glScalef(xscale, 1.0f, 1.0f); }
/* function to draw markers */ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) { float xpos, ypixels, xscale, yscale; int icon_id= 0; xpos = marker->frame; /* no time correction for framelen! space is drawn with old values */ ypixels= v2d->mask.ymax-v2d->mask.ymin; UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f/xscale, 1.0f, 1.0f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* vertical line - dotted */ // NOTE: currently only used for sequencer if (flag & DRAW_MARKERS_LINES) { setlinestyle(3); if (marker->flag & SELECT) glColor4ub(255, 255, 255, 96); else glColor4ub(0, 0, 0, 96); glBegin(GL_LINES); glVertex2f((xpos*xscale)+0.5f, 12.0f); glVertex2f((xpos*xscale)+0.5f, 34.0f*yscale); /* a bit lazy but we know it cant be greater then 34 strips high */ glEnd(); setlinestyle(0); } /* 5 px to offset icon to align properly, space / pixels corrects for zoom */ if (flag & DRAW_MARKERS_LOCAL) { icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT : (marker->flag & SELECT) ? ICON_PMARKER_SEL : ICON_PMARKER; } else { icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER; } UI_icon_draw(xpos*xscale-5.0f, 16.0f, icon_id); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); /* and the marker name too, shifted slightly to the top-right */ if (marker->name && marker->name[0]) { float x, y; if (marker->flag & SELECT) { UI_ThemeColor(TH_TEXT_HI); x= xpos*xscale + 4.0f; y= (ypixels <= 39.0f)? (ypixels-10.0f) : 29.0f; } else { UI_ThemeColor(TH_TEXT); if((marker->frame <= cfra) && (marker->frame+5 > cfra)) { x= xpos*xscale + 4.0f; y= (ypixels <= 39.0f)? (ypixels - 10.0f) : 29.0f; } else { x= xpos*xscale + 4.0f; y= 17.0f; } } UI_DrawString(x, y, marker->name); } glScalef(xscale, 1.0f, 1.0f); }
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) { MovieClip *clip = ED_space_clip_get_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]; float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT); /* 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); 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); clip_draw_dopesheet_background(ar, clip); 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 */ for (i = 0; i < channel->tot_segment; i++) { int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, 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); draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha); } else { draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); } } /* keyframes */ i = 0; while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); draw_keyframe_shape(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); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) { float xscale, yscale, x, y; char str[32]; short slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_getscale(v2d, &xscale, &yscale); glScalef(1.0f/xscale, 1.0f, 1.0f); if (time) { /* Timecode: * - In general, minutes and seconds should be shown, as most clips will be * within this length. Hours will only be included if relevant. * - Only show frames when zoomed in enough for them to be relevant * (using separator of '!' for frames). * When showing frames, use slightly different display to avoid confusion with mm:ss format * TODO: factor into reusable function. * Meanwhile keep in sync: * source/blender/editors/animation/anim_draw.c * source/blender/editors/interface/view2d.c */ float val= FRA2TIME(CFRA); int hours=0, minutes=0, seconds=0, frames=0; char neg[2]= ""; /* get values */ if (val < 0) { /* correction for negative values */ sprintf(neg, "-"); val = -val; } if (val >= 3600) { /* hours */ /* XXX should we only display a single digit for hours since clips are * VERY UNLIKELY to be more than 1-2 hours max? However, that would * go against conventions... */ hours= (int)val / 3600; val= (float)fmod(val, 3600); } if (val >= 60) { /* minutes */ minutes= (int)val / 60; val= (float)fmod(val, 60); } { /* seconds + frames * Frames are derived from 'fraction' of second. We need to perform some additional rounding * to cope with 'half' frames, etc., which should be fine in most cases */ seconds= (int)val; frames= (int)floor( ((val - seconds) * FPS) + 0.5f ); } /* print timecode to temp string buffer */ if (hours) sprintf(str, " %s%02d:%02d:%02d!%02d", neg, hours, minutes, seconds, frames); else if (minutes) sprintf(str, " %s%02d:%02d!%02d", neg, minutes, seconds, frames); else sprintf(str, " %s%d!%02d", neg, seconds, frames); } else sprintf(str, " %d", CFRA); slen= (short)UI_GetStringWidth(str) - 1; /* get starting coordinates for drawing */ x= cfra * xscale; y= 18; /* draw green box around/behind text */ UI_ThemeColorShadeAlpha(TH_CFRAME, 0, -100); glRectf(x, y, x+slen, y+15); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); UI_DrawString(x-5, y+3, str); // XXX may need to be updated for font stuff /* restore view transform */ glScalef(xscale, 1.0, 1.0); }