Refactor grid and scale indicator text drawing
authorJacques Lucke <mail@jlucke.com>
Thu, 2 May 2019 10:00:12 +0000 (12:00 +0200)
committerJacques Lucke <mail@jlucke.com>
Thu, 2 May 2019 10:00:12 +0000 (12:00 +0200)
This affects the timeline, dopesheet, graph editor, sequencer,
clip editor and nla editor.

Removed structs and enums: `V2D_ARG_DUMMY`, `eView2D_Units`,
`eView2D_Clamp`, `eView2D_Gridlines`, `View2DGrid`.

A main goal of this refactor is to get rid of the very generic
`View2DGrid` struct. The drawing code became very complex
because there were many different combinations of settings.

This refactor implements a different approach.
Instead of one very generic API, there are many slighly
different functions that do exactly, what we need in the
different editors. Only very little code is duplicated,
because the API functions compose some shared low level code.

This structure makes the code much easier to debug and change,
because every function has much fewer responsibilities.

Additionally, this refactor fixes some long standing bugs.
E.g. when `Show Seconds` is enabled, you zoom in and pan the view.
Or that the step size between displayed frame numbers was
always `>= 2`, no matter how close you zoom in.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D4776

13 files changed:
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/CMakeLists.txt
source/blender/editors/interface/view2d.c
source/blender/editors/interface/view2d_draw.c [new file with mode: 0644]
source/blender/editors/space_action/space_action.c
source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_graph/graph_draw.c
source/blender/editors/space_graph/graph_intern.h
source/blender/editors/space_graph/space_graph.c
source/blender/editors/space_nla/space_nla.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/transform/transform_snap.c

index fee1efcf25bb31c52fe7fe01ad0e04fb726d5066..07dbb49ac071ec41ede5993bcd237c5fb92b2c26 100644 (file)
@@ -56,40 +56,7 @@ enum eView2D_CommonViewTypes {
   V2D_COMMONVIEW_PANELS_UI,
 };
 
-/* ---- Defines for Scroller/Grid Arguments ----- */
-
-/* 'dummy' argument to pass when argument is irrelevant */
-#define V2D_ARG_DUMMY -1
-
-/* Grid units */
-enum eView2D_Units {
-  /* for drawing time */
-  V2D_UNIT_SECONDS = 0,
-  V2D_UNIT_FRAMES,
-  V2D_UNIT_FRAMESCALE,
-
-  /* for drawing values */
-  V2D_UNIT_VALUES,
-};
-
-/* clamping of grid values to whole numbers */
-enum eView2D_Clamp {
-  V2D_GRID_NOCLAMP = 0,
-  V2D_GRID_CLAMP,
-};
-
-/* flags for grid-lines to draw */
-enum eView2D_Gridlines {
-  V2D_HORIZONTAL_LINES = (1 << 0),
-  V2D_VERTICAL_LINES = (1 << 1),
-  V2D_HORIZONTAL_AXIS = (1 << 2),
-  V2D_VERTICAL_AXIS = (1 << 3),
-  V2D_HORIZONTAL_FINELINES = (1 << 4),
-
-  V2D_GRIDLINES_MAJOR = (V2D_VERTICAL_LINES | V2D_VERTICAL_AXIS | V2D_HORIZONTAL_LINES |
-                         V2D_HORIZONTAL_AXIS),
-  V2D_GRIDLINES_ALL = (V2D_GRIDLINES_MAJOR | V2D_HORIZONTAL_FINELINES),
-};
+/* ---- Defines for Scroller Arguments ----- */
 
 /* ------ Defines for Scrollers ----- */
 
@@ -124,7 +91,6 @@ enum eView2D_Gridlines {
 /* Type definitions:                          */
 
 struct View2D;
-struct View2DGrid;
 struct View2DScrollers;
 
 struct ARegion;
@@ -135,7 +101,6 @@ struct bScreen;
 struct rctf;
 struct wmKeyConfig;
 
-typedef struct View2DGrid View2DGrid;
 typedef struct View2DScrollers View2DScrollers;
 
 /* ----------------------------------------- */
@@ -159,37 +124,58 @@ bool UI_view2d_tab_set(struct View2D *v2d, int tab);
 void UI_view2d_zoom_cache_reset(void);
 
 /* view matrix operations */
-void UI_view2d_view_ortho(struct View2D *v2d);
+void UI_view2d_view_ortho(const struct View2D *v2d);
 void UI_view2d_view_orthoSpecial(struct ARegion *ar, struct View2D *v2d, const bool xaxis);
 void UI_view2d_view_restore(const struct bContext *C);
 
 /* grid drawing */
-View2DGrid *UI_view2d_grid_calc(struct Scene *scene,
-                                struct View2D *v2d,
-                                short xunits,
-                                short xclamp,
-                                short yunits,
-                                short yclamp,
-                                int winx,
-                                int winy);
-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);
+
+void UI_view2d_draw_lines_y__values(const struct View2D *v2d);
+void UI_view2d_draw_lines_x__values(const struct View2D *v2d);
+void UI_view2d_draw_lines_x__discrete_values(const struct View2D *v2d);
+void UI_view2d_draw_lines_x__discrete_time(const struct View2D *v2d, const struct Scene *scene);
+void UI_view2d_draw_lines_x__discrete_frames_or_seconds(const struct View2D *v2d,
+                                                        const struct Scene *scene,
+                                                        bool display_seconds);
+void UI_view2d_draw_lines_x__frames_or_seconds(const struct View2D *v2d,
+                                               const struct Scene *scene,
+                                               bool display_seconds);
+
+float UI_view2d_grid_resolution_x__frames_or_seconds(const struct View2D *v2d,
+                                                     const struct Scene *scene,
+                                                     bool display_seconds);
+float UI_view2d_grid_resolution_y__values(const struct View2D *v2d);
+
+/* scale indicator text drawing */
+void UI_view2d_draw_scale_y__values(const struct ARegion *ar,
+                                    const struct View2D *v2d,
+                                    const struct rcti *rect);
+void UI_view2d_draw_scale_y__block(const struct ARegion *ar,
+                                   const struct View2D *v2d,
+                                   const struct rcti *rect);
+void UI_view2d_draw_scale_x__values(const struct ARegion *ar,
+                                    const struct View2D *v2d,
+                                    const struct rcti *rect);
+void UI_view2d_draw_scale_x__discrete_values(const struct ARegion *ar,
+                                             const struct View2D *v2d,
+                                             const struct rcti *rect);
+void UI_view2d_draw_scale_x__discrete_time(const struct ARegion *ar,
+                                           const struct View2D *v2d,
+                                           const struct rcti *rect,
+                                           const struct Scene *scene);
+void UI_view2d_draw_scale_x__discrete_frames_or_seconds(const struct ARegion *ar,
+                                                        const struct View2D *v2d,
+                                                        const struct rcti *rect,
+                                                        const struct Scene *scene,
+                                                        bool display_seconds);
+void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *ar,
+                                               const struct View2D *v2d,
+                                               const struct rcti *rect,
+                                               const struct Scene *scene,
+                                               bool display_seconds);
 
 /* scrollbar drawing */
 View2DScrollers *UI_view2d_scrollers_calc(struct View2D *v2d, const struct rcti *mask_custom);
index 55a44b4d314348869c5514a4554c3cc3c81a970f..6ab1761e7f81c42fda353a86e708516860c2ae0b 100644 (file)
@@ -72,6 +72,7 @@ set(SRC
   interface_widgets.c
   resources.c
   view2d.c
+  view2d_draw.c
   view2d_ops.c
 
   interface_eyedropper_intern.h
index 072497dbb7435400a00b1d404b63c59d845dac49..58d26c4a840122fc29ccc6ccadb17088ccb1f00f 100644 (file)
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
+#include "BLI_array.h"
 #include "BLI_utildefines.h"
 #include "BLI_link_utils.h"
 #include "BLI_rect.h"
 #include "BLI_math.h"
 #include "BLI_memarena.h"
 #include "BLI_timecode.h"
+#include "BLI_string.h"
 
 #include "BKE_context.h"
 #include "BKE_screen.h"
@@ -1117,7 +1119,7 @@ void UI_view2d_zoom_cache_reset(void)
 /* View Matrix Setup */
 
 /* mapping function to ensure 'cur' draws extended over the area where sliders are */
-static void view2d_map_cur_using_mask(View2D *v2d, rctf *r_curmasked)
+static void view2d_map_cur_using_mask(const View2D *v2d, rctf *r_curmasked)
 {
   *r_curmasked = v2d->cur;
 
@@ -1149,7 +1151,7 @@ static void view2d_map_cur_using_mask(View2D *v2d, rctf *r_curmasked)
 }
 
 /* Set view matrices to use 'cur' rect as viewing frame for View2D drawing */
-void UI_view2d_view_ortho(View2D *v2d)
+void UI_view2d_view_ortho(const View2D *v2d)
 {
   rctf curmasked;
   const int sizex = BLI_rcti_size_x(&v2d->mask);
@@ -1238,337 +1240,6 @@ void UI_view2d_view_restore(const bContext *C)
 /* *********************************************************************** */
 /* Gridlines */
 
-/* View2DGrid is typedef'd in UI_view2d.h */
-struct View2DGrid {
-  float dx, dy;         /* stepsize (in pixels) between gridlines */
-  float startx, starty; /* initial coordinates to start drawing grid from */
-  int powerx, powery;   /* step as power of 10 */
-};
-
-/* --------------- */
-
-/* try to write step as a power of 10 */
-static void step_to_grid(float *step, const int unit, int *r_power)
-{
-  const float loga = (float)log10(*step);
-  float rem;
-
-  int power = (int)(loga);
-
-  rem = loga - power;
-  rem = (float)pow(10.0, rem);
-
-  if (loga < 0.0f) {
-    if (rem < 0.2f) {
-      rem = 0.2f;
-    }
-    else if (rem < 0.5f) {
-      rem = 0.5f;
-    }
-    else {
-      rem = 1.0f;
-    }
-
-    *step = rem * (float)pow(10.0, power);
-
-    /* for frames, we want 1.0 frame intervals only */
-    if (unit == V2D_UNIT_FRAMES) {
-      rem = 1.0f;
-      /* use 2 since there are grid lines drawn in between,
-       * this way to get 1 line per frame */
-      *step = 2.0f;
-    }
-
-    /* prevents printing 1.0 2.0 3.0 etc */
-    if (rem == 1.0f) {
-      power++;
-    }
-  }
-  else {
-    if (rem < 2.0f) {
-      rem = 2.0f;
-    }
-    else if (rem < 5.0f) {
-      rem = 5.0f;
-    }
-    else {
-      rem = 10.0f;
-    }
-
-    *step = rem * (float)pow(10.0, power);
-
-    power++;
-    /* prevents printing 1.0, 2.0, 3.0, etc. */
-    if (rem == 10.0f) {
-      power++;
-    }
-  }
-
-  *r_power = power;
-}
-
-/**
- * Initialize settings necessary for drawing gridlines in a 2d-view
- *
- * - Currently, will return pointer to View2DGrid struct that needs to
- *   be freed with UI_view2d_grid_free()
- * - Units + clamping args will be checked, to make sure they are valid values that can be used
- *   so it is very possible that we won't return grid at all!
- *
- * - xunits,yunits = V2D_UNIT_*  grid steps in seconds or frames
- * - xclamp,yclamp = V2D_CLAMP_* only show whole-number intervals
- * - winx          = width of region we're drawing to, note: not used but keeping for completeness.
- * - winy          = height of region we're drawing into
- */
-View2DGrid *UI_view2d_grid_calc(Scene *scene,
-                                View2D *v2d,
-                                short xunits,
-                                short xclamp,
-                                short yunits,
-                                short yclamp,
-                                int UNUSED(winx),
-                                int winy)
-{
-
-  View2DGrid *grid;
-  float space, seconddiv;
-
-  /* check that there are at least some workable args */
-  if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) && ELEM(V2D_ARG_DUMMY, yunits, yclamp)) {
-    return NULL;
-  }
-
-  /* grid here is allocated... */
-  grid = MEM_callocN(sizeof(View2DGrid), "View2DGrid");
-
-  /* rule: gridstep is minimal GRIDSTEP pixels */
-  if (xunits == V2D_UNIT_SECONDS) {
-    seconddiv = (float)(0.01 * FPS);
-  }
-  else {
-    seconddiv = 1.0f;
-  }
-
-  /* calculate x-axis grid scale (only if both args are valid) */
-  if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
-    space = BLI_rctf_size_x(&v2d->cur);
-
-    if (space != 0.0f) {
-      const float pixels = (float)BLI_rcti_size_x(&v2d->mask);
-      if (pixels != 0.0f) {
-        grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels);
-        step_to_grid(&grid->dx, xunits, &grid->powerx);
-        grid->dx *= seconddiv;
-      }
-    }
-
-    if (xclamp == V2D_GRID_CLAMP) {
-      CLAMP_MIN(grid->dx, 0.1f);
-      CLAMP_MIN(grid->powerx, 0);
-      grid->powerx -= 2;
-    }
-  }
-
-  /* calculate y-axis grid scale (only if both args are valid) */
-  if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
-    space = BLI_rctf_size_y(&v2d->cur);
-    if (space != 0.0f) {
-      const float pixels = (float)winy;
-      if (pixels != 0.0f) {
-        grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels;
-        step_to_grid(&grid->dy, yunits, &grid->powery);
-      }
-    }
-
-    if (yclamp == V2D_GRID_CLAMP) {
-      CLAMP_MIN(grid->dy, 1.0f);
-      CLAMP_MIN(grid->powery, 1);
-    }
-  }
-
-  /* calculate start position */
-  if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
-    grid->startx = seconddiv * (v2d->cur.xmin / seconddiv -
-                                (float)fmod(v2d->cur.xmin / seconddiv, grid->dx / seconddiv));
-    if (v2d->cur.xmin < 0.0f) {
-      grid->startx -= grid->dx;
-    }
-  }
-  else {
-    grid->startx = v2d->cur.xmin;
-  }
-
-  if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
-    grid->starty = (v2d->cur.ymin - (float)fmod(v2d->cur.ymin, grid->dy));
-    if (v2d->cur.ymin < 0.0f) {
-      grid->starty -= grid->dy;
-    }
-  }
-  else {
-    grid->starty = v2d->cur.ymin;
-  }
-
-  return grid;
-}
-
-/* Draw gridlines in the given 2d-region */
-void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
-{
-  float vec1[2], vec2[2];
-  int a, step;
-  int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
-  int horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) /
-                              (U.v2d_min_gridsize * UI_DPI_FAC);
-  uchar grid_line_color[3];
-
-  /* check for grid first, as it may not exist */
-  if (grid == NULL) {
-    return;
-  }
-
-  /* Count the needed vertices for the gridlines */
-  unsigned vertex_count = 0;
-  if (flag & V2D_VERTICAL_LINES) {
-    /* vertical lines */
-    vertex_count += 2 * vertical_minor_step;       /* minor gridlines */
-    vertex_count += 2 * (vertical_minor_step + 2); /* major gridlines */
-  }
-  if (flag & V2D_HORIZONTAL_LINES) {
-    /* horizontal lines */
-    vertex_count += 2 * (horizontal_major_step + 1); /* major gridlines */
-
-    /* fine lines */
-    if (flag & V2D_HORIZONTAL_FINELINES) {
-      vertex_count += 2 * (horizontal_major_step + 1);
-    }
-  }
-  /* axes */
-  if (flag & V2D_HORIZONTAL_AXIS) {
-    vertex_count += 2;
-  }
-  if (flag & V2D_VERTICAL_AXIS) {
-    vertex_count += 2;
-  }
-
-  /* If there is nothing to render, exit early */
-  if (vertex_count == 0) {
-    return;
-  }
-
-  GPUVertFormat *format = immVertexFormat();
-  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-  uint color = GPU_vertformat_attr_add(
-      format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
-  immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-  immBegin(GPU_PRIM_LINES, vertex_count);
-
-  /* vertical lines */
-  if (flag & V2D_VERTICAL_LINES) {
-    /* initialize initial settings */
-    vec1[0] = vec2[0] = grid->startx;
-    vec1[1] = grid->starty;
-    vec2[1] = v2d->cur.ymax;
-
-    /* minor gridlines */
-    step = vertical_minor_step;
-    if (step != 0) {
-      UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
-
-      for (a = 0; a < step; a++) {
-        immAttrSkip(color);
-        immVertex2fv(pos, vec1);
-        immAttr3ubv(color, grid_line_color);
-        immVertex2fv(pos, vec2);
-
-        vec2[0] = vec1[0] += grid->dx;
-      }
-    }
-
-    /* major gridlines */
-    vec2[0] = vec1[0] -= 0.5f * grid->dx;
-
-    UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
-
-    step++;
-    for (a = 0; a <= step; a++) {
-      immAttrSkip(color);
-      immVertex2fv(pos, vec1);
-      immAttr3ubv(color, grid_line_color);
-      immVertex2fv(pos, vec2);
-
-      vec2[0] = vec1[0] -= grid->dx;
-    }
-  }
-
-  /* horizontal lines */
-  if (flag & V2D_HORIZONTAL_LINES) {
-    /* only major gridlines */
-    vec1[1] = vec2[1] = grid->starty;
-    vec1[0] = grid->startx;
-    vec2[0] = v2d->cur.xmax;
-
-    step = horizontal_major_step;
-
-    UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
-
-    for (a = 0; a <= step; a++) {
-      immAttrSkip(color);
-      immVertex2fv(pos, vec1);
-      immAttr3ubv(color, grid_line_color);
-      immVertex2fv(pos, vec2);
-
-      vec2[1] = vec1[1] += grid->dy;
-    }
-
-    /* fine grid lines */
-    vec2[1] = vec1[1] -= 0.5f * grid->dy;
-    step++;
-
-    if (flag & V2D_HORIZONTAL_FINELINES) {
-      UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
-      for (a = 0; a < step; a++) {
-        immAttrSkip(color);
-        immVertex2fv(pos, vec1);
-        immAttr3ubv(color, grid_line_color);
-        immVertex2fv(pos, vec2);
-
-        vec2[1] = vec1[1] -= grid->dy;
-      }
-    }
-  }
-
-  /* Axes are drawn as darker lines */
-  UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color);
-
-  /* horizontal axis */
-  if (flag & V2D_HORIZONTAL_AXIS) {
-    vec1[0] = v2d->cur.xmin;
-    vec2[0] = v2d->cur.xmax;
-    vec1[1] = vec2[1] = 0.0f;
-
-    immAttrSkip(color);
-    immVertex2fv(pos, vec1);
-    immAttr3ubv(color, grid_line_color);
-    immVertex2fv(pos, vec2);
-  }
-
-  /* vertical axis */
-  if (flag & V2D_VERTICAL_AXIS) {
-    vec1[1] = v2d->cur.ymin;
-    vec2[1] = v2d->cur.ymax;
-    vec1[0] = vec2[0] = 0.0f;
-
-    immAttrSkip(color);
-    immVertex2fv(pos, vec1);
-    immAttr3ubv(color, grid_line_color);
-    immVertex2fv(pos, vec2);
-  }
-
-  immEnd();
-  immUnbindProgram();
-}
-
 /* Draw a constant grid in given 2d-region */
 void UI_view2d_constant_grid_draw(View2D *v2d, float step)
 {
@@ -1726,135 +1397,6 @@ 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 + 4 * 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)
-{
-  *r_dx = grid->dx;
-  *r_dy = grid->dy;
-}
-
-/* free temporary memory used for drawing grid */
-void UI_view2d_grid_free(View2DGrid *grid)
-{
-  /* only free if there's a grid */
-  if (grid) {
-    MEM_freeN(grid);
-  }
-}
-
 /* *********************************************************************** */
 /* Scrollers */
 
diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c
new file mode 100644 (file)
index 0000000..91128e4
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup edinterface
+ */
+
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_array.h"
+#include "BLI_utildefines.h"
+#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_timecode.h"
+#include "BLI_string.h"
+
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+
+#include "WM_api.h"
+
+#include "BLF_api.h"
+
+#include "UI_interface.h"
+#include "UI_view2d.h"
+
+#include "interface_intern.h"
+
+/* Compute display grid resolution
+ ********************************************************/
+
+#define MIN_MAJOR_LINE_DISTANCE (UI_DPI_FAC * 50)
+
+static float select_major_distance(const float *possible_distances,
+                                   uint amount,
+                                   float pixel_width,
+                                   float view_width)
+{
+  BLI_assert(amount >= 1);
+
+  if (IS_EQF(view_width, 0.0f)) {
+    return possible_distances[0];
+  }
+
+  float pixels_per_view_unit = pixel_width / view_width;
+
+  for (uint i = 0; i < amount; i++) {
+    float distance = possible_distances[i];
+    if (pixels_per_view_unit * distance >= MIN_MAJOR_LINE_DISTANCE) {
+      return distance;
+    }
+  }
+  return possible_distances[amount - 1];
+}
+
+static const float discrete_value_scales[] = {
+    1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000};
+
+static const float continuous_value_scales[] = {0.01, 0.02, 0.05,  0.1,   0.2,   0.5,   1,   2,
+                                                5,    10,   20,    50,    100,   200,   500, 1000,
+                                                2000, 5000, 10000, 20000, 50000, 100000};
+
+static uint view2d_major_step_x__discrete(const View2D *v2d)
+{
+  return select_major_distance(discrete_value_scales,
+                               ARRAY_SIZE(discrete_value_scales),
+                               BLI_rcti_size_x(&v2d->mask),
+                               BLI_rctf_size_x(&v2d->cur));
+}
+
+static float view2d_major_step_x__continuous(const View2D *v2d)
+{
+  return select_major_distance(continuous_value_scales,
+                               ARRAY_SIZE(continuous_value_scales),
+                               BLI_rcti_size_x(&v2d->mask),
+                               BLI_rctf_size_x(&v2d->cur));
+}
+
+static float view2d_major_step_y__continuous(const View2D *v2d)
+{
+  return select_major_distance(continuous_value_scales,
+                               ARRAY_SIZE(continuous_value_scales),
+                               BLI_rcti_size_y(&v2d->mask),
+                               BLI_rctf_size_y(&v2d->cur));
+}
+
+static float view2d_major_step_x__time(const View2D *v2d, const Scene *scene)
+{
+  double fps = FPS;
+
+  float *possible_distances = NULL;
+  BLI_array_staticdeclare(possible_distances, 32);
+
+  for (uint step = 1; step < fps; step *= 2) {
+    BLI_array_append(possible_distances, step);
+  }
+  BLI_array_append(possible_distances, fps);
+  BLI_array_append(possible_distances, 2 * fps);
+  BLI_array_append(possible_distances, 5 * fps);
+  BLI_array_append(possible_distances, 10 * fps);
+  BLI_array_append(possible_distances, 30 * fps);
+  BLI_array_append(possible_distances, 60 * fps);
+  BLI_array_append(possible_distances, 2 * 60 * fps);
+  BLI_array_append(possible_distances, 5 * 60 * fps);
+  BLI_array_append(possible_distances, 10 * 60 * fps);
+  BLI_array_append(possible_distances, 30 * 60 * fps);
+  BLI_array_append(possible_distances, 60 * 60 * fps);
+
+  float distance = select_major_distance(possible_distances,
+                                         BLI_array_len(possible_distances),
+                                         BLI_rcti_size_x(&v2d->mask),
+                                         BLI_rctf_size_x(&v2d->cur));
+
+  BLI_array_free(possible_distances);
+  return distance;
+}
+
+/* Draw parallel lines
+ ************************************/
+
+typedef struct ParallelLinesSet {
+  float offset;
+  float distance;
+} ParallelLinesSet;
+
+static void get_parallel_lines_draw_steps(const ParallelLinesSet *lines,
+                                          float region_start,
+                                          float region_end,
+                                          float *r_first,
+                                          uint *r_steps)
+{
+  BLI_assert(lines->distance > 0);
+  BLI_assert(region_start <= region_end);
+
+  *r_first = ceilf((region_start - lines->offset) / lines->distance) * lines->distance +
+             lines->offset;
+
+  if (region_start <= *r_first && region_end >= *r_first) {
+    *r_steps = MAX2(0, floorf((region_end - *r_first) / lines->distance)) + 1;
+  }
+  else {
+    *r_steps = 0;
+  }
+}
+
+static void draw_parallel_lines(const ParallelLinesSet *lines,
+                                const rctf *rect,
+                                const uchar *color,
+                                char direction)
+{
+  float first;
+  uint steps;
+
+  if (direction == 'v') {
+    get_parallel_lines_draw_steps(lines, rect->xmin, rect->xmax, &first, &steps);
+  }
+  else {
+    BLI_assert(direction == 'h');
+    get_parallel_lines_draw_steps(lines, rect->ymin, rect->ymax, &first, &steps);
+  }
+
+  if (steps == 0) {
+    return;
+  }
+
+  GPUVertFormat *format = immVertexFormat();
+  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+  immUniformColor3ubv(color);
+  immBegin(GPU_PRIM_LINES, steps * 2);
+
+  if (direction == 'v') {
+    for (uint i = 0; i < steps; i++) {
+      float xpos = first + i * lines->distance;
+      immVertex2f(pos, xpos, rect->ymin);
+      immVertex2f(pos, xpos, rect->ymax);
+    }
+  }
+  else {
+    for (uint i = 0; i < steps; i++) {
+      float ypos = first + i * lines->distance;
+      immVertex2f(pos, rect->xmin, ypos);
+      immVertex2f(pos, rect->xmax, ypos);
+    }
+  }
+
+  immEnd();
+  immUnbindProgram();
+}
+
+static void view2d_draw_lines_internal(const View2D *v2d,
+                                       const ParallelLinesSet *lines,
+                                       const uchar *color,
+                                       char direction)
+{
+  GPU_matrix_push_projection();
+  UI_view2d_view_ortho(v2d);
+  draw_parallel_lines(lines, &v2d->cur, color, direction);
+  GPU_matrix_pop_projection();
+}
+
+static void view2d_draw_lines(const View2D *v2d,
+                              float major_distance,
+                              bool display_minor_lines,
+                              char direction)
+{
+  uchar major_color[3];
+  uchar minor_color[3];
+  UI_GetThemeColor3ubv(TH_GRID, major_color);
+  UI_GetThemeColorShade3ubv(TH_GRID, 16, minor_color);
+
+  ParallelLinesSet major_lines;
+  major_lines.distance = major_distance;
+  major_lines.offset = 0;
+  view2d_draw_lines_internal(v2d, &major_lines, major_color, direction);
+
+  if (display_minor_lines) {
+    ParallelLinesSet minor_lines;
+    minor_lines.distance = major_distance;
+    minor_lines.offset = major_distance / 2.0f;
+    view2d_draw_lines_internal(v2d, &minor_lines, minor_color, direction);
+  }
+}
+
+/* Scale indicator text drawing
+ **************************************************/
+
+typedef void (*PositionToString)(
+    void *user_data, float v2d_pos, float v2d_step, uint max_len, char *r_str);
+
+static void draw_horizontal_scale_indicators(const ARegion *ar,
+                                             const View2D *v2d,
+                                             float distance,
+                                             const rcti *rect,
+                                             PositionToString to_string,
+                                             void *to_string_data)
+{
+  GPU_matrix_push_projection();
+  wmOrtho2_region_pixelspace(ar);
+
+  float start;
+  uint steps;
+  {
+    ParallelLinesSet lines;
+    lines.distance = distance;
+    lines.offset = 0;
+    get_parallel_lines_draw_steps(&lines,
+                                  UI_view2d_region_to_view_x(v2d, rect->xmin),
+                                  UI_view2d_region_to_view_x(v2d, rect->xmax),
+                                  &start,
+                                  &steps);
+  }
+
+  const int font_id = BLF_default();
+  UI_FontThemeColor(font_id, TH_TEXT);
+
+  BLF_batch_draw_begin();
+
+  float ypos = rect->ymin + 4 * UI_DPI_FAC;
+  float xmin = rect->xmin;
+  float xmax = rect->xmax;
+
+  for (uint i = 0; i < steps; i++) {
+    float xpos_view = start + i * distance;
+    float xpos_region = UI_view2d_view_to_region_x(v2d, xpos_view);
+    char text[32];
+    to_string(to_string_data, xpos_view, distance, sizeof(text), text);
+    float text_width = BLF_width(font_id, text, strlen(text));
+
+    if (xpos_region - text_width / 2.0f >= xmin && xpos_region + text_width / 2.0f <= xmax) {
+      BLF_draw_default_ascii(xpos_region - text_width / 2.0f, ypos, 0.0f, text, sizeof(text));
+    }
+  }
+
+  BLF_batch_draw_end();
+
+  GPU_matrix_pop_projection();
+}
+
+static void draw_vertical_scale_indicators(const ARegion *ar,
+                                           const View2D *v2d,
+                                           float distance,
+                                           float display_offset,
+                                           const rcti *rect,
+                                           PositionToString to_string,
+                                           void *to_string_data)
+{
+  GPU_matrix_push_projection();
+  wmOrtho2_region_pixelspace(ar);
+
+  float start;
+  uint steps;
+  {
+    ParallelLinesSet lines;
+    lines.distance = distance;
+    lines.offset = 0;
+    get_parallel_lines_draw_steps(&lines,
+                                  UI_view2d_region_to_view_y(v2d, rect->ymin),
+                                  UI_view2d_region_to_view_y(v2d, rect->ymax),
+                                  &start,
+                                  &steps);
+  }
+
+  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);
+
+  BLF_batch_draw_begin();
+
+  float xpos = rect->xmax - 2.0f * UI_DPI_FAC;
+  float ymin = rect->ymin;
+  float ymax = rect->ymax;
+
+  for (uint i = 0; i < steps; i++) {
+    float ypos_view = start + i * distance;
+    float ypos_region = UI_view2d_view_to_region_y(v2d, ypos_view + display_offset);
+    char text[32];
+    to_string(to_string_data, ypos_view, distance, sizeof(text), text);
+    float text_width = BLF_width(font_id, text, strlen(text));
+
+    if (ypos_region - text_width / 2.0f >= ymin && ypos_region + text_width / 2.0f <= ymax) {
+      BLF_draw_default_ascii(xpos, ypos_region - text_width / 2.0f, 0.0f, text, sizeof(text));
+    }
+  }
+
+  BLF_batch_draw_end();
+  BLF_disable(font_id, BLF_ROTATION);
+
+  GPU_matrix_pop_projection();
+}
+
+static void view_to_string__frame_number(
+    void *UNUSED(user_data), float v2d_pos, float UNUSED(v2d_step), uint max_len, char *r_str)
+{
+  BLI_snprintf(r_str, max_len, "%d", (int)v2d_pos);
+}
+
+static void view_to_string__time(
+    void *user_data, float v2d_pos, float UNUSED(v2d_step), uint max_len, char *r_str)
+{
+  const Scene *scene = (const Scene *)user_data;
+
+  int brevity_level = 0;
+  BLI_timecode_string_from_time(
+      r_str, max_len, brevity_level, v2d_pos / (float)FPS, FPS, U.timecode_style);
+}
+
+static void view_to_string__value(
+    void *UNUSED(user_data), float v2d_pos, float v2d_step, uint max_len, char *r_str)
+{
+  if (v2d_step >= 1.0f) {
+    BLI_snprintf(r_str, max_len, "%d", (int)v2d_pos);
+  }
+  else if (v2d_step >= 0.1f) {
+    BLI_snprintf(r_str, max_len, "%.1f", v2d_pos);
+  }
+  else if (v2d_step >= 0.01f) {
+    BLI_snprintf(r_str, max_len, "%.2f", v2d_pos);
+  }
+  else {
+    BLI_snprintf(r_str, max_len, "%.3f", v2d_pos);
+  }
+}
+
+/* Grid Resolution API
+ **************************************************/
+
+float UI_view2d_grid_resolution_x__frames_or_seconds(const struct View2D *v2d,
+                                                     const struct Scene *scene,
+                                                     bool display_seconds)
+{
+  if (display_seconds) {
+    return view2d_major_step_x__time(v2d, scene);
+  }
+  else {
+    return view2d_major_step_x__continuous(v2d);
+  }
+}
+
+float UI_view2d_grid_resolution_y__values(const struct View2D *v2d)
+{
+  return view2d_major_step_y__continuous(v2d);
+}
+
+/* Line Drawing API
+ **************************************************/
+
+void UI_view2d_draw_lines_x__discrete_values(const View2D *v2d)
+{
+  uint major_line_distance = view2d_major_step_x__discrete(v2d);
+  view2d_draw_lines(v2d, major_line_distance, major_line_distance > 1, 'v');
+}
+
+void UI_view2d_draw_lines_x__values(const View2D *v2d)
+{
+  float major_line_distance = view2d_major_step_x__continuous(v2d);
+  view2d_draw_lines(v2d, major_line_distance, true, 'v');
+}
+
+void UI_view2d_draw_lines_y__values(const View2D *v2d)
+{
+  float major_line_distance = view2d_major_step_y__continuous(v2d);
+  view2d_draw_lines(v2d, major_line_distance, true, 'h');
+}
+
+void UI_view2d_draw_lines_x__discrete_time(const View2D *v2d, const Scene *scene)
+{
+  float major_line_distance = view2d_major_step_x__time(v2d, scene);
+  view2d_draw_lines(v2d, major_line_distance, major_line_distance > 1, 'v');
+}
+
+void UI_view2d_draw_lines_x__discrete_frames_or_seconds(const View2D *v2d,
+                                                        const Scene *scene,
+                                                        bool display_seconds)
+{
+  if (display_seconds) {
+    UI_view2d_draw_lines_x__discrete_time(v2d, scene);
+  }
+  else {
+    UI_view2d_draw_lines_x__discrete_values(v2d);
+  }
+}
+
+void UI_view2d_draw_lines_x__frames_or_seconds(const View2D *v2d,
+                                               const Scene *scene,
+                                               bool display_seconds)
+{
+  if (display_seconds) {
+    UI_view2d_draw_lines_x__discrete_time(v2d, scene);
+  }
+  else {
+    UI_view2d_draw_lines_x__values(v2d);
+  }
+}
+
+/* Scale indicator text drawing API
+ **************************************************/
+
+void UI_view2d_draw_scale_x__discrete_values(const ARegion *ar,
+                                             const View2D *v2d,
+                                             const rcti *rect)
+{
+  float number_step = view2d_major_step_x__discrete(v2d);
+  draw_horizontal_scale_indicators(ar, v2d, number_step, rect, view_to_string__frame_number, NULL);
+}
+
+void UI_view2d_draw_scale_x__discrete_time(const ARegion *ar,
+                                           const View2D *v2d,
+                                           const rcti *rect,
+                                           const Scene *scene)
+{
+  float step = view2d_major_step_x__time(v2d, scene);
+  draw_horizontal_scale_indicators(ar, v2d, step, rect, view_to_string__time, (void *)scene);
+}
+
+void UI_view2d_draw_scale_x__values(const ARegion *ar, const View2D *v2d, const rcti *rect)
+{
+  float step = view2d_major_step_x__continuous(v2d);
+  draw_horizontal_scale_indicators(ar, v2d, step, rect, view_to_string__value, NULL);
+}
+
+void UI_view2d_draw_scale_y__values(const ARegion *ar, const View2D *v2d, const rcti *rect)
+{
+  float step = view2d_major_step_y__continuous(v2d);
+  draw_vertical_scale_indicators(ar, v2d, step, 0.0f, rect, view_to_string__value, NULL);
+}
+
+void UI_view2d_draw_scale_y__block(const ARegion *ar, const View2D *v2d, const rcti *rect)
+{
+  draw_vertical_scale_indicators(ar, v2d, 1.0f, 0.5f, rect, view_to_string__value, NULL);
+}
+
+void UI_view2d_draw_scale_x__discrete_frames_or_seconds(const struct ARegion *ar,
+                                                        const struct View2D *v2d,
+                                                        const struct rcti *rect,
+                                                        const struct Scene *scene,
+                                                        bool display_seconds)
+{
+  if (display_seconds) {
+    UI_view2d_draw_scale_x__discrete_time(ar, v2d, rect, scene);
+  }
+  else {
+    UI_view2d_draw_scale_x__discrete_values(ar, v2d, rect);
+  }
+}
+
+void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *ar,
+                                               const struct View2D *v2d,
+                                               const struct rcti *rect,
+                                               const struct Scene *scene,
+                                               bool display_seconds)
+{
+  if (display_seconds) {
+    UI_view2d_draw_scale_x__discrete_time(ar, v2d, rect, scene);
+  }
+  else {
+    UI_view2d_draw_scale_x__values(ar, v2d, rect);
+  }
+}
index e802ef8d01069567b3900d636e62c0daf8d64fad..843abbd16db3d5e11d2b14707b355fc9835d7aa2 100644 (file)
@@ -179,11 +179,9 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
   Object *obact = CTX_data_active_object(C);
   bAnimContext ac;
   View2D *v2d = &ar->v2d;
-  View2DGrid *grid;
   View2DScrollers *scrollers;
   short marker_flag = 0;
   short cfra_flag = 0;
-  short unit = 0;
 
   /* clear and setup matrix */
   UI_ThemeClearColor(TH_BACK);
@@ -192,16 +190,7 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_view_ortho(v2d);
 
   /* time grid */
-  unit = (saction->flag & SACTION_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
-  grid = UI_view2d_grid_calc(CTX_data_scene(C),
-                             v2d,
-                             unit,
-                             V2D_GRID_CLAMP,
-                             V2D_ARG_DUMMY,
-                             V2D_ARG_DUMMY,
-                             ar->winx,
-                             ar->winy);
-  UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+  UI_view2d_draw_lines_x__discrete_frames_or_seconds(v2d, scene, saction->flag & SACTION_DRAWTIME);
 
   ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
 
@@ -251,8 +240,8 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_scrollers_free(scrollers);
 
   /* frame numbers */
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unit, true);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+      ar, v2d, &v2d->hor, scene, saction->flag & SACTION_DRAWTIME);
 
   /* draw current frame number-indicator on top of scrollers */
   if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
index 8a5f48d11d27c6396597e188b88d3f61948f7e1e..ef5de1acee311b896b92e991d70d2a7a3629527c 100644 (file)
@@ -339,14 +339,10 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
 {
   MovieClip *clip = ED_space_clip_get_clip(sc);
   View2D *v2d = &ar->v2d;
-  View2DGrid *grid;
-  short unitx = V2D_UNIT_FRAMESCALE, unity = V2D_UNIT_VALUES;
 
   /* grid */
-  grid = UI_view2d_grid_calc(
-      scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
-  UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_lines_x__values(v2d);
+  UI_view2d_draw_lines_y__values(v2d);
 
   if (clip) {
     uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
index c411f9d4e045bd9640259ef7e9ba333e492d0e2b..542f99e49eebb1d81a14d7a4275a4a6919f53f44 100644 (file)
@@ -1047,13 +1047,9 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_scrollers_free(scrollers);
 
   /* scale indicators */
-  short unitx = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
-  short unity = V2D_UNIT_VALUES;
-  View2DGrid *grid = UI_view2d_grid_calc(
-      scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unitx, false);
-  UI_view2d_grid_draw_numbers_vertical(scene, v2d, grid, &v2d->vert, unity, 0.0);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+      ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS);
+  UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert);
 
   /* current frame indicator */
   if (sc->flag & SC_SHOW_SECONDS) {
@@ -1069,9 +1065,8 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
   SpaceClip *sc = CTX_wm_space_clip(C);
   MovieClip *clip = ED_space_clip_get_clip(sc);
   View2D *v2d = &ar->v2d;
-  View2DGrid *grid;
   View2DScrollers *scrollers;
-  short unit = 0, cfra_flag = 0;
+  short cfra_flag = 0;
 
   if (clip) {
     BKE_tracking_dopesheet_update(&clip->tracking);
@@ -1084,10 +1079,7 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_view_ortho(v2d);
 
   /* time grid */
-  unit = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
-  grid = UI_view2d_grid_calc(
-      scene, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
-  UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+  UI_view2d_draw_lines_x__discrete_frames_or_seconds(v2d, scene, sc->flag & SC_SHOW_SECONDS);
 
   /* data... */
   clip_draw_dopesheet_main(sc, ar, scene);
@@ -1107,8 +1099,8 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_scrollers_free(scrollers);
 
   /* frame numbers */
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unit, true);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+      ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS);
 
   /* current frame number indicator */
   UI_view2d_view_orthoSpecial(ar, v2d, 1);
index 5f118151a33c41d445fdb7b90c593930e2eeac40..dfc59a79c49583b54824d41523ffdbd1f3918e8e 100644 (file)
@@ -493,20 +493,18 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *ar, FCurve *fcu)
 /* Helper func - just draw the F-Curve by sampling the visible region
  * (for drawing curves with modifiers). */
 static void draw_fcurve_curve(
-    bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, View2DGrid *grid, unsigned int pos)
+    bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, unsigned int pos)
 {
   SpaceGraph *sipo = (SpaceGraph *)ac->sl;
   float samplefreq;
   float stime, etime;
   float unitFac, offset;
-  float dx, dy;
   short mapping_flag = ANIM_get_normalization_flags(ac);
   int i, n;
 
   /* when opening a blend file on a different sized screen or while dragging the toolbar this can
    * happen best just bail out in this case. */
-  UI_view2d_grid_size(grid, &dx, &dy);
-  if (dx <= 0.0f) {
+  if (UI_view2d_scale_get_x(v2d) <= 0.0f) {
     return;
   }
 
@@ -529,11 +527,11 @@ static void draw_fcurve_curve(
    * loop (i.e. too close to 0), then clamp it to a determined "safe" value. The value
    *  chosen here is just the coarsest value which still looks reasonable...
    */
-  /* grid->dx represents the number of 'frames' between gridlines,
-   * but we divide by U.v2d_min_gridsize to get pixels-steps */
+
   /* TODO: perhaps we should have 1.0 frames
    * as upper limit so that curves don't get too distorted? */
-  samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
+  float pixels_per_sample = 1.5f;
+  samplefreq = pixels_per_sample / UI_view2d_scale_get_x(v2d);
 
   if (sipo->flag & SIPO_BEAUTYDRAW_OFF) {
     /* Low Precision = coarse lower-bound clamping
@@ -1043,8 +1041,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *ar)
 /* This is called twice from space_graph.c -> graph_main_region_draw()
  * Unselected then selected F-Curves are drawn so that they do not occlude each other.
  */
-void graph_draw_curves(
-    bAnimContext *ac, SpaceGraph *sipo, ARegion *ar, View2DGrid *grid, short sel)
+void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *ar, short sel)
 {
   ListBase anim_data = {NULL, NULL};
   bAnimListElem *ale;
@@ -1131,7 +1128,7 @@ void graph_draw_curves(
         /* draw a curve affected by modifiers or only allowed to have integer values
          * by sampling it at various small-intervals over the visible region
          */
-        draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+        draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, shdr_pos);
       }
       else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
         /* just draw curve based on defined data (i.e. no modifiers) */
@@ -1140,7 +1137,7 @@ void graph_draw_curves(
             draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, shdr_pos);
           }
           else {
-            draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+            draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, shdr_pos);
           }
         }
         else if (fcu->fpt) {
index 606f4bc3fe356e57bed55788a365a431536bd476..6ec8e54dce956d1d32f4c4f1a0de2d7260a8295e 100644 (file)
@@ -28,7 +28,6 @@ struct ARegion;
 struct ARegionType;
 struct ScrArea;
 struct SpaceGraph;
-struct View2DGrid;
 struct bAnimContext;
 struct bAnimListElem;
 struct bContext;
@@ -42,7 +41,6 @@ void graph_draw_channel_names(struct bContext *C, struct bAnimContext *ac, struc
 void graph_draw_curves(struct bAnimContext *ac,
                        struct SpaceGraph *sipo,
                        struct ARegion *ar,
-                       struct View2DGrid *grid,
                        short sel);
 void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceGraph *sipo, struct ARegion *ar);
 
index d8e1b9d203553a127d387943a4fa254c4f875b06..86d0b961a31c035191f32661fbc0f7266489b185 100644 (file)
@@ -198,10 +198,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
   Scene *scene = CTX_data_scene(C);
   bAnimContext ac;
   View2D *v2d = &ar->v2d;
-  View2DGrid *grid;
   View2DScrollers *scrollers;
   float col[3];
-  short unitx = 0, unity = V2D_UNIT_VALUES, cfra_flag = 0;
+  short cfra_flag = 0;
 
   /* clear and setup matrix */
   UI_GetThemeColor3fv(TH_BACK, col);
@@ -211,18 +210,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_view_ortho(v2d);
 
   /* grid */
-  unitx = ((sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME)) ?
-              V2D_UNIT_SECONDS :
-              V2D_UNIT_FRAMESCALE;
-  grid = UI_view2d_grid_calc(CTX_data_scene(C),
-                             v2d,
-                             unitx,
-                             V2D_GRID_NOCLAMP,
-                             unity,
-                             V2D_GRID_NOCLAMP,
-                             ar->winx,
-                             ar->winy);
-  UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+  bool display_seconds = (sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME);
+  UI_view2d_draw_lines_x__frames_or_seconds(v2d, scene, display_seconds);
+  UI_view2d_draw_lines_y__values(v2d);
 
   ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
 
@@ -237,8 +227,8 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
     graph_draw_ghost_curves(&ac, sipo, ar);
 
     /* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
-    graph_draw_curves(&ac, sipo, ar, grid, 0);
-    graph_draw_curves(&ac, sipo, ar, grid, 1);
+    graph_draw_curves(&ac, sipo, ar, 0);
+    graph_draw_curves(&ac, sipo, ar, 1);
 
     /* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
     get_graph_keyframe_extents(
@@ -326,9 +316,8 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_scrollers_free(scrollers);
 
   /* scale numbers */
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unitx, false);
-  UI_view2d_grid_draw_numbers_vertical(scene, v2d, grid, &v2d->vert, unity, 0.0f);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__frames_or_seconds(ar, v2d, &v2d->hor, scene, display_seconds);
+  UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert);
 
   /* draw current frame number-indicator on top of scrollers */
   if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
index 6c5a046a0cb53e887b126f386d6624c036735eb3..b054f550c6c278f451e35f30b70ff70607773c99 100644 (file)
@@ -231,9 +231,8 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
   Scene *scene = CTX_data_scene(C);
   bAnimContext ac;
   View2D *v2d = &ar->v2d;
-  View2DGrid *grid;
   View2DScrollers *scrollers;
-  short unit = 0, cfra_flag = 0;
+  short cfra_flag = 0;
 
   /* clear and setup matrix */
   UI_ThemeClearColor(TH_BACK);
@@ -242,16 +241,7 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_view_ortho(v2d);
 
   /* time grid */
-  unit = (snla->flag & SNLA_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
-  grid = UI_view2d_grid_calc(CTX_data_scene(C),
-                             v2d,
-                             unit,
-                             V2D_GRID_CLAMP,
-                             V2D_ARG_DUMMY,
-                             V2D_ARG_DUMMY,
-                             ar->winx,
-                             ar->winy);
-  UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+  UI_view2d_draw_lines_x__discrete_frames_or_seconds(v2d, scene, snla->flag & SNLA_DRAWTIME);
 
   ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
 
@@ -300,8 +290,8 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
   UI_view2d_scrollers_free(scrollers);
 
   /* frame numbers */
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unit, true);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+      ar, v2d, &v2d->hor, scene, snla->flag & SNLA_DRAWTIME);
 
   /* draw current frame number-indicator on top of scrollers */
   if ((snla->flag & SNLA_NODRAWCFRANUM) == 0) {
index c8390b2a8ea1faccd56aa34489e283f822a2c79e..86bc315b994f7968494a1af8a60e319d89ee3a72 100644 (file)
@@ -1996,7 +1996,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
   SpaceSeq *sseq = CTX_wm_space_seq(C);
   View2D *v2d = &ar->v2d;
   View2DScrollers *scrollers;
-  short unit = 0, cfra_flag = 0;
+  short cfra_flag = 0;
   float col[3];
 
   /* clear and setup matrix */
@@ -2087,17 +2087,14 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
   UI_view2d_view_restore(C);
 
   /* scrollers */
-  unit = (sseq->flag & SEQ_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDS;
   scrollers = UI_view2d_scrollers_calc(v2d, NULL);
   UI_view2d_scrollers_draw(v2d, scrollers);
   UI_view2d_scrollers_free(scrollers);
 
   /* scale numbers */
-  View2DGrid *grid = UI_view2d_grid_calc(
-      scene, v2d, unit, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP, ar->winx, ar->winy);
-  UI_view2d_grid_draw_numbers_horizontal(scene, v2d, grid, &v2d->hor, unit, true);
-  UI_view2d_grid_draw_numbers_vertical(scene, v2d, grid, &v2d->vert, V2D_UNIT_VALUES, 0.5f);
-  UI_view2d_grid_free(grid);
+  UI_view2d_draw_scale_x__discrete_frames_or_seconds(
+      ar, v2d, &v2d->hor, scene, !(sseq->flag & SEQ_DRAWFRAMES));
+  UI_view2d_draw_scale_y__block(ar, v2d, &v2d->vert);
 
   /* draw current frame number-indicator on top of scrollers */
   if ((sseq->flag & SEQ_NO_DRAW_CFRANUM) == 0) {
index 7b978487177c140304e032bdd0a3351349b53203..58a50da9846700ba13625de039d8009226330e14 100644 (file)
@@ -1563,24 +1563,11 @@ static void applyGridIncrement(
     /* custom aspect for fcurve */
     if (t->spacetype == SPACE_GRAPH) {
       View2D *v2d = &t->ar->v2d;
-      View2DGrid *grid;
+      Scene *scene = t->scene;
       SpaceGraph *sipo = t->sa->spacedata.first;
-      int unity = V2D_UNIT_VALUES;
-      int unitx = (sipo->flag & SIPO_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
-
-      /* grid */
-      grid = UI_view2d_grid_calc(t->scene,
-                                 v2d,
-                                 unitx,
-                                 V2D_GRID_NOCLAMP,
-                                 unity,
-                                 V2D_GRID_NOCLAMP,
-                                 t->ar->winx,
-                                 t->ar->winy);
-
-      UI_view2d_grid_size(grid, &asp_local[0], &asp_local[1]);
-      UI_view2d_grid_free(grid);
-
+      asp_local[0] = UI_view2d_grid_resolution_x__frames_or_seconds(
+          v2d, scene, sipo->flag & SIPO_DRAWTIME);
+      asp_local[1] = UI_view2d_grid_resolution_y__values(v2d);
       asp = asp_local;
     }
   }