Пример #1
0
/**
 * 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
 * \return length of \a str
 *
 * \note in some cases this is used to print non-seconds values.
 */
size_t BLI_timecode_string_from_time_seconds(
        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_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds);
	}
	else {
		rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
	}

	return rlen;
}
Пример #2
0
/* add the relevant text to the cache of text-strings to draw in pixelspace */
static void nla_draw_strip_text(AnimData *adt,
                                NlaTrack *nlt,
                                NlaStrip *strip,
                                int index,
                                View2D *v2d,
                                float xminc,
                                float xmaxc,
                                float yminc,
                                float ymaxc)
{
  const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) &&
                         (nlt->flag & NLATRACK_SOLO) == 0);
  char str[256];
  size_t str_len;
  char col[4];

  /* just print the name and the range */
  if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
    str_len = BLI_snprintf_rlen(str, sizeof(str), "%d) Temp-Meta", index);
  }
  else {
    str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
  }

  /* set text color - if colors (see above) are light, draw black text, otherwise draw white */
  if (strip->flag & (NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_TWEAKUSER)) {
    col[0] = col[1] = col[2] = 0;
  }
  else {
    col[0] = col[1] = col[2] = 255;
  }

  /* text opacity depends on whether if there's a solo'd track, this isn't it */
  if (non_solo == 0) {
    col[3] = 255;
  }
  else {
    col[3] = 128;
  }

  /* set bounding-box for text
   * - padding of 2 'units' on either side
   */
  /* TODO: make this centered? */
  rctf rect = {
      .xmin = xminc,
      .ymin = yminc,
      .xmax = xmaxc,
      .ymax = ymaxc,
  };

  /* add this string to the cache of texts to draw */
  UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
Пример #3
0
/* add frame extents to cache of text-strings to draw in pixelspace
 * for now, only used when transforming strips
 */
static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, View2D *v2d, float UNUSED(yminc), float ymaxc)
{
	const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
	const char col[4] = {220, 220, 220, 255}; /* light gray */
	char numstr[32];
	size_t numstr_len;
	
	
	/* Always draw times above the strip, whereas sequencer drew below + above.
	 * However, we should be fine having everything on top, since these tend to be 
	 * quite spaced out. 
	 *	- 1 dp is compromise between lack of precision (ints only, as per sequencer)
	 *	  while also preserving some accuracy, since we do use floats
	 */
	/* start frame */
	numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
	UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
	
	/* end frame */
	numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->end);
	UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col);
}
Пример #4
0
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.0f) {
		/* 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 = fmodf(time, 3600);
	}

	if (time >= 60.0f) {
		/* minutes */
		minutes = (int)time / 60;
		time = fmodf(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 = round_fl_to_int((float)(((double)time - (double)seconds) * fps));
	}
	else {
		/* seconds (with pixel offset rounding) */
		seconds = round_fl_to_int(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_rlen(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames);
				}
				else if (minutes) {
					rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames);
				}
				else {
					rlen = BLI_snprintf_rlen(str, maxncpy, "%s%d+%02d", neg, seconds, frames);
				}
			}
			else {
				/* don't include 'frames' in display */
				if (hours) {
					rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
				}
				else {
					rlen = BLI_snprintf_rlen(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_rlen(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
			}
			else {
				rlen = BLI_snprintf_rlen(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_rlen(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time);
			}
			else {
				rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad,  ms_dp, time);
			}
			break;
		}
		case USER_TIMECODE_SUBRIP:
		{
			/* SubRip, like SMPTE milliseconds but seconds and milliseconds are separated by a comma, not a dot... */

			/* precision of decimal part */
			const int ms_dp = (power <= 0) ? (1 - power) : 1;
			const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f);

			rlen = BLI_snprintf_rlen(
			           str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms);
			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_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds);
			}
			else {
				rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
			}
			break;
		}
		case USER_TIMECODE_SMPTE_FULL:
		default:
		{
			/* full SMPTE format */
			rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
			break;
		}
	}

	return rlen;
}
Пример #5
0
/* draw a handle, for each end of a sequence strip */
static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_clamped, const short direction)
{
	float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
	float x1, x2, y1, y2;
	unsigned int whichsel = 0;
	
	x1 = seq->startdisp;
	x2 = seq->enddisp;
	
	y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
	y2 = seq->machine + SEQ_STRIP_OFSTOP;

	/* set up co-ordinates/dimensions for either left or right handle */
	if (direction == SEQ_LEFTHANDLE) {
		rx1 = x1;
		rx2 = x1 + handsize_clamped * 0.75f;
		
		v1[0] = x1 + handsize_clamped / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
		v2[0] = x1 + handsize_clamped / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
		v3[0] = v2[0] + handsize_clamped / 4; v3[1] = (y1 + y2) / 2.0f;
		
		whichsel = SEQ_LEFTSEL;
	}
	else if (direction == SEQ_RIGHTHANDLE) {
		rx1 = x2 - handsize_clamped * 0.75f;
		rx2 = x2;
		
		v1[0] = x2 - handsize_clamped / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
		v2[0] = x2 - handsize_clamped / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
		v3[0] = v2[0] - handsize_clamped / 4; v3[1] = (y1 + y2) / 2.0f;
		
		whichsel = SEQ_RIGHTSEL;
	}
	
	/* draw! */
	if (!(seq->type & SEQ_TYPE_EFFECT) ||
	    BKE_sequence_effect_get_num_inputs(seq->type) == 0)
	{
		glEnable(GL_BLEND);
		
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		if (seq->flag & whichsel) glColor4ub(0, 0, 0, 80);
		else if (seq->flag & SELECT) glColor4ub(255, 255, 255, 30);
		else glColor4ub(0, 0, 0, 22);
		
		glRectf(rx1, y1, rx2, y2);
		
		if (seq->flag & whichsel) glColor4ub(255, 255, 255, 200);
		else glColor4ub(0, 0, 0, 50);
		
		glEnable(GL_POLYGON_SMOOTH);
		glBegin(GL_TRIANGLES);
		glVertex2fv(v1); glVertex2fv(v2); glVertex2fv(v3);
		glEnd();
		
		glDisable(GL_POLYGON_SMOOTH);
		glDisable(GL_BLEND);
	}
	
	if ((G.moving & G_TRANSFORM_SEQ) || (seq->flag & whichsel)) {
		const char col[4] = {255, 255, 255, 255};
		char numstr[32];
		size_t numstr_len;

		if (direction == SEQ_LEFTHANDLE) {
			numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->startdisp);
			x1 = rx1;
			y1 -= 0.45f;
		}
		else {
			numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
			x1 = x2 - handsize_clamped * 0.75f;
			y1 = y2 + 0.05f;
		}
		UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
	}
}
Пример #6
0
static size_t unit_as_string(char *str, int len_max, double value, int prec, bUnitCollection *usys,
                             /* non exposed options */
                             const bUnitDef *unit, char pad)
{
	double value_conv;
	size_t len, i;

	if (unit) {
		/* use unit without finding the best one */
	}
	else if (value == 0.0) {
		/* use the default units since there is no way to convert */
		unit = unit_default(usys);
	}
	else {
		unit = unit_best_fit(value, usys, NULL, 1);
	}

	value_conv = value / unit->scalar;

	/* Convert to a string */
	len = BLI_snprintf_rlen(str, len_max, "%.*f", prec, value_conv);

	/* Add unit prefix and strip zeros */

	/* replace trailing zero's with spaces
	 * so the number is less complicated but alignment in a button wont
	 * jump about while dragging */
	i = len - 1;

	if (prec > 0) {
		while (i > 0 && str[i] == '0') { /* 4.300 -> 4.3 */
			str[i--] = pad;
		}

		if (i > 0 && str[i] == '.') { /* 10. -> 10 */
			str[i--] = pad;
		}
	}

	/* Now add the suffix */
	if (i < len_max) {
		int j = 0;
		i++;
		while (unit->name_short[j] && (i < len_max)) {
			str[i++] = unit->name_short[j++];
		}
#if 0
		if (pad) {
			/* this loop only runs if so many zeros were removed that
			 * the unit name only used padded chars,
			 * In that case add padding for the name. */

			while (i <= len + j && (i < len_max)) {
				str[i++] = pad;
			}
		}
#endif
	}

	/* terminate no matter whats done with padding above */
	if (i >= len_max)
		i = len_max - 1;

	str[i] = '\0';
	return i;
}