static void ed_marker_move_update_header(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); MarkerMove *mm = op->customdata; TimeMarker *marker, *selmarker = NULL; const int offs = RNA_int_get(op->ptr, "frames"); char str[256]; char str_offs[NUM_STR_REP_LEN]; int totmark; const bool use_time = ed_marker_move_use_time(mm); for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) { if (marker->flag & SELECT) { selmarker = marker; totmark++; } } if (hasNumInput(&mm->num)) { outputNumInput(&mm->num, str_offs, &scene->unit); } else if (use_time) { BLI_snprintf(str_offs, sizeof(str_offs), "%.2f", FRA2TIME(offs)); } else { BLI_snprintf(str_offs, sizeof(str_offs), "%d", offs); } if (totmark == 1 && selmarker) { /* we print current marker value */ if (use_time) { BLI_snprintf(str, sizeof(str), "Marker %.2f offset %s", FRA2TIME(selmarker->frame), str_offs); } else { BLI_snprintf(str, sizeof(str), "Marker %d offset %s", selmarker->frame, str_offs); } } else { BLI_snprintf(str, sizeof(str), "Marker offset %s", str_offs); } ED_area_headerprint(CTX_wm_area(C), str); }
/* Draw current frame number in a little green box beside the current frame indicator */ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const bool time) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; float xscale, yscale, x, y; char numstr[32] = " t"; /* t is the character to start replacing from */ int slen; /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_scale_get(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) { BLI_timecode_string_from_time(&numstr[4], sizeof(numstr) - 4, 0, FRA2TIME(cfra), FPS, U.timecode_style); } else { BLI_timecode_string_from_time_seconds(&numstr[4], sizeof(numstr) - 4, 1, cfra); } slen = UI_fontstyle_string_width(fstyle, 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_fontstyle_draw_simple(fstyle, x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); }
/* 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); }
static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event) { Scene *scene = CTX_data_scene(C); MarkerMove *mm = op->customdata; View2D *v2d = UI_view2d_fromcontext(C); TimeMarker *marker, *selmarker = NULL; float dx, fac; char str[256]; switch (event->type) { case ESCKEY: ed_marker_move_cancel(C, op); return OPERATOR_CANCELLED; case RIGHTMOUSE: /* press = user manually demands transform to be canceled */ if (event->val == KM_PRESS) { ed_marker_move_cancel(C, op); return OPERATOR_CANCELLED; } /* else continue; <--- see if release event should be caught for tweak-end */ case RETKEY: case PADENTER: case LEFTMOUSE: case MIDDLEMOUSE: if (WM_modal_tweak_exit(event, mm->event_type)) { ed_marker_move_exit(C, op); WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL); return OPERATOR_FINISHED; } break; case MOUSEMOVE: if (hasNumInput(&mm->num)) break; dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); if (event->x != mm->evtx) { /* XXX maybe init for first time */ int a, offs, totmark = 0; mm->evtx = event->x; fac = ((float)(event->x - mm->firstx) * dx); if (mm->slink->spacetype == SPACE_TIME) apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0); else apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/); offs = (int)fac; RNA_int_set(op->ptr, "frames", offs); ed_marker_move_apply(C, op); /* cruft below is for header print */ for (a = 0, marker = mm->markers->first; marker; marker = marker->next) { if (marker->flag & SELECT) { selmarker = marker; a++; totmark++; } } if (totmark == 1) { /* we print current marker value */ if (mm->slink->spacetype == SPACE_TIME) { SpaceTime *stime = (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) BLI_snprintf(str, sizeof(str), "Marker %d offset %d", selmarker->frame, offs); else BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); } else if (mm->slink->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)mm->slink; if (saction->flag & SACTION_DRAWTIME) BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); else BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); } else { BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); } } else { /* we only print the offset */ if (mm->slink->spacetype == SPACE_TIME) { SpaceTime *stime = (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) BLI_snprintf(str, sizeof(str), "Marker offset %d ", offs); else BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs)); } else if (mm->slink->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)mm->slink; if (saction->flag & SACTION_DRAWTIME) BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs)); else BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs)); } else { BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs)); } } ED_area_headerprint(CTX_wm_area(C), str); } } if (event->val == KM_PRESS) { if (handleNumInput(&mm->num, event)) { char str_tx[NUM_STR_REP_LEN]; float value = RNA_int_get(op->ptr, "frames"); applyNumInput(&mm->num, &value); if (hasNumInput(&mm->num)) { outputNumInput(&mm->num, str_tx); } else { BLI_snprintf(str_tx, sizeof(str_tx), "%d", (int)value); } RNA_int_set(op->ptr, "frames", value); ed_marker_move_apply(C, op); // ed_marker_header_update(C, op, str, (int)value); // strcat(str, str_tx); BLI_snprintf(str, sizeof(str), "Marker offset %s", str_tx); ED_area_headerprint(CTX_wm_area(C), str); } } return OPERATOR_RUNNING_MODAL; }
static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) { Scene *scene= CTX_data_scene(C); MarkerMove *mm= op->customdata; View2D *v2d= UI_view2d_fromcontext(C); TimeMarker *marker, *selmarker=NULL; float dx, fac; char str[256]; switch(evt->type) { case ESCKEY: ed_marker_move_cancel(C, op); return OPERATOR_CANCELLED; case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: if(WM_modal_tweak_exit(evt, mm->event_type)) { ed_marker_move_exit(C, op); WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); return OPERATOR_FINISHED; } break; case MOUSEMOVE: dx= v2d->mask.xmax-v2d->mask.xmin; dx= (v2d->cur.xmax-v2d->cur.xmin)/dx; if (evt->x != mm->evtx) { /* XXX maybe init for firsttime */ int a, offs, totmark=0; mm->evtx= evt->x; fac= ((float)(evt->x - mm->firstx)*dx); if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0); else apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID); offs= (int)fac; RNA_int_set(op->ptr, "frames", offs); ed_marker_move_apply(C, op); /* cruft below is for header print */ for (a=0, marker= mm->markers->first; marker; marker= marker->next) { if (marker->flag & SELECT) { selmarker= marker; a++; totmark++; } } if (totmark==1) { /* we print current marker value */ if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) { SpaceTime *stime= (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) sprintf(str, "Marker %d offset %d", selmarker->frame, offs); else sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); } else if (mm->slink->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)mm->slink; if (saction->flag & SACTION_DRAWTIME) sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); else sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); } else { sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); } } else { /* we only print the offset */ if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) { SpaceTime *stime= (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) sprintf(str, "Marker offset %d ", offs); else sprintf(str, "Marker offset %.2f ", FRA2TIME(offs)); } else if (mm->slink->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)mm->slink; if (saction->flag & SACTION_DRAWTIME) sprintf(str, "Marker offset %.2f ", FRA2TIME(offs)); else sprintf(str, "Marker offset %.2f ", (double)(offs)); } else { sprintf(str, "Marker offset %.2f ", (double)(offs)); } } WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); ED_area_headerprint(CTX_wm_area(C), str); } } return OPERATOR_RUNNING_MODAL; }
static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu, tGpTimingData *gtd) { Scene *scene = CTX_data_scene(C); bAction *act; FCurve *fcu; PointerRNA ptr; PropertyRNA *prop = NULL; int nbr_gaps = 0, i; if (gtd->mode == GP_STROKECONVERT_TIMING_NONE) return; /* gap_duration and gap_randomness are in frames, but we need seconds!!! */ gtd->gap_duration = FRA2TIME(gtd->gap_duration); gtd->gap_randomness = FRA2TIME(gtd->gap_randomness); /* Enable path! */ cu->flag |= CU_PATH; cu->pathlen = gtd->frame_range; /* Get RNA pointer to read/write path time values */ RNA_id_pointer_create((ID *)cu, &ptr); prop = RNA_struct_find_property(&ptr, "eval_time"); /* Ensure we have an F-Curve to add keyframes to */ act = verify_adt_action((ID *)cu, true); fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, true); if (G.debug & G_DEBUG) { printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time); for (i = 0; i < gtd->num_points; i++) { printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]); } } if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) { float cfra; /* Linear extrapolation! */ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR; cu->ctime = 0.0f; cfra = (float)gtd->start_frame; insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); cu->ctime = cu->pathlen; if (gtd->realtime) { cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */ } else { cfra = (float)gtd->end_frame; } insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); } else { /* Use actual recorded timing! */ RNG *rng = BLI_rng_new(0); float time_range; /* CustomGaps specific */ float tot_gaps_time = 0.0f; /* Pre-process gaps, in case we don't want to keep their original timing */ if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) { gp_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time); } if (gtd->realtime) { time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */ } else { time_range = (float)(gtd->end_frame - gtd->start_frame); } if (G.debug & G_DEBUG) { printf("GP Stroke Path Conversion: Starting keying!\n"); } gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time); BLI_rng_free(rng); } /* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */ calchandles_fcurve(fcu); if (G.debug & G_DEBUG) { printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time); for (i = 0; i < gtd->num_points; i++) { printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]); } printf("\n\n"); } WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); /* send updates */ DAG_id_tag_update(&cu->id, 0); }
/* 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); }
float AnimationExporter::convert_time(float frame) { return FRA2TIME(frame); }