diff options
-rw-r--r-- | source/blender/blenlib/BLI_timecode.h | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/timecode.c | 28 | ||||
-rw-r--r-- | source/blender/editors/include/UI_view2d.h | 10 | ||||
-rw-r--r-- | source/blender/editors/interface/view2d.c | 308 |
4 files changed, 168 insertions, 182 deletions
diff --git a/source/blender/blenlib/BLI_timecode.h b/source/blender/blenlib/BLI_timecode.h index 80f4a2d1927..97851a5af90 100644 --- a/source/blender/blenlib/BLI_timecode.h +++ b/source/blender/blenlib/BLI_timecode.h @@ -27,7 +27,7 @@ #include "BLI_compiler_attrs.h" size_t BLI_timecode_string_from_time( - char *str, const size_t len, const int power, const float time_seconds, + char *str, const size_t len, const int brevity_level, const float time_seconds, const double scene_fps, const short timecode_style) ATTR_NONNULL(); @@ -36,7 +36,7 @@ size_t BLI_timecode_string_from_time_simple( ATTR_NONNULL(); size_t BLI_timecode_string_from_time_seconds( - char *str, const size_t len, const int power, const float time_seconds) + char *str, const size_t len, const int brevity_level, const float time_seconds) ATTR_NONNULL(); #endif /* __BLI_TIMECODE_H__ */ diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c index d87f1037254..53d0347d088 100644 --- a/source/blender/blenlib/intern/timecode.c +++ b/source/blender/blenlib/intern/timecode.c @@ -41,7 +41,7 @@ * * \param str: destination string * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` - * \param power: special setting for #View2D grid drawing, + * \param brevity_level: 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 @@ -50,7 +50,7 @@ */ size_t BLI_timecode_string_from_time( - char *str, const size_t maxncpy, const int power, const float time_seconds, + char *str, const size_t maxncpy, const int brevity_level, const float time_seconds, const double fps, const short timecode_style) { int hours = 0, minutes = 0, seconds = 0, frames = 0; @@ -81,7 +81,7 @@ size_t BLI_timecode_string_from_time( time = fmodf(time, 60); } - if (power <= 0) { + if (brevity_level <= 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 @@ -103,7 +103,7 @@ size_t BLI_timecode_string_from_time( * (using separator of '+' for frames). * When showing frames, use slightly different display to avoid confusion with mm:ss format */ - if (power <= 0) { + if (brevity_level <= 0) { /* include "frames" in display */ if (hours) { rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames); @@ -143,7 +143,7 @@ size_t BLI_timecode_string_from_time( /* reduced SMPTE. Instead of frames, milliseconds are shown */ /* precision of decimal part */ - const int ms_dp = (power <= 0) ? (1 - power) : 1; + const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1; /* to get 2 digit whole-number part for seconds display * (i.e. 3 is for 2 digits + radix, on top of full length) */ @@ -163,7 +163,7 @@ size_t BLI_timecode_string_from_time( * are separated by a comma, not a dot... */ /* precision of decimal part */ - const int ms_dp = (power <= 0) ? (1 - power) : 1; + const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1; const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f); rlen = BLI_snprintf_rlen( @@ -173,9 +173,9 @@ size_t BLI_timecode_string_from_time( 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); + /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */ + if (brevity_level <= 0) { + rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds); } else { rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); @@ -228,7 +228,7 @@ size_t BLI_timecode_string_from_time_simple( * * \param str: destination string * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` - * \param power: special setting for #View2D grid drawing, + * \param brevity_level: 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 @@ -236,13 +236,13 @@ size_t BLI_timecode_string_from_time_simple( * \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) + char *str, const size_t maxncpy, const int brevity_level, 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); + /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */ + if (brevity_level <= 0) { + rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds); } else { rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 98e00eab9c9..6efbcf09e97 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -70,8 +70,6 @@ enum eView2D_Units { /* for drawing values */ V2D_UNIT_VALUES, - V2D_UNIT_DEGREES, - V2D_UNIT_TIME, }; /* clamping of grid values to whole numbers */ @@ -169,6 +167,12 @@ void UI_view2d_grid_draw(struct View2D *v2d, View2DGrid *grid, int flag); void UI_view2d_constant_grid_draw(struct View2D *v2d, float step); void UI_view2d_multi_grid_draw(struct View2D *v2d, int colorid, float step, int level_size, int totlevels); void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy); +void UI_view2d_grid_draw_numbers_horizontal(const struct Scene *scene, const struct View2D *v2d, + const View2DGrid *grid, const struct rcti *rect, + int unit, bool whole_numbers_only); +void UI_view2d_grid_draw_numbers_vertical(const struct Scene *scene, const struct View2D *v2d, + const View2DGrid *grid, const struct rcti *rect, + int unit, float text_offset); void UI_view2d_grid_free(View2DGrid *grid); /* scrollbar drawing */ @@ -210,6 +214,8 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C); struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C); void UI_view2d_scale_get(struct View2D *v2d, float *r_x, float *r_y); +float UI_view2d_scale_get_x(const struct View2D *v2d); +float UI_view2d_scale_get_y(const struct View2D *v2d); void UI_view2d_scale_get_inverse(struct View2D *v2d, float *r_x, float *r_y); void UI_view2d_center_get(struct View2D *v2d, float *r_x, float *r_y); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 7d5a2e73113..a01088277f2 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1714,6 +1714,129 @@ void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_s immUnbindProgram(); } +static void get_scale_indicator_text( + const Scene *scene, + float value, + int brevity_level, + short unit, + uint max_length, + char *r_str) +{ + if (unit == V2D_UNIT_SECONDS) { + BLI_timecode_string_from_time(r_str, max_length, brevity_level, value / (float)FPS, FPS, U.timecode_style); + } + else { + BLI_timecode_string_from_time_seconds(r_str, max_length, brevity_level, value); + } +} + +void UI_view2d_grid_draw_numbers_horizontal( + const Scene *scene, + const View2D *v2d, + const View2DGrid *grid, + const rcti *rect, + int unit, + bool whole_numbers_only) +{ + BLI_assert(grid); + float xstep = grid->dx * UI_view2d_scale_get_x(v2d); + if (xstep <= 0.0f) { + return; + } + + float initial_xpos = UI_view2d_view_to_region_x(v2d, grid->startx); + float ypos = (float)rect->ymin + 2 * UI_DPI_FAC; + float initial_value = grid->startx; + float value_step = grid->dx; + int brevity_level = grid->powerx; + + /* Make sure that the value_step is >= 1 when only whole numbers are displayed. + * Otherwise the same number could be displayed more than once. */ + if (whole_numbers_only) { + while (value_step < 0.9999f) { + xstep *= 2.0f; + value_step *= 2.0f; + } + } + + /* Skip first few steps if they don't intersect + * the rectangle that will contain the numbers. */ + while (initial_xpos < rect->xmin) { + initial_xpos += xstep; + initial_value += value_step; + } + + if (unit == V2D_UNIT_FRAMES) { + brevity_level = 1; + } + + const int font_id = BLF_default(); + UI_FontThemeColor(font_id, TH_TEXT); + + BLF_batch_draw_begin(); + + for (float xpos = initial_xpos, value = initial_value; + xpos < rect->xmax; + xpos += xstep, value += value_step) + { + char text[32]; + get_scale_indicator_text(scene, value, brevity_level, unit, sizeof(text), text); + float text_width = BLF_width(font_id, text, strlen(text)); + BLF_draw_default_ascii(xpos - text_width / 2.0f, ypos, 0.0f, text, sizeof(text)); + } + + BLF_batch_draw_end(); +} + +void UI_view2d_grid_draw_numbers_vertical( + const Scene *scene, + const View2D *v2d, + const View2DGrid *grid, + const rcti *rect, + int unit, + float text_offset) +{ + BLI_assert(grid); + float ystep = grid->dy * UI_view2d_scale_get_y(v2d); + if (ystep <= 0.0f) { + return; + } + + const int font_id = BLF_default(); + UI_FontThemeColor(font_id, TH_TEXT); + + BLF_enable(font_id, BLF_ROTATION); + BLF_rotation(font_id, M_PI_2); + + float initial_value = grid->starty; + float value_step = grid->dy; + float xpos = rect->xmax - 2.0f * UI_DPI_FAC; + float initial_ypos = UI_view2d_view_to_region_y(v2d, grid->starty); + + /* Currently only used by the sequencer to display + * channel numbers in the center. */ + initial_ypos += text_offset * ystep; + + /* Skip first few steps if they don't intersect + * the rectangle that will contain the numbers. */ + while (initial_ypos < rect->ymin) { + initial_ypos += ystep; + initial_value += value_step; + } + + for (float ypos = initial_ypos, value = initial_value; + ypos < rect->ymax; + ypos += ystep, value += value_step) + { + char text[32]; + get_scale_indicator_text(scene, value, grid->powery, unit, sizeof(text), text); + float text_width = BLF_width(font_id, text, sizeof(text)); + BLF_draw_default_ascii(xpos, ypos - text_width / 2.0f, 0.0f, text, sizeof(text)); + } + + BLF_disable(font_id, BLF_ROTATION); +} + /* the price we pay for not exposting structs :( */ void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy) { @@ -1904,61 +2027,10 @@ View2DScrollers *UI_view2d_scrollers_calc( return scrollers; } -/* Print scale marking along a time scrollbar */ -static void scroll_printstr(Scene *scene, float x, float y, float val, int power, short unit, char dir) -{ - int len; - char timecode_str[32]; - - /* adjust the scale unit to work ok */ - if (dir == 'v') { - /* here we bump up the power by factor of 10, as - * rotation values (hence 'degrees') are divided by 10 to - * be able to show the curves at the same time - */ - if (ELEM(unit, V2D_UNIT_DEGREES, V2D_UNIT_TIME)) { - power += 1; - val *= 10; - } - } - - /* get string to print */ - 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_seconds(timecode_str, sizeof(timecode_str), power, val); - } - - /* get length of string, - * and adjust printing location to fit it into the horizontal scrollbar */ - len = strlen(timecode_str); - if (dir == 'h') { - /* seconds/timecode display has slightly longer strings... */ - if (unit == V2D_UNIT_SECONDS) { - x -= 3 * len; - } - else { - x -= 4 * len; - } - } - - /* Add degree sympbol to end of string for vertical scrollbar? */ - if ((dir == 'v') && (unit == V2D_UNIT_DEGREES)) { - timecode_str[len] = 186; - timecode_str[len + 1] = 0; - } - - /* draw it */ - BLF_draw_default_ascii(x, y, 0.0f, timecode_str, sizeof(timecode_str)); -} - /* Draw scrollbars in the given 2d-region */ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs) { bTheme *btheme = UI_GetTheme(); - Scene *scene = CTX_data_scene(C); rcti vert, hor; const int scroll = view2d_scroll_mapped(v2d->scroll); const char emboss_alpha = btheme->tui.widget_emboss[3]; @@ -2006,73 +2078,10 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v UI_draw_widget_scroll(&wcol, &hor, &slider, state); - /* scale indicators */ - if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) { - const int font_id = BLF_default(); - View2DGrid *grid = vs->grid; - float fac, dfac, fac2, val; - - /* the numbers: convert grid->startx and -dx to scroll coordinates - * - fac is x-coordinate to draw to - * - dfac is gap between scale markings - */ - fac = (grid->startx - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur); - fac = (float)hor.xmin + fac * BLI_rcti_size_x(&hor); - - dfac = grid->dx / BLI_rctf_size_x(&v2d->cur); - dfac = dfac * BLI_rcti_size_x(&hor); - - /* set starting value, and text color */ - UI_FontThemeColor(font_id, TH_TEXT); - val = grid->startx; - - /* if we're clamping to whole numbers only, make sure entries won't be repeated */ - if (vs->xclamp == V2D_GRID_CLAMP) { - while (grid->dx < 0.9999f) { - grid->dx *= 2.0f; - dfac *= 2.0f; - } - } - if (vs->xunits == V2D_UNIT_FRAMES) { - grid->powerx = 1; - } - - /* draw numbers in the appropriate range */ - if (dfac > 0.0f) { - float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin); - - BLF_batch_draw_begin(); - - for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) { - - /* make prints look nicer for scrollers */ - if (fac < hor.xmin + 0.5f * U.widget_unit) { - continue; - } - - switch (vs->xunits) { - case V2D_UNIT_FRAMES: /* frames (as whole numbers)*/ - scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_FRAMES, 'h'); - break; - - case V2D_UNIT_FRAMESCALE: /* frames (not always as whole numbers) */ - scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_FRAMESCALE, 'h'); - break; - - case V2D_UNIT_SECONDS: /* seconds */ - fac2 = val / (float)FPS; - scroll_printstr(scene, fac, h, fac2, grid->powerx, V2D_UNIT_SECONDS, 'h'); - break; - - 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 */ - scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_DEGREES, 'v'); - break; - } - } - - BLF_batch_draw_end(); + { + if (scroll & V2D_SCROLL_SCALE_HORIZONTAL) { + UI_view2d_grid_draw_numbers_horizontal( + CTX_data_scene(C), v2d, vs->grid, &vs->hor, vs->xunits, vs->xclamp == V2D_GRID_CLAMP); } } } @@ -2112,51 +2121,14 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v UI_draw_widget_scroll(&wcol, &vert, &slider, state); - - /* scale indiators */ - if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) { - View2DGrid *grid = vs->grid; - float fac, dfac, val; - - /* the numbers: convert grid->starty and dy to scroll coordinates - * - fac is y-coordinate to draw to - * - dfac is gap between scale markings - * - these involve a correction for horizontal scrollbar - * NOTE: it's assumed that that scrollbar is there if this is involved! - */ - fac = (grid->starty - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur); - fac = vert.ymin + fac * BLI_rcti_size_y(&vert); - - dfac = grid->dy / BLI_rctf_size_y(&v2d->cur); - dfac = dfac * BLI_rcti_size_y(&vert); - - /* set starting value, and text color */ - const int font_id = BLF_default(); - UI_FontThemeColor(font_id, TH_TEXT); - val = grid->starty; - - /* if vertical clamping (to whole numbers) is used (i.e. in Sequencer), - * apply correction */ - if (vs->yclamp == V2D_GRID_CLAMP) { - fac += 0.5f * dfac; - } - - /* draw vertical steps */ - if (dfac > 0.0f) { - BLF_rotation(font_id, M_PI_2); - BLF_enable(font_id, BLF_ROTATION); - - for (; fac < vert.ymax - 10; fac += dfac, val += grid->dy) { - - /* make prints look nicer for scrollers */ - if (fac < vert.ymin + 10) { - continue; - } - - scroll_printstr(scene, (float)(vert.xmax) - 2.0f, fac, val, grid->powery, vs->yunits, 'v'); + { + if (scroll & V2D_SCROLL_SCALE_VERTICAL) { + float text_offset = 0.0f; + if (vs->yclamp & V2D_GRID_CLAMP) { + text_offset = 0.5f; } - - BLF_disable(font_id, BLF_ROTATION); + UI_view2d_grid_draw_numbers_vertical( + CTX_data_scene(C), v2d, vs->grid, &vs->vert, vs->yunits, text_offset); } } } @@ -2519,12 +2491,20 @@ View2D *UI_view2d_fromcontext_rwin(const bContext *C) void UI_view2d_scale_get(View2D *v2d, float *r_x, float *r_y) { if (r_x) { - *r_x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur); + *r_x = UI_view2d_scale_get_x(v2d); } if (r_y) { - *r_y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur); + *r_y = UI_view2d_scale_get_y(v2d); } } +float UI_view2d_scale_get_x(const View2D *v2d) +{ + return BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur); +} +float UI_view2d_scale_get_y(const View2D *v2d) +{ + return BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur); +} /** * Same as ``UI_view2d_scale_get() - 1.0f / x, y`` */ |