forked from bartvdbraak/blender
UI: Refactor timecode functions into BLI_timecode
- deduplicate timecode_simple_string from image.c - replace V2D_UNIT_SECONDSSEQ with V2D_UNIT_SECONDS - avoid possible buffer overflow bugs (sprintf -> BLI_snprintf) - remove option not to use timecode and split into 2 functions Patch D227 by Andrew Buttery with own refactoring.
This commit is contained in:
parent
f70d966047
commit
39eb314cb9
@ -68,6 +68,7 @@
|
|||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_threads.h"
|
#include "BLI_threads.h"
|
||||||
|
#include "BLI_timecode.h" /* for stamp timecode format */
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "BKE_bmfont.h"
|
#include "BKE_bmfont.h"
|
||||||
@ -1520,30 +1521,6 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timecode_simple_string(char *text, size_t text_size, const int cfra, int const frs_sec)
|
|
||||||
{
|
|
||||||
int f = (int)(cfra % frs_sec);
|
|
||||||
int s = (int)(cfra / frs_sec);
|
|
||||||
int h = 0;
|
|
||||||
int m = 0;
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
m = (int)(s / 60);
|
|
||||||
s %= 60;
|
|
||||||
|
|
||||||
if (m) {
|
|
||||||
h = (int)(m / 60);
|
|
||||||
m %= 60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frs_sec < 100) {
|
|
||||||
BLI_snprintf(text, text_size, "%02d:%02d:%02d.%02d", h, m, s, f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BLI_snprintf(text, text_size, "%02d:%02d:%02d.%03d", h, m, s, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16)
|
#define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16)
|
||||||
/* could allow access externally - 512 is for long names,
|
/* could allow access externally - 512 is for long names,
|
||||||
@ -1607,8 +1584,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scene->r.stamp & R_STAMP_TIME) {
|
if (scene->r.stamp & R_STAMP_TIME) {
|
||||||
timecode_simple_string(text, sizeof(text), scene->r.cfra, scene->r.frs_sec);
|
const short timecode_style = USER_TIMECODE_SMPTE_FULL;
|
||||||
BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Time %s" : "%s", text);
|
BLI_timecode_string_from_time(text, sizeof(text), 0, FRA2TIME(scene->r.cfra), FPS, timecode_style);
|
||||||
|
BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Timecode %s" : "%s", text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stamp_data->time[0] = '\0';
|
stamp_data->time[0] = '\0';
|
||||||
|
41
source/blender/blenlib/BLI_timecode.h
Normal file
41
source/blender/blenlib/BLI_timecode.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* ***** 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) 2008 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Contributor(s): Joshua Leung
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BLI_TIMECODE_H__
|
||||||
|
#define __BLI_TIMECODE_H__
|
||||||
|
|
||||||
|
/** \file BLI_timecode.h
|
||||||
|
* \ingroup BLI
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t BLI_timecode_string_from_time(
|
||||||
|
char *str, const size_t len, const int power, const float time_seconds,
|
||||||
|
const double scene_fps, const short timecode_style);
|
||||||
|
|
||||||
|
size_t BLI_timecode_string_from_time_simple(
|
||||||
|
char *str, const size_t len, const int power, const float time_seconds);
|
||||||
|
|
||||||
|
#endif /* __BLI_TIMECODE_H__ */
|
@ -98,6 +98,7 @@ set(SRC
|
|||||||
intern/task.c
|
intern/task.c
|
||||||
intern/threads.c
|
intern/threads.c
|
||||||
intern/time.c
|
intern/time.c
|
||||||
|
intern/timecode.c
|
||||||
intern/uvproject.c
|
intern/uvproject.c
|
||||||
intern/voronoi.c
|
intern/voronoi.c
|
||||||
intern/voxel.c
|
intern/voxel.c
|
||||||
@ -166,6 +167,7 @@ set(SRC
|
|||||||
BLI_sys_types.h
|
BLI_sys_types.h
|
||||||
BLI_task.h
|
BLI_task.h
|
||||||
BLI_threads.h
|
BLI_threads.h
|
||||||
|
BLI_timecode.h
|
||||||
BLI_utildefines.h
|
BLI_utildefines.h
|
||||||
BLI_uvproject.h
|
BLI_uvproject.h
|
||||||
BLI_vfontdata.h
|
BLI_vfontdata.h
|
||||||
|
218
source/blender/blenlib/intern/timecode.c
Normal file
218
source/blender/blenlib/intern/timecode.c
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* ***** 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) 2008 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Contributor(s): Joshua Leung
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file blender/blendlib/intern/timecode.c
|
||||||
|
* \ingroup blendlib
|
||||||
|
*
|
||||||
|
* Time-Code string formatting
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "BLI_string.h"
|
||||||
|
#include "BLI_math.h"
|
||||||
|
|
||||||
|
#include "BLI_timecode.h" /* own include */
|
||||||
|
|
||||||
|
#include "BLI_strict_flags.h"
|
||||||
|
|
||||||
|
#include "DNA_userdef_types.h" /* for eTimecodeStyles only */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate timecode/frame number string and store in \a str
|
||||||
|
*
|
||||||
|
* \param str destination string
|
||||||
|
* \param maxncpy maximum number of characters to copy ``sizeof(str)``
|
||||||
|
* \param power special setting for #View2D grid drawing,
|
||||||
|
* used to specify how detailed we need to be
|
||||||
|
* \param time_seconds time total time in seconds
|
||||||
|
* \param fps frames per second, typically from the #FPS macro
|
||||||
|
* \param timecode_style enum from eTimecodeStyles
|
||||||
|
* \return length of \a str
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t BLI_timecode_string_from_time(
|
||||||
|
char *str, const size_t maxncpy, const int power, const float time_seconds,
|
||||||
|
const double fps, const short timecode_style)
|
||||||
|
{
|
||||||
|
int hours = 0, minutes = 0, seconds = 0, frames = 0;
|
||||||
|
float time = time_seconds;
|
||||||
|
char neg[2] = {'\0'};
|
||||||
|
size_t rlen;
|
||||||
|
|
||||||
|
/* get cframes */
|
||||||
|
if (time < 0) {
|
||||||
|
/* correction for negative cfraues */
|
||||||
|
neg[0] = '-';
|
||||||
|
time = -time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time >= 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)time / 3600;
|
||||||
|
time = (float)fmod(time, 3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time >= 60) {
|
||||||
|
/* minutes */
|
||||||
|
minutes = (int)time / 60;
|
||||||
|
time = (float)fmod(time, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (power <= 0) {
|
||||||
|
/* 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)time;
|
||||||
|
frames = iroundf((float)(((double)time - (double)seconds) * fps));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* seconds (with pixel offset rounding) */
|
||||||
|
seconds = iroundf(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (timecode_style) {
|
||||||
|
case USER_TIMECODE_MINIMAL:
|
||||||
|
{
|
||||||
|
/* - 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
|
||||||
|
*/
|
||||||
|
if (power <= 0) {
|
||||||
|
/* include "frames" in display */
|
||||||
|
if (hours) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames);
|
||||||
|
}
|
||||||
|
else if (minutes) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%d+%02d", neg, seconds, frames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* don't include 'frames' in display */
|
||||||
|
if (hours) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d", neg, minutes, seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_TIMECODE_SMPTE_MSF:
|
||||||
|
{
|
||||||
|
/* reduced SMPTE format that always shows minutes, seconds, frames. Hours only shown as needed. */
|
||||||
|
if (hours) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d", neg, minutes, seconds, frames);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_TIMECODE_MILLISECONDS:
|
||||||
|
{
|
||||||
|
/* reduced SMPTE. Instead of frames, milliseconds are shown */
|
||||||
|
|
||||||
|
/* precision of decimal part */
|
||||||
|
const int ms_dp = (power <= 0) ? (1 - power) : 1;
|
||||||
|
|
||||||
|
/* to get 2 digit whole-number part for seconds display
|
||||||
|
* (i.e. 3 is for 2 digits + radix, on top of full length) */
|
||||||
|
const int s_pad = ms_dp + 3;
|
||||||
|
|
||||||
|
if (hours) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, time);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_TIMECODE_SECONDS_ONLY:
|
||||||
|
{
|
||||||
|
/* only show the original seconds display */
|
||||||
|
/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */
|
||||||
|
if (power <= 0) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%.*f", 1 - power, time_seconds);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%d", iroundf(time_seconds));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_TIMECODE_SMPTE_FULL:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* full SMPTE format */
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate time string and store in \a str
|
||||||
|
*
|
||||||
|
* \param str destination string
|
||||||
|
* \param maxncpy maximum number of characters to copy ``sizeof(str)``
|
||||||
|
* \param power special setting for #View2D grid drawing,
|
||||||
|
* used to specify how detailed we need to be
|
||||||
|
* \param time_seconds time total time in seconds
|
||||||
|
* \param seconds time in seconds.
|
||||||
|
* \return length of \a str
|
||||||
|
*
|
||||||
|
* \note in some cases this is used to print non-seconds values.
|
||||||
|
*/
|
||||||
|
size_t BLI_timecode_string_from_time_simple(
|
||||||
|
char *str, const size_t maxncpy, const int power, const float time_seconds)
|
||||||
|
{
|
||||||
|
size_t rlen;
|
||||||
|
|
||||||
|
/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */
|
||||||
|
if (power <= 0) {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%.*f", 1 - power, time_seconds);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rlen = BLI_snprintf(str, maxncpy, "%d", iroundf(time_seconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rlen;
|
||||||
|
}
|
@ -37,6 +37,7 @@
|
|||||||
#include "DNA_userdef_types.h"
|
#include "DNA_userdef_types.h"
|
||||||
|
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
|
#include "BLI_timecode.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_blender.h"
|
#include "BKE_blender.h"
|
||||||
@ -55,126 +56,11 @@
|
|||||||
#include "UI_resources.h"
|
#include "UI_resources.h"
|
||||||
#include "UI_view2d.h"
|
#include "UI_view2d.h"
|
||||||
|
|
||||||
/* *************************************************** */
|
|
||||||
/* TIME CODE FORMATTING */
|
|
||||||
|
|
||||||
/* Generate timecode/frame number string and store in the supplied string
|
|
||||||
* - buffer: must be at least 13 chars long
|
|
||||||
* - power: special setting for View2D grid drawing,
|
|
||||||
* used to specify how detailed we need to be
|
|
||||||
* - timecodes: boolean specifying whether timecodes or
|
|
||||||
* frame numbers get drawn
|
|
||||||
* - cfra: time in frames or seconds, consistent with the values shown by timecodes
|
|
||||||
*/
|
|
||||||
// TODO: have this in kernel instead under scene?
|
|
||||||
void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short timecodes, float cfra)
|
|
||||||
{
|
|
||||||
if (timecodes) {
|
|
||||||
int hours = 0, minutes = 0, seconds = 0, frames = 0;
|
|
||||||
float raw_seconds = cfra;
|
|
||||||
char neg[2] = {'\0'};
|
|
||||||
|
|
||||||
/* get cframes */
|
|
||||||
if (cfra < 0) {
|
|
||||||
/* correction for negative cfraues */
|
|
||||||
neg[0] = '-';
|
|
||||||
cfra = -cfra;
|
|
||||||
}
|
|
||||||
if (cfra >= 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)cfra / 3600;
|
|
||||||
cfra = (float)fmod(cfra, 3600);
|
|
||||||
}
|
|
||||||
if (cfra >= 60) {
|
|
||||||
/* minutes */
|
|
||||||
minutes = (int)cfra / 60;
|
|
||||||
cfra = (float)fmod(cfra, 60);
|
|
||||||
}
|
|
||||||
if (power <= 0) {
|
|
||||||
/* 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)cfra;
|
|
||||||
frames = (int)floor( (((double)cfra - (double)seconds) * FPS) + 0.5);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* seconds (with pixel offset rounding) */
|
|
||||||
seconds = (int)floor(cfra + GLA_PIXEL_OFS);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (U.timecode_style) {
|
|
||||||
case USER_TIMECODE_MINIMAL:
|
|
||||||
{
|
|
||||||
/* - 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
|
|
||||||
*/
|
|
||||||
if (power <= 0) {
|
|
||||||
/* include "frames" in display */
|
|
||||||
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 {
|
|
||||||
/* don't include 'frames' in display */
|
|
||||||
if (hours) sprintf(str, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
|
|
||||||
else sprintf(str, "%s%02d:%02d", neg, minutes, seconds);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_TIMECODE_SMPTE_MSF:
|
|
||||||
{
|
|
||||||
/* reduced SMPTE format that always shows minutes, seconds, frames. Hours only shown as needed. */
|
|
||||||
if (hours) sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
|
|
||||||
else sprintf(str, "%s%02d:%02d:%02d", neg, minutes, seconds, frames);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_TIMECODE_MILLISECONDS:
|
|
||||||
{
|
|
||||||
/* reduced SMPTE. Instead of frames, milliseconds are shown */
|
|
||||||
int ms_dp = (power <= 0) ? (1 - power) : 1; /* precision of decimal part */
|
|
||||||
int s_pad = ms_dp + 3; /* to get 2 digit whole-number part for seconds display (i.e. 3 is for 2 digits + radix, on top of full length) */
|
|
||||||
|
|
||||||
if (hours) sprintf(str, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, cfra);
|
|
||||||
else sprintf(str, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, cfra);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_TIMECODE_SECONDS_ONLY:
|
|
||||||
{
|
|
||||||
/* only show the original seconds display */
|
|
||||||
/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */
|
|
||||||
if (power <= 0) sprintf(str, "%.*f", 1 - power, raw_seconds);
|
|
||||||
else sprintf(str, "%d", (int)floor(raw_seconds + GLA_PIXEL_OFS));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_TIMECODE_SMPTE_FULL:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* full SMPTE format */
|
|
||||||
sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */
|
|
||||||
if (power <= 0) sprintf(str, "%.*f", 1 - power, cfra);
|
|
||||||
else sprintf(str, "%d", (int)floor(cfra + GLA_PIXEL_OFS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
/* CURRENT FRAME DRAWING */
|
/* CURRENT FRAME DRAWING */
|
||||||
|
|
||||||
/* Draw current frame number in a little green box beside the current frame indicator */
|
/* 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)
|
static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const bool time)
|
||||||
{
|
{
|
||||||
float xscale, yscale, x, y;
|
float xscale, yscale, x, y;
|
||||||
char numstr[32] = " t"; /* t is the character to start replacing from */
|
char numstr[32] = " t"; /* t is the character to start replacing from */
|
||||||
@ -189,10 +75,12 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time)
|
|||||||
* - power = 0, gives 'standard' behavior for time
|
* - power = 0, gives 'standard' behavior for time
|
||||||
* but power = 1 is required for frames (to get integer frames)
|
* but power = 1 is required for frames (to get integer frames)
|
||||||
*/
|
*/
|
||||||
if (time)
|
if (time) {
|
||||||
ANIM_timecode_string_from_frame(&numstr[4], scene, 0, time, FRA2TIME(cfra));
|
BLI_timecode_string_from_time(&numstr[4], sizeof(numstr) - 4, 0, FRA2TIME(cfra), FPS, U.timecode_style);
|
||||||
else
|
}
|
||||||
ANIM_timecode_string_from_frame(&numstr[4], scene, 1, time, cfra);
|
else {
|
||||||
|
BLI_timecode_string_from_time_simple(&numstr[4], sizeof(numstr) - 4, 1, cfra);
|
||||||
|
}
|
||||||
slen = (short)UI_GetStringWidth(numstr) - 1;
|
slen = (short)UI_GetStringWidth(numstr) - 1;
|
||||||
|
|
||||||
/* get starting coordinates for drawing */
|
/* get starting coordinates for drawing */
|
||||||
@ -239,7 +127,7 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
|
|||||||
/* Draw current frame number in a little box */
|
/* Draw current frame number in a little box */
|
||||||
if (flag & DRAWCFRA_SHOW_NUMBOX) {
|
if (flag & DRAWCFRA_SHOW_NUMBOX) {
|
||||||
UI_view2d_view_orthoSpecial(CTX_wm_region(C), v2d, 1);
|
UI_view2d_view_orthoSpecial(CTX_wm_region(C), v2d, 1);
|
||||||
draw_cfra_number(scene, v2d, vec[0], (flag & DRAWCFRA_UNIT_SECONDS));
|
draw_cfra_number(scene, v2d, vec[0], (flag & DRAWCFRA_UNIT_SECONDS) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,9 +471,6 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, struct AnimData *adt, st
|
|||||||
/* DRAWING API */
|
/* DRAWING API */
|
||||||
/* anim_draw.c */
|
/* anim_draw.c */
|
||||||
|
|
||||||
/* Get string representing the given frame number as an appropriately represented frame or timecode */
|
|
||||||
void ANIM_timecode_string_from_frame(char *str, struct Scene *scene, int power, short timecodes, float cfra);
|
|
||||||
|
|
||||||
/* ---------- Current Frame Drawing ---------------- */
|
/* ---------- Current Frame Drawing ---------------- */
|
||||||
|
|
||||||
/* flags for Current Frame Drawing */
|
/* flags for Current Frame Drawing */
|
||||||
|
@ -78,7 +78,6 @@ enum eView2D_Units {
|
|||||||
V2D_UNIT_VALUES,
|
V2D_UNIT_VALUES,
|
||||||
V2D_UNIT_DEGREES,
|
V2D_UNIT_DEGREES,
|
||||||
V2D_UNIT_TIME,
|
V2D_UNIT_TIME,
|
||||||
V2D_UNIT_SECONDSSEQ
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clamping of grid values to whole numbers */
|
/* clamping of grid values to whole numbers */
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
#include "BLI_timecode.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_screen.h"
|
#include "BKE_screen.h"
|
||||||
@ -1613,7 +1614,13 @@ static void scroll_printstr(Scene *scene, float x, float y, float val, int power
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get string to print */
|
/* get string to print */
|
||||||
ANIM_timecode_string_from_frame(timecode_str, scene, power, (unit == V2D_UNIT_SECONDS), val);
|
if (unit == V2D_UNIT_SECONDS) {
|
||||||
|
/* not neces*/
|
||||||
|
BLI_timecode_string_from_time(timecode_str, sizeof(timecode_str), power, val, FPS, U.timecode_style);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_timecode_string_from_time_simple(timecode_str, sizeof(timecode_str), power, val);
|
||||||
|
}
|
||||||
|
|
||||||
/* get length of string, and adjust printing location to fit it into the horizontal scrollbar */
|
/* get length of string, and adjust printing location to fit it into the horizontal scrollbar */
|
||||||
len = strlen(timecode_str);
|
len = strlen(timecode_str);
|
||||||
@ -1737,17 +1744,6 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
|
|||||||
scroll_printstr(scene, fac, h, fac2, grid->powerx, V2D_UNIT_SECONDS, 'h');
|
scroll_printstr(scene, fac, h, fac2, grid->powerx, V2D_UNIT_SECONDS, 'h');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case V2D_UNIT_SECONDSSEQ: /* seconds with special calculations (only used for sequencer only) */
|
|
||||||
{
|
|
||||||
float time;
|
|
||||||
|
|
||||||
fac2 = val / (float)FPS;
|
|
||||||
time = (float)floor(fac2);
|
|
||||||
fac2 = fac2 - time;
|
|
||||||
|
|
||||||
scroll_printstr(scene, fac, h, time + (float)FPS * fac2 / 100.0f, grid->powerx, V2D_UNIT_SECONDSSEQ, 'h');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case V2D_UNIT_DEGREES: /* Graph Editor for rotation Drivers */
|
case V2D_UNIT_DEGREES: /* Graph Editor for rotation Drivers */
|
||||||
/* HACK: although we're drawing horizontal, we make this draw as 'vertical', just to get degree signs */
|
/* HACK: although we're drawing horizontal, we make this draw as 'vertical', just to get degree signs */
|
||||||
scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_DEGREES, 'v');
|
scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_DEGREES, 'v');
|
||||||
|
@ -1483,7 +1483,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
|
|||||||
UI_view2d_view_restore(C);
|
UI_view2d_view_restore(C);
|
||||||
|
|
||||||
/* scrollers */
|
/* scrollers */
|
||||||
unit = (sseq->flag & SEQ_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDSSEQ;
|
unit = (sseq->flag & SEQ_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDS;
|
||||||
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
|
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
|
||||||
UI_view2d_scrollers_draw(C, v2d, scrollers);
|
UI_view2d_scrollers_draw(C, v2d, scrollers);
|
||||||
UI_view2d_scrollers_free(scrollers);
|
UI_view2d_scrollers_free(scrollers);
|
||||||
|
Loading…
Reference in New Issue
Block a user